@akagilnc/pi-workflow-roles 0.1.4745 → 0.1.4759
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/dist/acp-host/production-host.js +51 -162
- package/dist/headless-host/production-host.js +51 -162
- package/dist/public-cli/main.js +52 -164
- package/dist/public-cli/post-admission.js +69 -130
- package/package.json +1 -1
- package/src/public-cli/cli.ts +0 -5
- package/src/public-cli/config.ts +0 -1
- package/src/public-cli/countersign-run.ts +1 -1
- package/src/public-cli/diarist-run.ts +1 -1
- package/src/public-cli/post-admission.ts +88 -187
- package/dist/public-cli/public-run-credentials.js +0 -49
- package/src/public-cli/public-run-credentials.ts +0 -71
package/src/public-cli/cli.ts
CHANGED
|
@@ -124,7 +124,6 @@ const RESUME_SEAT_DISPATCH: Record<
|
|
|
124
124
|
) => Promise<{
|
|
125
125
|
exitCode: number;
|
|
126
126
|
terminal?: TerminalResult;
|
|
127
|
-
staleWriterLeaseReclaimed?: true;
|
|
128
127
|
}>;
|
|
129
128
|
}
|
|
130
129
|
> = {
|
|
@@ -473,19 +472,15 @@ export type CliResult = {
|
|
|
473
472
|
/** Settled Terminal when an admitted Role run produced one (programmatic/tests). */
|
|
474
473
|
terminal?: TerminalResult;
|
|
475
474
|
hostFailure?: HostSelectionFailure;
|
|
476
|
-
/** Typed #556 fact from public resume/dispatch when a dead holder lock was unlinked. */
|
|
477
|
-
staleWriterLeaseReclaimed?: true;
|
|
478
475
|
};
|
|
479
476
|
|
|
480
477
|
function cliResultFromRoleRun(result: {
|
|
481
478
|
exitCode: number;
|
|
482
479
|
terminal?: TerminalResult;
|
|
483
|
-
staleWriterLeaseReclaimed?: true;
|
|
484
480
|
}): CliResult {
|
|
485
481
|
return {
|
|
486
482
|
exitCode: result.exitCode,
|
|
487
483
|
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
488
|
-
...(result.staleWriterLeaseReclaimed === true ? { staleWriterLeaseReclaimed: true as const } : {}),
|
|
489
484
|
};
|
|
490
485
|
}
|
|
491
486
|
|
package/src/public-cli/config.ts
CHANGED
|
@@ -813,7 +813,6 @@ export function listRolesForDisplay(
|
|
|
813
813
|
|
|
814
814
|
/**
|
|
815
815
|
* Read configured credential presence from a Pi auth.json document.
|
|
816
|
-
* Presence drives the selected-provider fail-closed seam (public-run-credentials).
|
|
817
816
|
*/
|
|
818
817
|
export function credentialProvidersFromAuthData(
|
|
819
818
|
data: unknown,
|
|
@@ -785,7 +785,7 @@ export async function runPublicCountersign(
|
|
|
785
785
|
function countersignAdapters(options?: {
|
|
786
786
|
beforeDispatch?: (
|
|
787
787
|
admitted: AdmittedCountersignInvocation,
|
|
788
|
-
lease
|
|
788
|
+
lease?: RunWriterLease,
|
|
789
789
|
) => void | Promise<void>;
|
|
790
790
|
}) {
|
|
791
791
|
return {
|
|
@@ -76,7 +76,7 @@ export function buildDiaristTurnRequest(
|
|
|
76
76
|
async function bindAndRelocateDiaristIfBoardBound(
|
|
77
77
|
admitted: AdmittedDiaristInvocation,
|
|
78
78
|
authority: DiaristRunEnv["principalAuthority"],
|
|
79
|
-
lease
|
|
79
|
+
lease?: RunWriterLease,
|
|
80
80
|
): Promise<void> {
|
|
81
81
|
const boardTicket = await readBoardTicketNumber(admitted.runDirectory);
|
|
82
82
|
if (boardTicket === undefined) return;
|
|
@@ -69,11 +69,6 @@ import {
|
|
|
69
69
|
import { projectHostTransitionPriorNative } from "../host-transition-prior-native.ts";
|
|
70
70
|
import type { CredentialProviders, SeatModelConfig } from "./config.ts";
|
|
71
71
|
import {
|
|
72
|
-
missingCredentialPreDispatchFailure,
|
|
73
|
-
postRunMissingCredentialFailure,
|
|
74
|
-
} from "./public-run-credentials.ts";
|
|
75
|
-
import {
|
|
76
|
-
acquireRunWriterLease,
|
|
77
72
|
clearCurrentCourt,
|
|
78
73
|
clearTypedProviderHttpObservation,
|
|
79
74
|
describeErrorIdentity,
|
|
@@ -81,11 +76,9 @@ import {
|
|
|
81
76
|
readCurrentCourt,
|
|
82
77
|
recordCurrentCourt,
|
|
83
78
|
renderResumeCommand,
|
|
84
|
-
RunWriterLeaseHeldError,
|
|
85
79
|
type CurrentCourtState,
|
|
86
80
|
type RunWriterLease,
|
|
87
81
|
type TypedProviderHttpObservation,
|
|
88
|
-
type WriterLeaseDiagnosticKind,
|
|
89
82
|
} from "./run-lifecycle.ts";
|
|
90
83
|
import {
|
|
91
84
|
processCancelDiagnostic,
|
|
@@ -234,8 +227,8 @@ async function recordBestEffortPostDispatchDiagnostic<A extends AdmittedRoleInvo
|
|
|
234
227
|
diagnostic: string,
|
|
235
228
|
io: CliIo,
|
|
236
229
|
): Promise<void> {
|
|
237
|
-
io.stderr(formatCliDiagnostic(diagnostic));
|
|
238
230
|
const payload = { diagnostic, recordedAt: new Date().toISOString() };
|
|
231
|
+
let retentionFailure: string | undefined;
|
|
239
232
|
try {
|
|
240
233
|
await env.sessionAppender(
|
|
241
234
|
env.principalAuthority,
|
|
@@ -243,7 +236,6 @@ async function recordBestEffortPostDispatchDiagnostic<A extends AdmittedRoleInvo
|
|
|
243
236
|
POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE,
|
|
244
237
|
payload,
|
|
245
238
|
);
|
|
246
|
-
return;
|
|
247
239
|
} catch (appendError) {
|
|
248
240
|
try {
|
|
249
241
|
const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
|
|
@@ -253,12 +245,17 @@ async function recordBestEffortPostDispatchDiagnostic<A extends AdmittedRoleInvo
|
|
|
253
245
|
{ encoding: "utf8", flag: "wx" },
|
|
254
246
|
);
|
|
255
247
|
} catch (artifactError) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
248
|
+
retentionFailure =
|
|
249
|
+
`post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
io.stderr(formatCliDiagnostic(diagnostic));
|
|
254
|
+
if (retentionFailure !== undefined) {
|
|
255
|
+
io.stderr(formatCliDiagnostic(retentionFailure));
|
|
261
256
|
}
|
|
257
|
+
} catch {
|
|
258
|
+
// Presentation is best-effort beside an already-formed host terminal.
|
|
262
259
|
}
|
|
263
260
|
}
|
|
264
261
|
|
|
@@ -327,13 +324,14 @@ export type PostAdmissionAdapters<
|
|
|
327
324
|
result: RoleTurnResult;
|
|
328
325
|
sessionFile: string;
|
|
329
326
|
}) => Promise<RoleTurnKnownFailure | undefined>;
|
|
330
|
-
beforeDispatch?: (admitted: A, lease
|
|
327
|
+
beforeDispatch?: (admitted: A, lease?: RunWriterLease) => Promise<void> | void;
|
|
331
328
|
/**
|
|
332
|
-
* After the host turn settles and before
|
|
333
|
-
* Post-turn bind/relocate (e.g. Diarist first assert) must run here so
|
|
334
|
-
* held lease follows the run directory and failures stay
|
|
329
|
+
* After the host turn settles and before any held writer lease is released.
|
|
330
|
+
* Post-turn bind/relocate (e.g. Diarist first assert) must run here so a
|
|
331
|
+
* held lease (when present) follows the run directory and failures stay
|
|
332
|
+
* controlled. Public manual resume (#987) may omit the lease.
|
|
335
333
|
*/
|
|
336
|
-
afterDispatch?: (admitted: A, lease
|
|
334
|
+
afterDispatch?: (admitted: A, lease?: RunWriterLease) => Promise<void> | void;
|
|
337
335
|
};
|
|
338
336
|
|
|
339
337
|
export type ControlledFailureInput = {
|
|
@@ -614,7 +612,8 @@ export async function dispatchPostAdmissionTurn<
|
|
|
614
612
|
env: PostAdmissionEnv;
|
|
615
613
|
io: CliIo;
|
|
616
614
|
request: RoleTurnRequest;
|
|
617
|
-
|
|
615
|
+
/** Absent on public manual resume (#987): no package lease gate before host CLI resume. */
|
|
616
|
+
lease?: RunWriterLease;
|
|
618
617
|
adapters: PostAdmissionAdapters<A, T>;
|
|
619
618
|
effectiveEngine?: string;
|
|
620
619
|
persistRunState?: boolean;
|
|
@@ -707,14 +706,11 @@ export async function dispatchPostAdmissionTurn<
|
|
|
707
706
|
if (adapters.afterDispatch !== undefined) await adapters.afterDispatch(admitted, lease);
|
|
708
707
|
return result;
|
|
709
708
|
} catch (error) {
|
|
710
|
-
|
|
711
|
-
result.terminal !== undefined
|
|
712
|
-
&& !isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
|
|
713
|
-
if (primaryFailure) {
|
|
709
|
+
if (result.terminal !== undefined) {
|
|
714
710
|
await recordBestEffortPostDispatchDiagnostic(
|
|
715
711
|
admitted,
|
|
716
712
|
env,
|
|
717
|
-
`afterDispatch failed beside
|
|
713
|
+
`afterDispatch failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
|
|
718
714
|
io,
|
|
719
715
|
);
|
|
720
716
|
return result;
|
|
@@ -740,23 +736,8 @@ export async function dispatchPostAdmissionTurn<
|
|
|
740
736
|
}
|
|
741
737
|
};
|
|
742
738
|
try {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
env.credentials,
|
|
746
|
-
);
|
|
747
|
-
if (missingCredential !== undefined) {
|
|
748
|
-
return {
|
|
749
|
-
...(await presentControlledFailure(
|
|
750
|
-
admitted,
|
|
751
|
-
withEngineDetourInvocationScope(missingCredential, request.invocationScopeId),
|
|
752
|
-
adapters,
|
|
753
|
-
env.principalAuthority,
|
|
754
|
-
io,
|
|
755
|
-
persistRunState,
|
|
756
|
-
)) as { exitCode: number; admitted: A; terminal: T },
|
|
757
|
-
...deferredPersist,
|
|
758
|
-
};
|
|
759
|
-
}
|
|
739
|
+
// #987: do not pre-block or classify host dispatch from AK credential
|
|
740
|
+
// catalog facts. Per-invocation runner/host evidence owns provider identity.
|
|
760
741
|
// #617 DK-4: capture previous invocation host before markRunRunning overwrites it.
|
|
761
742
|
// Single authority projectHostTransitionPriorNative classifies the prior native volume.
|
|
762
743
|
// Same-run resume (#637) keeps host identity on the run's invocation page.
|
|
@@ -1001,15 +982,10 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1001
982
|
adapters.resolveRunnerKnownFailure !== undefined && sessionFile !== ""
|
|
1002
983
|
? await adapters.resolveRunnerKnownFailure({ result, sessionFile })
|
|
1003
984
|
: result.knownFailure;
|
|
1004
|
-
const credentialFailure = postRunMissingCredentialFailure(
|
|
1005
|
-
result,
|
|
1006
|
-
env.model,
|
|
1007
|
-
env.credentials,
|
|
1008
|
-
);
|
|
1009
985
|
resolution = await resolveAuditedRunnerFailureResolution({
|
|
1010
986
|
runner: runnerKnownFailure,
|
|
1011
987
|
sessionFile,
|
|
1012
|
-
credential:
|
|
988
|
+
credential: undefined,
|
|
1013
989
|
runDirectory: admitted.runDirectory,
|
|
1014
990
|
});
|
|
1015
991
|
// A direct, current signal from the host/runner itself (timeout / host
|
|
@@ -1030,7 +1006,6 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1030
1006
|
result.timedOut
|
|
1031
1007
|
|| result.knownFailure !== undefined
|
|
1032
1008
|
|| runnerKnownFailure !== undefined
|
|
1033
|
-
|| credentialFailure !== undefined
|
|
1034
1009
|
|| processCancelName !== undefined;
|
|
1035
1010
|
hostSignalFailed =
|
|
1036
1011
|
directHostFailureSignal
|
|
@@ -1153,35 +1128,11 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1153
1128
|
try {
|
|
1154
1129
|
await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
|
|
1155
1130
|
} catch (error) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
// this function uses (ADR 0080: one settlement disposition owner)
|
|
1161
|
-
// — not escape uncaught to auto-resume's dispatch-retry path,
|
|
1162
|
-
// whose exhausted-budget terminal carries no recorded submissions
|
|
1163
|
-
// at all. skipRunStateWrite: the write that just threw is the same
|
|
1164
|
-
// write presentControlledFailure would otherwise retry — don't
|
|
1165
|
-
// call a known-failing operation twice.
|
|
1166
|
-
const failed = await settleAfterTurnStarted(
|
|
1167
|
-
admitted,
|
|
1168
|
-
withEngineDetourInvocationScope({
|
|
1169
|
-
timedOut: false,
|
|
1170
|
-
code: null,
|
|
1171
|
-
stderr: "",
|
|
1172
|
-
thrown: error,
|
|
1173
|
-
skipRunStateWrite: true,
|
|
1174
|
-
}, request.invocationScopeId),
|
|
1175
|
-
adapters,
|
|
1176
|
-
env.principalAuthority,
|
|
1131
|
+
await recordBestEffortPostDispatchDiagnostic(
|
|
1132
|
+
admitted,
|
|
1133
|
+
env,
|
|
1134
|
+
`run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
|
|
1177
1135
|
io,
|
|
1178
|
-
persistRunState,
|
|
1179
|
-
);
|
|
1180
|
-
return await finishAfterTurn(
|
|
1181
|
-
withProcessCancelSkipAutoResume(
|
|
1182
|
-
{ ...failed, turnDispatched: true as const, ...deferredPersist },
|
|
1183
|
-
env.signal,
|
|
1184
|
-
),
|
|
1185
1136
|
);
|
|
1186
1137
|
}
|
|
1187
1138
|
}
|
|
@@ -1282,30 +1233,11 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1282
1233
|
try {
|
|
1283
1234
|
await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
|
|
1284
1235
|
} catch (error) {
|
|
1285
|
-
|
|
1286
|
-
// branch above — route through the shared controlled-failure seam so
|
|
1287
|
-
// the real failure surfaces loudly instead of escaping uncaught to
|
|
1288
|
-
// auto-resume's dispatch-retry path with no recorded submissions.
|
|
1289
|
-
// skipRunStateWrite: don't retry the write that just threw.
|
|
1290
|
-
const failed = await settleAfterTurnStarted(
|
|
1236
|
+
await recordBestEffortPostDispatchDiagnostic(
|
|
1291
1237
|
admitted,
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
code: null,
|
|
1295
|
-
stderr: "",
|
|
1296
|
-
thrown: error,
|
|
1297
|
-
skipRunStateWrite: true,
|
|
1298
|
-
}, request.invocationScopeId),
|
|
1299
|
-
adapters,
|
|
1300
|
-
env.principalAuthority,
|
|
1238
|
+
env,
|
|
1239
|
+
`run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
|
|
1301
1240
|
io,
|
|
1302
|
-
persistRunState,
|
|
1303
|
-
);
|
|
1304
|
-
return await finishAfterTurn(
|
|
1305
|
-
withProcessCancelSkipAutoResume(
|
|
1306
|
-
{ ...failed, turnDispatched: true as const, ...deferredPersist },
|
|
1307
|
-
env.signal,
|
|
1308
|
-
),
|
|
1309
1241
|
);
|
|
1310
1242
|
}
|
|
1311
1243
|
}
|
|
@@ -1318,20 +1250,23 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1318
1250
|
...deferredPersist,
|
|
1319
1251
|
});
|
|
1320
1252
|
} finally {
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1253
|
+
// Public manual resume (#987) holds no package writer lease.
|
|
1254
|
+
if (lease !== undefined) {
|
|
1255
|
+
try {
|
|
1256
|
+
await lease.release();
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
// lease.release() is documented best-effort and never rejects in the
|
|
1259
|
+
// production acquireRunWriterLease implementation (createWriterLease
|
|
1260
|
+
// reports cleanup failures via callback, never throws) — this guard is
|
|
1261
|
+
// structural only: an uncaught throw from a finally block silently
|
|
1262
|
+
// replaces whatever the try already returned, including a properly
|
|
1263
|
+
// tagged turnDispatched:true result (#840 r9 判词 class 1 boundary).
|
|
1264
|
+
io.stderr(
|
|
1265
|
+
formatCliDiagnostic(
|
|
1266
|
+
`writer lease release failed unexpectedly (best-effort continue): ${describeErrorIdentity(error)}`,
|
|
1267
|
+
),
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1335
1270
|
}
|
|
1336
1271
|
}
|
|
1337
1272
|
}
|
|
@@ -1543,8 +1478,10 @@ export async function runPostAdmissionSeatResume<
|
|
|
1543
1478
|
}): Promise<{ exitCode: number; admitted?: A; terminal?: T }> {
|
|
1544
1479
|
let request = input.request;
|
|
1545
1480
|
|
|
1546
|
-
// Load once for runDirectory / structural rejection / afterAdmittedLoad
|
|
1547
|
-
//
|
|
1481
|
+
// Load once for runDirectory / structural rejection / afterAdmittedLoad.
|
|
1482
|
+
// Court identity for public manual resume is judged in the turn builder
|
|
1483
|
+
// (#987: no package writer-lease gate before host CLI resume). Station-child
|
|
1484
|
+
// auto-resume still acquires the shared lease in runWithAutoResumeLoop.
|
|
1548
1485
|
let loaded;
|
|
1549
1486
|
try {
|
|
1550
1487
|
loaded = await input.load(request);
|
|
@@ -1575,8 +1512,9 @@ export async function runPostAdmissionSeatResume<
|
|
|
1575
1512
|
|
|
1576
1513
|
const buildRequestAfterLease = async (): Promise<RoleTurnRequest> => {
|
|
1577
1514
|
let openCourtAttemptId: string | undefined;
|
|
1578
|
-
// Build uses the admitted
|
|
1579
|
-
//
|
|
1515
|
+
// Build uses the admitted for this resume (rehydrated when open court
|
|
1516
|
+
// materials ride). Settlement identity stays on the outer admitted.
|
|
1517
|
+
// Name kept for station-child callers that still build under lease.
|
|
1580
1518
|
let admittedForBuild = loaded.admitted;
|
|
1581
1519
|
|
|
1582
1520
|
// Bare resume: open-court pointer is the continue signal (not ledger seal).
|
|
@@ -1652,9 +1590,10 @@ export async function runPostAdmissionSeatResume<
|
|
|
1652
1590
|
return turnRequest;
|
|
1653
1591
|
};
|
|
1654
1592
|
|
|
1655
|
-
// Court recovery / open
|
|
1593
|
+
// Court recovery / open, then dispatch. Public manual resume does not take a
|
|
1594
|
+
// package writer lease before the host CLI (#987 / ADR 0080 one-shot).
|
|
1656
1595
|
// Station-child same-ticket/same-parent resume is call-local auto-resume
|
|
1657
|
-
// (#840 / #416)
|
|
1596
|
+
// (#840 / #416) and still acquires the shared lease in its loop.
|
|
1658
1597
|
// afterAdmittedPrepare runs inside this try so mint failure and cleanup share one finally.
|
|
1659
1598
|
try {
|
|
1660
1599
|
if (input.afterAdmittedPrepare !== undefined) {
|
|
@@ -1873,10 +1812,11 @@ export async function runPostAdmissionResumable<
|
|
|
1873
1812
|
}
|
|
1874
1813
|
|
|
1875
1814
|
/**
|
|
1876
|
-
* Manual resume:
|
|
1877
|
-
* short-circuit (#833 / #416). Court open
|
|
1878
|
-
*
|
|
1879
|
-
*
|
|
1815
|
+
* Manual resume: pass-through to the host CLI resume — no package writer-lease
|
|
1816
|
+
* pre-gate (#987), no sealed-accepted short-circuit (#833 / #416). Court open
|
|
1817
|
+
* (summons / message / open court) is built when using buildRequestAfterLease;
|
|
1818
|
+
* sole-final stays per-attempt. Station-child auto-resume keeps shared lease
|
|
1819
|
+
* acquire in runWithAutoResumeLoop + dispatchAfterWriterLease.
|
|
1880
1820
|
*/
|
|
1881
1821
|
export async function runPostAdmissionManualResume<
|
|
1882
1822
|
A extends AdmittedRoleInvocation,
|
|
@@ -1885,9 +1825,9 @@ export async function runPostAdmissionManualResume<
|
|
|
1885
1825
|
admitted: A;
|
|
1886
1826
|
env: PostAdmissionEnv;
|
|
1887
1827
|
io: CliIo;
|
|
1888
|
-
/** Eager turn request (non-court path / seats that build before
|
|
1828
|
+
/** Eager turn request (non-court path / seats that build before dispatch). */
|
|
1889
1829
|
request?: RoleTurnRequest;
|
|
1890
|
-
/**
|
|
1830
|
+
/** Turn builder (#637). Mutually exclusive with a prebuilt request. */
|
|
1891
1831
|
buildRequestAfterLease?: () => Promise<RoleTurnRequest>;
|
|
1892
1832
|
adapters: PostAdmissionAdapters<A, T>;
|
|
1893
1833
|
/** Seat-table engine axis on resume (#600). */
|
|
@@ -1896,7 +1836,6 @@ export async function runPostAdmissionManualResume<
|
|
|
1896
1836
|
exitCode: number;
|
|
1897
1837
|
admitted?: A;
|
|
1898
1838
|
terminal?: T;
|
|
1899
|
-
staleWriterLeaseReclaimed?: true;
|
|
1900
1839
|
}> {
|
|
1901
1840
|
const {
|
|
1902
1841
|
admitted,
|
|
@@ -1910,67 +1849,34 @@ export async function runPostAdmissionManualResume<
|
|
|
1910
1849
|
// #617 DK-3: manual resume writes the live seat/env model (same as new legs).
|
|
1911
1850
|
const effectiveModel = env.model;
|
|
1912
1851
|
|
|
1913
|
-
let lease: RunWriterLease;
|
|
1914
|
-
let staleWriterLeaseReclaimed: true | undefined;
|
|
1915
|
-
try {
|
|
1916
|
-
lease = await acquireRunWriterLease(admitted.runDirectory, (diagnostic, kind?: WriterLeaseDiagnosticKind) => {
|
|
1917
|
-
// Record the typed fact before the fallible sink: if io.stderr throws
|
|
1918
|
-
// (acquire deliberately swallows diagnostic-sink failures), the reclaim
|
|
1919
|
-
// still happened and must stay observable.
|
|
1920
|
-
if (kind === "stale-reclaimed") staleWriterLeaseReclaimed = true;
|
|
1921
|
-
io.stderr(diagnostic);
|
|
1922
|
-
});
|
|
1923
|
-
} catch (error) {
|
|
1924
|
-
if (error instanceof RunWriterLeaseHeldError) {
|
|
1925
|
-
io.stderr(formatCliDiagnostic(error.message));
|
|
1926
|
-
// A held rejection after our own reclaim must still carry the fact that
|
|
1927
|
-
// this caller reclaimed the stale lock — e.g. another resumer re-locked
|
|
1928
|
-
// before our retry create (#629).
|
|
1929
|
-
return {
|
|
1930
|
-
exitCode: 1,
|
|
1931
|
-
...(staleWriterLeaseReclaimed === true
|
|
1932
|
-
? { staleWriterLeaseReclaimed: true as const }
|
|
1933
|
-
: {}),
|
|
1934
|
-
};
|
|
1935
|
-
}
|
|
1936
|
-
throw error;
|
|
1937
|
-
}
|
|
1938
|
-
|
|
1939
1852
|
// Explicit public resume is a new counting unit — mint once for this call.
|
|
1940
1853
|
const invocationScopeId = mintEngineDetourInvocationScope({
|
|
1941
1854
|
...(effectiveEngine === undefined ? {} : { effectiveEngine }),
|
|
1942
1855
|
});
|
|
1943
1856
|
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1857
|
+
if (request === undefined) {
|
|
1858
|
+
if (buildRequestAfterLease === undefined) {
|
|
1859
|
+
throw new Error(
|
|
1860
|
+
"runPostAdmissionManualResume requires request or buildRequestAfterLease",
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
request = await buildRequestAfterLease();
|
|
1864
|
+
}
|
|
1865
|
+
request = withEngineDetourInvocationScope(request, invocationScopeId);
|
|
1866
|
+
|
|
1867
|
+
const result = await dispatchPostAdmissionTurn({
|
|
1868
|
+
admitted,
|
|
1869
|
+
env: {
|
|
1870
|
+
...env,
|
|
1871
|
+
...(effectiveModel === undefined ? {} : { model: effectiveModel }),
|
|
1872
|
+
...(admitted.correlationId === undefined
|
|
1873
|
+
? {}
|
|
1874
|
+
: { correlationId: admitted.correlationId }),
|
|
1957
1875
|
},
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
...env,
|
|
1963
|
-
...(effectiveModel === undefined ? {} : { model: effectiveModel }),
|
|
1964
|
-
...(admitted.correlationId === undefined
|
|
1965
|
-
? {}
|
|
1966
|
-
: { correlationId: admitted.correlationId }),
|
|
1967
|
-
},
|
|
1968
|
-
io,
|
|
1969
|
-
request: turnRequest,
|
|
1970
|
-
lease,
|
|
1971
|
-
adapters,
|
|
1972
|
-
...(effectiveEngine === undefined ? {} : { effectiveEngine }),
|
|
1973
|
-
}),
|
|
1876
|
+
io,
|
|
1877
|
+
request,
|
|
1878
|
+
adapters,
|
|
1879
|
+
...(effectiveEngine === undefined ? {} : { effectiveEngine }),
|
|
1974
1880
|
});
|
|
1975
1881
|
if (
|
|
1976
1882
|
result.terminal !== undefined &&
|
|
@@ -1986,10 +1892,5 @@ export async function runPostAdmissionManualResume<
|
|
|
1986
1892
|
if (result.terminal !== undefined) {
|
|
1987
1893
|
(result.terminal as { autoResumeCount?: number }).autoResumeCount = 0;
|
|
1988
1894
|
}
|
|
1989
|
-
return
|
|
1990
|
-
...result,
|
|
1991
|
-
...(staleWriterLeaseReclaimed === true
|
|
1992
|
-
? { staleWriterLeaseReclaimed: true as const }
|
|
1993
|
-
: {}),
|
|
1994
|
-
};
|
|
1895
|
+
return result;
|
|
1995
1896
|
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared public-run credential seam: one owner for missing selected-provider
|
|
3
|
-
* detection, typed failure construction, pre-dispatch fail-closed payload, and
|
|
4
|
-
* post-run credential annotation. Role runners supply model/credential facts only.
|
|
5
|
-
*/
|
|
6
|
-
import { missingPublicProviderCredential, } from "./config.js";
|
|
7
|
-
/**
|
|
8
|
-
* Production-owned provider failure when the selected public seat provider has
|
|
9
|
-
* no configured credential. Cause/identity come from CredentialProviders, not
|
|
10
|
-
* stderr wording. Runner-supplied knownFailure still wins over this annotation.
|
|
11
|
-
*/
|
|
12
|
-
export function knownFailureForMissingProviderCredential(model, credentials) {
|
|
13
|
-
if (model === undefined || credentials === undefined)
|
|
14
|
-
return undefined;
|
|
15
|
-
// Only the public credential catalog is fail-closed here; offline/test providers
|
|
16
|
-
// are not represented in auth.json shape and must not be washed into MissingProviderCredential.
|
|
17
|
-
if (model.provider !== "openai-codex" && model.provider !== "xai")
|
|
18
|
-
return undefined;
|
|
19
|
-
if (!missingPublicProviderCredential(model.provider, credentials)) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
cause: "provider",
|
|
24
|
-
identity: {
|
|
25
|
-
name: "MissingProviderCredential",
|
|
26
|
-
code: model.provider,
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
export function missingCredentialPreDispatchFailure(model, credentials) {
|
|
31
|
-
const knownFailure = knownFailureForMissingProviderCredential(model, credentials);
|
|
32
|
-
if (knownFailure === undefined)
|
|
33
|
-
return undefined;
|
|
34
|
-
return {
|
|
35
|
-
timedOut: false,
|
|
36
|
-
code: 1,
|
|
37
|
-
stderr: `Missing credential for provider ${String(knownFailure.identity?.code ?? "unknown")}`,
|
|
38
|
-
knownFailure,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Post-run credential annotation for the shared evidence-priority chain.
|
|
43
|
-
* Only annotates nonzero/timeout exits; never invents a credential failure on success.
|
|
44
|
-
*/
|
|
45
|
-
export function postRunMissingCredentialFailure(result, model, credentials) {
|
|
46
|
-
if (!(result.timedOut || result.code !== 0))
|
|
47
|
-
return undefined;
|
|
48
|
-
return knownFailureForMissingProviderCredential(model, credentials);
|
|
49
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared public-run credential seam: one owner for missing selected-provider
|
|
3
|
-
* detection, typed failure construction, pre-dispatch fail-closed payload, and
|
|
4
|
-
* post-run credential annotation. Role runners supply model/credential facts only.
|
|
5
|
-
*/
|
|
6
|
-
import {
|
|
7
|
-
missingPublicProviderCredential,
|
|
8
|
-
type CredentialProviders,
|
|
9
|
-
type SeatModelConfig,
|
|
10
|
-
} from "./config.ts";
|
|
11
|
-
import type { RoleTurnKnownFailure } from "../host-contracts.ts";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Production-owned provider failure when the selected public seat provider has
|
|
15
|
-
* no configured credential. Cause/identity come from CredentialProviders, not
|
|
16
|
-
* stderr wording. Runner-supplied knownFailure still wins over this annotation.
|
|
17
|
-
*/
|
|
18
|
-
export function knownFailureForMissingProviderCredential(
|
|
19
|
-
model: SeatModelConfig | undefined,
|
|
20
|
-
credentials: CredentialProviders | undefined,
|
|
21
|
-
): RoleTurnKnownFailure | undefined {
|
|
22
|
-
if (model === undefined || credentials === undefined) return undefined;
|
|
23
|
-
// Only the public credential catalog is fail-closed here; offline/test providers
|
|
24
|
-
// are not represented in auth.json shape and must not be washed into MissingProviderCredential.
|
|
25
|
-
if (model.provider !== "openai-codex" && model.provider !== "xai") return undefined;
|
|
26
|
-
if (!missingPublicProviderCredential(model.provider, credentials)) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
cause: "provider",
|
|
31
|
-
identity: {
|
|
32
|
-
name: "MissingProviderCredential",
|
|
33
|
-
code: model.provider,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Pre-dispatch fail-closed payload when selected public provider lacks credentials. */
|
|
39
|
-
export type MissingCredentialPreDispatchFailure = Readonly<{
|
|
40
|
-
timedOut: false;
|
|
41
|
-
code: 1;
|
|
42
|
-
stderr: string;
|
|
43
|
-
knownFailure: RoleTurnKnownFailure;
|
|
44
|
-
}>;
|
|
45
|
-
|
|
46
|
-
export function missingCredentialPreDispatchFailure(
|
|
47
|
-
model: SeatModelConfig | undefined,
|
|
48
|
-
credentials: CredentialProviders | undefined,
|
|
49
|
-
): MissingCredentialPreDispatchFailure | undefined {
|
|
50
|
-
const knownFailure = knownFailureForMissingProviderCredential(model, credentials);
|
|
51
|
-
if (knownFailure === undefined) return undefined;
|
|
52
|
-
return {
|
|
53
|
-
timedOut: false,
|
|
54
|
-
code: 1,
|
|
55
|
-
stderr: `Missing credential for provider ${String(knownFailure.identity?.code ?? "unknown")}`,
|
|
56
|
-
knownFailure,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Post-run credential annotation for the shared evidence-priority chain.
|
|
62
|
-
* Only annotates nonzero/timeout exits; never invents a credential failure on success.
|
|
63
|
-
*/
|
|
64
|
-
export function postRunMissingCredentialFailure(
|
|
65
|
-
result: Readonly<{ timedOut: boolean; code: number | null }>,
|
|
66
|
-
model: SeatModelConfig | undefined,
|
|
67
|
-
credentials: CredentialProviders | undefined,
|
|
68
|
-
): RoleTurnKnownFailure | undefined {
|
|
69
|
-
if (!(result.timedOut || result.code !== 0)) return undefined;
|
|
70
|
-
return knownFailureForMissingProviderCredential(model, credentials);
|
|
71
|
-
}
|