@akagilnc/pi-workflow-roles 0.1.1817 → 0.1.1837
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/audit-escalation.js +1 -1
- package/dist/compliance-transport.js +7 -6
- package/dist/evidence-child-executor.js +65 -23
- package/dist/navigator-attendance.js +9 -1
- package/dist/public-cli/main.js +187 -224
- package/dist/receipt-delivery-policy.js +14 -5
- package/dist/sitian-record-entry.js +24 -29
- package/dist/sitian-role-run-coordinates.js +28 -0
- package/package.json +1 -1
- package/scripts/build-package.mjs +2 -0
- package/src/audit-escalation.ts +5 -1
- package/src/compliance-transport.ts +9 -6
- package/src/doctor-role.ts +1 -1
- package/src/evidence-child-executor.ts +65 -27
- package/src/judge-role.ts +2 -1
- package/src/navigator-attendance.ts +14 -1
- package/src/public-cli/invocation.ts +16 -72
- package/src/public-cli/merger-run.ts +4 -16
- package/src/public-cli/run-lifecycle.ts +8 -10
- package/src/receipt-delivery-policy.ts +20 -8
- package/src/reviewer-role.ts +2 -2
- package/src/role-runtime.ts +3 -2
- package/src/sitian-record-entry.ts +4 -0
- package/src/sitian-role-run-coordinates.ts +45 -0
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
resolveActivationLedgerHome,
|
|
20
20
|
} from "../activation-ledger-topology.ts";
|
|
21
21
|
import { resolveBookKeyFromGit } from "../activation-ledger-git.ts";
|
|
22
|
+
import { roleRunSessionCoordinates } from "../sitian-role-run-coordinates.ts";
|
|
22
23
|
import {
|
|
23
24
|
loadDoctorCase,
|
|
24
25
|
} from "../doctor-evidence.ts";
|
|
@@ -57,14 +58,6 @@ export type FrozenAttachment = {
|
|
|
57
58
|
readonly mediaKind: "regular-file";
|
|
58
59
|
};
|
|
59
60
|
|
|
60
|
-
/** Durable Pi session file principal name under a Role run's private session directory. */
|
|
61
|
-
export const ROLE_RUN_SESSION_FILE_NAME = "session.jsonl" as const;
|
|
62
|
-
|
|
63
|
-
/** Exact Pi session file principal path for a Role run session directory. */
|
|
64
|
-
export function roleRunSessionFile(sessionDirectory: string): string {
|
|
65
|
-
return join(sessionDirectory, ROLE_RUN_SESSION_FILE_NAME);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
61
|
/** Shared admitted Role run identity (#106 common Invocation + #109 Coder). */
|
|
69
62
|
export type AdmittedRoleInvocationBase = {
|
|
70
63
|
readonly runId: string;
|
|
@@ -583,16 +576,9 @@ export async function admitJudgeInvocation(
|
|
|
583
576
|
requireOptionPath("--project", options.project);
|
|
584
577
|
}
|
|
585
578
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
586
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
587
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
588
579
|
const runId = (options.createRunId ?? uuidv7)();
|
|
589
|
-
const runDirectory =
|
|
590
|
-
|
|
591
|
-
"runs",
|
|
592
|
-
`${runId}@judge`,
|
|
593
|
-
);
|
|
594
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
595
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
580
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
581
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "judge", home: options.home });
|
|
596
582
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
597
583
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
598
584
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -728,16 +714,9 @@ export async function admitCoderInvocation(
|
|
|
728
714
|
}
|
|
729
715
|
|
|
730
716
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
731
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
732
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
733
717
|
const runId = (options.createRunId ?? uuidv7)();
|
|
734
|
-
const runDirectory =
|
|
735
|
-
|
|
736
|
-
"runs",
|
|
737
|
-
`${runId}@coder`,
|
|
738
|
-
);
|
|
739
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
740
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
718
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
719
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "coder", home: options.home });
|
|
741
720
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
742
721
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
743
722
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -850,16 +829,9 @@ export async function admitFixerInvocation(
|
|
|
850
829
|
}
|
|
851
830
|
|
|
852
831
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
853
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
854
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
855
832
|
const runId = (options.createRunId ?? uuidv7)();
|
|
856
|
-
const runDirectory =
|
|
857
|
-
|
|
858
|
-
"runs",
|
|
859
|
-
`${runId}@fixer`,
|
|
860
|
-
);
|
|
861
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
862
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
833
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
834
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "fixer", home: options.home });
|
|
863
835
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
864
836
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
865
837
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -1131,16 +1103,9 @@ export async function admitCollectorInvocation(
|
|
|
1131
1103
|
repository = resolveGitHubRemoteRepository(projectRoot);
|
|
1132
1104
|
}
|
|
1133
1105
|
|
|
1134
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
1135
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
1136
1106
|
const runId = (options.createRunId ?? uuidv7)();
|
|
1137
|
-
const runDirectory =
|
|
1138
|
-
|
|
1139
|
-
"runs",
|
|
1140
|
-
`${runId}@collector`,
|
|
1141
|
-
);
|
|
1142
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
1143
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
1107
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
1108
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "collector", home: options.home });
|
|
1144
1109
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
1145
1110
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
1146
1111
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -1449,8 +1414,9 @@ export async function admitDoctorInvocation(
|
|
|
1449
1414
|
}
|
|
1450
1415
|
|
|
1451
1416
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
1452
|
-
const
|
|
1453
|
-
const ledgerHome
|
|
1417
|
+
const runId = (options.createRunId ?? uuidv7)();
|
|
1418
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
1419
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "doctor", home: options.home });
|
|
1454
1420
|
|
|
1455
1421
|
let caseRunsPath: string;
|
|
1456
1422
|
try {
|
|
@@ -1492,14 +1458,6 @@ export async function admitDoctorInvocation(
|
|
|
1492
1458
|
);
|
|
1493
1459
|
}
|
|
1494
1460
|
|
|
1495
|
-
const runId = (options.createRunId ?? uuidv7)();
|
|
1496
|
-
const runDirectory = join(
|
|
1497
|
-
activationBookDirectory(ledgerHome, bookKey),
|
|
1498
|
-
"runs",
|
|
1499
|
-
`${runId}@doctor`,
|
|
1500
|
-
);
|
|
1501
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
1502
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
1503
1461
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
1504
1462
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
1505
1463
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -1659,16 +1617,9 @@ export async function admitReviewerInvocation(
|
|
|
1659
1617
|
}
|
|
1660
1618
|
|
|
1661
1619
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
1662
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
1663
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
1664
1620
|
const runId = (options.createRunId ?? uuidv7)();
|
|
1665
|
-
const runDirectory =
|
|
1666
|
-
|
|
1667
|
-
"runs",
|
|
1668
|
-
`${runId}@reviewer`,
|
|
1669
|
-
);
|
|
1670
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
1671
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
1621
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
1622
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "reviewer", home: options.home });
|
|
1672
1623
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
1673
1624
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
1674
1625
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -1887,16 +1838,9 @@ export async function admitMergerInvocation(
|
|
|
1887
1838
|
options.gitState ?? createProductionMergerGitState(projectRoot),
|
|
1888
1839
|
);
|
|
1889
1840
|
|
|
1890
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
1891
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
1892
1841
|
const runId = (options.createRunId ?? uuidv7)();
|
|
1893
|
-
const runDirectory =
|
|
1894
|
-
|
|
1895
|
-
"runs",
|
|
1896
|
-
`${runId}@merger`,
|
|
1897
|
-
);
|
|
1898
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
1899
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
1842
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
1843
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "merger", home: options.home });
|
|
1900
1844
|
const attachmentsDirectory = join(runDirectory, "attachments");
|
|
1901
1845
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
1902
1846
|
ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
|
|
@@ -6,12 +6,8 @@
|
|
|
6
6
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
7
7
|
import { join, resolve } from "node:path";
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
activationBookDirectory,
|
|
12
|
-
ensureRealDirectoryTree,
|
|
13
|
-
resolveActivationLedgerHome,
|
|
14
|
-
} from "../activation-ledger-topology.ts";
|
|
9
|
+
import { ensureRealDirectoryTree } from "../activation-ledger-topology.ts";
|
|
10
|
+
import { roleRunSessionCoordinates } from "../sitian-role-run-coordinates.ts";
|
|
15
11
|
import {
|
|
16
12
|
loadPackagedMethodSkillMaterial,
|
|
17
13
|
resolvePackagedMethodSkillPath,
|
|
@@ -30,7 +26,6 @@ import {
|
|
|
30
26
|
admitMergerInvocation,
|
|
31
27
|
buildMergerTransportPrompt,
|
|
32
28
|
MergerEnvelopeDerivationError,
|
|
33
|
-
roleRunSessionFile,
|
|
34
29
|
type AdmittedMergerInvocation,
|
|
35
30
|
} from "./invocation.ts";
|
|
36
31
|
import {
|
|
@@ -414,16 +409,9 @@ async function admitMergerShellForActivationFailure(options: {
|
|
|
414
409
|
createRunId?: () => string;
|
|
415
410
|
}): Promise<AdmittedMergerInvocation> {
|
|
416
411
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
417
|
-
const bookKey = resolveBookKeyFromGit(projectRoot);
|
|
418
|
-
const ledgerHome = resolveActivationLedgerHome(() => options.home);
|
|
419
412
|
const runId = (options.createRunId ?? uuidv7)();
|
|
420
|
-
const runDirectory =
|
|
421
|
-
|
|
422
|
-
"runs",
|
|
423
|
-
`${runId}@merger`,
|
|
424
|
-
);
|
|
425
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
426
|
-
const sessionFile = roleRunSessionFile(sessionDirectory);
|
|
413
|
+
const { ledgerHome, bookKey, runDirectory, sessionDirectory, sessionFile } =
|
|
414
|
+
roleRunSessionCoordinates({ cwd: projectRoot, runId, role: "merger", home: options.home });
|
|
427
415
|
ensureRealDirectoryTree(ledgerHome, sessionDirectory);
|
|
428
416
|
await mkdir(runDirectory, { recursive: true });
|
|
429
417
|
const emptyDerived = {
|
|
@@ -15,7 +15,6 @@ import { CliUsageError } from "./cli-errors.ts";
|
|
|
15
15
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
16
16
|
import type { FixerPrerequisite } from "../package-contracts/fixer-packet.ts";
|
|
17
17
|
import {
|
|
18
|
-
roleRunSessionFile,
|
|
19
18
|
type AdmittedCoderInvocation,
|
|
20
19
|
type AdmittedFixerInvocation,
|
|
21
20
|
type AdmittedJudgeInvocation,
|
|
@@ -187,10 +186,12 @@ export async function writeRoleRunState(
|
|
|
187
186
|
export async function readRoleRunState(
|
|
188
187
|
runDirectory: string,
|
|
189
188
|
): Promise<RoleRunRecord | undefined> {
|
|
189
|
+
let raw: unknown;
|
|
190
190
|
try {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
raw = JSON.parse(await readFile(join(runDirectory, RUN_STATE_FILE), "utf8"));
|
|
192
|
+
} catch {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
194
195
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
195
196
|
return undefined;
|
|
196
197
|
}
|
|
@@ -225,12 +226,12 @@ export async function readRoleRunState(
|
|
|
225
226
|
typeof record.runDirectory === "string" && record.runDirectory.trim() !== ""
|
|
226
227
|
? record.runDirectory
|
|
227
228
|
: runDirectory;
|
|
228
|
-
//
|
|
229
|
-
//
|
|
229
|
+
// Legacy states predate sessionFile. Their persisted session directory is
|
|
230
|
+
// the authority for the historical principal, even if project topology moved.
|
|
230
231
|
const sessionFile =
|
|
231
232
|
typeof record.sessionFile === "string" && record.sessionFile.trim() !== ""
|
|
232
233
|
? record.sessionFile
|
|
233
|
-
:
|
|
234
|
+
: join(record.sessionDirectory, "session.jsonl");
|
|
234
235
|
let resumable: TypedHttp429Observation | undefined;
|
|
235
236
|
if (record.resumable !== undefined && record.resumable !== null) {
|
|
236
237
|
if (
|
|
@@ -264,9 +265,6 @@ export async function readRoleRunState(
|
|
|
264
265
|
...(phase === undefined ? {} : { phase }),
|
|
265
266
|
...(resumable === undefined ? {} : { resumable }),
|
|
266
267
|
};
|
|
267
|
-
} catch {
|
|
268
|
-
return undefined;
|
|
269
|
-
}
|
|
270
268
|
}
|
|
271
269
|
|
|
272
270
|
export async function markRunAdmitted(
|
|
@@ -7,7 +7,7 @@ export const NO_RECEIPT_LIFECYCLE_ENTRY_TYPE = "ak-no-receipt-lifecycle" as cons
|
|
|
7
7
|
/** The sole schema shared by lifecycle owners and Terminal projections. */
|
|
8
8
|
export type NoReceiptLifecycleFacts = {
|
|
9
9
|
terminalToolCalled: boolean;
|
|
10
|
-
rejectedReceipts: readonly { reason: string }[];
|
|
10
|
+
rejectedReceipts: readonly { reason: string; diagnosticAvailable: boolean }[];
|
|
11
11
|
deliveryTurns: typeof RECEIPT_DELIVERY_TURN_LIMIT;
|
|
12
12
|
sessionCompletion: "settled-without-accepted-receipt";
|
|
13
13
|
runPointer: string;
|
|
@@ -30,12 +30,15 @@ export function parseNoReceiptLifecycleFacts(input: unknown): NoReceiptLifecycle
|
|
|
30
30
|
|| typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === ""
|
|
31
31
|
|| !Array.isArray(input.rejectedReceipts)
|
|
32
32
|
|| !input.rejectedReceipts.every((item) => isRecord(item)
|
|
33
|
-
&& typeof item.reason === "string"
|
|
33
|
+
&& typeof item.reason === "string")) {
|
|
34
34
|
throw new TypeError("malformed no-receipt lifecycle facts");
|
|
35
35
|
}
|
|
36
36
|
return {
|
|
37
37
|
terminalToolCalled: input.terminalToolCalled,
|
|
38
|
-
rejectedReceipts: input.rejectedReceipts.map((item) => ({
|
|
38
|
+
rejectedReceipts: input.rejectedReceipts.map((item) => ({
|
|
39
|
+
reason: item.reason as string,
|
|
40
|
+
diagnosticAvailable: (item.reason as string).trim() !== "",
|
|
41
|
+
})),
|
|
39
42
|
deliveryTurns: RECEIPT_DELIVERY_TURN_LIMIT,
|
|
40
43
|
sessionCompletion: "settled-without-accepted-receipt",
|
|
41
44
|
runPointer: input.runPointer,
|
|
@@ -45,14 +48,20 @@ export function parseNoReceiptLifecycleFacts(input: unknown): NoReceiptLifecycle
|
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
export function noReceiptLifecycleFacts(
|
|
48
|
-
input: Omit<NoReceiptLifecycleFacts, "deliveryTurns" | "sessionCompletion" | "acceptedReceipt"> & {
|
|
51
|
+
input: Omit<NoReceiptLifecycleFacts, "rejectedReceipts" | "deliveryTurns" | "sessionCompletion" | "acceptedReceipt"> & {
|
|
52
|
+
rejectedReceipts: readonly { reason: string }[];
|
|
53
|
+
deliveryTurns: number;
|
|
54
|
+
},
|
|
49
55
|
): NoReceiptLifecycleFacts {
|
|
50
56
|
if (input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT) {
|
|
51
57
|
throw new TypeError("no-receipt lifecycle requires an exhausted delivery budget");
|
|
52
58
|
}
|
|
53
59
|
return {
|
|
54
60
|
terminalToolCalled: input.terminalToolCalled,
|
|
55
|
-
rejectedReceipts: input.rejectedReceipts.map(({ reason }) => ({
|
|
61
|
+
rejectedReceipts: input.rejectedReceipts.map(({ reason }) => ({
|
|
62
|
+
reason,
|
|
63
|
+
diagnosticAvailable: reason.trim() !== "",
|
|
64
|
+
})),
|
|
56
65
|
deliveryTurns: RECEIPT_DELIVERY_TURN_LIMIT,
|
|
57
66
|
sessionCompletion: "settled-without-accepted-receipt",
|
|
58
67
|
runPointer: input.runPointer,
|
|
@@ -65,14 +74,17 @@ export function createReceiptDeliveryPolicy() {
|
|
|
65
74
|
let accepted = false;
|
|
66
75
|
let terminalToolCalled = false;
|
|
67
76
|
let deliveryTurns = 0;
|
|
68
|
-
const rejectedReceipts: { reason: string }[] = [];
|
|
77
|
+
const rejectedReceipts: { reason: string; diagnosticAvailable: boolean }[] = [];
|
|
69
78
|
return {
|
|
70
|
-
recordAccepted() {
|
|
79
|
+
recordAccepted() {
|
|
80
|
+
accepted = true;
|
|
81
|
+
terminalToolCalled = true;
|
|
82
|
+
},
|
|
71
83
|
/** Infrastructure owns terminality and must never trigger receipt催交. */
|
|
72
84
|
stopForInfrastructure() { accepted = true; },
|
|
73
85
|
recordRejected(reason: string) {
|
|
74
86
|
terminalToolCalled = true;
|
|
75
|
-
rejectedReceipts.push({ reason });
|
|
87
|
+
rejectedReceipts.push({ reason, diagnosticAvailable: reason.trim() !== "" });
|
|
76
88
|
deliveryTurns = Math.min(RECEIPT_DELIVERY_TURN_LIMIT, deliveryTurns + 1);
|
|
77
89
|
},
|
|
78
90
|
recordDeliveryRequest() {
|
package/src/reviewer-role.ts
CHANGED
|
@@ -163,9 +163,9 @@ export function createReviewerRoleRuntime(pi: ExtensionAPI, dependencies: Review
|
|
|
163
163
|
try { await dependencies.shutdownAgent?.(); } catch (error) { hostActions.failInfrastructure(ledger.recordInfrastructureFailure(error), toolCtx, id); }
|
|
164
164
|
return { content: [{ type: "text" as const, text: "Reviewer report accepted" }], details: candidate, terminate: true as const, ...(usage === undefined ? {} : { usage }) };
|
|
165
165
|
},
|
|
166
|
-
noReceipt: async (auditNoReceipt) => {
|
|
166
|
+
noReceipt: async (auditNoReceipt, usageProjection) => {
|
|
167
167
|
try { await dependencies.shutdownAgent?.(); } catch (error) { hostActions.failInfrastructure(ledger.recordInfrastructureFailure(error), toolCtx, id); }
|
|
168
|
-
return { content: [{ type: "text" as const, text: "Reviewer report accepted; compliance audit produced no receipt" }], details: { ...candidate, auditNoReceipt }, terminate: true as const };
|
|
168
|
+
return { content: [{ type: "text" as const, text: "Reviewer report accepted; compliance audit produced no receipt" }], details: { ...candidate, auditNoReceipt }, terminate: true as const, ...usageProjection };
|
|
169
169
|
},
|
|
170
170
|
revise: (violations) => {
|
|
171
171
|
throw new AggregateError([], `Reviewer receipt rejected:\n${violations.join("\n")}`, { cause: Object.freeze([...violations]) });
|
package/src/role-runtime.ts
CHANGED
|
@@ -567,8 +567,9 @@ export function createRoleRuntimeExtension(
|
|
|
567
567
|
// whose queued next turn is consumed before settlement.
|
|
568
568
|
pi.on("agent_end", (event) => {
|
|
569
569
|
const lastMessage = event.messages.at(-1);
|
|
570
|
-
if (lastMessage?.role === "assistant"
|
|
571
|
-
|
|
570
|
+
if (lastMessage?.role === "assistant"
|
|
571
|
+
&& (lastMessage.stopReason === "error" || lastMessage.stopReason === "aborted")) {
|
|
572
|
+
// Provider failure/abort has no tool_result event; classify it here so the
|
|
572
573
|
// receipt policy cannot turn infrastructure death into an exit-0 lifecycle.
|
|
573
574
|
receiptDelivery.stopForInfrastructure();
|
|
574
575
|
return;
|
|
@@ -7,6 +7,10 @@ import { dirname, resolve, join } from "node:path";
|
|
|
7
7
|
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
|
|
9
9
|
import { resolveBookKeyFromGit } from "./activation-ledger-git.ts";
|
|
10
|
+
export {
|
|
11
|
+
roleRunSessionCoordinates,
|
|
12
|
+
type RoleRunSessionCoordinates,
|
|
13
|
+
} from "./sitian-role-run-coordinates.ts";
|
|
10
14
|
import {
|
|
11
15
|
activationBookDirectory,
|
|
12
16
|
ensureRealDirectoryTree,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
|
|
3
|
+
import { resolveBookKeyFromGit } from "./activation-ledger-git.ts";
|
|
4
|
+
import {
|
|
5
|
+
activationBookDirectory,
|
|
6
|
+
resolveActivationLedgerHome,
|
|
7
|
+
} from "./activation-ledger-topology.ts";
|
|
8
|
+
|
|
9
|
+
export type RoleRunSessionCoordinates = {
|
|
10
|
+
readonly ledgerHome: string;
|
|
11
|
+
readonly bookKey: string;
|
|
12
|
+
readonly runDirectory: string;
|
|
13
|
+
readonly sessionDirectory: string;
|
|
14
|
+
readonly sessionFile: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Sole source of public top-level Role run session coordinates.
|
|
19
|
+
* Callers supply identity only; no destination can be injected.
|
|
20
|
+
*/
|
|
21
|
+
export function roleRunSessionCoordinates(options: {
|
|
22
|
+
readonly cwd: string;
|
|
23
|
+
readonly runId: string;
|
|
24
|
+
readonly role: string;
|
|
25
|
+
/** Machine-home identity; not a record destination. */
|
|
26
|
+
readonly home?: string;
|
|
27
|
+
}): RoleRunSessionCoordinates {
|
|
28
|
+
const ledgerHome = resolveActivationLedgerHome(
|
|
29
|
+
options.home === undefined ? undefined : () => options.home!,
|
|
30
|
+
);
|
|
31
|
+
const bookKey = resolveBookKeyFromGit(options.cwd);
|
|
32
|
+
const runDirectory = join(
|
|
33
|
+
activationBookDirectory(ledgerHome, bookKey),
|
|
34
|
+
"runs",
|
|
35
|
+
`${options.runId}@${options.role}`,
|
|
36
|
+
);
|
|
37
|
+
const sessionDirectory = join(runDirectory, "session");
|
|
38
|
+
return {
|
|
39
|
+
ledgerHome,
|
|
40
|
+
bookKey,
|
|
41
|
+
runDirectory,
|
|
42
|
+
sessionDirectory,
|
|
43
|
+
sessionFile: join(sessionDirectory, "session.jsonl"),
|
|
44
|
+
};
|
|
45
|
+
}
|