@akagilnc/pi-workflow-roles 0.1.5365 → 0.1.5375
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 +5585 -5655
- package/dist/activation-ledger-git.js +2 -2
- package/dist/activation-ledger-topology.js +1 -7
- package/dist/analyst-entry.js +4 -8
- package/dist/analyst-gate-cycles-read.js +3 -11
- package/dist/analyst-index.js +3 -9
- package/dist/analyst-ledger.js +1 -11
- package/dist/analyst-metric-families/acceptance-success-rework.js +1 -3
- package/dist/analyst-metric-families/round-timeline.js +1 -3
- package/dist/analyst-page.js +2 -2
- package/dist/archivist-record-topology.js +2 -2
- package/dist/audit-escalation.js +2 -1
- package/dist/auditor-soul.js +2 -1
- package/dist/collector-config.js +6 -8
- package/dist/compliance-transport.js +2 -1
- package/dist/countersign-contracts.js +2 -1
- package/dist/diarist-contracts.js +3 -2
- package/dist/doctor-contracts.js +1 -3
- package/dist/doctor-evidence.js +7 -8
- package/dist/dossier-resolution.js +1 -3
- package/dist/engine-detour-usage.js +1 -3
- package/dist/gatekeeper-role.js +2 -9
- package/dist/gleaner-left-contracts.js +2 -1
- package/dist/headless-host/description.js +14 -17
- package/dist/headless-host/production-host.js +1665 -1737
- package/dist/host-session-record.js +3 -2
- package/dist/inspector-contracts.js +2 -1
- package/dist/ledger-session-read.js +1 -3
- package/dist/merger-contracts.js +9 -9
- package/dist/migrate-book-topology.js +348 -314
- package/dist/navigator-attendance.js +9 -11
- package/dist/navigator-invocation-identity.js +3 -2
- package/dist/navigator-public-session.js +3 -5
- package/dist/navigator-session-contracts.js +8 -10
- package/dist/navigator-work-base.js +5 -8
- package/dist/notary-contracts.js +3 -5
- package/dist/package-contracts/auditor-output.js +1 -3
- package/dist/package-contracts/fixer-packet.js +3 -6
- package/dist/package-contracts/gatekeeper-output.js +1 -3
- package/dist/package-contracts/navigator-output.js +8 -8
- package/dist/package-contracts/terminating-infrastructure.js +5 -9
- package/dist/package-contracts/terminating-tools.js +4 -3
- package/dist/public-cli/analyst-run.js +3 -2
- package/dist/public-cli/auto-resume.js +4 -9
- package/dist/public-cli/cli.js +66 -64
- package/dist/public-cli/config.js +12 -11
- package/dist/public-cli/countersign-run.js +1 -3
- package/dist/public-cli/host-providers.js +7 -14
- package/dist/public-cli/instruction-seat-run.js +69 -43
- package/dist/public-cli/invocation.js +141 -136
- package/dist/public-cli/main.js +1919 -1968
- package/dist/public-cli/post-admission.js +89 -89
- package/dist/public-cli/role-seat-runtime.js +29 -0
- package/dist/public-cli/run-lifecycle.js +20 -32
- package/dist/public-cli/settlement.js +10 -26
- package/dist/public-cli/turn-request.js +14 -0
- package/dist/public-role-summons.js +23 -35
- package/dist/receipt-delivery-policy.js +1 -3
- package/dist/role-run-placement.js +7 -5
- package/dist/role-run-relocation.js +12 -19
- package/dist/run-terminal-artifacts.js +1 -11
- package/dist/run-ticket-number.js +2 -4
- package/dist/session-assistant-usage.js +2 -1
- package/dist/session-dialogue.js +1 -14
- package/dist/sitian-reader.js +2 -4
- package/dist/submission-correctable-error.js +2 -1
- package/dist/submission-errors.js +2 -1
- package/dist/submission-gate.js +2 -1
- package/dist/submission-ledger.js +4 -5
- package/dist/ticket-provenance-contracts.js +1 -3
- package/dist/ticket-provenance.js +2 -1
- package/dist/typed-provider-http.js +4 -7
- package/dist/unknown-value.js +28 -0
- package/dist/user-dialogue-stdin.js +2 -1
- package/package.json +1 -1
- package/src/acp-host/role-turn-host.ts +4 -2
- package/src/activation-ledger-git.ts +3 -2
- package/src/activation-ledger-topology.ts +4 -12
- package/src/analyst-entry.ts +3 -11
- package/src/analyst-gate-cycles-read.ts +3 -15
- package/src/analyst-index.ts +3 -13
- package/src/analyst-ledger.ts +2 -16
- package/src/analyst-metric-families/acceptance-success-rework.ts +2 -4
- package/src/analyst-metric-families/round-timeline.ts +2 -4
- package/src/analyst-page.ts +2 -2
- package/src/archivist-record-topology.ts +2 -2
- package/src/audit-escalation.ts +2 -1
- package/src/auditor-soul.ts +3 -1
- package/src/book-topology-migration-placement.ts +8 -21
- package/src/book-topology-migrators-t11.ts +16 -15
- package/src/book-topology-mixed-volume-migrators.ts +3 -6
- package/src/book-topology-record-class-migrators.ts +7 -10
- package/src/book-topology-runs-migrator.ts +4 -3
- package/src/collector-config.ts +7 -9
- package/src/compliance-transport.ts +2 -1
- package/src/countersign-contracts.ts +2 -1
- package/src/diarist-contracts.ts +3 -2
- package/src/doctor-contracts.ts +3 -1
- package/src/doctor-evidence.ts +8 -7
- package/src/doctor-role.ts +4 -2
- package/src/dossier-resolution.ts +2 -4
- package/src/engine-detour-tool.ts +0 -2
- package/src/engine-detour-usage.ts +2 -4
- package/src/external-host-turn-loop.ts +3 -1
- package/src/factory-board.ts +1 -8
- package/src/gatekeeper-role.ts +2 -10
- package/src/gleaner-left-contracts.ts +3 -1
- package/src/headless-host/description.ts +15 -18
- package/src/headless-host/role-turn-host.ts +10 -9
- package/src/host-session-record.ts +4 -2
- package/src/inspector-contracts.ts +2 -1
- package/src/ledger-session-read.ts +2 -5
- package/src/merger-contracts.ts +10 -9
- package/src/navigator-attendance.ts +10 -12
- package/src/navigator-invocation-identity.ts +3 -2
- package/src/navigator-public-session.ts +4 -6
- package/src/navigator-session-contracts.ts +8 -11
- package/src/navigator-work-base.ts +5 -8
- package/src/navigator-work-context.ts +2 -1
- package/src/notary-contracts.ts +4 -6
- package/src/oauth-keepalive.ts +5 -18
- package/src/package-contracts/auditor-output.ts +2 -4
- package/src/package-contracts/fixer-packet.ts +4 -6
- package/src/package-contracts/gatekeeper-output.ts +2 -4
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +8 -8
- package/src/package-contracts/terminating-infrastructure.ts +6 -20
- package/src/package-contracts/terminating-tools.ts +8 -12
- package/src/pi/adapter.ts +0 -1
- package/src/pi/role-turn-host.ts +0 -1
- package/src/public-cli/analyst-run.ts +4 -2
- package/src/public-cli/auto-resume.ts +5 -12
- package/src/public-cli/cli.ts +77 -83
- package/src/public-cli/config.ts +16 -27
- package/src/public-cli/countersign-run.ts +2 -4
- package/src/public-cli/host-providers.ts +10 -27
- package/src/public-cli/instruction-seat-run.ts +87 -58
- package/src/public-cli/invocation.ts +159 -172
- package/src/public-cli/post-admission.ts +115 -103
- package/src/public-cli/role-seat-runtime.ts +72 -0
- package/src/public-cli/run-lifecycle.ts +27 -67
- package/src/public-cli/settlement.ts +11 -33
- package/src/public-cli/terminal.ts +2 -17
- package/src/public-cli/turn-request.ts +26 -0
- package/src/public-role-summons.ts +24 -48
- package/src/receipt-delivery-policy.ts +1 -4
- package/src/reviewer-role.ts +0 -1
- package/src/role-envelope.ts +5 -3
- package/src/role-run-placement.ts +9 -10
- package/src/role-run-relocation.ts +13 -23
- package/src/role-runtime.ts +9 -15
- package/src/run-terminal-artifacts.ts +2 -16
- package/src/run-ticket-number.ts +4 -10
- package/src/session-assistant-usage.ts +3 -1
- package/src/session-dialogue.ts +1 -4
- package/src/session-identity.ts +0 -1
- package/src/sitian-reader.ts +2 -4
- package/src/submission-correctable-error.ts +3 -1
- package/src/submission-errors.ts +2 -1
- package/src/submission-gate.ts +3 -1
- package/src/submission-ledger.ts +5 -6
- package/src/ticket-provenance-contracts.ts +1 -4
- package/src/ticket-provenance.ts +3 -1
- package/src/ticket-snapshot.ts +2 -4
- package/src/ticket-trajectory.ts +1 -8
- package/src/typed-provider-http.ts +5 -15
- package/src/unknown-value.ts +34 -0
- package/src/user-dialogue-stdin.ts +3 -1
- package/src/worker-role.ts +2 -5
- package/src/worker-submission-gates.ts +5 -7
|
@@ -27,6 +27,7 @@ import { resolveBookKeyFromGit } from "../activation-ledger-git.ts";
|
|
|
27
27
|
import {
|
|
28
28
|
ensureRoleRunDirectory,
|
|
29
29
|
ensureRoleRunPlacement,
|
|
30
|
+
isUnboundRunDirectory,
|
|
30
31
|
listBookRunDirectories,
|
|
31
32
|
roleRunArtifactsDirectory,
|
|
32
33
|
roleRunPlacement,
|
|
@@ -36,7 +37,7 @@ import type {
|
|
|
36
37
|
DurablePrincipal,
|
|
37
38
|
DurablePrincipalAuthority,
|
|
38
39
|
} from "../host-contracts.ts";
|
|
39
|
-
import type { PackagedRole } from "../packaged-role-registry.ts";
|
|
40
|
+
import type { PackagedRole, PublicRoleRecord } from "../packaged-role-registry.ts";
|
|
40
41
|
import {
|
|
41
42
|
packagedAdmittedSubject,
|
|
42
43
|
packagedArgvResult,
|
|
@@ -109,6 +110,8 @@ import {
|
|
|
109
110
|
} from "./option-definitions.ts";
|
|
110
111
|
import type { PublicThinkingLevel } from "./registry.ts";
|
|
111
112
|
|
|
113
|
+
import { errorText, isRecord } from "../unknown-value.ts";
|
|
114
|
+
|
|
112
115
|
export type FrozenAttachment = {
|
|
113
116
|
/** Original caller path retained only as provenance. */
|
|
114
117
|
readonly provenancePath: string;
|
|
@@ -445,39 +448,46 @@ export async function recordEffectiveInvocationModel(
|
|
|
445
448
|
host?: string,
|
|
446
449
|
engineModel?: string | null,
|
|
447
450
|
): Promise<void> {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
delete next.thinking;
|
|
459
|
-
} else {
|
|
460
|
-
next.thinking = model.thinking;
|
|
451
|
+
await updateDurableJsonPage(join(runDirectory, "invocation.json"), (current) => {
|
|
452
|
+
const next: Record<string, unknown> = { ...current };
|
|
453
|
+
if (model !== undefined) {
|
|
454
|
+
next.provider = model.provider;
|
|
455
|
+
next.model = model.model;
|
|
456
|
+
if (model.thinking === undefined) {
|
|
457
|
+
delete next.thinking;
|
|
458
|
+
} else {
|
|
459
|
+
next.thinking = model.thinking;
|
|
460
|
+
}
|
|
461
461
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
462
|
+
if (engine === null) {
|
|
463
|
+
delete next.engine;
|
|
464
|
+
} else if (engine !== undefined) {
|
|
465
|
+
next.engine = engine;
|
|
466
|
+
}
|
|
467
|
+
if (engineModel === null) {
|
|
468
|
+
delete next.engineModel;
|
|
469
|
+
} else if (engineModel !== undefined) {
|
|
470
|
+
next.engineModel = engineModel;
|
|
471
|
+
}
|
|
472
|
+
if (host !== undefined) {
|
|
473
|
+
next.host = host;
|
|
474
|
+
}
|
|
475
|
+
return next;
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Read one durable JSON object, let the caller keep its field rules, and write
|
|
481
|
+
* the page back. `undefined` means the caller decided not to change the page.
|
|
482
|
+
*/
|
|
483
|
+
async function updateDurableJsonPage(
|
|
484
|
+
path: string,
|
|
485
|
+
update: (current: Record<string, unknown>) => Record<string, unknown> | undefined,
|
|
486
|
+
): Promise<void> {
|
|
487
|
+
const current = JSON.parse(await readFile(path, "utf8")) as Record<string, unknown>;
|
|
488
|
+
const next = update(current);
|
|
489
|
+
if (next === undefined) return;
|
|
490
|
+
await writeFile(path, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
481
491
|
}
|
|
482
492
|
|
|
483
493
|
/** Merge observed launch-time fields into the single existing invocation.json identity page. */
|
|
@@ -485,16 +495,10 @@ async function mergeInvocationIdentityPage(
|
|
|
485
495
|
runDirectory: string,
|
|
486
496
|
fields: Record<string, unknown>,
|
|
487
497
|
): Promise<void> {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
`${JSON.stringify({
|
|
493
|
-
...current,
|
|
494
|
-
...fields,
|
|
495
|
-
}, null, 2)}\n`,
|
|
496
|
-
"utf8",
|
|
497
|
-
);
|
|
498
|
+
await updateDurableJsonPage(join(runDirectory, "invocation.json"), (current) => ({
|
|
499
|
+
...current,
|
|
500
|
+
...fields,
|
|
501
|
+
}));
|
|
498
502
|
}
|
|
499
503
|
|
|
500
504
|
/**
|
|
@@ -509,27 +513,20 @@ export async function persistAdmittedSourceRunPath(
|
|
|
509
513
|
if (sourceRunPath.trim() === "") {
|
|
510
514
|
throw new Error("persistAdmittedSourceRunPath requires a non-empty sourceRunPath");
|
|
511
515
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
const sameSubject = auditorSubject === undefined || current.auditorSubject === auditorSubject;
|
|
523
|
-
if (current.sourceRunPath === sourceRunPath && sameSubject) return;
|
|
524
|
-
await writeFile(
|
|
525
|
-
admittedPath,
|
|
526
|
-
`${JSON.stringify({
|
|
516
|
+
await updateDurableJsonPage(admitted.admittedRequestPath, (current) => {
|
|
517
|
+
if (typeof current.sourceRunPath === "string" && current.sourceRunPath !== sourceRunPath) {
|
|
518
|
+
throw new Error(
|
|
519
|
+
`persistAdmittedSourceRunPath refuses to replace ${current.sourceRunPath} with ${sourceRunPath}`,
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
const sameSubject = auditorSubject === undefined || current.auditorSubject === auditorSubject;
|
|
523
|
+
if (current.sourceRunPath === sourceRunPath && sameSubject) return undefined;
|
|
524
|
+
return {
|
|
527
525
|
...current,
|
|
528
526
|
sourceRunPath,
|
|
529
527
|
...(auditorSubject === undefined ? {} : { auditorSubject }),
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
);
|
|
528
|
+
};
|
|
529
|
+
});
|
|
533
530
|
}
|
|
534
531
|
|
|
535
532
|
/**
|
|
@@ -551,25 +548,21 @@ export async function recordAdmittedCorrelation(
|
|
|
551
548
|
admitted: AdmittedRoleInvocation,
|
|
552
549
|
correlationId: string,
|
|
553
550
|
): Promise<void> {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
)
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
admitted.admittedRequestPath,
|
|
570
|
-
`${JSON.stringify({ ...current, correlationId, correlationIds }, null, 2)}\n`,
|
|
571
|
-
"utf8",
|
|
572
|
-
);
|
|
551
|
+
let correlationIds: string[] = [];
|
|
552
|
+
await updateDurableJsonPage(admitted.admittedRequestPath, (current) => {
|
|
553
|
+
const prior = [
|
|
554
|
+
...(Array.isArray(current.correlationIds)
|
|
555
|
+
? current.correlationIds.filter((value): value is string =>
|
|
556
|
+
typeof value === "string" && value.trim() !== ""
|
|
557
|
+
)
|
|
558
|
+
: []),
|
|
559
|
+
...(typeof current.correlationId === "string" && current.correlationId.trim() !== ""
|
|
560
|
+
? [current.correlationId]
|
|
561
|
+
: []),
|
|
562
|
+
];
|
|
563
|
+
correlationIds = [...new Set([...prior, correlationId])];
|
|
564
|
+
return { ...current, correlationId, correlationIds };
|
|
565
|
+
});
|
|
573
566
|
await mergeInvocationIdentityPage(admitted.runDirectory, {
|
|
574
567
|
correlationId,
|
|
575
568
|
correlationIds,
|
|
@@ -588,7 +581,7 @@ export async function relocateAdmittedRunToTicket(
|
|
|
588
581
|
authority: DurablePrincipalAuthority,
|
|
589
582
|
heldLease?: { relocate(runDirectory: string): void },
|
|
590
583
|
): Promise<RunDirectoryRelocation | undefined> {
|
|
591
|
-
if (admitted.ticketNumber === undefined || !admitted.runDirectory
|
|
584
|
+
if (admitted.ticketNumber === undefined || !isUnboundRunDirectory(admitted.runDirectory)) return undefined;
|
|
592
585
|
const oldRunDirectory = admitted.runDirectory;
|
|
593
586
|
const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(oldRunDirectory));
|
|
594
587
|
const target = roleRunPlacement(ledgerHome, {
|
|
@@ -670,12 +663,13 @@ export async function recordChildDiaristRun(
|
|
|
670
663
|
parent: AdmittedRoleInvocation,
|
|
671
664
|
childRunId: string,
|
|
672
665
|
): Promise<void> {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
666
|
+
await updateDurableJsonPage(parent.admittedRequestPath, (page) => {
|
|
667
|
+
const existing = Array.isArray(page.childDiaristRunIds)
|
|
668
|
+
? page.childDiaristRunIds.filter((runId): runId is string => typeof runId === "string")
|
|
669
|
+
: [];
|
|
670
|
+
const childDiaristRunIds = existing.includes(childRunId) ? existing : [...existing, childRunId];
|
|
671
|
+
return { ...page, childDiaristRunIds };
|
|
672
|
+
});
|
|
679
673
|
}
|
|
680
674
|
|
|
681
675
|
/**
|
|
@@ -692,16 +686,15 @@ export async function bindTicketNumberOnRunDirectory(
|
|
|
692
686
|
"bindTicketNumberOnRunDirectory",
|
|
693
687
|
);
|
|
694
688
|
const admittedPath = join(runDirectory, "admitted-request.json");
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
);
|
|
689
|
+
let unchanged = false;
|
|
690
|
+
await updateDurableJsonPage(admittedPath, (admitted) => {
|
|
691
|
+
if (admitted.ticketNumber === ticketNumber) {
|
|
692
|
+
unchanged = true;
|
|
693
|
+
return undefined;
|
|
694
|
+
}
|
|
695
|
+
return { ...admitted, ticketNumber };
|
|
696
|
+
});
|
|
697
|
+
if (unchanged) return;
|
|
705
698
|
await mergeInvocationIdentityPage(runDirectory, { ticketNumber });
|
|
706
699
|
}
|
|
707
700
|
|
|
@@ -1097,20 +1090,34 @@ function requireOptionPath(
|
|
|
1097
1090
|
* next option), and a leading `-` (read as the next Skill option). Not a
|
|
1098
1091
|
* general free-text gate — only the projection admission seam.
|
|
1099
1092
|
*/
|
|
1093
|
+
function skillArgTokenFault(
|
|
1094
|
+
value: string | undefined,
|
|
1095
|
+
): "empty" | "whitespace" | "optionLike" | undefined {
|
|
1096
|
+
if (value === undefined || value.trim() === "") return "empty";
|
|
1097
|
+
if (/\s/.test(value)) return "whitespace";
|
|
1098
|
+
if (value.startsWith("-")) return "optionLike";
|
|
1099
|
+
return undefined;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1100
1102
|
function requireSkillArgToken(
|
|
1101
1103
|
value: string | undefined,
|
|
1102
1104
|
messages: { empty: string; whitespace: string; optionLike: string },
|
|
1103
1105
|
): string {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1106
|
+
const fault = skillArgTokenFault(value);
|
|
1107
|
+
if (fault !== undefined) throw new CliUsageError(messages[fault]);
|
|
1108
|
+
return value as string;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* Durable reviewer base on resume. Same token rule as fresh `--base`,
|
|
1113
|
+
* with the resume-owned missing/damaged split.
|
|
1114
|
+
*/
|
|
1115
|
+
export function admittedReviewerBaseFault(
|
|
1116
|
+
value: string | undefined,
|
|
1117
|
+
): "missing" | "damaged" | undefined {
|
|
1118
|
+
const fault = skillArgTokenFault(value);
|
|
1119
|
+
if (fault === undefined) return undefined;
|
|
1120
|
+
return fault === "empty" ? "missing" : "damaged";
|
|
1114
1121
|
}
|
|
1115
1122
|
|
|
1116
1123
|
/**
|
|
@@ -1420,6 +1427,11 @@ export type PublicSeatParse = {
|
|
|
1420
1427
|
* Sole admit call. Kind comes from the composition-root record.
|
|
1421
1428
|
* Placement stays ticketAdmissionFields. Seat field checks live in this function only.
|
|
1422
1429
|
*/
|
|
1430
|
+
type RoleForAdmission<K extends PublicRoleRecord["admission"]> = Extract<
|
|
1431
|
+
PublicRoleRecord,
|
|
1432
|
+
{ readonly admission: K }
|
|
1433
|
+
>["role"];
|
|
1434
|
+
|
|
1423
1435
|
export function admitPublicRole<R extends PackagedRole>(
|
|
1424
1436
|
role: R,
|
|
1425
1437
|
parsed: PublicSeatParse,
|
|
@@ -1427,6 +1439,8 @@ export function admitPublicRole<R extends PackagedRole>(
|
|
|
1427
1439
|
override?: {
|
|
1428
1440
|
readonly assertedTicketNumber?: number;
|
|
1429
1441
|
readonly deferPersistence?: boolean;
|
|
1442
|
+
/** Locator already resolved on the new-summon path. Absent callers still resolve. */
|
|
1443
|
+
readonly resolvedSourceRun?: NotarySourceRunLocator;
|
|
1430
1444
|
},
|
|
1431
1445
|
): Promise<Extract<AdmittedRoleInvocation, { readonly role: R }>>;
|
|
1432
1446
|
export async function admitPublicRole(
|
|
@@ -1436,6 +1450,8 @@ export async function admitPublicRole(
|
|
|
1436
1450
|
override?: {
|
|
1437
1451
|
readonly assertedTicketNumber?: number;
|
|
1438
1452
|
readonly deferPersistence?: boolean;
|
|
1453
|
+
/** Locator already resolved on the new-summon path. Absent callers still resolve. */
|
|
1454
|
+
readonly resolvedSourceRun?: NotarySourceRunLocator;
|
|
1439
1455
|
},
|
|
1440
1456
|
): Promise<AdmittedRoleInvocation> {
|
|
1441
1457
|
const record = packagedRoleMetadata(role);
|
|
@@ -1454,7 +1470,7 @@ export async function admitPublicRole(
|
|
|
1454
1470
|
switch (record.admission) {
|
|
1455
1471
|
case "instruction":
|
|
1456
1472
|
return admitStandardMaterialInvocation(
|
|
1457
|
-
role as "
|
|
1473
|
+
role as RoleForAdmission<"instruction">,
|
|
1458
1474
|
{
|
|
1459
1475
|
...shared,
|
|
1460
1476
|
instruction,
|
|
@@ -1493,9 +1509,6 @@ export async function admitPublicRole(
|
|
|
1493
1509
|
});
|
|
1494
1510
|
}
|
|
1495
1511
|
case "worker-packet": {
|
|
1496
|
-
if (parsed.project !== undefined) {
|
|
1497
|
-
requireOptionPath("--project", parsed.project);
|
|
1498
|
-
}
|
|
1499
1512
|
if (instruction.trim() === "") {
|
|
1500
1513
|
throw new CliUsageError("fixer requires a nonblank repair instruction");
|
|
1501
1514
|
}
|
|
@@ -1553,25 +1566,14 @@ export async function admitPublicRole(
|
|
|
1553
1566
|
});
|
|
1554
1567
|
}
|
|
1555
1568
|
case "collect-target": {
|
|
1556
|
-
|
|
1557
|
-
requireOptionPath("--project", parsed.project);
|
|
1558
|
-
}
|
|
1559
|
-
let explicitPrNumber: number | undefined;
|
|
1560
|
-
if (parsed.prNumber !== undefined) {
|
|
1561
|
-
try {
|
|
1562
|
-
explicitPrNumber = parseCollectorPrNumber(parsed.prNumber);
|
|
1563
|
-
} catch (error) {
|
|
1564
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
1565
|
-
throw new CliUsageError(detail, { cause: error });
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1569
|
+
const explicitPrNumber = parsed.prNumber;
|
|
1568
1570
|
const projectRoot = resolve(parsed.project ?? shared.cwd);
|
|
1569
1571
|
let repository: CollectorRepository;
|
|
1570
1572
|
if (parsed.repo !== undefined) {
|
|
1571
1573
|
try {
|
|
1572
1574
|
repository = parseCollectorRepository(parsed.repo);
|
|
1573
1575
|
} catch (error) {
|
|
1574
|
-
const detail =
|
|
1576
|
+
const detail = errorText(error);
|
|
1575
1577
|
throw new CliUsageError(detail, { cause: error });
|
|
1576
1578
|
}
|
|
1577
1579
|
} else {
|
|
@@ -1585,7 +1587,7 @@ export async function admitPublicRole(
|
|
|
1585
1587
|
manifestCanonicalJson = manifest.canonicalJson;
|
|
1586
1588
|
} catch (error) {
|
|
1587
1589
|
throw new CliUsageError(
|
|
1588
|
-
|
|
1590
|
+
errorText(error),
|
|
1589
1591
|
{ cause: error },
|
|
1590
1592
|
);
|
|
1591
1593
|
}
|
|
@@ -1615,19 +1617,12 @@ export async function admitPublicRole(
|
|
|
1615
1617
|
return { ...admittedCollector, repository };
|
|
1616
1618
|
}
|
|
1617
1619
|
case "case-identity": {
|
|
1618
|
-
if (parsed.
|
|
1619
|
-
requireOptionPath("--project", parsed.project);
|
|
1620
|
-
}
|
|
1621
|
-
const issueNumber = parsed.issueNumber ?? Number.NaN;
|
|
1622
|
-
if (
|
|
1623
|
-
!Number.isInteger(issueNumber) ||
|
|
1624
|
-
issueNumber < 1 ||
|
|
1625
|
-
!DOCTOR_ISSUE_NUMBER_PATTERN.test(String(issueNumber))
|
|
1626
|
-
) {
|
|
1620
|
+
if (parsed.issueNumber === undefined) {
|
|
1627
1621
|
throw new CliUsageError(
|
|
1628
|
-
`doctor --issue must be a positive integer, got ${
|
|
1622
|
+
`doctor --issue must be a positive integer, got ${Number.NaN}`,
|
|
1629
1623
|
);
|
|
1630
1624
|
}
|
|
1625
|
+
const issueNumber = parsed.issueNumber;
|
|
1631
1626
|
let frozenAttachments: readonly FrozenAttachment[] = [];
|
|
1632
1627
|
const admittedDoctor = await admitStandardMaterialInvocation("doctor", {
|
|
1633
1628
|
...shared,
|
|
@@ -1647,7 +1642,7 @@ export async function admitPublicRole(
|
|
|
1647
1642
|
});
|
|
1648
1643
|
} catch (error) {
|
|
1649
1644
|
if (error instanceof CliUsageError) throw error;
|
|
1650
|
-
const detail =
|
|
1645
|
+
const detail = errorText(error);
|
|
1651
1646
|
throw new CliUsageError(detail, { cause: error });
|
|
1652
1647
|
}
|
|
1653
1648
|
if (parsed.runs === undefined) {
|
|
@@ -1665,7 +1660,7 @@ export async function admitPublicRole(
|
|
|
1665
1660
|
caseRunsPath = await realpath(caseRunsPath);
|
|
1666
1661
|
} catch (error) {
|
|
1667
1662
|
if (error instanceof CliUsageError) throw error;
|
|
1668
|
-
const detail =
|
|
1663
|
+
const detail = errorText(error);
|
|
1669
1664
|
throw new CliUsageError(
|
|
1670
1665
|
`doctor case could not be constructed from retained evidence: ${detail}`,
|
|
1671
1666
|
{ cause: error },
|
|
@@ -1683,22 +1678,21 @@ export async function admitPublicRole(
|
|
|
1683
1678
|
return { ...admittedDoctor, attachments: frozenAttachments };
|
|
1684
1679
|
}
|
|
1685
1680
|
case "source-locator": {
|
|
1686
|
-
if (parsed.project !== undefined) {
|
|
1687
|
-
requireOptionPath("--project", parsed.project);
|
|
1688
|
-
}
|
|
1689
1681
|
const projectRoot = resolve(parsed.project ?? shared.cwd);
|
|
1690
|
-
let sourceRun
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1682
|
+
let sourceRun = override?.resolvedSourceRun;
|
|
1683
|
+
if (sourceRun === undefined) {
|
|
1684
|
+
try {
|
|
1685
|
+
sourceRun = await resolveNotarySourceRunLocator({
|
|
1686
|
+
projectRoot,
|
|
1687
|
+
sourceRun: parsed.sourceRun ?? "",
|
|
1688
|
+
home: shared.home,
|
|
1689
|
+
});
|
|
1690
|
+
} catch (error) {
|
|
1691
|
+
if (error instanceof NotarySourceRunError) {
|
|
1692
|
+
throw new CliUsageError(error.message, { cause: error });
|
|
1693
|
+
}
|
|
1694
|
+
throw error;
|
|
1700
1695
|
}
|
|
1701
|
-
throw error;
|
|
1702
1696
|
}
|
|
1703
1697
|
// Board ticket on the source run wins; otherwise the summons ticket. Code does not infer one.
|
|
1704
1698
|
const inheritedTicketNumber = await readBoardTicketNumber(sourceRun.runDirectory);
|
|
@@ -1719,9 +1713,6 @@ export async function admitPublicRole(
|
|
|
1719
1713
|
});
|
|
1720
1714
|
}
|
|
1721
1715
|
case "gleaner": {
|
|
1722
|
-
if (parsed.project !== undefined) {
|
|
1723
|
-
requireOptionPath("--project", parsed.project);
|
|
1724
|
-
}
|
|
1725
1716
|
const baseRevision = parsed.baseRevision ?? "";
|
|
1726
1717
|
if (baseRevision.trim() === "") {
|
|
1727
1718
|
throw new CliUsageError("--base requires a nonempty revision");
|
|
@@ -1736,16 +1727,19 @@ export async function admitPublicRole(
|
|
|
1736
1727
|
});
|
|
1737
1728
|
}
|
|
1738
1729
|
case "review-basis": {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1730
|
+
if (parsed.lens === undefined) {
|
|
1731
|
+
throw new CliUsageError("--lens requires completeness or correctness");
|
|
1732
|
+
}
|
|
1733
|
+
if (parsed.baseRevision === undefined) {
|
|
1734
|
+
throw new CliUsageError("--base requires a nonempty revision");
|
|
1742
1735
|
}
|
|
1743
|
-
const baseRevision = requireReviewerBaseRevision(parsed.baseRevision);
|
|
1744
1736
|
const rawRefs = parsed.authorityRefs ?? [];
|
|
1745
1737
|
if (rawRefs.length === 0) {
|
|
1746
1738
|
throw new CliUsageError("reviewer requires --authority-ref <ref>");
|
|
1747
1739
|
}
|
|
1748
|
-
const
|
|
1740
|
+
const lens = parsed.lens;
|
|
1741
|
+
const baseRevision = parsed.baseRevision;
|
|
1742
|
+
const authorityRefs = Object.freeze([...rawRefs]);
|
|
1749
1743
|
const admittedReviewer = await admitStandardMaterialInvocation("reviewer", {
|
|
1750
1744
|
...shared,
|
|
1751
1745
|
instruction,
|
|
@@ -1760,9 +1754,6 @@ export async function admitPublicRole(
|
|
|
1760
1754
|
return { ...admittedReviewer, authorityRefs };
|
|
1761
1755
|
}
|
|
1762
1756
|
case "merge-envelope": {
|
|
1763
|
-
if (parsed.project !== undefined) {
|
|
1764
|
-
requireOptionPath("--project", parsed.project);
|
|
1765
|
-
}
|
|
1766
1757
|
if (instruction.trim() === "") {
|
|
1767
1758
|
throw new CliUsageError("merger requires a nonblank task instruction");
|
|
1768
1759
|
}
|
|
@@ -1885,9 +1876,6 @@ async function placeRoleAdmission(options: {
|
|
|
1885
1876
|
/** Countersign reserves coordinates, then materializes after identity lookup. */
|
|
1886
1877
|
readonly materialize?: boolean;
|
|
1887
1878
|
}): Promise<PlacedRoleAdmission> {
|
|
1888
|
-
if (options.project !== undefined) {
|
|
1889
|
-
requireOptionPath("--project", options.project);
|
|
1890
|
-
}
|
|
1891
1879
|
const projectRoot = resolve(options.project ?? options.cwd);
|
|
1892
1880
|
const runId = options.runId ?? (options.createRunId ?? uuidv7)();
|
|
1893
1881
|
const ticketFields = ticketAdmissionFields(options.assertedTicketNumber);
|
|
@@ -1988,7 +1976,7 @@ async function persistPlacedAdmission(
|
|
|
1988
1976
|
* doctor resolves the case, then freezes attachments; merger writes merger-input.json).
|
|
1989
1977
|
*/
|
|
1990
1978
|
async function admitStandardMaterialInvocation<
|
|
1991
|
-
R extends
|
|
1979
|
+
R extends PackagedRole,
|
|
1992
1980
|
Extra extends object = {},
|
|
1993
1981
|
>(
|
|
1994
1982
|
role: R,
|
|
@@ -2217,8 +2205,8 @@ export async function loadAdmittedJudgeRequest(
|
|
|
2217
2205
|
const raw = JSON.parse(
|
|
2218
2206
|
await readFile(join(runDirectory, "admitted-request.json"), "utf8"),
|
|
2219
2207
|
) as unknown;
|
|
2220
|
-
if (
|
|
2221
|
-
const record = raw
|
|
2208
|
+
if (!isRecord(raw)) return undefined;
|
|
2209
|
+
const record = raw;
|
|
2222
2210
|
if (!packagedPublicInstructionSubject(record.role)) return undefined;
|
|
2223
2211
|
if (typeof record.instruction !== "string") return undefined;
|
|
2224
2212
|
if (typeof record.instructionEmpty !== "boolean") return undefined;
|
|
@@ -2260,7 +2248,7 @@ export type AdmitFixerInvocationOptions = {
|
|
|
2260
2248
|
|
|
2261
2249
|
function parsePositivePrOption(raw: string | undefined): number {
|
|
2262
2250
|
if (raw === undefined || raw.trim() === "") throw new CliUsageError("--pr requires a positive pull request number");
|
|
2263
|
-
try { return parseCollectorPrNumber(raw); } catch (error) { throw new CliUsageError(
|
|
2251
|
+
try { return parseCollectorPrNumber(raw); } catch (error) { throw new CliUsageError(errorText(error), { cause: error }); }
|
|
2264
2252
|
}
|
|
2265
2253
|
function parseRepoOption(raw: string | undefined): string {
|
|
2266
2254
|
if (raw === undefined || raw.trim() === "") throw new CliUsageError("--repo requires owner/repo");
|
|
@@ -2308,7 +2296,7 @@ export function resolveGitHubRemoteRepository(
|
|
|
2308
2296
|
try {
|
|
2309
2297
|
return parseCollectorRepository(ownerRepo);
|
|
2310
2298
|
} catch (error) {
|
|
2311
|
-
const detail =
|
|
2299
|
+
const detail = errorText(error);
|
|
2312
2300
|
throw new CliUsageError(detail, { cause: error });
|
|
2313
2301
|
}
|
|
2314
2302
|
}
|
|
@@ -2393,7 +2381,7 @@ export async function resolveDoctorCaseRunsPath(options: {
|
|
|
2393
2381
|
try {
|
|
2394
2382
|
real = await realpath(resolved);
|
|
2395
2383
|
} catch (error) {
|
|
2396
|
-
const detail =
|
|
2384
|
+
const detail = errorText(error);
|
|
2397
2385
|
throw new CliUsageError(
|
|
2398
2386
|
`doctor --runs is not a readable retained runs root: ${detail}`,
|
|
2399
2387
|
{ cause: error },
|
|
@@ -2415,7 +2403,6 @@ export async function resolveDoctorCaseRunsPath(options: {
|
|
|
2415
2403
|
return real;
|
|
2416
2404
|
}
|
|
2417
2405
|
|
|
2418
|
-
|
|
2419
2406
|
export type AdmitReviewerInvocationOptions = {
|
|
2420
2407
|
home: string;
|
|
2421
2408
|
principalAuthority: DurablePrincipalAuthority;
|