@akagilnc/pi-workflow-roles 0.1.5483 → 0.1.5571
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 +6312 -6376
- package/dist/analyst-gate-cycles-read.js +28 -78
- package/dist/analyst-ledger.js +26 -42
- 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-entry.js +4 -3
- package/dist/archivist-record-pointer.js +71 -36
- package/dist/atomic-write.js +2 -2
- package/dist/auditor-dossier-tool.js +11 -6
- package/dist/auditor-soul.js +5 -12
- package/dist/collector-config.js +6 -5
- package/dist/doctor-evidence.js +8 -4
- package/dist/engine-detour-usage.js +8 -22
- package/dist/headless-host/production-host.js +5969 -6011
- package/dist/host-descriptions.js +0 -4
- package/dist/host-session-record.js +266 -267
- package/dist/ledger-session-read.js +5 -0
- package/dist/migrate-book-topology.js +1369 -722
- package/dist/navigator-public-session.js +13 -17
- package/dist/notary-source-run.js +8 -16
- package/dist/packaged-role-registry.js +5 -56
- package/dist/pi/durable-principal.js +2 -3
- package/dist/pi/role-turn-host.js +79 -15
- package/dist/public-cli/auto-resume.js +8 -47
- package/dist/public-cli/instruction-seat-run.js +9 -7
- package/dist/public-cli/invocation.js +67 -100
- package/dist/public-cli/main.js +2689 -2532
- package/dist/public-cli/post-admission.js +96 -55
- package/dist/public-cli/run-lifecycle.js +44 -100
- package/dist/public-cli/settlement.js +184 -429
- package/dist/public-cli/terminal.js +0 -12
- package/dist/role-run-placement.js +53 -16
- package/dist/role-run-relocation.js +111 -52
- package/dist/run-dossier-files.js +30 -0
- package/dist/run-dossier.js +322 -0
- package/dist/run-terminal-artifacts.js +69 -202
- package/dist/run-ticket-number.js +49 -7
- package/dist/session-assistant-usage.js +9 -18
- package/dist/session-identity.js +49 -19
- package/dist/sitian-appender.js +29 -18
- package/dist/sitian-facade.js +11 -0
- package/dist/sitian-reader.js +44 -29
- package/dist/submission-gate.js +1 -1
- package/dist/submission-ledger.js +4 -4
- package/dist/ticket-provenance-contracts.js +2 -8
- package/dist/ticket-provenance.js +25 -9
- 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 +11 -4
- package/src/analyst-gate-cycles-read.ts +31 -88
- package/src/analyst-ledger.ts +36 -51
- 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 +6 -5
- package/src/archivist-record-pointer.ts +92 -42
- package/src/atomic-write.ts +3 -1
- package/src/auditor-dossier-tool.ts +14 -8
- package/src/auditor-soul.ts +5 -10
- 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/collector-config.ts +5 -3
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-evidence.ts +7 -3
- package/src/engine-detour-tool.ts +1 -1
- package/src/engine-detour-usage.ts +12 -25
- package/src/external-host-turn-loop.ts +25 -0
- package/src/factory-board.ts +16 -81
- package/src/headless-host/production-host.ts +1 -4
- package/src/headless-host/role-turn-host.ts +56 -21
- package/src/host-descriptions.ts +0 -6
- package/src/host-session-record.ts +224 -140
- package/src/ledger-session-read.ts +6 -0
- package/src/navigator-public-session.ts +13 -18
- package/src/navigator-work-context.ts +3 -1
- package/src/notary-role.ts +2 -1
- package/src/notary-source-run.ts +8 -18
- package/src/packaged-role-registry.ts +1 -65
- package/src/pi/adapter.ts +50 -7
- package/src/pi/durable-principal.ts +2 -4
- package/src/pi/role-turn-host.ts +85 -14
- package/src/public-cli/auto-resume.ts +7 -43
- package/src/public-cli/instruction-seat-run.ts +13 -6
- package/src/public-cli/invocation.ts +90 -144
- package/src/public-cli/post-admission.ts +111 -72
- package/src/public-cli/run-lifecycle.ts +47 -115
- package/src/public-cli/settlement.ts +221 -589
- package/src/public-cli/terminal.ts +1 -61
- package/src/role-envelope.ts +4 -2
- package/src/role-run-placement.ts +65 -17
- package/src/role-run-relocation.ts +110 -70
- package/src/role-runtime.ts +46 -69
- package/src/run-dossier-files.ts +33 -0
- package/src/run-dossier.ts +357 -0
- package/src/run-terminal-artifacts.ts +84 -240
- package/src/run-ticket-number.ts +82 -14
- package/src/session-assistant-usage.ts +8 -20
- package/src/session-identity.ts +52 -21
- package/src/sitian-appender.ts +33 -26
- package/src/sitian-facade.ts +22 -0
- package/src/sitian-reader.ts +62 -32
- package/src/submission-gate.ts +1 -1
- package/src/submission-ledger.ts +4 -4
- package/src/ticket-provenance-contracts.ts +3 -6
- package/src/ticket-provenance.ts +23 -11
- package/src/ticket-snapshot.ts +3 -2
- package/src/ticket-trajectory.ts +95 -109
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
activationBookDirectory,
|
|
17
17
|
resolveActivationLedgerHome,
|
|
18
18
|
} from "../activation-ledger-topology.ts";
|
|
19
|
-
import { listBookRunDirectories } from "../role-run-placement.ts";
|
|
19
|
+
import { findRoleRunDirectory, listBookRunDirectories, parseRunLeaf, sessionFileIn } from "../role-run-placement.ts";
|
|
20
20
|
import { isSafePositiveTicketNumber } from "../run-ticket-number.ts";
|
|
21
21
|
import { CliUsageError } from "./cli-errors.ts";
|
|
22
22
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
@@ -25,6 +25,7 @@ import { parseCollectorRepository } from "../collector-config.ts";
|
|
|
25
25
|
import type { DoctorCaseIdentity } from "../doctor-contracts.ts";
|
|
26
26
|
import type { NotarySourceRunLocator } from "../notary-contracts.ts";
|
|
27
27
|
import {
|
|
28
|
+
retainedRunPathsMatch,
|
|
28
29
|
rewriteAdmittedRoleRunPage,
|
|
29
30
|
rewriteRunDirectoryPathValue,
|
|
30
31
|
} from "../role-run-relocation.ts";
|
|
@@ -62,6 +63,7 @@ import {
|
|
|
62
63
|
type ReviewerLens,
|
|
63
64
|
} from "./invocation.ts";
|
|
64
65
|
|
|
66
|
+
import { readPageSync, writeSectionSync } from "../run-dossier.ts";
|
|
65
67
|
import { isRecord, errorText, isEnoent } from "../unknown-value.ts";
|
|
66
68
|
|
|
67
69
|
export type RoleRunState = "admitted" | "running" | "resumable" | "terminal";
|
|
@@ -82,7 +84,6 @@ export type RoleRunRecord = {
|
|
|
82
84
|
/** Exact Pi session file principal reopened on resume (not directory-latest). */
|
|
83
85
|
readonly sessionFile: string;
|
|
84
86
|
readonly runDirectory: string;
|
|
85
|
-
readonly admittedRequestPath: string;
|
|
86
87
|
/** Coder/Fixer — preserved for resume continuation. */
|
|
87
88
|
readonly phase?: CoderPhase | FixerPhase;
|
|
88
89
|
};
|
|
@@ -153,7 +154,6 @@ export function buildAutoResumeContinuationPrompt(options: {
|
|
|
153
154
|
).join("\n");
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
const RUN_STATE_FILE = "run-state.json";
|
|
157
157
|
const WRITER_LOCK_FILE = "writer.lock";
|
|
158
158
|
|
|
159
159
|
export async function writeRoleRunState(
|
|
@@ -161,15 +161,11 @@ export async function writeRoleRunState(
|
|
|
161
161
|
record: Omit<RoleRunRecord, "runDirectory">,
|
|
162
162
|
): Promise<void> {
|
|
163
163
|
const payload: RoleRunRecord = { ...record, runDirectory };
|
|
164
|
-
|
|
165
|
-
join(runDirectory, RUN_STATE_FILE),
|
|
166
|
-
`${JSON.stringify(payload, null, 2)}\n`,
|
|
167
|
-
"utf8",
|
|
168
|
-
);
|
|
164
|
+
writeSectionSync(runDirectory, "runState", { ...payload });
|
|
169
165
|
}
|
|
170
166
|
|
|
171
167
|
/**
|
|
172
|
-
* Uninterpreted principal wire as stored on run-state.
|
|
168
|
+
* Uninterpreted principal wire as stored on the state.jsonl run-state row.
|
|
173
169
|
* Legacy rows may omit sessionFile; only DurablePrincipalAuthority decodes it.
|
|
174
170
|
*/
|
|
175
171
|
type RoleRunPrincipalWire = {
|
|
@@ -185,7 +181,6 @@ type RoleRunStateDisk = {
|
|
|
185
181
|
readonly bookKey: string;
|
|
186
182
|
readonly projectRoot: string;
|
|
187
183
|
readonly runDirectory: string;
|
|
188
|
-
readonly admittedRequestPath: string;
|
|
189
184
|
readonly principalWire: RoleRunPrincipalWire;
|
|
190
185
|
readonly phase?: CoderPhase | FixerPhase;
|
|
191
186
|
/** Open court turn (#637); omit when no unsealed current court. */
|
|
@@ -262,20 +257,13 @@ function parseCurrentCourtState(raw: unknown): CurrentCourtState | undefined {
|
|
|
262
257
|
}
|
|
263
258
|
|
|
264
259
|
async function readRoleRunStateRaw(runDirectory: string): Promise<unknown | undefined> {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
// identity — callers route it through the controlled-failure seam
|
|
273
|
-
// (markRunRunning/markRunTerminal/recordCurrentCourt)
|
|
274
|
-
// instead of it being relabeled "run state missing" (#836).
|
|
275
|
-
if (errorCodeOf(error) === "ENOENT") return undefined;
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
return raw;
|
|
260
|
+
// Only true absence (no state.jsonl run-state row) is a lawful "no run state
|
|
261
|
+
// yet". A real read failure (EISDIR, EACCES, ...) or an illegal latest payload
|
|
262
|
+
// is genuine infrastructure/data damage and must keep its own identity —
|
|
263
|
+
// callers route it through the controlled-failure seam
|
|
264
|
+
// (markRunRunning/markRunTerminal/recordCurrentCourt) instead of it being
|
|
265
|
+
// relabeled "run state missing" (#836). readPageSync throws those.
|
|
266
|
+
return readPageSync(runDirectory, "runState");
|
|
279
267
|
}
|
|
280
268
|
|
|
281
269
|
function parseRoleRunIdentity(raw: unknown, runDirectory: string): {
|
|
@@ -286,15 +274,15 @@ function parseRoleRunIdentity(raw: unknown, runDirectory: string): {
|
|
|
286
274
|
readonly state: RoleRunState;
|
|
287
275
|
} {
|
|
288
276
|
if (!isRecord(raw)) {
|
|
289
|
-
throw new TypeError("Invalid run-state
|
|
277
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
290
278
|
}
|
|
291
279
|
const record = raw;
|
|
292
280
|
if (typeof record.runId !== "string" || record.runId.trim() === "") {
|
|
293
|
-
throw new TypeError("Invalid run-state
|
|
281
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
294
282
|
}
|
|
295
283
|
const role = typeof record.role === "string" ? packagedRoleMetadata(record.role)?.role : undefined;
|
|
296
284
|
if (role === undefined) {
|
|
297
|
-
throw new TypeError("Invalid run-state
|
|
285
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
298
286
|
}
|
|
299
287
|
if (
|
|
300
288
|
record.state !== "admitted" &&
|
|
@@ -302,9 +290,9 @@ function parseRoleRunIdentity(raw: unknown, runDirectory: string): {
|
|
|
302
290
|
record.state !== "resumable" &&
|
|
303
291
|
record.state !== "terminal"
|
|
304
292
|
) {
|
|
305
|
-
throw new TypeError("Invalid run-state
|
|
293
|
+
throw new TypeError("Invalid state.jsonl run-state");
|
|
306
294
|
}
|
|
307
|
-
if (typeof record.bookKey !== "string") throw new TypeError("Invalid run-state
|
|
295
|
+
if (typeof record.bookKey !== "string") throw new TypeError("Invalid state.jsonl run-state");
|
|
308
296
|
return {
|
|
309
297
|
runId: record.runId,
|
|
310
298
|
role,
|
|
@@ -321,9 +309,8 @@ async function readRoleRunStateDisk(
|
|
|
321
309
|
if (raw === undefined) return undefined;
|
|
322
310
|
const identity = parseRoleRunIdentity(raw, runDirectory);
|
|
323
311
|
const record = raw as Record<string, unknown>;
|
|
324
|
-
if (typeof record.projectRoot !== "string") throw new TypeError("Invalid run-state
|
|
325
|
-
if (typeof record.sessionDirectory !== "string") throw new TypeError("Invalid run-state
|
|
326
|
-
if (typeof record.admittedRequestPath !== "string") throw new TypeError("Invalid run-state.json");
|
|
312
|
+
if (typeof record.projectRoot !== "string") throw new TypeError("Invalid state.jsonl run-state");
|
|
313
|
+
if (typeof record.sessionDirectory !== "string") throw new TypeError("Invalid state.jsonl run-state");
|
|
327
314
|
const storedRunDirectory =
|
|
328
315
|
typeof record.runDirectory === "string" && record.runDirectory.trim() !== ""
|
|
329
316
|
? record.runDirectory
|
|
@@ -352,11 +339,6 @@ async function readRoleRunStateDisk(
|
|
|
352
339
|
bookKey: identity.bookKey,
|
|
353
340
|
projectRoot: record.projectRoot,
|
|
354
341
|
runDirectory: runDir,
|
|
355
|
-
admittedRequestPath: rewriteRunDirectoryPathValue(
|
|
356
|
-
record.admittedRequestPath,
|
|
357
|
-
storedRunDirectory,
|
|
358
|
-
runDirectory,
|
|
359
|
-
) as string,
|
|
360
342
|
principalWire,
|
|
361
343
|
...(phase === undefined ? {} : { phase }),
|
|
362
344
|
...(currentCourt === undefined ? {} : { currentCourt }),
|
|
@@ -378,15 +360,10 @@ async function writeRoleRunStateDisk(
|
|
|
378
360
|
...(disk.principalWire.sessionFile === undefined
|
|
379
361
|
? {}
|
|
380
362
|
: { sessionFile: disk.principalWire.sessionFile }),
|
|
381
|
-
admittedRequestPath: disk.admittedRequestPath,
|
|
382
363
|
...(disk.phase === undefined ? {} : { phase: disk.phase }),
|
|
383
364
|
...(disk.currentCourt === undefined ? {} : { currentCourt: disk.currentCourt }),
|
|
384
365
|
};
|
|
385
|
-
|
|
386
|
-
join(runDirectory, RUN_STATE_FILE),
|
|
387
|
-
`${JSON.stringify(payload, null, 2)}\n`,
|
|
388
|
-
"utf8",
|
|
389
|
-
);
|
|
366
|
+
writeSectionSync(runDirectory, "runState", payload);
|
|
390
367
|
}
|
|
391
368
|
|
|
392
369
|
/** One authority.decode of the uninterpreted wire → record + opaque principal (frozen wire itself). */
|
|
@@ -407,7 +384,6 @@ function materializeRoleRunFromDisk(
|
|
|
407
384
|
sessionDirectory: coordinates.sessionDirectory,
|
|
408
385
|
sessionFile: coordinates.sessionFile,
|
|
409
386
|
runDirectory: disk.runDirectory,
|
|
410
|
-
admittedRequestPath: disk.admittedRequestPath,
|
|
411
387
|
...(disk.phase === undefined ? {} : { phase: disk.phase }),
|
|
412
388
|
},
|
|
413
389
|
};
|
|
@@ -466,7 +442,6 @@ export async function markRunAdmitted(
|
|
|
466
442
|
projectRoot: admitted.projectRoot,
|
|
467
443
|
sessionDirectory,
|
|
468
444
|
sessionFile,
|
|
469
|
-
admittedRequestPath: admitted.admittedRequestPath,
|
|
470
445
|
...(workerPhase === undefined ? {} : { phase: workerPhase }),
|
|
471
446
|
});
|
|
472
447
|
}
|
|
@@ -474,7 +449,7 @@ export async function markRunAdmitted(
|
|
|
474
449
|
/**
|
|
475
450
|
* Shared dispatch execution seam: transition to running, then record the
|
|
476
451
|
* effective launch model (initial or resume override) and the authoritative
|
|
477
|
-
* seat engine/host onto invocation.
|
|
452
|
+
* seat engine/host onto the invocation section.
|
|
478
453
|
* Role runners must not coordinate lifecycle ledger writes themselves.
|
|
479
454
|
* Engine axis is authoritative here (#617): present string is written; omit/undefined
|
|
480
455
|
* clears any prior engine key so unset-engine + resume does not keep a stale value.
|
|
@@ -915,31 +890,12 @@ export async function findRunDirectoryById(
|
|
|
915
890
|
if (errorCodeOf(error) === "ENOENT") return undefined;
|
|
916
891
|
throw error;
|
|
917
892
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
runDirectories = await listBookRunDirectories(bookDir);
|
|
925
|
-
} catch (error) {
|
|
926
|
-
if (errorCodeOf(error) === "ENOENT") continue;
|
|
927
|
-
throw error;
|
|
928
|
-
}
|
|
929
|
-
for (const runDirectory of runDirectories) {
|
|
930
|
-
const entry = basename(runDirectory);
|
|
931
|
-
if (
|
|
932
|
-
(onlyRole === undefined && (entry === `${runId}@judge` || entry.startsWith(`${runId}@`))) ||
|
|
933
|
-
entry === `${runId}@${onlyRole}`
|
|
934
|
-
) {
|
|
935
|
-
matches.push(runDirectory);
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
if (matches.length === 0) return undefined;
|
|
940
|
-
if (matches.length === 1) return matches[0];
|
|
941
|
-
throw new Error(
|
|
942
|
-
`ambiguous role run id ${runId}: ${matches.join(", ")}`,
|
|
893
|
+
return findRoleRunDirectory(
|
|
894
|
+
bookKeys
|
|
895
|
+
.filter((bookKey) => onlyBookKey === undefined || bookKey === onlyBookKey)
|
|
896
|
+
.map((bookKey) => activationBookDirectory(ledgerHome, bookKey)),
|
|
897
|
+
runId,
|
|
898
|
+
onlyRole,
|
|
943
899
|
);
|
|
944
900
|
}
|
|
945
901
|
|
|
@@ -963,19 +919,8 @@ export function parentRunPathFromGatePointerInstruction(
|
|
|
963
919
|
export async function readRunParentPath(
|
|
964
920
|
runDirectory: string,
|
|
965
921
|
): Promise<string | undefined> {
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
raw = JSON.parse(
|
|
969
|
-
await readFile(join(runDirectory, "admitted-request.json"), "utf8"),
|
|
970
|
-
);
|
|
971
|
-
} catch (error) {
|
|
972
|
-
if (errorCodeOf(error) === "ENOENT") return undefined;
|
|
973
|
-
throw error;
|
|
974
|
-
}
|
|
975
|
-
if (!isRecord(raw)) {
|
|
976
|
-
return undefined;
|
|
977
|
-
}
|
|
978
|
-
const record = raw;
|
|
922
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
923
|
+
if (record === undefined) return undefined;
|
|
979
924
|
if (typeof record.sourceRunPath === "string" && record.sourceRunPath.trim() !== "") {
|
|
980
925
|
return record.sourceRunPath;
|
|
981
926
|
}
|
|
@@ -999,7 +944,7 @@ async function runHasFormedSessionPrincipal(runDirectory: string): Promise<boole
|
|
|
999
944
|
typeof disk.principalWire.sessionFile === "string" &&
|
|
1000
945
|
disk.principalWire.sessionFile.trim() !== ""
|
|
1001
946
|
? disk.principalWire.sessionFile
|
|
1002
|
-
:
|
|
947
|
+
: sessionFileIn(disk.principalWire.sessionDirectory);
|
|
1003
948
|
try {
|
|
1004
949
|
const stat = await lstat(sessionFile);
|
|
1005
950
|
return stat.isFile() && !stat.isSymbolicLink();
|
|
@@ -1040,17 +985,14 @@ export async function findLatestRunIdForSeatTicket(input: {
|
|
|
1040
985
|
if (errorCodeOf(error) === "ENOENT") return undefined;
|
|
1041
986
|
throw error;
|
|
1042
987
|
}
|
|
1043
|
-
const suffix = `@${input.role}`;
|
|
1044
988
|
let best: string | undefined;
|
|
1045
989
|
for (const runDirectory of runDirectories) {
|
|
1046
|
-
const
|
|
1047
|
-
if (
|
|
1048
|
-
const runId =
|
|
1049
|
-
if (runId.length === 0) continue;
|
|
990
|
+
const parsed = parseRunLeaf(basename(runDirectory));
|
|
991
|
+
if (parsed === undefined || parsed.role !== input.role) continue;
|
|
992
|
+
const runId = parsed.runId;
|
|
1050
993
|
const parentPath = await readRunParentPath(runDirectory);
|
|
1051
|
-
//
|
|
1052
|
-
|
|
1053
|
-
if (parentPath !== input.parentRunPath && basename(parentPath ?? "") !== basename(input.parentRunPath)) continue;
|
|
994
|
+
// Follow the parent's retained placement without collapsing distinct book/subject bindings.
|
|
995
|
+
if (!await retainedRunPathsMatch(parentPath, input.parentRunPath, input.parentRunPath)) continue;
|
|
1054
996
|
// Durable fact: never resume-select a provisional that never formed principal.
|
|
1055
997
|
if (!(await runHasFormedSessionPrincipal(runDirectory))) continue;
|
|
1056
998
|
if (best === undefined || runId > best) best = runId;
|
|
@@ -1148,7 +1090,7 @@ async function loadResumableRunRecord(
|
|
|
1148
1090
|
throw new CliUsageError(`unknown role run id: ${runId}`);
|
|
1149
1091
|
}
|
|
1150
1092
|
const { run, principal } = materialized;
|
|
1151
|
-
// Reconstruct admitted identity from durable run record + admitted
|
|
1093
|
+
// Reconstruct admitted identity from durable run record + the admitted section.
|
|
1152
1094
|
let instruction = "";
|
|
1153
1095
|
let instructionEmpty = true;
|
|
1154
1096
|
let attachments: FrozenAttachment[] = [];
|
|
@@ -1176,11 +1118,9 @@ async function loadResumableRunRecord(
|
|
|
1176
1118
|
let sourceRunPath: string | undefined;
|
|
1177
1119
|
let sourceRun: NotarySourceRunLocator | undefined;
|
|
1178
1120
|
try {
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
if (isRecord(raw)) {
|
|
1183
|
-
const record = raw as Record<string, unknown>;
|
|
1121
|
+
const record = readPageSync(run.runDirectory, "admitted");
|
|
1122
|
+
if (record === undefined) throw new Error("state.jsonl has no admitted-request row");
|
|
1123
|
+
{
|
|
1184
1124
|
const storedRunDirectory =
|
|
1185
1125
|
typeof record.runDirectory === "string" && record.runDirectory.trim() !== ""
|
|
1186
1126
|
? record.runDirectory
|
|
@@ -1226,7 +1166,7 @@ async function loadResumableRunRecord(
|
|
|
1226
1166
|
lens = record.lens;
|
|
1227
1167
|
}
|
|
1228
1168
|
// Collector — admitted repository/PR identity (#633 resume).
|
|
1229
|
-
if (
|
|
1169
|
+
if (isSafePositiveTicketNumber(record.prNumber)) {
|
|
1230
1170
|
prNumber = record.prNumber;
|
|
1231
1171
|
}
|
|
1232
1172
|
if (typeof record.repository === "string" && record.repository.trim() !== "") {
|
|
@@ -1245,7 +1185,7 @@ async function loadResumableRunRecord(
|
|
|
1245
1185
|
waitWindowMs = record.waitWindowMs;
|
|
1246
1186
|
}
|
|
1247
1187
|
// Doctor — admitted single-case identity (#633 resume).
|
|
1248
|
-
if (
|
|
1188
|
+
if (isSafePositiveTicketNumber(record.issueNumber)) {
|
|
1249
1189
|
issueNumber = record.issueNumber;
|
|
1250
1190
|
}
|
|
1251
1191
|
if (typeof record.caseRunsPath === "string" && record.caseRunsPath.trim() !== "") {
|
|
@@ -1256,9 +1196,7 @@ async function loadResumableRunRecord(
|
|
|
1256
1196
|
) {
|
|
1257
1197
|
const ci = record.caseIdentity as Record<string, unknown>;
|
|
1258
1198
|
if (
|
|
1259
|
-
|
|
1260
|
-
Number.isSafeInteger(ci.issueNumber) &&
|
|
1261
|
-
ci.issueNumber >= 1 &&
|
|
1199
|
+
isSafePositiveTicketNumber(ci.issueNumber) &&
|
|
1262
1200
|
typeof ci.runsPath === "string" &&
|
|
1263
1201
|
ci.runsPath.trim() !== ""
|
|
1264
1202
|
) {
|
|
@@ -1341,13 +1279,8 @@ async function loadResumableRunRecord(
|
|
|
1341
1279
|
}
|
|
1342
1280
|
let model: InvocationEffectiveModel | undefined;
|
|
1343
1281
|
try {
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1346
|
-
);
|
|
1347
|
-
if (
|
|
1348
|
-
isRecord(invocationRaw)
|
|
1349
|
-
) {
|
|
1350
|
-
const rec = invocationRaw as Record<string, unknown>;
|
|
1282
|
+
const rec = readPageSync(run.runDirectory, "invocation");
|
|
1283
|
+
if (rec !== undefined) {
|
|
1351
1284
|
if (typeof rec.provider === "string" && typeof rec.model === "string") {
|
|
1352
1285
|
model = {
|
|
1353
1286
|
provider: rec.provider,
|
|
@@ -1376,9 +1309,9 @@ async function loadResumableRunRecord(
|
|
|
1376
1309
|
);
|
|
1377
1310
|
}
|
|
1378
1311
|
}
|
|
1379
|
-
const sourceRunLeaf = basename(sourceRunPath ?? "")
|
|
1380
|
-
const referencedRunId = sourceRun?.runId ?? sourceRunLeaf
|
|
1381
|
-
const referencedRole = sourceRun?.role ?? sourceRunLeaf
|
|
1312
|
+
const sourceRunLeaf = parseRunLeaf(basename(sourceRunPath ?? ""));
|
|
1313
|
+
const referencedRunId = sourceRun?.runId ?? sourceRunLeaf?.runId;
|
|
1314
|
+
const referencedRole = sourceRun?.role ?? sourceRunLeaf?.role;
|
|
1382
1315
|
if (referencedRunId !== undefined && referencedRunId !== "") {
|
|
1383
1316
|
const currentSourceRunDirectory = await findRunDirectoryById(
|
|
1384
1317
|
home,
|
|
@@ -1446,7 +1379,6 @@ function resumedBaseAdmitted(loaded: {
|
|
|
1446
1379
|
attachments: loaded.admittedFields.attachments,
|
|
1447
1380
|
runDirectory: loaded.run.runDirectory,
|
|
1448
1381
|
principal: loaded.principal,
|
|
1449
|
-
admittedRequestPath: loaded.run.admittedRequestPath,
|
|
1450
1382
|
...(loaded.admittedFields.model === undefined ? {} : { model: loaded.admittedFields.model }),
|
|
1451
1383
|
...restoredTicketFields(loaded.admittedFields),
|
|
1452
1384
|
};
|