@akagilnc/pi-workflow-roles 0.1.5295 → 0.1.5301
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 +7 -3
- package/README.zh-CN.md +7 -3
- package/dist/acp-host/production-host.js +10 -367
- package/dist/diarist-contracts.js +1 -96
- package/dist/headless-host/production-host.js +10 -367
- package/dist/migrate-book-topology.js +75 -77
- package/dist/public-cli/countersign-run.js +3 -124
- package/dist/public-cli/instruction-seat-run.js +5 -97
- package/dist/public-cli/invocation.js +0 -33
- package/dist/public-cli/main.js +10 -362
- package/dist/public-cli/post-admission.js +2 -14
- package/dist/public-cli/run-lifecycle.js +0 -85
- package/dist/public-role-summons.js +2 -2
- package/package.json +1 -1
- package/src/diarist-contracts.ts +1 -116
- package/src/diarist-role.ts +0 -6
- package/src/public-cli/countersign-run.ts +7 -184
- package/src/public-cli/instruction-seat-run.ts +6 -101
- package/src/public-cli/invocation.ts +2 -64
- package/src/public-cli/post-admission.ts +2 -15
- package/src/public-cli/run-lifecycle.ts +0 -117
- package/src/public-role-summons.ts +3 -3
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One public role run: admit → turn request → post-admission → settle.
|
|
3
3
|
* Seat differences are composition-root fields. An omitted reviewer lens
|
|
4
|
-
* starts two ordinary single-axis runs here.
|
|
5
|
-
* identity on this entry; the court diarist station stays in countersign-run.
|
|
4
|
+
* starts two ordinary single-axis runs here.
|
|
6
5
|
*/
|
|
7
6
|
import { dirname, resolve, sep } from "node:path";
|
|
8
7
|
import { AUDITOR_DOSSIER_PROMPT } from "../compliance-transport.ts";
|
|
@@ -39,7 +38,6 @@ import { CliUsageError } from "./cli-errors.ts";
|
|
|
39
38
|
import {
|
|
40
39
|
admitPublicRole,
|
|
41
40
|
bindAdmittedTicketNumber,
|
|
42
|
-
bindCourtTicketNumbersOnAdmitted,
|
|
43
41
|
buildInstructionTransportPrompt,
|
|
44
42
|
materializeCountersignInvocation,
|
|
45
43
|
persistAdmittedSourceRunPath,
|
|
@@ -98,12 +96,11 @@ import {
|
|
|
98
96
|
import {
|
|
99
97
|
invokeCourtDiarist,
|
|
100
98
|
latestPayloadEscalated,
|
|
101
|
-
runCountersignCourtDiaristStation,
|
|
102
99
|
type CountersignRunEnv,
|
|
103
100
|
} from "./countersign-run.ts";
|
|
104
101
|
export type InstructionSeatRunEnv = PostAdmissionEnv & Pick<
|
|
105
102
|
CountersignRunEnv,
|
|
106
|
-
"reviewReask" | "gateReviewInstruction" | "parentRunPath"
|
|
103
|
+
"reviewReask" | "gateReviewInstruction" | "parentRunPath"
|
|
107
104
|
>;
|
|
108
105
|
|
|
109
106
|
type SeatRunResult = {
|
|
@@ -460,8 +457,7 @@ async function runOmittedLensBatch(
|
|
|
460
457
|
|
|
461
458
|
/**
|
|
462
459
|
* Countersign on the shared entry: gate parent resume, deferred materialization,
|
|
463
|
-
*
|
|
464
|
-
* Court refresh stays on runCountersignCourtDiaristStation.
|
|
460
|
+
* then the same one-shot settlement as every other seat.
|
|
465
461
|
*/
|
|
466
462
|
async function runCountersignBody(
|
|
467
463
|
parsed: PublicSeatParse,
|
|
@@ -516,88 +512,14 @@ async function runCountersignBody(
|
|
|
516
512
|
});
|
|
517
513
|
};
|
|
518
514
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
let childDiaristRunId: string | undefined;
|
|
523
|
-
let pausedDiaristTerminal: TerminalResult | undefined;
|
|
524
|
-
|
|
525
|
-
if (gateParentRunPath === undefined && env.runCourtDiaristStation === undefined) {
|
|
526
|
-
let outcome: Awaited<ReturnType<typeof invokeCourtDiarist>>;
|
|
527
|
-
try {
|
|
528
|
-
outcome = await invokeCourtDiarist({
|
|
529
|
-
instruction: parsed.instruction ?? "",
|
|
530
|
-
projectRoot: admitted.projectRoot,
|
|
531
|
-
failureLabel: "unbound summons",
|
|
532
|
-
correlationId: admitted.runId,
|
|
533
|
-
...(env.boundTicketNumber === undefined ? {} : { boundTicketNumber: env.boundTicketNumber }),
|
|
534
|
-
}, env, io);
|
|
535
|
-
} catch (error) {
|
|
536
|
-
await materializeAdmission(
|
|
537
|
-
isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined,
|
|
538
|
-
);
|
|
539
|
-
await markRunAdmitted(admitted, env.principalAuthority);
|
|
540
|
-
return await presentControlledFailure(admitted, {
|
|
541
|
-
timedOut: false,
|
|
542
|
-
code: null,
|
|
543
|
-
stderr: "",
|
|
544
|
-
thrown: error,
|
|
545
|
-
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
546
|
-
}
|
|
547
|
-
identityDiaristRan = true;
|
|
548
|
-
if (outcome.identity.kind === "escalate") pausedDiaristTerminal = outcome.terminal;
|
|
549
|
-
if (outcome.admitted?.runDirectory.includes(`${sep}unbound${sep}runs${sep}`)) {
|
|
550
|
-
childDiaristRunId = outcome.admitted.runId;
|
|
551
|
-
}
|
|
552
|
-
if (outcome.failedWithoutEscalate !== undefined) {
|
|
553
|
-
const diagnostic = outcome.failedWithoutEscalate.diagnostic;
|
|
554
|
-
await materializeAdmission(
|
|
555
|
-
isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined,
|
|
556
|
-
);
|
|
557
|
-
if (childDiaristRunId !== undefined) await recordChildDiaristRun(admitted, childDiaristRunId);
|
|
558
|
-
await markRunAdmitted(admitted, env.principalAuthority);
|
|
559
|
-
return await presentControlledFailure(admitted, {
|
|
560
|
-
timedOut: false,
|
|
561
|
-
code: null,
|
|
562
|
-
stderr: "",
|
|
563
|
-
thrown: new Error(diagnostic),
|
|
564
|
-
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
565
|
-
}
|
|
566
|
-
if (outcome.identity.kind === "ticket") {
|
|
567
|
-
typedTicket = outcome.identity.ticketNumber;
|
|
568
|
-
typedCourtTicketNumbers = outcome.identity.courtTicketNumbers;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
await materializeAdmission(typedTicket);
|
|
515
|
+
await materializeAdmission(
|
|
516
|
+
isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined,
|
|
517
|
+
);
|
|
573
518
|
await markRunAdmitted(admitted, env.principalAuthority);
|
|
574
|
-
if (childDiaristRunId !== undefined) {
|
|
575
|
-
await recordChildDiaristRun(admitted, childDiaristRunId);
|
|
576
|
-
}
|
|
577
|
-
if (pausedDiaristTerminal !== undefined) {
|
|
578
|
-
// The child already submitted its own pause; no parent turn exists yet.
|
|
579
|
-
io.stdout(formatTerminalResult(pausedDiaristTerminal));
|
|
580
|
-
return { exitCode: 0, admitted, terminal: pausedDiaristTerminal };
|
|
581
|
-
}
|
|
582
519
|
if (gateParentRunPath !== undefined) {
|
|
583
520
|
await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
|
|
584
521
|
admitted = { ...admitted, sourceRunPath: gateParentRunPath };
|
|
585
522
|
}
|
|
586
|
-
if (identityDiaristRan && typedTicket !== undefined) {
|
|
587
|
-
try {
|
|
588
|
-
await bindAdmittedTicketNumber(admitted, typedTicket);
|
|
589
|
-
await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
|
|
590
|
-
await bindCourtTicketNumbersOnAdmitted(admitted, typedCourtTicketNumbers ?? [typedTicket]);
|
|
591
|
-
} catch (error) {
|
|
592
|
-
return await presentControlledFailure(admitted, {
|
|
593
|
-
timedOut: false,
|
|
594
|
-
code: null,
|
|
595
|
-
stderr: "",
|
|
596
|
-
thrown: error,
|
|
597
|
-
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
523
|
const turnProjection: RoleTurnRequestProjectionOptions = {
|
|
602
524
|
packageRoot: env.packageRoot,
|
|
603
525
|
home: env.home,
|
|
@@ -630,13 +552,6 @@ async function runCountersignBody(
|
|
|
630
552
|
...seatAdapters(admitted, env),
|
|
631
553
|
beforeDispatch: async (admittedSeat, lease) => {
|
|
632
554
|
if (!packagedAdmitsCountersign(admittedSeat.role)) return;
|
|
633
|
-
if (!identityDiaristRan || typedTicket !== undefined) {
|
|
634
|
-
const refresh = await runCountersignCourtDiaristStation(admittedSeat, env, io);
|
|
635
|
-
if (refresh !== undefined) {
|
|
636
|
-
io.stdout(formatTerminalResult(refresh.terminal));
|
|
637
|
-
return refresh.terminal;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
555
|
await relocateAdmittedRunToTicket(admittedSeat, env.principalAuthority, lease);
|
|
641
556
|
Object.assign(turnRequest, buildInstructionSeatTurnRequest(admittedSeat, turnProjection));
|
|
642
557
|
},
|
|
@@ -1019,16 +934,6 @@ export async function continueParentAfterChild(
|
|
|
1019
934
|
return runPublicInstructionSeatResume({ runId: parentRunId }, env, io);
|
|
1020
935
|
}
|
|
1021
936
|
const admitted = loaded.admitted;
|
|
1022
|
-
// Court diarist refresh advances only after a diarist child; gate officers
|
|
1023
|
-
// (notary/auditor/…) resume straight into queueConclusionFromChild (#1057).
|
|
1024
|
-
if (admitted.role === "countersign" && admitted.ticketNumber !== undefined
|
|
1025
|
-
&& child.role === "diarist") {
|
|
1026
|
-
const refresh = await runCountersignCourtDiaristStation(admitted, env, io, child.ticketNumber);
|
|
1027
|
-
if (refresh !== undefined) {
|
|
1028
|
-
io.stdout(formatTerminalResult(refresh.terminal));
|
|
1029
|
-
return { exitCode: 0, admitted, terminal: refresh.terminal };
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
937
|
const resolved = await queueConclusionFromChild(child, env, io);
|
|
1033
938
|
if (resolved !== undefined && "stop" in resolved) return resolved.stop;
|
|
1034
939
|
if (resolved !== undefined && resolved.status === "escalate") {
|
|
@@ -60,7 +60,6 @@ import {
|
|
|
60
60
|
import {
|
|
61
61
|
loadDoctorCase,
|
|
62
62
|
} from "../doctor-evidence.ts";
|
|
63
|
-
import { projectCourtTicketNumbers } from "../diarist-contracts.ts";
|
|
64
63
|
import type { DoctorCaseIdentity } from "../doctor-contracts.ts";
|
|
65
64
|
import {
|
|
66
65
|
emptyCollectorManifest,
|
|
@@ -156,17 +155,6 @@ export type AdmittedJudgeInvocation = AdmittedRoleInvocationBase & {
|
|
|
156
155
|
|
|
157
156
|
export type AdmittedCountersignInvocation = AdmittedRoleInvocationBase & {
|
|
158
157
|
readonly role: "countersign";
|
|
159
|
-
/**
|
|
160
|
-
* #871 typed co-review set for this countersign run (durable run fact).
|
|
161
|
-
* Main ticket remains `ticketNumber`; this set drives per-ticket court diarist refresh.
|
|
162
|
-
* Whole-set replace on new typed submission — never union with history.
|
|
163
|
-
*/
|
|
164
|
-
courtTicketNumbers?: readonly number[];
|
|
165
|
-
/**
|
|
166
|
-
* Load-time durable set damage diagnostic (#871 B7). Resume must settle as
|
|
167
|
-
* countersign controlled failure with this text — never structural exit 2 or main-only.
|
|
168
|
-
*/
|
|
169
|
-
courtTicketNumbersDamage?: string;
|
|
170
158
|
/**
|
|
171
159
|
* Parent run directory (#747 / #987 gate same-parent resume). Persisted on first
|
|
172
160
|
* mint when gate supplies parentRunPath; independent of ticket-number lookup.
|
|
@@ -338,7 +326,7 @@ export function issueAdmissionPlacement(
|
|
|
338
326
|
readonly cwd: string;
|
|
339
327
|
readonly runId: string;
|
|
340
328
|
readonly role: AdmittedRoleInvocation["role"];
|
|
341
|
-
/**
|
|
329
|
+
/** Typed identity, when supplied; never derive it from CLI prose. */
|
|
342
330
|
readonly subject: RoleRunSubject;
|
|
343
331
|
readonly home?: string;
|
|
344
332
|
/** Placement may be computed before a same-ticket lookup without touching disk. */
|
|
@@ -594,56 +582,6 @@ export async function recordAdmittedCorrelation(
|
|
|
594
582
|
mutable.correlationIds = correlationIds;
|
|
595
583
|
}
|
|
596
584
|
|
|
597
|
-
/**
|
|
598
|
-
* #871: persist the typed co-review set as a countersign run fact (admitted-request +
|
|
599
|
-
* invocation.json). Whole-set replace — never union with a prior set. Main ticket
|
|
600
|
-
* binding stays on `ticketNumber` alone. Projection reuses the sole contract helper;
|
|
601
|
-
* principal membership is mandatory.
|
|
602
|
-
*/
|
|
603
|
-
export async function bindCourtTicketNumbersOnAdmitted(
|
|
604
|
-
admitted: AdmittedCountersignInvocation,
|
|
605
|
-
courtTicketNumbers: readonly number[],
|
|
606
|
-
): Promise<void> {
|
|
607
|
-
if (admitted.ticketNumber === undefined) {
|
|
608
|
-
throw new Error(
|
|
609
|
-
"bindCourtTicketNumbersOnAdmitted requires a bound principal ticketNumber",
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
const principal = requireSafePositiveTicketNumber(
|
|
613
|
-
admitted.ticketNumber,
|
|
614
|
-
"bindCourtTicketNumbersOnAdmitted principal ticketNumber",
|
|
615
|
-
);
|
|
616
|
-
// Strict write path: every member must already be a lawful number (no soft filter).
|
|
617
|
-
for (const item of courtTicketNumbers) {
|
|
618
|
-
if (!isSafePositiveTicketNumber(item)) {
|
|
619
|
-
throw new Error(
|
|
620
|
-
`bindCourtTicketNumbersOnAdmitted requires safe positive integers, got ${String(item)}`,
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
const projected = projectCourtTicketNumbers(courtTicketNumbers, {
|
|
625
|
-
principalTicket: principal,
|
|
626
|
-
});
|
|
627
|
-
if (projected === null || projected.length === 0) {
|
|
628
|
-
throw new Error("bindCourtTicketNumbersOnAdmitted requires a non-empty ticket set");
|
|
629
|
-
}
|
|
630
|
-
const frozen = Object.freeze([...projected]);
|
|
631
|
-
const admittedPath = admitted.admittedRequestPath;
|
|
632
|
-
const current = JSON.parse(await readFile(admittedPath, "utf8")) as Record<
|
|
633
|
-
string,
|
|
634
|
-
unknown
|
|
635
|
-
>;
|
|
636
|
-
await writeFile(
|
|
637
|
-
admittedPath,
|
|
638
|
-
`${JSON.stringify({ ...current, courtTicketNumbers: frozen }, null, 2)}\n`,
|
|
639
|
-
"utf8",
|
|
640
|
-
);
|
|
641
|
-
await mergeInvocationIdentityPage(admitted.runDirectory, {
|
|
642
|
-
courtTicketNumbers: frozen,
|
|
643
|
-
});
|
|
644
|
-
admitted.courtTicketNumbers = frozen;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
585
|
/** File a role run under its latest typed ticket identity. */
|
|
648
586
|
export async function relocateAdmittedRunToTicket(
|
|
649
587
|
admitted: AdmittedRoleInvocation,
|
|
@@ -1904,7 +1842,7 @@ export type AdmitJudgeInvocationOptions = {
|
|
|
1904
1842
|
|
|
1905
1843
|
export type AdmitInspectorInvocationOptions = AdmitJudgeInvocationOptions & {
|
|
1906
1844
|
correlationId?: string;
|
|
1907
|
-
/** Typed identity
|
|
1845
|
+
/** Typed identity from the caller or an already-bound run. */
|
|
1908
1846
|
assertedTicketNumber?: number;
|
|
1909
1847
|
};
|
|
1910
1848
|
|
|
@@ -211,15 +211,6 @@ async function settleProcessCancelAfterTurn<A extends AdmittedRoleInvocation, T
|
|
|
211
211
|
};
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
/**
|
|
215
|
-
* Nested station-child role already finished its own call-local loop.
|
|
216
|
-
* Parent records that failure once and must not auto-resume into a re-summon
|
|
217
|
-
* (#840 父子不层叠). Other beforeDispatch failures keep the shared #416 budget.
|
|
218
|
-
*/
|
|
219
|
-
export class StationChildExhaustedError extends Error {
|
|
220
|
-
override readonly name = "StationChildExhaustedError";
|
|
221
|
-
}
|
|
222
|
-
|
|
223
214
|
function withOnceSuccessfulBeforeDispatch<
|
|
224
215
|
A extends AdmittedRoleInvocation,
|
|
225
216
|
T extends TerminalResult = TerminalResult,
|
|
@@ -825,16 +816,12 @@ export async function dispatchPostAdmissionTurn<
|
|
|
825
816
|
io,
|
|
826
817
|
persistRunState,
|
|
827
818
|
)) as { exitCode: number; admitted: A; terminal: T };
|
|
828
|
-
if (error instanceof StationChildExhaustedError) {
|
|
829
|
-
return { ...settled, skipAutoResume: true as const, ...deferredPersist };
|
|
830
|
-
}
|
|
831
819
|
return { ...settled, ...deferredPersist };
|
|
832
820
|
}
|
|
833
821
|
}
|
|
834
822
|
|
|
835
|
-
// Turn request is assembled after beforeDispatch so this turn sees
|
|
836
|
-
//
|
|
837
|
-
// writes (#742). Dialogue continuation stays caller/peer opaque. #1092: no
|
|
823
|
+
// Turn request is assembled after beforeDispatch so this turn sees any
|
|
824
|
+
// seat-specific admission changes. Dialogue continuation stays caller/peer opaque. #1092: no
|
|
838
825
|
// code-side 起居录 path freeze or readingMaterial inject — roles read by ticket.
|
|
839
826
|
// No package-resume parallel face or typed resume identity.
|
|
840
827
|
// #990: one-shot / auto-resume may freeze principal+runDirectory before
|
|
@@ -31,10 +31,6 @@ export {
|
|
|
31
31
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
32
32
|
import type { FixerPrerequisite } from "../package-contracts/fixer-packet.ts";
|
|
33
33
|
import { parseCollectorRepository } from "../collector-config.ts";
|
|
34
|
-
import {
|
|
35
|
-
interpretDurableCourtTicketNumbers,
|
|
36
|
-
sameCourtTicketNumbers,
|
|
37
|
-
} from "../diarist-contracts.ts";
|
|
38
34
|
import type { DoctorCaseIdentity } from "../doctor-contracts.ts";
|
|
39
35
|
import type { NotarySourceRunLocator } from "../notary-contracts.ts";
|
|
40
36
|
import {
|
|
@@ -1177,13 +1173,6 @@ type LoadedAdmittedRequestFields = {
|
|
|
1177
1173
|
readonly derived?: DerivedMergerEnvelope;
|
|
1178
1174
|
readonly correlationId?: string;
|
|
1179
1175
|
readonly ticketNumber?: number;
|
|
1180
|
-
/** #871 typed co-review set restored on countersign resume. */
|
|
1181
|
-
readonly courtTicketNumbers?: readonly number[];
|
|
1182
|
-
/**
|
|
1183
|
-
* #871 durable set present-but-damaged diagnostic. Countersign resume settles
|
|
1184
|
-
* controlled failure with this text; not a structural usage rejection.
|
|
1185
|
-
*/
|
|
1186
|
-
readonly courtTicketNumbersDamage?: string;
|
|
1187
1176
|
/** Collector — admitted repository/PR identity restored on resume (#633). */
|
|
1188
1177
|
readonly prNumber?: number;
|
|
1189
1178
|
readonly repository?: string;
|
|
@@ -1223,90 +1212,13 @@ function parsePersistedTicketIdentity(
|
|
|
1223
1212
|
};
|
|
1224
1213
|
}
|
|
1225
1214
|
|
|
1226
|
-
/**
|
|
1227
|
-
* #871 durable set from one run page.
|
|
1228
|
-
* Absent → absent. Present damage keeps the original reason (no throw here).
|
|
1229
|
-
*/
|
|
1230
|
-
function readDurableCourtTicketNumbersPage(
|
|
1231
|
-
record: Record<string, unknown>,
|
|
1232
|
-
principalTicket: number | undefined,
|
|
1233
|
-
pageLabel: string,
|
|
1234
|
-
):
|
|
1235
|
-
| { readonly kind: "absent" }
|
|
1236
|
-
| { readonly kind: "ok"; readonly tickets: readonly number[] }
|
|
1237
|
-
| { readonly kind: "damage"; readonly reason: string } {
|
|
1238
|
-
const interpreted = interpretDurableCourtTicketNumbers(record, {
|
|
1239
|
-
...(principalTicket === undefined ? {} : { principalTicket }),
|
|
1240
|
-
});
|
|
1241
|
-
if (interpreted.kind === "damage") {
|
|
1242
|
-
return {
|
|
1243
|
-
kind: "damage",
|
|
1244
|
-
reason: `role run ${pageLabel} courtTicketNumbers is damaged: ${interpreted.reason}`,
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
if (interpreted.kind === "ok") {
|
|
1248
|
-
return { kind: "ok", tickets: interpreted.tickets };
|
|
1249
|
-
}
|
|
1250
|
-
return { kind: "absent" };
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
/**
|
|
1254
|
-
* Merge admitted + invocation #871 sets.
|
|
1255
|
-
* Both present must match; one present wins; both absent stays legacy.
|
|
1256
|
-
* Damage / cross-page mismatch return a diagnostic — countersign resume settles
|
|
1257
|
-
* controlled failure; load itself does not structural-reject.
|
|
1258
|
-
*/
|
|
1259
|
-
function mergeDurableCourtTicketNumbers(input: {
|
|
1260
|
-
readonly admittedRecord: Record<string, unknown> | undefined;
|
|
1261
|
-
readonly invocationRecord: Record<string, unknown> | undefined;
|
|
1262
|
-
readonly principalTicket: number | undefined;
|
|
1263
|
-
}):
|
|
1264
|
-
| { readonly kind: "ok"; readonly tickets?: readonly number[] }
|
|
1265
|
-
| { readonly kind: "damage"; readonly reason: string } {
|
|
1266
|
-
const fromAdmitted =
|
|
1267
|
-
input.admittedRecord === undefined
|
|
1268
|
-
? ({ kind: "absent" } as const)
|
|
1269
|
-
: readDurableCourtTicketNumbersPage(
|
|
1270
|
-
input.admittedRecord,
|
|
1271
|
-
input.principalTicket,
|
|
1272
|
-
"admitted-request",
|
|
1273
|
-
);
|
|
1274
|
-
const fromInvocation =
|
|
1275
|
-
input.invocationRecord === undefined
|
|
1276
|
-
? ({ kind: "absent" } as const)
|
|
1277
|
-
: readDurableCourtTicketNumbersPage(
|
|
1278
|
-
input.invocationRecord,
|
|
1279
|
-
input.principalTicket,
|
|
1280
|
-
"invocation",
|
|
1281
|
-
);
|
|
1282
|
-
if (fromAdmitted.kind === "damage") return fromAdmitted;
|
|
1283
|
-
if (fromInvocation.kind === "damage") return fromInvocation;
|
|
1284
|
-
if (fromAdmitted.kind === "ok" && fromInvocation.kind === "ok") {
|
|
1285
|
-
if (!sameCourtTicketNumbers(fromAdmitted.tickets, fromInvocation.tickets)) {
|
|
1286
|
-
return {
|
|
1287
|
-
kind: "damage",
|
|
1288
|
-
reason:
|
|
1289
|
-
"role run courtTicketNumbers differs between admitted-request and invocation",
|
|
1290
|
-
};
|
|
1291
|
-
}
|
|
1292
|
-
return { kind: "ok", tickets: fromAdmitted.tickets };
|
|
1293
|
-
}
|
|
1294
|
-
if (fromAdmitted.kind === "ok") return { kind: "ok", tickets: fromAdmitted.tickets };
|
|
1295
|
-
if (fromInvocation.kind === "ok") return { kind: "ok", tickets: fromInvocation.tickets };
|
|
1296
|
-
return { kind: "ok" };
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
1215
|
function restoredTicketFields(fields: LoadedAdmittedRequestFields): {
|
|
1300
1216
|
correlationId?: string;
|
|
1301
1217
|
ticketNumber?: number;
|
|
1302
|
-
courtTicketNumbers?: readonly number[];
|
|
1303
1218
|
} {
|
|
1304
1219
|
return {
|
|
1305
1220
|
...(fields.correlationId === undefined ? {} : { correlationId: fields.correlationId }),
|
|
1306
1221
|
...(fields.ticketNumber === undefined ? {} : { ticketNumber: fields.ticketNumber }),
|
|
1307
|
-
...(fields.courtTicketNumbers === undefined
|
|
1308
|
-
? {}
|
|
1309
|
-
: { courtTicketNumbers: fields.courtTicketNumbers }),
|
|
1310
1222
|
};
|
|
1311
1223
|
}
|
|
1312
1224
|
|
|
@@ -1352,10 +1264,6 @@ async function loadResumableRunRecord(
|
|
|
1352
1264
|
let derived: DerivedMergerEnvelope | undefined;
|
|
1353
1265
|
let correlationId: string | undefined;
|
|
1354
1266
|
let ticketNumber: number | undefined;
|
|
1355
|
-
let courtTicketNumbers: readonly number[] | undefined;
|
|
1356
|
-
let courtTicketNumbersDamage: string | undefined;
|
|
1357
|
-
let admittedIdentityRecord: Record<string, unknown> | undefined;
|
|
1358
|
-
let invocationIdentityRecord: Record<string, unknown> | undefined;
|
|
1359
1267
|
let prNumber: number | undefined;
|
|
1360
1268
|
let repository: string | undefined;
|
|
1361
1269
|
let repositoryDisplay: string | undefined;
|
|
@@ -1525,7 +1433,6 @@ async function loadResumableRunRecord(
|
|
|
1525
1433
|
};
|
|
1526
1434
|
}
|
|
1527
1435
|
}
|
|
1528
|
-
admittedIdentityRecord = record;
|
|
1529
1436
|
const fromAdmitted = parsePersistedTicketIdentity(record);
|
|
1530
1437
|
correlationId = fromAdmitted.correlationId;
|
|
1531
1438
|
ticketNumber = fromAdmitted.ticketNumber;
|
|
@@ -1549,7 +1456,6 @@ async function loadResumableRunRecord(
|
|
|
1549
1456
|
!Array.isArray(invocationRaw)
|
|
1550
1457
|
) {
|
|
1551
1458
|
const rec = invocationRaw as Record<string, unknown>;
|
|
1552
|
-
invocationIdentityRecord = rec;
|
|
1553
1459
|
if (typeof rec.provider === "string" && typeof rec.model === "string") {
|
|
1554
1460
|
model = {
|
|
1555
1461
|
provider: rec.provider,
|
|
@@ -1584,19 +1490,6 @@ async function loadResumableRunRecord(
|
|
|
1584
1490
|
);
|
|
1585
1491
|
}
|
|
1586
1492
|
}
|
|
1587
|
-
// #871: resolve set after main ticket so principal membership can be checked.
|
|
1588
|
-
// Present-but-damaged / cross-page mismatch keep diagnostic for countersign
|
|
1589
|
-
// controlled-failure; both-absent stays legacy; single lawful page restores.
|
|
1590
|
-
const mergedSet = mergeDurableCourtTicketNumbers({
|
|
1591
|
-
admittedRecord: admittedIdentityRecord,
|
|
1592
|
-
invocationRecord: invocationIdentityRecord,
|
|
1593
|
-
principalTicket: ticketNumber,
|
|
1594
|
-
});
|
|
1595
|
-
if (mergedSet.kind === "damage") {
|
|
1596
|
-
courtTicketNumbersDamage = mergedSet.reason;
|
|
1597
|
-
} else if (mergedSet.tickets !== undefined) {
|
|
1598
|
-
courtTicketNumbers = mergedSet.tickets;
|
|
1599
|
-
}
|
|
1600
1493
|
const sourceRunLeaf = basename(sourceRunPath ?? "").split("@");
|
|
1601
1494
|
const referencedRunId = sourceRun?.runId ?? sourceRunLeaf[0];
|
|
1602
1495
|
const referencedRole = sourceRun?.role ?? sourceRunLeaf[1];
|
|
@@ -1634,10 +1527,6 @@ async function loadResumableRunRecord(
|
|
|
1634
1527
|
...(derived === undefined ? {} : { derived }),
|
|
1635
1528
|
...(correlationId === undefined ? {} : { correlationId }),
|
|
1636
1529
|
...(ticketNumber === undefined ? {} : { ticketNumber }),
|
|
1637
|
-
...(courtTicketNumbers === undefined ? {} : { courtTicketNumbers }),
|
|
1638
|
-
...(courtTicketNumbersDamage === undefined
|
|
1639
|
-
? {}
|
|
1640
|
-
: { courtTicketNumbersDamage }),
|
|
1641
1530
|
...(prNumber === undefined ? {} : { prNumber }),
|
|
1642
1531
|
...(repository === undefined ? {} : { repository }),
|
|
1643
1532
|
...(repositoryDisplay === undefined ? {} : { repositoryDisplay }),
|
|
@@ -1782,12 +1671,6 @@ function admitResumedRole(loaded: {
|
|
|
1782
1671
|
const admitted: AdmittedCountersignInvocation = {
|
|
1783
1672
|
role: "countersign",
|
|
1784
1673
|
...base,
|
|
1785
|
-
...(base.courtTicketNumbers === undefined
|
|
1786
|
-
? {}
|
|
1787
|
-
: { courtTicketNumbers: base.courtTicketNumbers }),
|
|
1788
|
-
...(fields.courtTicketNumbersDamage === undefined
|
|
1789
|
-
? {}
|
|
1790
|
-
: { courtTicketNumbersDamage: fields.courtTicketNumbersDamage }),
|
|
1791
1674
|
};
|
|
1792
1675
|
return admitted;
|
|
1793
1676
|
}
|
|
@@ -421,8 +421,8 @@ export async function summonPublicRole(
|
|
|
421
421
|
// Nested court stations keep station-child semantics; dual-lens
|
|
422
422
|
// ordinary Reviewer axes opt out (#946 / ADR 0082).
|
|
423
423
|
...(options.stationChild === false ? {} : { stationChild: true }),
|
|
424
|
-
// Forward composition-root adapters so nested
|
|
425
|
-
//
|
|
424
|
+
// Forward composition-root adapters so nested stations (e.g.
|
|
425
|
+
// secretariat → diarist) select the same faux/production table (#924).
|
|
426
426
|
...(options.hostAdapters === undefined
|
|
427
427
|
? {}
|
|
428
428
|
: { hostAdapters: options.hostAdapters }),
|
|
@@ -535,7 +535,7 @@ export async function summonPublicRole(
|
|
|
535
535
|
}
|
|
536
536
|
|
|
537
537
|
const stderr = captured?.stderrText();
|
|
538
|
-
//
|
|
538
|
+
// Secretariat can return its preliminary diarist's escalation verbatim.
|
|
539
539
|
// The terminal's independent run, not the officer, is the gate pointer.
|
|
540
540
|
const runDirectory = result.terminal !== undefined
|
|
541
541
|
&& result.terminal.roleOutcome.role !== options.role
|