@akagilnc/pi-workflow-roles 0.1.5504 → 0.1.5575
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/README.zh-CN.md +1 -1
- package/dist/acp-host/production-host.js +5965 -5994
- package/dist/analyst-gate-cycles-read.js +23 -55
- package/dist/analyst-ledger.js +21 -35
- package/dist/analyst-metric-families/acceptance-success-rework.js +25 -1
- package/dist/analyst-metric-families/round-timeline.js +2 -5
- package/dist/archivist-record-pointer.js +38 -30
- package/dist/auditor-dossier-tool.js +4 -3
- package/dist/auditor-soul.js +3 -11
- package/dist/doctor-evidence.js +3 -3
- package/dist/engine-detour-usage.js +6 -14
- package/dist/headless-host/production-host.js +5316 -5324
- package/dist/host-descriptions.js +0 -4
- package/dist/host-session-record.js +266 -267
- package/dist/migrate-book-topology.js +1314 -696
- package/dist/notary-source-run.js +1 -1
- package/dist/packaged-role-registry.js +5 -44
- package/dist/pi/role-turn-host.js +53 -3
- package/dist/public-cli/auto-resume.js +8 -47
- package/dist/public-cli/instruction-seat-run.js +5 -3
- package/dist/public-cli/invocation.js +51 -56
- package/dist/public-cli/main.js +1916 -1748
- package/dist/public-cli/post-admission.js +96 -55
- package/dist/public-cli/run-lifecycle.js +27 -53
- package/dist/public-cli/settlement.js +157 -302
- package/dist/role-run-placement.js +1 -11
- package/dist/role-run-relocation.js +72 -50
- package/dist/run-dossier-files.js +30 -0
- package/dist/run-dossier.js +322 -0
- package/dist/run-terminal-artifacts.js +68 -197
- package/dist/run-ticket-number.js +16 -3
- package/dist/session-identity.js +49 -18
- package/dist/sitian-appender.js +13 -16
- package/dist/sitian-facade.js +11 -0
- package/dist/sitian-reader.js +44 -29
- package/dist/submission-gate.js +1 -1
- package/dist/ticket-provenance.js +22 -7
- package/package.json +1 -1
- package/scripts/build-package.mjs +2 -0
- package/src/acp-host/production-host.ts +1 -1
- package/src/acp-host/role-turn-host.ts +9 -2
- package/src/analyst-gate-cycles-read.ts +26 -60
- package/src/analyst-ledger.ts +27 -42
- package/src/analyst-metric-families/acceptance-success-rework.ts +24 -1
- package/src/analyst-metric-families/gate-cycles.ts +1 -1
- package/src/analyst-metric-families/round-timeline.ts +2 -5
- package/src/analyst-page.ts +3 -3
- package/src/archivist-record-entry.ts +2 -2
- package/src/archivist-record-pointer.ts +50 -36
- package/src/auditor-dossier-tool.ts +7 -5
- package/src/auditor-soul.ts +3 -9
- package/src/book-topology-migration-placement.ts +16 -3
- package/src/book-topology-record-class-migrators.ts +4 -2
- package/src/book-topology-runs-migrator.ts +6 -3
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-evidence.ts +2 -2
- package/src/engine-detour-tool.ts +1 -1
- package/src/engine-detour-usage.ts +6 -16
- package/src/external-host-turn-loop.ts +25 -0
- package/src/headless-host/production-host.ts +1 -4
- package/src/headless-host/role-turn-host.ts +54 -20
- package/src/host-descriptions.ts +0 -6
- package/src/host-session-record.ts +224 -140
- package/src/notary-source-run.ts +1 -1
- package/src/packaged-role-registry.ts +1 -50
- package/src/pi/adapter.ts +50 -7
- package/src/pi/role-turn-host.ts +51 -3
- package/src/public-cli/auto-resume.ts +7 -43
- package/src/public-cli/instruction-seat-run.ts +9 -2
- package/src/public-cli/invocation.ts +61 -87
- package/src/public-cli/post-admission.ts +111 -72
- package/src/public-cli/run-lifecycle.ts +27 -72
- package/src/public-cli/settlement.ts +193 -418
- package/src/public-cli/terminal.ts +1 -1
- package/src/role-run-placement.ts +2 -13
- package/src/role-run-relocation.ts +71 -68
- package/src/role-runtime.ts +6 -10
- package/src/run-dossier-files.ts +33 -0
- package/src/run-dossier.ts +357 -0
- package/src/run-terminal-artifacts.ts +83 -237
- package/src/run-ticket-number.ts +41 -11
- package/src/session-identity.ts +52 -20
- package/src/sitian-appender.ts +17 -18
- package/src/sitian-facade.ts +22 -0
- package/src/sitian-reader.ts +62 -32
- package/src/submission-gate.ts +1 -1
- package/src/ticket-provenance.ts +20 -7
- package/src/ticket-trajectory.ts +10 -10
|
@@ -13,10 +13,11 @@ import { CliUsageError } from "./cli-errors.js";
|
|
|
13
13
|
import { projectPublicTurnAxes } from "./turn-request.js";
|
|
14
14
|
import { bindAdmittedTicketNumber, buildInstructionTransportPrompt, freezeAttachmentsIntoRun, relocateAdmittedRunToTicket, } from "./invocation.js";
|
|
15
15
|
import { readRecordedSubmissionRows } from "../submission-ledger.js";
|
|
16
|
-
import { readDeclaredTicketNumber } from "../run-ticket-number.js";
|
|
16
|
+
import { parseTicketNumber, readDeclaredTicketNumber } from "../run-ticket-number.js";
|
|
17
17
|
import { pathContainedIn } from "../activation-ledger-topology.js";
|
|
18
18
|
import { pickEngineAxis } from "../package-resources/engine-material.js";
|
|
19
19
|
import { readStoredHostSessionId } from "../session-identity.js";
|
|
20
|
+
import { reportRunRecord } from "../sitian-facade.js";
|
|
20
21
|
import { createReceiptDeliveryPolicy, deliveryLimitFromConfig, } from "../receipt-delivery-policy.js";
|
|
21
22
|
import { rewriteRunDirectoryPathValue } from "../role-run-relocation.js";
|
|
22
23
|
import { isOfficerReviewSeat } from "../packaged-role-registry.js";
|
|
@@ -40,10 +41,9 @@ import { mintEngineDetourInvocationScope, withEngineDetourInvocationScope, } fro
|
|
|
40
41
|
import { clearCurrentCourt, describeErrorIdentity, markRunRunning, readCurrentCourt, recordCurrentCourt, } from "./run-lifecycle.js";
|
|
41
42
|
import { processCancelDiagnostic, processCancelSignalName, } from "./process-cancel.js";
|
|
42
43
|
import { DEFAULT_ROLE_TURN_HOST } from "../host-descriptions.js";
|
|
43
|
-
import { recordRunStart } from "../host-session-record.js";
|
|
44
44
|
import { classifyPostAdmissionFailure, exitCodeForTerminalOutcome, explicitInternalKnownFailureClassificationInput, formatCliDiagnostic, formatErrorCauseDetail, ledgerReadScope, isLawfulTypedTerminalOutcome, presentStructuralRejection, settleFailureTerminalResult, settleHostEndedNoReceipt, noteSettlementFault, attachRecordedSubmissions, retainPackageFault, } from "./settlement.js";
|
|
45
45
|
import {} from "./terminal.js";
|
|
46
|
-
import {
|
|
46
|
+
import { persistReturnedRunState, presentTerminal, runWithAutoResumeLoop, TurnDispatchedFailure, } from "./auto-resume.js";
|
|
47
47
|
import { isRecord, errorText } from "../unknown-value.js";
|
|
48
48
|
function projectRelocatedTurnIdentity(request, result, admitted, relocation) {
|
|
49
49
|
const rewrite = (value) => rewriteRunDirectoryPathValue(value, relocation.oldRunDirectory, relocation.newRunDirectory);
|
|
@@ -87,7 +87,7 @@ async function settleProcessCancelAfterTurn(input) {
|
|
|
87
87
|
? { knownDiagnostic: processCancelDiagnostic(input.cancelName) }
|
|
88
88
|
: { knownFailure: input.result.knownFailure }),
|
|
89
89
|
cancelName: input.cancelName,
|
|
90
|
-
}, input.invocationScopeId), input.adapters, input.env.principalAuthority, input.io, input.persistRunState, input.notePackageFault);
|
|
90
|
+
}, input.invocationScopeId), input.adapters, input.env.principalAuthority, input.io, input.persistRunState, input.notePackageFault, input.courtAttemptId);
|
|
91
91
|
return {
|
|
92
92
|
...failed,
|
|
93
93
|
turnDispatched: true,
|
|
@@ -170,7 +170,9 @@ export async function resolveResumeMethodMaterialAdapters(input) {
|
|
|
170
170
|
return { kind: "terminal", ...terminal };
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
export async function presentControlledFailure(admitted, failureInput, adapters, authority, io, persistRunState = true, notePackageFault
|
|
173
|
+
export async function presentControlledFailure(admitted, failureInput, adapters, authority, io, persistRunState = true, notePackageFault,
|
|
174
|
+
/** Open-court identity already on the turn request / currentCourt (#1161). */
|
|
175
|
+
courtAttemptId) {
|
|
174
176
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
175
177
|
const knownFailure = failureInput.knownFailure;
|
|
176
178
|
// knownFailure channel owns details when present; otherwise caller knownDetails.
|
|
@@ -231,6 +233,9 @@ export async function presentControlledFailure(admitted, failureInput, adapters,
|
|
|
231
233
|
const settled = await settleFailureTerminalResult(admitted, failure, authority, {
|
|
232
234
|
recordAttemptHistory: true,
|
|
233
235
|
...(notePackageFault === undefined ? {} : { notePackageFault }),
|
|
236
|
+
...(courtAttemptId === undefined || courtAttemptId.length === 0
|
|
237
|
+
? {}
|
|
238
|
+
: { courtAttemptId }),
|
|
234
239
|
...(failureInput.invocationScopeId === undefined ||
|
|
235
240
|
failureInput.invocationScopeId.length === 0
|
|
236
241
|
? {}
|
|
@@ -263,9 +268,9 @@ export async function presentControlledFailure(admitted, failureInput, adapters,
|
|
|
263
268
|
* the true cause through its own existing dispatch-exception machinery once
|
|
264
269
|
* the retry budget is exhausted.
|
|
265
270
|
*/
|
|
266
|
-
async function settleAfterTurnStarted(admitted, failureInput, adapters, authority, io, persistRunState, notePackageFault) {
|
|
271
|
+
async function settleAfterTurnStarted(admitted, failureInput, adapters, authority, io, persistRunState, notePackageFault, courtAttemptId) {
|
|
267
272
|
try {
|
|
268
|
-
return (await presentControlledFailure(admitted, failureInput, adapters, authority, io, persistRunState, notePackageFault));
|
|
273
|
+
return (await presentControlledFailure(admitted, failureInput, adapters, authority, io, persistRunState, notePackageFault, courtAttemptId));
|
|
269
274
|
}
|
|
270
275
|
catch (error) {
|
|
271
276
|
throw new TurnDispatchedFailure(error);
|
|
@@ -321,9 +326,9 @@ function settlementScopeForTurn(request) {
|
|
|
321
326
|
*
|
|
322
327
|
* The caller owns the live delivery policy; the request projects its next send.
|
|
323
328
|
*/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const
|
|
329
|
+
/** Bare in-call催交 resume: hostSessionId absent; adapter is the sole load authority. */
|
|
330
|
+
function buildReceiptDeliveryRequest(input) {
|
|
331
|
+
const { request, receiptDelivery } = input;
|
|
327
332
|
return {
|
|
328
333
|
...request,
|
|
329
334
|
continuation: {
|
|
@@ -332,7 +337,6 @@ async function buildReceiptDeliveryRequest(input) {
|
|
|
332
337
|
...receiptDelivery.deliveryState(),
|
|
333
338
|
deliveryTurns: receiptDelivery.issuedDeliveryRequests() + 1,
|
|
334
339
|
}),
|
|
335
|
-
...(hostSessionId === undefined ? {} : { hostSessionId }),
|
|
336
340
|
},
|
|
337
341
|
deliveryRequestLimit: receiptDelivery.limit,
|
|
338
342
|
};
|
|
@@ -378,19 +382,19 @@ async function settleCompletedHostTurn(input) {
|
|
|
378
382
|
// machinery once the retry budget is exhausted.
|
|
379
383
|
let stderrLogWriteFailure;
|
|
380
384
|
try {
|
|
381
|
-
|
|
385
|
+
reportRunRecord(admitted.runDirectory, "stderr", { text: result.stderr }, "post-admission");
|
|
382
386
|
}
|
|
383
387
|
catch (error) {
|
|
384
388
|
stderrLogWriteFailure = error;
|
|
385
|
-
// Best-effort: stderr
|
|
389
|
+
// Best-effort: the stderr log line is secondary to the host terminal. A write
|
|
386
390
|
// failure leaves a durable note and, on a host failure, rides in
|
|
387
391
|
// packageFact. It does not become the cause.
|
|
388
|
-
await recordBestEffortPostDispatchDiagnostic(admitted, env, `stderr
|
|
392
|
+
await recordBestEffortPostDispatchDiagnostic(admitted, env, `stderr log write failed (best-effort continue): ${describeErrorIdentity(error)}`, io);
|
|
389
393
|
}
|
|
390
394
|
// Host facts are resolved before trySettle. A host failure skips trySettle
|
|
391
395
|
// so a later read cannot replace that report. A clean host whose settlement
|
|
392
396
|
// read throws is noted above and is not turned into a failure terminal.
|
|
393
|
-
// stderr
|
|
397
|
+
// the stderr log line and run-state writes are notes beside the host terminal.
|
|
394
398
|
let settled;
|
|
395
399
|
let settledOutcome;
|
|
396
400
|
// The host CLI's own report: timeout, declared failure, cancel, or exit.
|
|
@@ -440,6 +444,9 @@ async function settleCompletedHostTurn(input) {
|
|
|
440
444
|
deferredPersist,
|
|
441
445
|
invocationScopeId: request.invocationScopeId,
|
|
442
446
|
notePackageFault: courtScope.notePackageFault,
|
|
447
|
+
...(courtScope.courtAttemptId === undefined
|
|
448
|
+
? {}
|
|
449
|
+
: { courtAttemptId: courtScope.courtAttemptId }),
|
|
443
450
|
})) };
|
|
444
451
|
}
|
|
445
452
|
if (persistRunState) {
|
|
@@ -476,11 +483,62 @@ async function settleCompletedHostTurn(input) {
|
|
|
476
483
|
// Secondary fact only — never the cause, and never merged into the
|
|
477
484
|
// host's own details.
|
|
478
485
|
...(stderrLogWriteFact === undefined ? {} : { packageFact: stderrLogWriteFact }),
|
|
479
|
-
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault);
|
|
486
|
+
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId);
|
|
480
487
|
return { kind: "settled", outcome: await finishAfterTurn(withProcessCancelSkipAutoResume({ ...failed, turnDispatched: true, ...deferredPersist }, env.signal)) };
|
|
481
488
|
}
|
|
482
489
|
return { kind: "still-missing" };
|
|
483
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* #858 / #1071: the first identifiable ticketNumber field declaration among the
|
|
493
|
+
* run's sealed rows files an unbound run (integer, digit string, or leading #N
|
|
494
|
+
* token). Terminal rows match settlement (#881): accepted and audit-escalation —
|
|
495
|
+
* an escalated submission still carries the original role params. Later
|
|
496
|
+
* receipts remain untouched; prose note/report is never consulted; this seam
|
|
497
|
+
* does not adjudicate a ticket change. Runs in the public call's own process
|
|
498
|
+
* (no role leg writes the run's current.json).
|
|
499
|
+
*/
|
|
500
|
+
export async function bindSealedTicketNumber(admitted) {
|
|
501
|
+
if (admitted.ticketNumber !== undefined)
|
|
502
|
+
return;
|
|
503
|
+
const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, ledgerReadScope(admitted));
|
|
504
|
+
let ticketNumber;
|
|
505
|
+
for (const row of rows) {
|
|
506
|
+
if (row.role !== admitted.role
|
|
507
|
+
|| (row.kind !== "accepted" && row.kind !== "audit-escalation")) {
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
const payload = row.accepted;
|
|
511
|
+
if (!isRecord(payload))
|
|
512
|
+
continue;
|
|
513
|
+
ticketNumber = readDeclaredTicketNumber(payload.ticketNumber);
|
|
514
|
+
if (ticketNumber !== undefined)
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
if (ticketNumber !== undefined)
|
|
518
|
+
await bindAdmittedTicketNumber(admitted, ticketNumber);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* The ticket a diarist asserted on a completed submission, whether or not the
|
|
522
|
+
* rest of that submission was later accepted (a bounds reask does not unsay the
|
|
523
|
+
* ticket). Before this ran in the leg's accept hook; the leg now only appends its
|
|
524
|
+
* ledger rows and the public call's own process binds the ticket from them.
|
|
525
|
+
*/
|
|
526
|
+
export async function bindDiaristAssertedTicketNumber(admitted) {
|
|
527
|
+
if (admitted.ticketNumber !== undefined)
|
|
528
|
+
return;
|
|
529
|
+
const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, ledgerReadScope(admitted));
|
|
530
|
+
for (const row of rows) {
|
|
531
|
+
if (row.role !== admitted.role || !isRecord(row.accepted))
|
|
532
|
+
continue;
|
|
533
|
+
if (row.accepted.status !== "completed" || !("ticketNumber" in row.accepted))
|
|
534
|
+
continue;
|
|
535
|
+
const ticketNumber = parseTicketNumber(row.accepted.ticketNumber);
|
|
536
|
+
if (ticketNumber !== undefined) {
|
|
537
|
+
await bindAdmittedTicketNumber(admitted, ticketNumber);
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
484
542
|
export async function dispatchPostAdmissionTurn(input) {
|
|
485
543
|
const { admitted, env, io, request, lease, adapters, effectiveEngine } = input;
|
|
486
544
|
const persistRunState = input.persistRunState !== false;
|
|
@@ -533,7 +591,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
533
591
|
knownDiagnostic: processCancelDiagnostic(cancelBeforeFinish),
|
|
534
592
|
cancelName: cancelBeforeFinish,
|
|
535
593
|
skipRunStateWrite: true,
|
|
536
|
-
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault)),
|
|
594
|
+
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId)),
|
|
537
595
|
turnDispatched: true,
|
|
538
596
|
skipAutoResume: true,
|
|
539
597
|
...deferredPersist,
|
|
@@ -575,24 +633,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
575
633
|
// an escalated submission still carries the original role params.
|
|
576
634
|
// Later receipts remain untouched; prose note/report is never consulted;
|
|
577
635
|
// this seam does not adjudicate a ticket change.
|
|
578
|
-
|
|
579
|
-
const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, ledgerReadScope(admitted));
|
|
580
|
-
let ticketNumber;
|
|
581
|
-
for (const row of rows) {
|
|
582
|
-
if (row.role !== admitted.role
|
|
583
|
-
|| (row.kind !== "accepted" && row.kind !== "audit-escalation")) {
|
|
584
|
-
continue;
|
|
585
|
-
}
|
|
586
|
-
const payload = row.accepted;
|
|
587
|
-
if (!isRecord(payload))
|
|
588
|
-
continue;
|
|
589
|
-
ticketNumber = readDeclaredTicketNumber(payload.ticketNumber);
|
|
590
|
-
if (ticketNumber !== undefined)
|
|
591
|
-
break;
|
|
592
|
-
}
|
|
593
|
-
if (ticketNumber !== undefined)
|
|
594
|
-
await bindAdmittedTicketNumber(admitted, ticketNumber);
|
|
595
|
-
}
|
|
636
|
+
await bindSealedTicketNumber(admitted);
|
|
596
637
|
// #863: shared post-admission bind must relocate unbound→ticket in-home
|
|
597
638
|
// before lease release (work-seat self-report and any prior board bind).
|
|
598
639
|
const relocation = await relocateAdmittedRunToTicket(admitted, env.principalAuthority, lease);
|
|
@@ -618,7 +659,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
618
659
|
code: null,
|
|
619
660
|
stderr: "",
|
|
620
661
|
thrown: error,
|
|
621
|
-
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault)),
|
|
662
|
+
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId)),
|
|
622
663
|
...(result.turnDispatched === true ? { turnDispatched: true } : {}),
|
|
623
664
|
...(result.skipAutoResume === true ? { skipAutoResume: true } : {}),
|
|
624
665
|
...deferredPersist,
|
|
@@ -649,7 +690,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
649
690
|
code: null,
|
|
650
691
|
stderr: "",
|
|
651
692
|
thrown: error,
|
|
652
|
-
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault));
|
|
693
|
+
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId));
|
|
653
694
|
return { ...settled, ...deferredPersist };
|
|
654
695
|
}
|
|
655
696
|
}
|
|
@@ -668,7 +709,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
668
709
|
turnRequest = { ...turnRequest, stationChild: env.stationChild };
|
|
669
710
|
}
|
|
670
711
|
// Selected host axis rides the shared Host envelope for in-turn tools
|
|
671
|
-
// (detour usage ledger) — never a pre-spawn
|
|
712
|
+
// (detour usage ledger) — never a pre-spawn current.json reread.
|
|
672
713
|
if (typeof env.host === "string" && env.host.trim() !== "") {
|
|
673
714
|
turnRequest = { ...turnRequest, host: env.host.trim() };
|
|
674
715
|
}
|
|
@@ -685,7 +726,6 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
685
726
|
// host CLI's native resume. Nothing here may gate, redirect or reshape
|
|
686
727
|
// that dispatch on prior conclusions, row counts or report presence;
|
|
687
728
|
// the authoritative post-turn settlement reads whatever really happened.
|
|
688
|
-
recordRunStart(admitted.runDirectory);
|
|
689
729
|
turnDispatched = true;
|
|
690
730
|
result = await env.roleTurnHost.executeTurn(turnRequest);
|
|
691
731
|
}
|
|
@@ -699,7 +739,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
699
739
|
// call is a second fact; it must not become a new Error in its place.
|
|
700
740
|
...(processCancelName === undefined ? {} : { cancelName: processCancelName }),
|
|
701
741
|
thrown: error,
|
|
702
|
-
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault);
|
|
742
|
+
}, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId);
|
|
703
743
|
return await finishAfterTurn(withProcessCancelSkipAutoResume({ ...settled, turnDispatched: true, ...deferredPersist }, env.signal));
|
|
704
744
|
}
|
|
705
745
|
// #1132: settle this turn through the ONE post-turn settlement authority,
|
|
@@ -734,11 +774,9 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
734
774
|
let deliveryResult;
|
|
735
775
|
let deliveryTurnRequest;
|
|
736
776
|
try {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
// Host and the other axes already selected on this turn ride the
|
|
741
|
-
// shared projection. The pre-projection request does not have them.
|
|
777
|
+
// Host and the other axes already selected on this turn ride the
|
|
778
|
+
// shared projection. The pre-projection request does not have them.
|
|
779
|
+
const deliveryRequest = buildReceiptDeliveryRequest({
|
|
742
780
|
request: turnRequest,
|
|
743
781
|
receiptDelivery,
|
|
744
782
|
});
|
|
@@ -758,7 +796,7 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
758
796
|
// its true cause, through the one settlement authority (ADR 0080).
|
|
759
797
|
// The turn started, so the caller's loop resumes instead of replaying
|
|
760
798
|
// the initial payload. The issued count survives that re-entry.
|
|
761
|
-
const settled = await settleAfterTurnStarted(admitted, withEngineDetourInvocationScope({ timedOut: false, code: null, stderr: "", thrown: error }, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState);
|
|
799
|
+
const settled = await settleAfterTurnStarted(admitted, withEngineDetourInvocationScope({ timedOut: false, code: null, stderr: "", thrown: error }, request.invocationScopeId), adapters, env.principalAuthority, io, persistRunState, courtScope.notePackageFault, courtScope.courtAttemptId);
|
|
762
800
|
return await finishAfterTurn(withProcessCancelSkipAutoResume({
|
|
763
801
|
...settled,
|
|
764
802
|
turnDispatched: true,
|
|
@@ -818,6 +856,9 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
818
856
|
deferredPersist,
|
|
819
857
|
invocationScopeId: request.invocationScopeId,
|
|
820
858
|
notePackageFault: courtScope.notePackageFault,
|
|
859
|
+
...(courtScope.courtAttemptId === undefined
|
|
860
|
+
? {}
|
|
861
|
+
: { courtAttemptId: courtScope.courtAttemptId }),
|
|
821
862
|
}));
|
|
822
863
|
}
|
|
823
864
|
if (persistRunState) {
|
|
@@ -1111,6 +1152,9 @@ export async function runPostAdmissionSeatResume(input) {
|
|
|
1111
1152
|
};
|
|
1112
1153
|
}
|
|
1113
1154
|
}
|
|
1155
|
+
// Public explicit resume: attach the stored native id when the caller
|
|
1156
|
+
// left it unset (399c3c8c). In-call auto-resume / 催交 / gate retry omit
|
|
1157
|
+
// the field; those load inside the host adapter (host-contracts).
|
|
1114
1158
|
let turnRequest = await input.buildTurnRequest(admittedForBuild, request);
|
|
1115
1159
|
if (turnRequest.continuation.kind === "resume"
|
|
1116
1160
|
&& turnRequest.continuation.hostSessionId === undefined) {
|
|
@@ -1211,7 +1255,7 @@ export async function runPostAdmissionSeatResume(input) {
|
|
|
1211
1255
|
catch (error) {
|
|
1212
1256
|
if (error instanceof TurnDispatchedFailure)
|
|
1213
1257
|
throw error;
|
|
1214
|
-
await presentResumeFailurePointer(input.io, error, (failure) =>
|
|
1258
|
+
await presentResumeFailurePointer(input.io, error, (failure) => writeResumeDiagnostic(loaded.admitted.runDirectory, loaded.admitted.runId, failure, loaded.admitted.role));
|
|
1215
1259
|
return { exitCode: error instanceof CliUsageError ? 2 : 1 };
|
|
1216
1260
|
}
|
|
1217
1261
|
}
|
|
@@ -1231,12 +1275,12 @@ async function pointExistingRunFailure(home, runId, authority, io, thrown) {
|
|
|
1231
1275
|
record = await readRoleRunState(runDirectory, authority);
|
|
1232
1276
|
}
|
|
1233
1277
|
catch {
|
|
1234
|
-
await presentResumeFailurePointer(io, thrown, (failure) =>
|
|
1278
|
+
await presentResumeFailurePointer(io, thrown, (failure) => writeResumeDiagnostic(runDirectory, runId, failure));
|
|
1235
1279
|
return true;
|
|
1236
1280
|
}
|
|
1237
1281
|
if (record === undefined)
|
|
1238
1282
|
return false;
|
|
1239
|
-
await presentResumeFailurePointer(io, thrown, (failure) =>
|
|
1283
|
+
await presentResumeFailurePointer(io, thrown, (failure) => writeResumeDiagnostic(runDirectory, runId, failure, record.role));
|
|
1240
1284
|
return true;
|
|
1241
1285
|
}
|
|
1242
1286
|
export async function presentLocatedResumeFailure(home, runId, authority, io, thrown) {
|
|
@@ -1275,18 +1319,15 @@ async function presentResumeFailurePointer(io, thrown, publish) {
|
|
|
1275
1319
|
}, io);
|
|
1276
1320
|
}
|
|
1277
1321
|
}
|
|
1278
|
-
async function
|
|
1279
|
-
|
|
1280
|
-
const path = join(dir, `resume-diagnostic-${randomUUID()}.json`);
|
|
1281
|
-
await writeFile(path, `${JSON.stringify({
|
|
1322
|
+
async function writeResumeDiagnostic(runDirectory, runId, failure, role) {
|
|
1323
|
+
return reportRunRecord(runDirectory, "resume-diagnostic", {
|
|
1282
1324
|
runId,
|
|
1283
1325
|
...(role === undefined ? {} : { role }),
|
|
1284
1326
|
diagnostic: failure.diagnostic,
|
|
1285
1327
|
...(failure.cause === undefined ? {} : { cause: failure.cause }),
|
|
1286
1328
|
...(failure.identity === undefined ? {} : { identity: failure.identity }),
|
|
1287
1329
|
...(failure.details === undefined ? {} : { details: failure.details }),
|
|
1288
|
-
},
|
|
1289
|
-
return path;
|
|
1330
|
+
}, "post-admission").recordFile;
|
|
1290
1331
|
}
|
|
1291
1332
|
/**
|
|
1292
1333
|
* Shared post-admission one-shot path: folds into runPostAdmissionResumable (#840 / #416).
|
|
@@ -16,6 +16,7 @@ import { retainedRunPathsMatch, rewriteAdmittedRoleRunPage, rewriteRunDirectoryP
|
|
|
16
16
|
import { appendEngineSessionMaterial, engineSessionMaterialFromOptions, pickEngineAxis, } from "../package-resources/engine-material.js";
|
|
17
17
|
import { packagedResumeSourcePath, packagedRoleMetadata, } from "../packaged-role-registry.js";
|
|
18
18
|
import { admittedReviewerBaseFault, recordEffectiveInvocationModel, requireAuthorityRef, isReviewerLens, } from "./invocation.js";
|
|
19
|
+
import { readPageSync, writeSectionSync } from "../run-dossier.js";
|
|
19
20
|
import { isRecord, errorText, isEnoent } from "../unknown-value.js";
|
|
20
21
|
/** Default for the #422 configurable single-call auto-resume ceiling
|
|
21
22
|
* (public-cli.json top-level `autoResumeLimit`). No longer the runtime truth
|
|
@@ -41,11 +42,10 @@ export function buildAutoResumeContinuationPrompt(options) {
|
|
|
41
42
|
...pickEngineAxis(options),
|
|
42
43
|
})).join("\n");
|
|
43
44
|
}
|
|
44
|
-
const RUN_STATE_FILE = "run-state.json";
|
|
45
45
|
const WRITER_LOCK_FILE = "writer.lock";
|
|
46
46
|
export async function writeRoleRunState(runDirectory, record) {
|
|
47
47
|
const payload = { ...record, runDirectory };
|
|
48
|
-
|
|
48
|
+
writeSectionSync(runDirectory, "runState", { ...payload });
|
|
49
49
|
}
|
|
50
50
|
function parseSameTicketSummonsMaterials(raw) {
|
|
51
51
|
if (!isRecord(raw))
|
|
@@ -106,43 +106,34 @@ function parseCurrentCourtState(raw) {
|
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
async function readRoleRunStateRaw(runDirectory) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// file is genuine infrastructure/data damage and must keep its own
|
|
117
|
-
// identity — callers route it through the controlled-failure seam
|
|
118
|
-
// (markRunRunning/markRunTerminal/recordCurrentCourt)
|
|
119
|
-
// instead of it being relabeled "run state missing" (#836).
|
|
120
|
-
if (errorCodeOf(error) === "ENOENT")
|
|
121
|
-
return undefined;
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
return raw;
|
|
109
|
+
// Only true absence (no state.jsonl run-state row) is a lawful "no run state
|
|
110
|
+
// yet". A real read failure (EISDIR, EACCES, ...) or an illegal latest payload
|
|
111
|
+
// is genuine infrastructure/data damage and must keep its own identity —
|
|
112
|
+
// callers route it through the controlled-failure seam
|
|
113
|
+
// (markRunRunning/markRunTerminal/recordCurrentCourt) instead of it being
|
|
114
|
+
// relabeled "run state missing" (#836). readPageSync throws those.
|
|
115
|
+
return readPageSync(runDirectory, "runState");
|
|
125
116
|
}
|
|
126
117
|
function parseRoleRunIdentity(raw, runDirectory) {
|
|
127
118
|
if (!isRecord(raw)) {
|
|
128
|
-
throw new TypeError("Invalid run-state
|
|
119
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
129
120
|
}
|
|
130
121
|
const record = raw;
|
|
131
122
|
if (typeof record.runId !== "string" || record.runId.trim() === "") {
|
|
132
|
-
throw new TypeError("Invalid run-state
|
|
123
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
133
124
|
}
|
|
134
125
|
const role = typeof record.role === "string" ? packagedRoleMetadata(record.role)?.role : undefined;
|
|
135
126
|
if (role === undefined) {
|
|
136
|
-
throw new TypeError("Invalid run-state
|
|
127
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
137
128
|
}
|
|
138
129
|
if (record.state !== "admitted" &&
|
|
139
130
|
record.state !== "running" &&
|
|
140
131
|
record.state !== "resumable" &&
|
|
141
132
|
record.state !== "terminal") {
|
|
142
|
-
throw new TypeError("Invalid run-state
|
|
133
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
143
134
|
}
|
|
144
135
|
if (typeof record.bookKey !== "string")
|
|
145
|
-
throw new TypeError("Invalid run-state
|
|
136
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
146
137
|
return {
|
|
147
138
|
runId: record.runId,
|
|
148
139
|
role,
|
|
@@ -158,11 +149,9 @@ async function readRoleRunStateDisk(runDirectory) {
|
|
|
158
149
|
const identity = parseRoleRunIdentity(raw, runDirectory);
|
|
159
150
|
const record = raw;
|
|
160
151
|
if (typeof record.projectRoot !== "string")
|
|
161
|
-
throw new TypeError("Invalid run-state
|
|
152
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
162
153
|
if (typeof record.sessionDirectory !== "string")
|
|
163
|
-
throw new TypeError("Invalid run-state
|
|
164
|
-
if (typeof record.admittedRequestPath !== "string")
|
|
165
|
-
throw new TypeError("Invalid run-state.json");
|
|
154
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
166
155
|
const storedRunDirectory = typeof record.runDirectory === "string" && record.runDirectory.trim() !== ""
|
|
167
156
|
? record.runDirectory
|
|
168
157
|
: runDirectory;
|
|
@@ -185,7 +174,6 @@ async function readRoleRunStateDisk(runDirectory) {
|
|
|
185
174
|
bookKey: identity.bookKey,
|
|
186
175
|
projectRoot: record.projectRoot,
|
|
187
176
|
runDirectory: runDir,
|
|
188
|
-
admittedRequestPath: rewriteRunDirectoryPathValue(record.admittedRequestPath, storedRunDirectory, runDirectory),
|
|
189
177
|
principalWire,
|
|
190
178
|
...(phase === undefined ? {} : { phase }),
|
|
191
179
|
...(currentCourt === undefined ? {} : { currentCourt }),
|
|
@@ -203,11 +191,10 @@ async function writeRoleRunStateDisk(runDirectory, disk) {
|
|
|
203
191
|
...(disk.principalWire.sessionFile === undefined
|
|
204
192
|
? {}
|
|
205
193
|
: { sessionFile: disk.principalWire.sessionFile }),
|
|
206
|
-
admittedRequestPath: disk.admittedRequestPath,
|
|
207
194
|
...(disk.phase === undefined ? {} : { phase: disk.phase }),
|
|
208
195
|
...(disk.currentCourt === undefined ? {} : { currentCourt: disk.currentCourt }),
|
|
209
196
|
};
|
|
210
|
-
|
|
197
|
+
writeSectionSync(runDirectory, "runState", payload);
|
|
211
198
|
}
|
|
212
199
|
/** One authority.decode of the uninterpreted wire → record + opaque principal (frozen wire itself). */
|
|
213
200
|
function materializeRoleRunFromDisk(disk, authority) {
|
|
@@ -224,7 +211,6 @@ function materializeRoleRunFromDisk(disk, authority) {
|
|
|
224
211
|
sessionDirectory: coordinates.sessionDirectory,
|
|
225
212
|
sessionFile: coordinates.sessionFile,
|
|
226
213
|
runDirectory: disk.runDirectory,
|
|
227
|
-
admittedRequestPath: disk.admittedRequestPath,
|
|
228
214
|
...(disk.phase === undefined ? {} : { phase: disk.phase }),
|
|
229
215
|
},
|
|
230
216
|
};
|
|
@@ -265,14 +251,13 @@ export async function markRunAdmitted(admitted, authority) {
|
|
|
265
251
|
projectRoot: admitted.projectRoot,
|
|
266
252
|
sessionDirectory,
|
|
267
253
|
sessionFile,
|
|
268
|
-
admittedRequestPath: admitted.admittedRequestPath,
|
|
269
254
|
...(workerPhase === undefined ? {} : { phase: workerPhase }),
|
|
270
255
|
});
|
|
271
256
|
}
|
|
272
257
|
/**
|
|
273
258
|
* Shared dispatch execution seam: transition to running, then record the
|
|
274
259
|
* effective launch model (initial or resume override) and the authoritative
|
|
275
|
-
* seat engine/host onto invocation.
|
|
260
|
+
* seat engine/host onto the invocation section.
|
|
276
261
|
* Role runners must not coordinate lifecycle ledger writes themselves.
|
|
277
262
|
* Engine axis is authoritative here (#617): present string is written; omit/undefined
|
|
278
263
|
* clears any prior engine key so unset-engine + resume does not keep a stale value.
|
|
@@ -664,19 +649,9 @@ export function parentRunPathFromGatePointerInstruction(instruction) {
|
|
|
664
649
|
* Missing page → undefined; damage / non-ENOENT IO propagates.
|
|
665
650
|
*/
|
|
666
651
|
export async function readRunParentPath(runDirectory) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
raw = JSON.parse(await readFile(join(runDirectory, "admitted-request.json"), "utf8"));
|
|
670
|
-
}
|
|
671
|
-
catch (error) {
|
|
672
|
-
if (errorCodeOf(error) === "ENOENT")
|
|
673
|
-
return undefined;
|
|
674
|
-
throw error;
|
|
675
|
-
}
|
|
676
|
-
if (!isRecord(raw)) {
|
|
652
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
653
|
+
if (record === undefined)
|
|
677
654
|
return undefined;
|
|
678
|
-
}
|
|
679
|
-
const record = raw;
|
|
680
655
|
if (typeof record.sourceRunPath === "string" && record.sourceRunPath.trim() !== "") {
|
|
681
656
|
return record.sourceRunPath;
|
|
682
657
|
}
|
|
@@ -789,7 +764,7 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
789
764
|
throw new CliUsageError(`unknown role run id: ${runId}`);
|
|
790
765
|
}
|
|
791
766
|
const { run, principal } = materialized;
|
|
792
|
-
// Reconstruct admitted identity from durable run record + admitted
|
|
767
|
+
// Reconstruct admitted identity from durable run record + the admitted section.
|
|
793
768
|
let instruction = "";
|
|
794
769
|
let instructionEmpty = true;
|
|
795
770
|
let attachments = [];
|
|
@@ -817,9 +792,10 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
817
792
|
let sourceRunPath;
|
|
818
793
|
let sourceRun;
|
|
819
794
|
try {
|
|
820
|
-
const
|
|
821
|
-
if (
|
|
822
|
-
|
|
795
|
+
const record = readPageSync(run.runDirectory, "admitted");
|
|
796
|
+
if (record === undefined)
|
|
797
|
+
throw new Error("state.jsonl has no admitted-request row");
|
|
798
|
+
{
|
|
823
799
|
const storedRunDirectory = typeof record.runDirectory === "string" && record.runDirectory.trim() !== ""
|
|
824
800
|
? record.runDirectory
|
|
825
801
|
: run.runDirectory;
|
|
@@ -954,9 +930,8 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
954
930
|
}
|
|
955
931
|
let model;
|
|
956
932
|
try {
|
|
957
|
-
const
|
|
958
|
-
if (
|
|
959
|
-
const rec = invocationRaw;
|
|
933
|
+
const rec = readPageSync(run.runDirectory, "invocation");
|
|
934
|
+
if (rec !== undefined) {
|
|
960
935
|
if (typeof rec.provider === "string" && typeof rec.model === "string") {
|
|
961
936
|
model = {
|
|
962
937
|
provider: rec.provider,
|
|
@@ -1043,7 +1018,6 @@ function resumedBaseAdmitted(loaded) {
|
|
|
1043
1018
|
attachments: loaded.admittedFields.attachments,
|
|
1044
1019
|
runDirectory: loaded.run.runDirectory,
|
|
1045
1020
|
principal: loaded.principal,
|
|
1046
|
-
admittedRequestPath: loaded.run.admittedRequestPath,
|
|
1047
1021
|
...(loaded.admittedFields.model === undefined ? {} : { model: loaded.admittedFields.model }),
|
|
1048
1022
|
...restoredTicketFields(loaded.admittedFields),
|
|
1049
1023
|
};
|