@akagilnc/pi-workflow-roles 0.1.4021 → 0.1.4035
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 +208 -107
- package/dist/headless-host/production-host.js +208 -107
- package/dist/navigator-attendance.js +2 -0
- package/dist/navigator-public-session.js +18 -34
- package/dist/navigator-session-contracts.js +19 -0
- package/dist/pi/known-failure.js +3 -4
- package/dist/public-cli/auto-resume.js +20 -7
- package/dist/public-cli/diarist-run.js +9 -23
- package/dist/public-cli/instruction-seat-run.js +3 -1
- package/dist/public-cli/judge-run.js +3 -1
- package/dist/public-cli/main.js +203 -112
- package/dist/public-cli/settlement.js +64 -61
- package/dist/public-cli/terminal.js +1 -11
- package/dist/submission-ledger.js +109 -11
- package/package.json +1 -1
- package/src/host-contracts.ts +8 -4
- package/src/navigator-attendance.ts +2 -0
- package/src/navigator-public-session.ts +19 -55
- package/src/navigator-session-contracts.ts +39 -0
- package/src/pi/known-failure.ts +3 -4
- package/src/public-cli/auto-resume.ts +57 -20
- package/src/public-cli/cli.ts +2 -2
- package/src/public-cli/collector-run.ts +3 -1
- package/src/public-cli/countersign-run.ts +34 -27
- package/src/public-cli/diarist-run.ts +10 -27
- package/src/public-cli/instruction-seat-run.ts +3 -1
- package/src/public-cli/judge-run.ts +3 -1
- package/src/public-cli/reviewer-run.ts +3 -1
- package/src/public-cli/settlement.ts +83 -84
- package/src/public-cli/terminal.ts +7 -16
- package/src/submission-ledger.ts +147 -13
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { sitianReport } from "./sitian-facade.js";
|
|
2
2
|
import {
|
|
3
3
|
NavigatorUnavailableError,
|
|
4
|
-
|
|
4
|
+
navigatorProviderFailureFromPublicTerminal,
|
|
5
5
|
navigatorProviderFailureFromError,
|
|
6
|
-
navigatorProviderFailureFromStatus,
|
|
7
6
|
navigatorUnavailableError,
|
|
8
7
|
parseNavigatorModelSetting,
|
|
9
8
|
resolveNavigatorSeatSelection
|
|
10
9
|
} from "./navigator-session-contracts.js";
|
|
11
|
-
import { lastRolePayloadRecord } from "./public-cli/terminal.js";
|
|
12
|
-
function providerFailureFromPublicTerminal(outcome) {
|
|
13
|
-
const facts = outcome.decisiveFacts;
|
|
14
|
-
const secondary = typeof facts.secondaryEvidence === "object" && facts.secondaryEvidence !== null ? facts.secondaryEvidence : void 0;
|
|
15
|
-
const httpStatus = typeof secondary?.httpStatus === "number" ? secondary.httpStatus : typeof facts.httpStatus === "number" ? facts.httpStatus : typeof facts.errorCode === "number" ? facts.errorCode : void 0;
|
|
16
|
-
const fromStatus = navigatorProviderFailureFromStatus(httpStatus);
|
|
17
|
-
if (fromStatus !== void 0) return fromStatus;
|
|
18
|
-
const diagnostics = secondary?.diagnostics ?? facts.diagnostics;
|
|
19
|
-
const fromDiagnostics = navigatorProviderFailureFromDiagnostics(diagnostics);
|
|
20
|
-
if (fromDiagnostics !== void 0) return fromDiagnostics;
|
|
21
|
-
const fromCode = navigatorProviderFailureFromError({
|
|
22
|
-
code: secondary?.code ?? facts.errorCode
|
|
23
|
-
});
|
|
24
|
-
if (fromCode !== void 0) return fromCode;
|
|
25
|
-
if (outcome.cause === "provider") return { source: "transport", cause: "transport" };
|
|
26
|
-
return { source: "session", cause: "session" };
|
|
27
|
-
}
|
|
28
10
|
function createNativeNavigatorSessionFactory() {
|
|
29
11
|
return async ({ context, subject, tool }) => {
|
|
30
12
|
const resolved = await resolveNavigatorSeatSelection(context);
|
|
@@ -80,14 +62,15 @@ function createNativeNavigatorSessionFactory() {
|
|
|
80
62
|
const outcome = summoned.terminal?.roleOutcome;
|
|
81
63
|
if (outcome === void 0) {
|
|
82
64
|
const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
|
|
83
|
-
providerFailure = { source: "transport", cause: "
|
|
65
|
+
providerFailure = { source: "transport", cause: "unknown" };
|
|
84
66
|
throw navigatorUnavailableError(
|
|
85
|
-
|
|
86
|
-
new Error(`Navigator public summon produced no terminal (${detail})`)
|
|
67
|
+
providerFailure.source,
|
|
68
|
+
new Error(`Navigator public summon produced no terminal (${detail})`),
|
|
69
|
+
providerFailure.cause
|
|
87
70
|
);
|
|
88
71
|
}
|
|
89
72
|
if (outcome.kind === "failure") {
|
|
90
|
-
providerFailure =
|
|
73
|
+
providerFailure = navigatorProviderFailureFromPublicTerminal(outcome);
|
|
91
74
|
throw navigatorUnavailableError(
|
|
92
75
|
providerFailure.source,
|
|
93
76
|
new Error(outcome.diagnostic),
|
|
@@ -101,21 +84,22 @@ function createNativeNavigatorSessionFactory() {
|
|
|
101
84
|
if (outcome.kind !== "accepted") {
|
|
102
85
|
return;
|
|
103
86
|
}
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
87
|
+
for (const payload of outcome.payloads ?? []) {
|
|
88
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) continue;
|
|
89
|
+
const candidates = payload.candidates;
|
|
90
|
+
if (!Array.isArray(candidates)) continue;
|
|
91
|
+
await tool.execute(
|
|
92
|
+
"navigator-public-prepare",
|
|
93
|
+
{ candidates },
|
|
94
|
+
void 0,
|
|
95
|
+
void 0,
|
|
96
|
+
context
|
|
97
|
+
);
|
|
107
98
|
}
|
|
108
|
-
await tool.execute(
|
|
109
|
-
"navigator-public-prepare",
|
|
110
|
-
{ candidates },
|
|
111
|
-
void 0,
|
|
112
|
-
void 0,
|
|
113
|
-
context
|
|
114
|
-
);
|
|
115
99
|
} catch (error) {
|
|
116
100
|
if (error instanceof NavigatorUnavailableError) throw error;
|
|
117
101
|
const fact = navigatorProviderFailureFromError(error);
|
|
118
|
-
providerFailure = fact ?? { source: "transport", cause: "
|
|
102
|
+
providerFailure = fact ?? { source: "transport", cause: "unknown" };
|
|
119
103
|
throw navigatorUnavailableError(providerFailure.source, error, providerFailure.cause);
|
|
120
104
|
}
|
|
121
105
|
})();
|
|
@@ -92,6 +92,24 @@ function navigatorProviderFailureFromDiagnostics(diagnostics) {
|
|
|
92
92
|
}
|
|
93
93
|
return void 0;
|
|
94
94
|
}
|
|
95
|
+
function navigatorProviderFailureFromPublicTerminal(outcome) {
|
|
96
|
+
const facts = outcome.decisiveFacts;
|
|
97
|
+
const secondary = typeof facts.secondaryEvidence === "object" && facts.secondaryEvidence !== null ? facts.secondaryEvidence : void 0;
|
|
98
|
+
const httpStatus = typeof secondary?.httpStatus === "number" ? secondary.httpStatus : typeof facts.httpStatus === "number" ? facts.httpStatus : typeof facts.errorCode === "number" ? facts.errorCode : void 0;
|
|
99
|
+
const fromStatus = navigatorProviderFailureFromStatus(httpStatus);
|
|
100
|
+
if (fromStatus !== void 0) return fromStatus;
|
|
101
|
+
const diagnostics = secondary?.diagnostics ?? facts.diagnostics;
|
|
102
|
+
const fromDiagnostics = navigatorProviderFailureFromDiagnostics(diagnostics);
|
|
103
|
+
if (fromDiagnostics !== void 0) return fromDiagnostics;
|
|
104
|
+
const fromCode = navigatorProviderFailureFromError({
|
|
105
|
+
code: secondary?.code ?? facts.errorCode
|
|
106
|
+
});
|
|
107
|
+
if (fromCode !== void 0) return fromCode;
|
|
108
|
+
if (outcome.cause === "provider") return { source: "transport", cause: "unknown" };
|
|
109
|
+
const typed = navigatorUnavailableKey(outcome.cause);
|
|
110
|
+
if (typed !== void 0) return { source: typed, cause: typed };
|
|
111
|
+
return { source: "unknown", cause: "unknown" };
|
|
112
|
+
}
|
|
95
113
|
const navigatorProviderFailureSchema = Type.Object({
|
|
96
114
|
source: Type.Union([
|
|
97
115
|
Type.Literal("context"),
|
|
@@ -208,6 +226,7 @@ export {
|
|
|
208
226
|
navigatorProviderFailure,
|
|
209
227
|
navigatorProviderFailureFromDiagnostics,
|
|
210
228
|
navigatorProviderFailureFromError,
|
|
229
|
+
navigatorProviderFailureFromPublicTerminal,
|
|
211
230
|
navigatorProviderFailureFromStatus,
|
|
212
231
|
navigatorUnavailableError,
|
|
213
232
|
parseNavigatorModelSetting,
|
package/dist/pi/known-failure.js
CHANGED
|
@@ -35,9 +35,8 @@ function sessionStopDetails(input) {
|
|
|
35
35
|
/**
|
|
36
36
|
* Project a native session assistant stop onto the existing knownFailure chain.
|
|
37
37
|
* Classification follows two-way testimony: typed HTTP status or SDK structure
|
|
38
|
-
* keeps provider; stopReason
|
|
39
|
-
*
|
|
40
|
-
* in details without rewriting; missing fields are omitted.
|
|
38
|
+
* keeps provider; stopReason / errorMessage prose alone never invents a class (#881).
|
|
39
|
+
* Present upstream payload is preserved in details without rewriting; missing fields are omitted.
|
|
41
40
|
*/
|
|
42
41
|
export function knownFailureFromProviderStop(input) {
|
|
43
42
|
if (input.stopReason !== "error" && input.stopReason !== "aborted")
|
|
@@ -45,7 +44,7 @@ export function knownFailureFromProviderStop(input) {
|
|
|
45
44
|
const diagnostic = nonEmptyString(input.errorMessage);
|
|
46
45
|
const details = sessionStopDetails(input);
|
|
47
46
|
return {
|
|
48
|
-
|
|
47
|
+
...(hasUpstreamErrorTestimony(input) ? { cause: "provider" } : {}),
|
|
49
48
|
...(diagnostic === undefined ? {} : { diagnostic }),
|
|
50
49
|
...(Object.keys(details).length === 0 ? {} : { details }),
|
|
51
50
|
};
|
|
@@ -18,7 +18,7 @@ import { join } from "node:path";
|
|
|
18
18
|
import { AUTO_RESUME_LIMIT, describeErrorIdentity, acquireRunWriterLease, markRunResumable, markRunTerminal, RunWriterLeaseHeldError, } from "./run-lifecycle.js";
|
|
19
19
|
import { parseAutoResumeLimit } from "./config.js";
|
|
20
20
|
import { isLawfulTypedTerminalOutcome, formatTerminalResult } from "./terminal.js";
|
|
21
|
-
import { presentFailureTerminal, presentStructuralRejection, resolveControlledFailureResumeObservation, } from "./settlement.js";
|
|
21
|
+
import { attachRecordedSubmissions, presentFailureTerminal, presentStructuralRejection, resolveControlledFailureResumeObservation, } from "./settlement.js";
|
|
22
22
|
const dummyIo = { stdout: () => { }, stderr: () => { } };
|
|
23
23
|
/**
|
|
24
24
|
* Persist run-state after a host-turn result, outside the retried dispatch try.
|
|
@@ -280,6 +280,20 @@ function unwrapTurnDispatchedFailure(error) {
|
|
|
280
280
|
}
|
|
281
281
|
return current;
|
|
282
282
|
}
|
|
283
|
+
async function attachDispatchExceptionTerminal(admitted, terminal, io) {
|
|
284
|
+
try {
|
|
285
|
+
return await attachRecordedSubmissions({
|
|
286
|
+
projectRoot: admitted.projectRoot,
|
|
287
|
+
runId: admitted.runId,
|
|
288
|
+
runDirectory: admitted.runDirectory,
|
|
289
|
+
}, terminal);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// Existing diagnostic seam: attach true cause on stderr, original Terminal stays.
|
|
293
|
+
io.stderr(`dispatch exception ledger attach failed (best-effort continue): ${describeErrorIdentity(error)}\n`);
|
|
294
|
+
return terminal;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
283
297
|
/**
|
|
284
298
|
* Typed failure terminal for a retry path that ended with only exceptions:
|
|
285
299
|
* loud, non-lawful, carrying the last true cause and the pointers to the
|
|
@@ -293,8 +307,8 @@ function dispatchExceptionFailureTerminal(input) {
|
|
|
293
307
|
? "dispatch threw an exception on every attempt"
|
|
294
308
|
: "the final dispatch threw an exception";
|
|
295
309
|
const diagnostic = `${history} (${input.endReason}; resumes used ${input.autoResumeAttempts}); last cause: ${describeErrorIdentity(causeError)}`;
|
|
310
|
+
// #881: no fabricated cause class — original error identity + error-file pointers carry the fact.
|
|
296
311
|
const decisiveFacts = {
|
|
297
|
-
cause: "unrecognized",
|
|
298
312
|
diagnostic,
|
|
299
313
|
resumesUsed: input.autoResumeAttempts,
|
|
300
314
|
dispatchErrorFiles: [...input.errorFiles],
|
|
@@ -316,7 +330,6 @@ function dispatchExceptionFailureTerminal(input) {
|
|
|
316
330
|
roleOutcome: {
|
|
317
331
|
kind: "failure",
|
|
318
332
|
role: input.role,
|
|
319
|
-
cause: "unrecognized",
|
|
320
333
|
diagnostic,
|
|
321
334
|
decisiveFacts,
|
|
322
335
|
},
|
|
@@ -431,7 +444,7 @@ export async function runWithAutoResumeLoop(options) {
|
|
|
431
444
|
else {
|
|
432
445
|
// Exception path: continue through the identical budget/session gates.
|
|
433
446
|
if (autoResumeAttempts >= limit) {
|
|
434
|
-
const terminal = dispatchExceptionFailureTerminal({
|
|
447
|
+
const terminal = await attachDispatchExceptionTerminal(options.admitted, dispatchExceptionFailureTerminal({
|
|
435
448
|
role: options.admitted.role,
|
|
436
449
|
runId: options.admitted.runId,
|
|
437
450
|
causeError: lastThrownError,
|
|
@@ -439,7 +452,7 @@ export async function runWithAutoResumeLoop(options) {
|
|
|
439
452
|
autoResumeAttempts,
|
|
440
453
|
endReason: "auto-resume budget exhausted",
|
|
441
454
|
everyAttemptThrew,
|
|
442
|
-
});
|
|
455
|
+
}), options.io);
|
|
443
456
|
await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
|
|
444
457
|
presentTerminal(terminal, options.io);
|
|
445
458
|
return {
|
|
@@ -448,7 +461,7 @@ export async function runWithAutoResumeLoop(options) {
|
|
|
448
461
|
};
|
|
449
462
|
}
|
|
450
463
|
if (!(await isPrincipalAvailable(options.admitted.principal))) {
|
|
451
|
-
const terminal = dispatchExceptionFailureTerminal({
|
|
464
|
+
const terminal = await attachDispatchExceptionTerminal(options.admitted, dispatchExceptionFailureTerminal({
|
|
452
465
|
role: options.admitted.role,
|
|
453
466
|
runId: options.admitted.runId,
|
|
454
467
|
causeError: lastThrownError,
|
|
@@ -456,7 +469,7 @@ export async function runWithAutoResumeLoop(options) {
|
|
|
456
469
|
autoResumeAttempts,
|
|
457
470
|
endReason: "session principal unavailable before further resume",
|
|
458
471
|
everyAttemptThrew,
|
|
459
|
-
});
|
|
472
|
+
}), options.io);
|
|
460
473
|
await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
|
|
461
474
|
presentTerminal(terminal, options.io);
|
|
462
475
|
return {
|
|
@@ -5,8 +5,8 @@ import { prepareSummonsResumeMaterials, runPostAdmissionOneShot, runPostAdmissio
|
|
|
5
5
|
import { loadResumableDiaristRun, markRunAdmitted, } from "./run-lifecycle.js";
|
|
6
6
|
import { tryResumeSameTicketSeatRun } from "./seat-ticket-binding.js";
|
|
7
7
|
import { presentStructuralRejection, trySettleDiaristTerminalResult, } from "./settlement.js";
|
|
8
|
-
import { lastRolePayloadRecord } from "./terminal.js";
|
|
9
8
|
import { projectRoleTurnRequest, } from "./turn-request.js";
|
|
9
|
+
import { readRunTicketNumber } from "../run-ticket-number.js";
|
|
10
10
|
/** Project admitted invocation onto the host-neutral turn request. */
|
|
11
11
|
export function buildDiaristTurnRequest(admitted, options) {
|
|
12
12
|
return projectRoleTurnRequest(admitted, { activation: { role: "diarist" } }, options);
|
|
@@ -110,29 +110,15 @@ export async function runPublicDiarist(argv, env, io, parseDiaristArgv) {
|
|
|
110
110
|
adapters: diaristAdapters(),
|
|
111
111
|
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
112
112
|
}).then(async (result) => {
|
|
113
|
-
// Accept
|
|
114
|
-
//
|
|
115
|
-
//
|
|
113
|
+
// Accept hook binds ticket onto durable pages (#771). Mirror that page fact
|
|
114
|
+
// onto the caller-visible admitted object — never pick a ticketNumber out of
|
|
115
|
+
// the payload sequence (#881 sole-collapse ban on ticket/escalate).
|
|
116
116
|
if (admitted.ticketNumber === undefined && result.admitted !== undefined) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
roleOutcome.kind === "accepted" &&
|
|
123
|
-
facts?.status !== "escalate") {
|
|
124
|
-
const raw = typeof facts?.ticketNumber === "number"
|
|
125
|
-
? facts.ticketNumber
|
|
126
|
-
: typeof facts?.sitian === "object"
|
|
127
|
-
&& facts.sitian !== null
|
|
128
|
-
&& typeof facts.sitian.ticketNumber === "number"
|
|
129
|
-
? facts.sitian.ticketNumber
|
|
130
|
-
: undefined;
|
|
131
|
-
if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) {
|
|
132
|
-
admitted.ticketNumber = raw;
|
|
133
|
-
if (result.admitted.ticketNumber === undefined) {
|
|
134
|
-
result.admitted.ticketNumber = raw;
|
|
135
|
-
}
|
|
117
|
+
const fromPages = await readRunTicketNumber(admitted.runDirectory);
|
|
118
|
+
if (fromPages !== undefined) {
|
|
119
|
+
await bindAdmittedTicketNumber(admitted, fromPages);
|
|
120
|
+
if (result.admitted.ticketNumber === undefined) {
|
|
121
|
+
result.admitted.ticketNumber = fromPages;
|
|
136
122
|
}
|
|
137
123
|
}
|
|
138
124
|
}
|
|
@@ -36,7 +36,9 @@ function instructionSeatAdapters(options) {
|
|
|
36
36
|
return infrastructureFailure === undefined
|
|
37
37
|
? result.knownFailure
|
|
38
38
|
: {
|
|
39
|
-
|
|
39
|
+
...(infrastructureFailure.cause === undefined
|
|
40
|
+
? {}
|
|
41
|
+
: { cause: infrastructureFailure.cause }),
|
|
40
42
|
diagnostic: infrastructureFailure.diagnostic,
|
|
41
43
|
...(infrastructureFailure.identity === undefined
|
|
42
44
|
? {}
|
|
@@ -18,7 +18,9 @@ function judgeAdapters() {
|
|
|
18
18
|
(infrastructureFailure === undefined
|
|
19
19
|
? undefined
|
|
20
20
|
: {
|
|
21
|
-
|
|
21
|
+
...(infrastructureFailure.cause === undefined
|
|
22
|
+
? {}
|
|
23
|
+
: { cause: infrastructureFailure.cause }),
|
|
22
24
|
diagnostic: infrastructureFailure.diagnostic,
|
|
23
25
|
...(infrastructureFailure.identity === undefined
|
|
24
26
|
? {}
|