@akagilnc/pi-workflow-roles 0.1.4800 → 0.1.4870
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 +19434 -18218
- package/dist/analyst-book-key.js +63 -0
- package/dist/analyst-cohort.js +167 -0
- package/dist/analyst-entry.js +320 -0
- package/dist/analyst-index.js +247 -0
- package/dist/analyst-ledger.js +561 -0
- package/dist/analyst-median.js +16 -0
- package/dist/analyst-metric-families/acceptance-success-rework.js +249 -0
- package/dist/analyst-metric-families/b2-frame-buckets-actions.js +189 -0
- package/dist/analyst-metric-families/gate-cycles.js +77 -0
- package/dist/analyst-metric-families/leg-wall-clock.js +56 -0
- package/dist/analyst-metric-families/round-timeline.js +126 -0
- package/dist/analyst-metric-families.js +23 -0
- package/dist/analyst-metric-family.js +11 -0
- package/dist/analyst-model-groups.js +135 -0
- package/dist/analyst-page.js +182 -0
- package/dist/atomic-write.js +23 -0
- package/dist/auditor-soul.js +1 -1
- package/dist/countersign-contracts.js +0 -2
- package/dist/diarist-contracts.js +0 -1
- package/dist/doctor-contracts.js +2 -2
- package/dist/gatekeeper-role.js +15 -16
- package/dist/gleaner-left-contracts.js +0 -2
- package/dist/headless-host/production-host.js +16967 -15749
- package/dist/host-contracts.js +0 -4
- package/dist/inspector-contracts.js +0 -2
- package/dist/institutional-resolution.js +4 -2
- package/dist/merger-contracts.js +0 -2
- package/dist/migrate-book-topology.js +3908 -3089
- package/dist/navigator-public-session.js +4 -3
- package/dist/notary-contracts.js +0 -2
- package/dist/package-contracts/auditor-output.js +0 -1
- package/dist/package-contracts/collector-output.js +0 -2
- package/dist/package-contracts/fixer-output.js +0 -2
- package/dist/package-contracts/gatekeeper-output.js +0 -2
- package/dist/package-contracts/judge-output.js +0 -2
- package/dist/package-contracts/navigator-output.js +0 -2
- package/dist/package-contracts/reviewer-output.js +0 -2
- package/dist/package-contracts/terminating-tools.js +32 -92
- package/dist/package-contracts/worker-output.js +0 -4
- package/dist/packaged-role-registry.js +518 -36
- package/dist/pi/role-turn-host.js +2 -1
- package/dist/public-cli/analyst-run.js +185 -0
- package/dist/public-cli/cli.js +885 -0
- package/dist/public-cli/config.js +12 -9
- package/dist/public-cli/countersign-run.js +4 -311
- package/dist/public-cli/instruction-seat-run.js +628 -158
- package/dist/public-cli/invocation.js +806 -1550
- package/dist/public-cli/main.js +6962 -9882
- package/dist/public-cli/option-definitions.js +51 -99
- package/dist/public-cli/post-admission.js +30 -2
- package/dist/public-cli/run-lifecycle.js +234 -353
- package/dist/public-cli/seat-ticket-binding.js +6 -0
- package/dist/public-cli/settlement.js +261 -675
- package/dist/public-cli/turn-request.js +76 -0
- package/dist/public-role-summons.js +38 -112
- package/dist/role-activation-flags.js +23 -45
- package/dist/secretariat-contracts.js +0 -2
- package/dist/session-identity.js +17 -8
- package/dist/session-opening-materials.js +3 -2
- package/extensions/role-runtime.ts +6 -80
- package/package.json +1 -1
- package/souls/coder.md +1 -2
- package/src/acp-host/role-turn-host.ts +4 -1
- package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
- package/src/auditor-role.ts +1 -2
- package/src/auditor-soul.ts +1 -1
- package/src/collector-role.ts +2 -2
- package/src/countersign-contracts.ts +0 -1
- package/src/countersign-role.ts +1 -1
- package/src/diarist-contracts.ts +0 -1
- package/src/diarist-role.ts +0 -1
- package/src/doctor-auditor.ts +1 -2
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-role.ts +3 -2
- package/src/external-host-turn-loop.ts +1 -1
- package/src/factory-board.ts +10 -7
- package/src/gatekeeper-role.ts +16 -10
- package/src/gleaner-left-contracts.ts +0 -1
- package/src/gleaner-left-role.ts +0 -1
- package/src/headless-host/role-turn-host.ts +7 -1
- package/src/host-contracts.ts +10 -6
- package/src/inspector-contracts.ts +0 -1
- package/src/inspector-role.ts +0 -2
- package/src/institutional-resolution.ts +6 -4
- package/src/judge-role.ts +3 -3
- package/src/merger-contracts.ts +0 -1
- package/src/merger-role.ts +2 -2
- package/src/navigator-public-session.ts +7 -6
- package/src/navigator-work-context.ts +6 -8
- package/src/notary-contracts.ts +0 -1
- package/src/notary-role.ts +2 -3
- package/src/package-contracts/auditor-output.ts +0 -1
- package/src/package-contracts/collector-output.ts +0 -1
- package/src/package-contracts/fixer-output.ts +0 -1
- package/src/package-contracts/gatekeeper-output.ts +0 -1
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +0 -1
- package/src/package-contracts/reviewer-output.ts +0 -1
- package/src/package-contracts/terminating-tools.ts +27 -99
- package/src/package-contracts/worker-output.ts +0 -2
- package/src/packaged-role-registry.ts +604 -35
- package/src/pi/role-turn-host.ts +2 -1
- package/src/public-cli/cli.ts +64 -259
- package/src/public-cli/config.ts +18 -10
- package/src/public-cli/countersign-run.ts +14 -449
- package/src/public-cli/instruction-seat-run.ts +758 -277
- package/src/public-cli/invocation.ts +1097 -2051
- package/src/public-cli/option-definitions.ts +62 -127
- package/src/public-cli/post-admission.ts +47 -2
- package/src/public-cli/run-lifecycle.ts +303 -613
- package/src/public-cli/seat-ticket-binding.ts +6 -0
- package/src/public-cli/settlement.ts +399 -1185
- package/src/public-cli/turn-request.ts +92 -1
- package/src/public-role-summons.ts +44 -128
- package/src/reviewer-role.ts +3 -2
- package/src/role-activation-flags.ts +20 -41
- package/src/role-runtime-dependencies.ts +25 -26
- package/src/role-runtime.ts +121 -232
- package/src/secretariat-contracts.ts +0 -1
- package/src/secretariat-role.ts +0 -2
- package/src/session-identity.ts +23 -8
- package/src/session-opening-materials.ts +2 -1
- package/src/worker-role.ts +3 -4
- package/dist/doctor-auditor.js +0 -25
- package/dist/public-cli/diarist-run.js +0 -130
- package/dist/public-cli/doctor-run.js +0 -87
- package/dist/public-cli/inspector-run.js +0 -151
- package/dist/public-cli/judge-run.js +0 -114
- package/dist/public-cli/notary-run.js +0 -174
- package/dist/public-cli/reviewer-run.js +0 -339
- package/src/public-cli/coder-run.ts +0 -255
- package/src/public-cli/collector-run.ts +0 -189
- package/src/public-cli/diarist-run.ts +0 -233
- package/src/public-cli/doctor-run.ts +0 -167
- package/src/public-cli/fixer-run.ts +0 -265
- package/src/public-cli/gleaner-left-run.ts +0 -167
- package/src/public-cli/inspector-run.ts +0 -261
- package/src/public-cli/judge-run.ts +0 -196
- package/src/public-cli/merger-run.ts +0 -294
- package/src/public-cli/notary-run.ts +0 -279
- package/src/public-cli/reviewer-run.ts +0 -480
- package/src/public-cli/secretariat-run.ts +0 -265
|
@@ -1,202 +1,212 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* run/rebind/nest path. (#744: evidence-child public seat deleted.)
|
|
2
|
+
* One public role run: admit → turn request → post-admission → settle.
|
|
3
|
+
* Seat differences are composition-root fields. An omitted reviewer lens
|
|
4
|
+
* starts two ordinary single-axis runs here. Countersign keeps deferred
|
|
5
|
+
* identity on this entry; the court diarist station stays in countersign-run.
|
|
7
6
|
*/
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
|
|
8
9
|
import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
|
|
10
|
+
import { isSafePositiveTicketNumber, readBoardTicketNumber } from "../run-ticket-number.ts";
|
|
11
|
+
import { NotarySourceRunError, resolveNotarySourceRunLocator } from "../notary-source-run.ts";
|
|
9
12
|
import { engineSessionMaterialFromOptions, pickEngineAxis } from "../package-resources/engine-material.ts";
|
|
10
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
loadPackagedMethodSkillMaterial,
|
|
15
|
+
type PackagedMethodSkillMaterial,
|
|
16
|
+
} from "../package-resources/method-skill.ts";
|
|
17
|
+
import type { PackagedRole } from "../packaged-role-registry.ts";
|
|
18
|
+
import {
|
|
19
|
+
packagedAdmitsCountersign,
|
|
20
|
+
packagedBindsBoardTicket,
|
|
21
|
+
packagedMethodLoadFailureCause,
|
|
22
|
+
packagedRebindSourceOnResume,
|
|
23
|
+
packagedRoleMetadata,
|
|
24
|
+
} from "../packaged-role-registry.ts";
|
|
25
|
+
import { isAuditorSoulRole } from "../auditor-soul.ts";
|
|
11
26
|
import { CliUsageError } from "./cli-errors.ts";
|
|
12
27
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
28
|
+
admitPublicRole,
|
|
29
|
+
bindAdmittedTicketNumber,
|
|
30
|
+
bindCourtTicketNumbersOnAdmitted,
|
|
16
31
|
buildInstructionTransportPrompt,
|
|
32
|
+
materializeCountersignInvocation,
|
|
17
33
|
persistAdmittedSourceRunPath,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type
|
|
34
|
+
recordAdmittedCorrelation,
|
|
35
|
+
relocateAdmittedRunToTicket,
|
|
36
|
+
withPreparedAttachments,
|
|
37
|
+
type AdmittedCountersignInvocation,
|
|
38
|
+
type AdmittedRoleInvocation,
|
|
39
|
+
type PublicSeatParse,
|
|
22
40
|
} from "./invocation.ts";
|
|
23
41
|
import {
|
|
42
|
+
presentControlledFailure,
|
|
24
43
|
prepareSummonsResumeMaterials,
|
|
44
|
+
resolveResumeMethodMaterialAdapters,
|
|
45
|
+
roleTurnOptions,
|
|
25
46
|
runPostAdmissionOneShot,
|
|
47
|
+
runPostAdmissionResumable,
|
|
26
48
|
runPostAdmissionSeatResume,
|
|
27
49
|
resumeTurnRequestProjectionOptions,
|
|
28
50
|
type PostAdmissionAdapters,
|
|
29
51
|
type PostAdmissionEnv,
|
|
30
52
|
} from "./post-admission.ts";
|
|
31
53
|
import {
|
|
32
|
-
|
|
54
|
+
buildAutoResumeContinuationPrompt,
|
|
55
|
+
loadResumablePublicRole,
|
|
33
56
|
markRunAdmitted,
|
|
57
|
+
parentRunPathFromGatePointerInstruction,
|
|
34
58
|
type PublicResumeRequest,
|
|
59
|
+
type RunWriterLease,
|
|
35
60
|
type SameTicketSummonsMaterials,
|
|
36
61
|
} from "./run-lifecycle.ts";
|
|
37
62
|
import { tryResumeSameTicketSeatRun } from "./seat-ticket-binding.ts";
|
|
38
63
|
import {
|
|
39
64
|
presentStructuralRejection,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
trySettleGatekeeperTerminalResult,
|
|
43
|
-
trySettleNavigatorTerminalResult,
|
|
65
|
+
seatKnownFailureResolver,
|
|
66
|
+
trySettlePublicSeat,
|
|
44
67
|
} from "./settlement.ts";
|
|
45
68
|
import type { CliIo } from "./cli-io.ts";
|
|
46
|
-
import type { TerminalResult } from "./terminal.ts";
|
|
47
69
|
import {
|
|
70
|
+
formatTerminalResult,
|
|
71
|
+
isLawfulTypedTerminalOutcome,
|
|
72
|
+
type TerminalResult,
|
|
73
|
+
} from "./terminal.ts";
|
|
74
|
+
import {
|
|
75
|
+
admittedSeatTurnDetails,
|
|
76
|
+
packagedSettleSkill,
|
|
48
77
|
projectRoleTurnRequest,
|
|
49
78
|
type RoleTurnRequestProjectionOptions,
|
|
50
79
|
} from "./turn-request.ts";
|
|
80
|
+
import {
|
|
81
|
+
invokeCourtDiarist,
|
|
82
|
+
runCountersignCourtDiaristStation,
|
|
83
|
+
type CountersignRunEnv,
|
|
84
|
+
} from "./countersign-run.ts";
|
|
51
85
|
|
|
52
|
-
export type
|
|
53
|
-
|
|
54
|
-
| "
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export type InstructionSeatRunEnv = PostAdmissionEnv & {
|
|
63
|
-
principalAuthority: DurablePrincipalAuthority;
|
|
64
|
-
createRunId?: () => string;
|
|
65
|
-
/**
|
|
66
|
-
* #756 nested gate re-ask for auditor: plain-language instruction on same-ticket resume.
|
|
67
|
-
* Only set by summonPublicRole when the prior officer reply was not three-state.
|
|
68
|
-
* Never a public CLI argv — must not pollute the --source-run parent lookup key (#747).
|
|
69
|
-
*/
|
|
70
|
-
reviewReask?: string;
|
|
71
|
-
/**
|
|
72
|
-
* #879 gate summons: verbatim parent-submission body for officer dialogue content.
|
|
73
|
-
* Rides summons.instruction / first-mint prompt when reviewReask is absent.
|
|
74
|
-
*/
|
|
75
|
-
gateReviewInstruction?: string;
|
|
86
|
+
export type InstructionSeatRunEnv = PostAdmissionEnv & Pick<
|
|
87
|
+
CountersignRunEnv,
|
|
88
|
+
"reviewReask" | "gateReviewInstruction" | "parentRunPath" | "runCourtDiaristStation"
|
|
89
|
+
>;
|
|
90
|
+
|
|
91
|
+
type SeatRunResult = {
|
|
92
|
+
exitCode: number;
|
|
93
|
+
admitted?: AdmittedRoleInvocation;
|
|
94
|
+
terminal?: TerminalResult;
|
|
76
95
|
};
|
|
77
96
|
|
|
78
|
-
|
|
97
|
+
function roleRecord(role: PackagedRole) {
|
|
98
|
+
const record = packagedRoleMetadata(role);
|
|
99
|
+
if (record === undefined) {
|
|
100
|
+
throw new CliUsageError(`unknown role: ${role}`);
|
|
101
|
+
}
|
|
102
|
+
return record;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Project any admitted public role onto the host-neutral turn request. */
|
|
79
106
|
export function buildInstructionSeatTurnRequest(
|
|
80
|
-
admitted:
|
|
107
|
+
admitted: AdmittedRoleInvocation,
|
|
81
108
|
options: RoleTurnRequestProjectionOptions,
|
|
82
109
|
): RoleTurnRequest {
|
|
83
110
|
return projectRoleTurnRequest(
|
|
84
111
|
admitted,
|
|
85
|
-
|
|
86
|
-
activation: {
|
|
87
|
-
role: admitted.role,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
112
|
+
admittedSeatTurnDetails(admitted, options.packageRoot),
|
|
90
113
|
options,
|
|
91
114
|
);
|
|
92
115
|
}
|
|
93
116
|
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
? {}
|
|
131
|
-
: { cause: infrastructureFailure.cause }),
|
|
132
|
-
diagnostic: infrastructureFailure.diagnostic,
|
|
133
|
-
...(infrastructureFailure.identity === undefined
|
|
134
|
-
? {}
|
|
135
|
-
: { identity: infrastructureFailure.identity }),
|
|
136
|
-
};
|
|
137
|
-
},
|
|
138
|
-
...(options?.beforeDispatch === undefined
|
|
139
|
-
? {}
|
|
140
|
-
: { beforeDispatch: options.beforeDispatch }),
|
|
141
|
-
};
|
|
117
|
+
function initialPrompt(
|
|
118
|
+
admitted: AdmittedRoleInvocation,
|
|
119
|
+
env: InstructionSeatRunEnv,
|
|
120
|
+
): string {
|
|
121
|
+
const record = roleRecord(admitted.role);
|
|
122
|
+
const reask = env.reviewReask ?? env.gateReviewInstruction;
|
|
123
|
+
if (reask !== undefined && "reaskPrompt" in record && record.reaskPrompt === true) {
|
|
124
|
+
return reask;
|
|
125
|
+
}
|
|
126
|
+
return buildInstructionTransportPrompt(
|
|
127
|
+
admitted,
|
|
128
|
+
engineSessionMaterialFromOptions({
|
|
129
|
+
...pickEngineAxis(env),
|
|
130
|
+
packageRoot: env.packageRoot,
|
|
131
|
+
}),
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function hostTurnCwd(env: InstructionSeatRunEnv): { readonly cwd: string } | undefined {
|
|
136
|
+
return env.executionCwd === undefined ? undefined : { cwd: env.executionCwd };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function wantsFreshExecutionCopy(role: PackagedRole): boolean {
|
|
140
|
+
const record = roleRecord(role);
|
|
141
|
+
return "freshExecutionCopy" in record && record.freshExecutionCopy === true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function infraFailure(role: PackagedRole) {
|
|
145
|
+
const resolveRunnerKnownFailure = seatKnownFailureResolver(role);
|
|
146
|
+
return resolveRunnerKnownFailure === undefined ? {} : { resolveRunnerKnownFailure };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isBoardTicketSeat(
|
|
150
|
+
seat: AdmittedRoleInvocation,
|
|
151
|
+
): seat is AdmittedRoleInvocation & { role: "diarist" } {
|
|
152
|
+
return packagedBindsBoardTicket(seat.role);
|
|
142
153
|
}
|
|
143
154
|
|
|
144
|
-
async function
|
|
145
|
-
role:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
case "auditor":
|
|
154
|
-
return admitAuditorInvocation(options);
|
|
155
|
+
async function bindAndRelocateDiarist(
|
|
156
|
+
admitted: AdmittedRoleInvocation & { role: "diarist" },
|
|
157
|
+
authority: DurablePrincipalAuthority,
|
|
158
|
+
lease?: RunWriterLease,
|
|
159
|
+
): Promise<void> {
|
|
160
|
+
const boardTicket = await readBoardTicketNumber(admitted.runDirectory);
|
|
161
|
+
if (boardTicket === undefined) return;
|
|
162
|
+
if (admitted.ticketNumber === undefined) {
|
|
163
|
+
await bindAdmittedTicketNumber(admitted, boardTicket);
|
|
155
164
|
}
|
|
165
|
+
await relocateAdmittedRunToTicket(admitted, authority, lease);
|
|
156
166
|
}
|
|
157
167
|
|
|
158
|
-
|
|
159
|
-
|
|
168
|
+
function seatAdapters(
|
|
169
|
+
admitted: AdmittedRoleInvocation,
|
|
160
170
|
env: InstructionSeatRunEnv,
|
|
161
|
-
|
|
162
|
-
):
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
171
|
+
material?: PackagedMethodSkillMaterial,
|
|
172
|
+
): PostAdmissionAdapters<AdmittedRoleInvocation> {
|
|
173
|
+
const record = roleRecord(admitted.role);
|
|
174
|
+
const present = "presentSettled" in record ? record.presentSettled : "default";
|
|
175
|
+
return {
|
|
176
|
+
trySettle: (seat, authority, scope) =>
|
|
177
|
+
trySettlePublicSeat(seat, authority, scope, material, env.packageRoot),
|
|
178
|
+
...(present === "always" ? { shouldPresentSettled: () => true } : {}),
|
|
179
|
+
...(present === "typed"
|
|
180
|
+
? { shouldPresentSettled: (terminal: TerminalResult) => isLawfulTypedTerminalOutcome(terminal.roleOutcome) }
|
|
181
|
+
: {}),
|
|
182
|
+
...infraFailure(admitted.role),
|
|
183
|
+
...(packagedBindsBoardTicket(admitted.role)
|
|
184
|
+
? {
|
|
185
|
+
beforeDispatch: async (seat: AdmittedRoleInvocation, lease?: RunWriterLease) => {
|
|
186
|
+
if (!isBoardTicketSeat(seat)) return;
|
|
187
|
+
if (env.correlationId !== undefined && env.correlationId.trim() !== "") {
|
|
188
|
+
await recordAdmittedCorrelation(seat, env.correlationId);
|
|
189
|
+
}
|
|
190
|
+
await bindAndRelocateDiarist(seat, env.principalAuthority, lease);
|
|
191
|
+
},
|
|
192
|
+
afterDispatch: async (seat: AdmittedRoleInvocation, lease?: RunWriterLease) => {
|
|
193
|
+
if (!isBoardTicketSeat(seat)) return;
|
|
194
|
+
await bindAndRelocateDiarist(seat, env.principalAuthority, lease);
|
|
195
|
+
},
|
|
196
|
+
}
|
|
197
|
+
: {}),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function usageExit(error: unknown, io: CliIo): SeatRunResult | undefined {
|
|
202
|
+
if (error instanceof CliUsageError) {
|
|
203
|
+
presentStructuralRejection(error, io);
|
|
204
|
+
return { exitCode: 2 };
|
|
205
|
+
}
|
|
206
|
+
return undefined;
|
|
194
207
|
}
|
|
195
208
|
|
|
196
|
-
|
|
197
|
-
async function withAuditorSoulEnv<
|
|
198
|
-
T,
|
|
199
|
-
>(options: {
|
|
209
|
+
async function withAuditorSoulEnv<T>(options: {
|
|
200
210
|
readonly subject?: "judge" | "doctor";
|
|
201
211
|
readonly sourceRunDirectory?: string;
|
|
202
212
|
readonly run: () => Promise<T>;
|
|
@@ -204,14 +214,10 @@ async function withAuditorSoulEnv<
|
|
|
204
214
|
if (options.subject === undefined && options.sourceRunDirectory === undefined) {
|
|
205
215
|
return options.run();
|
|
206
216
|
}
|
|
207
|
-
const { AK_ROLE_AUDITOR_SUBJECT_ENV, AK_ROLE_AUDITOR_SOURCE_RUN_ENV } = await import(
|
|
208
|
-
"../auditor-soul.ts"
|
|
209
|
-
);
|
|
217
|
+
const { AK_ROLE_AUDITOR_SUBJECT_ENV, AK_ROLE_AUDITOR_SOURCE_RUN_ENV } = await import("../auditor-soul.ts");
|
|
210
218
|
const priorSubject = process.env[AK_ROLE_AUDITOR_SUBJECT_ENV];
|
|
211
219
|
const priorSource = process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV];
|
|
212
|
-
if (options.subject !== undefined)
|
|
213
|
-
process.env[AK_ROLE_AUDITOR_SUBJECT_ENV] = options.subject;
|
|
214
|
-
}
|
|
220
|
+
if (options.subject !== undefined) process.env[AK_ROLE_AUDITOR_SUBJECT_ENV] = options.subject;
|
|
215
221
|
if (options.sourceRunDirectory !== undefined) {
|
|
216
222
|
process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV] = options.sourceRunDirectory;
|
|
217
223
|
}
|
|
@@ -229,147 +235,295 @@ async function withAuditorSoulEnv<
|
|
|
229
235
|
}
|
|
230
236
|
}
|
|
231
237
|
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
async function dispatchAdmitted(
|
|
239
|
+
admitted: AdmittedRoleInvocation,
|
|
234
240
|
env: InstructionSeatRunEnv,
|
|
235
241
|
io: CliIo,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
242
|
+
): Promise<SeatRunResult> {
|
|
243
|
+
const record = roleRecord(admitted.role);
|
|
244
|
+
let material: PackagedMethodSkillMaterial | undefined;
|
|
245
|
+
const skill = packagedSettleSkill(admitted);
|
|
246
|
+
if (skill !== undefined) {
|
|
247
|
+
try {
|
|
248
|
+
material = await loadPackagedMethodSkillMaterial(env.packageRoot, skill);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
const knownCause = packagedMethodLoadFailureCause(admitted.role);
|
|
251
|
+
return await presentControlledFailure(admitted, {
|
|
252
|
+
timedOut: false,
|
|
253
|
+
code: null,
|
|
254
|
+
stderr: "",
|
|
255
|
+
thrown: error,
|
|
256
|
+
...(knownCause === undefined ? {} : { knownCause }),
|
|
257
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
250
258
|
}
|
|
251
|
-
throw error;
|
|
252
259
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// No bare catch→fresh.
|
|
262
|
-
const projectRoot = parsed.project ?? env.cwd;
|
|
263
|
-
if (role === "auditor") {
|
|
264
|
-
if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
|
|
265
|
-
presentStructuralRejection(
|
|
266
|
-
new CliUsageError("auditor --subject requires judge|doctor"),
|
|
267
|
-
io,
|
|
268
|
-
);
|
|
269
|
-
return { exitCode: 2 };
|
|
270
|
-
}
|
|
271
|
-
auditorSubject = parsed.subject;
|
|
272
|
-
const source = typeof parsed.sourceRun === "string" ? parsed.sourceRun.trim() : "";
|
|
273
|
-
if (source === "") {
|
|
274
|
-
presentStructuralRejection(
|
|
275
|
-
new CliUsageError("auditor --source-run requires a run locator"),
|
|
260
|
+
const adapters = seatAdapters(admitted, env, material);
|
|
261
|
+
const execute = async (activeEnv: InstructionSeatRunEnv): Promise<SeatRunResult> => {
|
|
262
|
+
const auto = "inCallAutoResume" in record && record.inCallAutoResume === true;
|
|
263
|
+
const cwd = hostTurnCwd(activeEnv);
|
|
264
|
+
if (auto) {
|
|
265
|
+
return await runPostAdmissionResumable({
|
|
266
|
+
admitted,
|
|
267
|
+
env: activeEnv,
|
|
276
268
|
io,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
269
|
+
buildInitialRequest: () => buildInstructionSeatTurnRequest(
|
|
270
|
+
admitted,
|
|
271
|
+
roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }, cwd),
|
|
272
|
+
),
|
|
273
|
+
buildResumeRequest: () => buildInstructionSeatTurnRequest(
|
|
274
|
+
admitted,
|
|
275
|
+
roleTurnOptions(activeEnv, admitted, {
|
|
276
|
+
kind: "resume",
|
|
277
|
+
prompt: buildAutoResumeContinuationPrompt({
|
|
278
|
+
packageRoot: activeEnv.packageRoot,
|
|
279
|
+
...pickEngineAxis(activeEnv),
|
|
280
|
+
}),
|
|
281
|
+
}, cwd),
|
|
282
|
+
),
|
|
283
|
+
adapters,
|
|
284
|
+
...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
|
|
286
285
|
});
|
|
287
|
-
auditorSourceRun = resolved.runDirectory;
|
|
288
|
-
// Auditor inherits board identity only — migration-derived is display, not admission.
|
|
289
|
-
auditorSourceTicket = await readBoardTicketNumber(resolved.runDirectory);
|
|
290
|
-
} catch (error) {
|
|
291
|
-
presentStructuralRejection(
|
|
292
|
-
new CliUsageError(error instanceof Error ? error.message : String(error)),
|
|
293
|
-
io,
|
|
294
|
-
);
|
|
295
|
-
return { exitCode: 2 };
|
|
296
286
|
}
|
|
287
|
+
return await runPostAdmissionOneShot({
|
|
288
|
+
admitted,
|
|
289
|
+
env: activeEnv,
|
|
290
|
+
io,
|
|
291
|
+
request: buildInstructionSeatTurnRequest(
|
|
292
|
+
admitted,
|
|
293
|
+
roleTurnOptions(activeEnv, admitted, { kind: "initial", prompt: initialPrompt(admitted, activeEnv) }, cwd),
|
|
294
|
+
),
|
|
295
|
+
adapters,
|
|
296
|
+
...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
if (!wantsFreshExecutionCopy(admitted.role)) return execute(env);
|
|
300
|
+
try {
|
|
301
|
+
if (env.executionCwd !== undefined) return await execute(env);
|
|
302
|
+
const { withEphemeralReviewerWorktree } = await import("../public-role-summons.ts");
|
|
303
|
+
return await withEphemeralReviewerWorktree({
|
|
304
|
+
projectRoot: admitted.projectRoot,
|
|
305
|
+
onCleanupDiagnostic: (diagnostic) => {
|
|
306
|
+
io.stderr(`${diagnostic}\n`);
|
|
307
|
+
},
|
|
308
|
+
run: (executionCwd) => execute({ ...env, executionCwd }),
|
|
309
|
+
});
|
|
310
|
+
} catch (error) {
|
|
311
|
+
return await presentControlledFailure(admitted, {
|
|
312
|
+
timedOut: false,
|
|
313
|
+
code: null,
|
|
314
|
+
stderr: "",
|
|
315
|
+
thrown: error,
|
|
316
|
+
}, adapters, env.principalAuthority, io) as SeatRunResult;
|
|
297
317
|
}
|
|
318
|
+
}
|
|
298
319
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Omitted lens on a parallel-lens seat: two ordinary single-axis runs, no parent run.
|
|
322
|
+
* Each leg reuses this call's argv and only adds `--lens`.
|
|
323
|
+
*/
|
|
324
|
+
async function runOmittedLensBatch(
|
|
325
|
+
argv: readonly string[],
|
|
326
|
+
parsed: PublicSeatParse,
|
|
327
|
+
env: InstructionSeatRunEnv,
|
|
328
|
+
io: CliIo,
|
|
329
|
+
): Promise<SeatRunResult> {
|
|
330
|
+
const { summonParallelReviewerLenses } = await import("../public-role-summons.ts");
|
|
331
|
+
const children = await summonParallelReviewerLenses({
|
|
332
|
+
argv,
|
|
333
|
+
cwd: env.cwd,
|
|
334
|
+
projectRoot: resolve(parsed.project ?? env.cwd),
|
|
335
|
+
baseRevision: parsed.baseRevision ?? "",
|
|
336
|
+
home: env.home,
|
|
337
|
+
agentDir: env.agentDir,
|
|
338
|
+
...(env.credentials === undefined ? {} : { credentials: env.credentials }),
|
|
339
|
+
...(env.model === undefined ? {} : { model: env.model }),
|
|
340
|
+
...(env.host === undefined ? {} : { host: env.host }),
|
|
341
|
+
...(env.engine === undefined ? {} : { engine: env.engine }),
|
|
342
|
+
...(env.engineModel === undefined ? {} : { engineModel: env.engineModel }),
|
|
343
|
+
packageRoot: env.packageRoot,
|
|
344
|
+
...(env.signal === undefined ? {} : { signal: env.signal }),
|
|
345
|
+
...(env.correlationId === undefined ? {} : { correlationId: env.correlationId }),
|
|
346
|
+
roleTurnHost: env.roleTurnHost,
|
|
347
|
+
...(env.hostAdapters === undefined ? {} : { hostAdapters: env.hostAdapters }),
|
|
348
|
+
principalAuthority: env.principalAuthority,
|
|
349
|
+
...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
|
|
350
|
+
});
|
|
351
|
+
const childResults = [children.completeness, children.correctness] as const;
|
|
352
|
+
const terminals = childResults
|
|
353
|
+
.map((child) => child.terminal)
|
|
354
|
+
.filter((terminal): terminal is TerminalResult => terminal !== undefined);
|
|
355
|
+
const failedChildren = childResults.filter((child) =>
|
|
356
|
+
child.terminal === undefined
|
|
357
|
+
|| !isLawfulTypedTerminalOutcome(child.terminal.roleOutcome)).length;
|
|
358
|
+
const overlayExit = childResults.some((child) => child.exitCode !== 0);
|
|
359
|
+
const failed = failedChildren > 0 || overlayExit;
|
|
360
|
+
const overlayDiagnostics = [...new Set(
|
|
361
|
+
childResults
|
|
362
|
+
.map((child) => child.stderr)
|
|
363
|
+
.filter((text): text is string => typeof text === "string" && text !== ""),
|
|
364
|
+
)];
|
|
365
|
+
const terminal: TerminalResult = {
|
|
366
|
+
batch: "reviewer",
|
|
367
|
+
roleOutcome: failed
|
|
304
368
|
? {
|
|
305
|
-
|
|
306
|
-
|
|
369
|
+
kind: "failure",
|
|
370
|
+
role: "reviewer",
|
|
371
|
+
diagnostic: failedChildren > 0
|
|
372
|
+
? "Reviewer batch child failure"
|
|
373
|
+
: (overlayDiagnostics[0] ?? "Reviewer batch infrastructure failure"),
|
|
374
|
+
decisiveFacts: { failedChildren },
|
|
375
|
+
payloads: terminals,
|
|
307
376
|
}
|
|
308
|
-
: {
|
|
309
|
-
|
|
377
|
+
: { kind: "accepted", role: "reviewer", payloads: terminals },
|
|
378
|
+
reviewerChildren: {
|
|
379
|
+
...(children.completeness.terminal === undefined ? {} : { completeness: children.completeness.terminal }),
|
|
380
|
+
...(children.correctness.terminal === undefined ? {} : { correctness: children.correctness.terminal }),
|
|
381
|
+
},
|
|
382
|
+
reviewerChildOutcomes: {
|
|
383
|
+
completeness: { exitCode: children.completeness.exitCode, ...(children.completeness.stderr === undefined ? {} : { stderr: children.completeness.stderr }) },
|
|
384
|
+
correctness: { exitCode: children.correctness.exitCode, ...(children.correctness.stderr === undefined ? {} : { stderr: children.correctness.stderr }) },
|
|
385
|
+
},
|
|
386
|
+
navigator: {
|
|
387
|
+
disposition: "unavailable",
|
|
388
|
+
source: "unknown",
|
|
389
|
+
reason: "Reviewer batch has no parent-run Navigator attendance",
|
|
390
|
+
},
|
|
391
|
+
artifacts: terminals.flatMap((item) => item.artifacts),
|
|
310
392
|
};
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
393
|
+
io.stdout(formatTerminalResult(terminal));
|
|
394
|
+
return { exitCode: failed ? 1 : 0, terminal };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Countersign on the shared entry: gate parent resume, deferred materialization,
|
|
399
|
+
* 起居郎 identity, then the same one-shot settlement as every other seat.
|
|
400
|
+
* Court refresh stays on runCountersignCourtDiaristStation.
|
|
401
|
+
*/
|
|
402
|
+
async function runCountersignBody(
|
|
403
|
+
parsed: PublicSeatParse,
|
|
404
|
+
env: InstructionSeatRunEnv,
|
|
405
|
+
io: CliIo,
|
|
406
|
+
): Promise<SeatRunResult> {
|
|
407
|
+
const gateParentRunPath =
|
|
408
|
+
typeof env.parentRunPath === "string" && env.parentRunPath.trim() !== ""
|
|
409
|
+
? env.parentRunPath
|
|
410
|
+
: undefined;
|
|
411
|
+
if (gateParentRunPath !== undefined) {
|
|
412
|
+
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction ?? parsed.instruction ?? "";
|
|
413
|
+
const resumed = await tryResumeSameTicketSeatRun({
|
|
414
|
+
home: env.home,
|
|
415
|
+
projectRoot: resolve(parsed.project ?? env.cwd),
|
|
416
|
+
role: "countersign",
|
|
417
|
+
parentRunPath: gateParentRunPath,
|
|
418
|
+
freshSummons: env.freshSummons,
|
|
419
|
+
summons: {
|
|
420
|
+
sourceRunPath: gateParentRunPath,
|
|
421
|
+
instruction: resumeInstruction,
|
|
422
|
+
instructionEmpty: resumeInstruction.trim() === "",
|
|
423
|
+
},
|
|
424
|
+
resume: (runId, materials) => runPublicInstructionSeatResume(
|
|
425
|
+
{ runId, ...(materials === undefined ? {} : { summons: materials }) },
|
|
426
|
+
env,
|
|
427
|
+
io,
|
|
428
|
+
),
|
|
330
429
|
});
|
|
331
|
-
if (resumed
|
|
332
|
-
// #836: reask without a prior same-parent run still mints; summons.instruction
|
|
333
|
-
// already carries the reask text. Do not structurally terminate the queue.
|
|
430
|
+
if (resumed != null) return resumed;
|
|
334
431
|
}
|
|
335
432
|
|
|
336
|
-
let admitted:
|
|
433
|
+
let admitted: AdmittedCountersignInvocation;
|
|
337
434
|
try {
|
|
338
|
-
admitted = await
|
|
339
|
-
home: env.home,
|
|
340
|
-
principalAuthority: env.principalAuthority,
|
|
341
|
-
cwd: env.cwd,
|
|
342
|
-
instruction: parsed.instruction,
|
|
343
|
-
attachmentPaths: parsed.attachmentPaths,
|
|
344
|
-
...(parsed.project === undefined ? {} : { project: parsed.project }),
|
|
345
|
-
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
346
|
-
...(env.model === undefined ? {} : { model: env.model }),
|
|
347
|
-
...(env.correlationId === undefined ? {} : { correlationId: env.correlationId }),
|
|
348
|
-
...(auditorSourceTicket === undefined
|
|
349
|
-
? {}
|
|
350
|
-
: { assertedTicketNumber: auditorSourceTicket }),
|
|
351
|
-
});
|
|
435
|
+
admitted = await admitPublicRole("countersign", parsed, env, { deferPersistence: true });
|
|
352
436
|
} catch (error) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return { exitCode: 2 };
|
|
356
|
-
}
|
|
437
|
+
const rejected = usageExit(error, io);
|
|
438
|
+
if (rejected !== undefined) return rejected;
|
|
357
439
|
throw error;
|
|
358
440
|
}
|
|
359
441
|
|
|
360
|
-
|
|
361
|
-
await
|
|
362
|
-
|
|
442
|
+
try {
|
|
443
|
+
return await withPreparedAttachments(parsed.attachmentPaths ?? [], async (preparedAttachments) => {
|
|
444
|
+
const materializeAdmission = async (ticketNumber?: number): Promise<void> => {
|
|
445
|
+
await materializeCountersignInvocation(admitted, {
|
|
446
|
+
home: env.home,
|
|
447
|
+
principalAuthority: env.principalAuthority,
|
|
448
|
+
preparedAttachments,
|
|
449
|
+
...(env.model === undefined ? {} : { model: env.model }),
|
|
450
|
+
...(ticketNumber === undefined ? {} : { ticketNumber }),
|
|
451
|
+
});
|
|
452
|
+
};
|
|
363
453
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
454
|
+
let typedTicket: number | undefined;
|
|
455
|
+
let typedCourtTicketNumbers: readonly number[] | undefined;
|
|
456
|
+
let identityDiaristRan = false;
|
|
457
|
+
|
|
458
|
+
if (env.runCourtDiaristStation === undefined) {
|
|
459
|
+
let outcome: Awaited<ReturnType<typeof invokeCourtDiarist>>;
|
|
460
|
+
try {
|
|
461
|
+
outcome = await invokeCourtDiarist({
|
|
462
|
+
instruction: parsed.instruction ?? "",
|
|
463
|
+
projectRoot: admitted.projectRoot,
|
|
464
|
+
failureLabel: "unbound summons",
|
|
465
|
+
...(env.boundTicketNumber === undefined ? {} : { boundTicketNumber: env.boundTicketNumber }),
|
|
466
|
+
}, env, io);
|
|
467
|
+
} catch (error) {
|
|
468
|
+
await materializeAdmission(
|
|
469
|
+
isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined,
|
|
470
|
+
);
|
|
471
|
+
await markRunAdmitted(admitted, env.principalAuthority);
|
|
472
|
+
return await presentControlledFailure(admitted, {
|
|
473
|
+
timedOut: false,
|
|
474
|
+
code: null,
|
|
475
|
+
stderr: "",
|
|
476
|
+
thrown: error,
|
|
477
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
478
|
+
}
|
|
479
|
+
identityDiaristRan = true;
|
|
480
|
+
if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== undefined) {
|
|
481
|
+
const diagnostic = outcome.identity.kind === "escalate"
|
|
482
|
+
? outcome.identity.diagnostic
|
|
483
|
+
: outcome.failedWithoutEscalate?.diagnostic ?? "";
|
|
484
|
+
await materializeAdmission(
|
|
485
|
+
isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined,
|
|
486
|
+
);
|
|
487
|
+
await markRunAdmitted(admitted, env.principalAuthority);
|
|
488
|
+
return await presentControlledFailure(admitted, {
|
|
489
|
+
timedOut: false,
|
|
490
|
+
code: null,
|
|
491
|
+
stderr: "",
|
|
492
|
+
thrown: new Error(diagnostic),
|
|
493
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
494
|
+
}
|
|
495
|
+
if (outcome.identity.kind === "ticket") {
|
|
496
|
+
typedTicket = isSafePositiveTicketNumber(env.boundTicketNumber)
|
|
497
|
+
? env.boundTicketNumber
|
|
498
|
+
: outcome.identity.ticketNumber;
|
|
499
|
+
typedCourtTicketNumbers = outcome.identity.courtTicketNumbers;
|
|
500
|
+
} else if (isSafePositiveTicketNumber(env.boundTicketNumber)) {
|
|
501
|
+
typedTicket = env.boundTicketNumber;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
await materializeAdmission(typedTicket);
|
|
370
506
|
await markRunAdmitted(admitted, env.principalAuthority);
|
|
507
|
+
if (gateParentRunPath !== undefined) {
|
|
508
|
+
await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
|
|
509
|
+
admitted = { ...admitted, sourceRunPath: gateParentRunPath };
|
|
510
|
+
}
|
|
511
|
+
if (identityDiaristRan && typedTicket !== undefined) {
|
|
512
|
+
try {
|
|
513
|
+
await bindAdmittedTicketNumber(admitted, typedTicket);
|
|
514
|
+
await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
|
|
515
|
+
await bindCourtTicketNumbersOnAdmitted(admitted, typedCourtTicketNumbers ?? [typedTicket]);
|
|
516
|
+
} catch (error) {
|
|
517
|
+
return await presentControlledFailure(admitted, {
|
|
518
|
+
timedOut: false,
|
|
519
|
+
code: null,
|
|
520
|
+
stderr: "",
|
|
521
|
+
thrown: error,
|
|
522
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
371
525
|
|
|
372
|
-
const
|
|
526
|
+
const turnProjection: RoleTurnRequestProjectionOptions = {
|
|
373
527
|
packageRoot: env.packageRoot,
|
|
374
528
|
home: env.home,
|
|
375
529
|
agentDir: env.agentDir,
|
|
@@ -381,7 +535,6 @@ export async function runPublicInstructionSeat(
|
|
|
381
535
|
: { correlationId: env.correlationId }),
|
|
382
536
|
continuation: {
|
|
383
537
|
kind: "initial",
|
|
384
|
-
// #879: gate first mint uses parent payload as content when present.
|
|
385
538
|
prompt: (env.reviewReask ?? env.gateReviewInstruction)
|
|
386
539
|
?? buildInstructionTransportPrompt(
|
|
387
540
|
admitted,
|
|
@@ -391,16 +544,344 @@ export async function runPublicInstructionSeat(
|
|
|
391
544
|
}),
|
|
392
545
|
),
|
|
393
546
|
},
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
547
|
+
};
|
|
548
|
+
const turnRequest = buildInstructionSeatTurnRequest(admitted, turnProjection);
|
|
549
|
+
const result = await runPostAdmissionOneShot({
|
|
397
550
|
admitted,
|
|
398
551
|
env,
|
|
399
552
|
io,
|
|
400
553
|
request: turnRequest,
|
|
401
|
-
adapters:
|
|
554
|
+
adapters: {
|
|
555
|
+
...seatAdapters(admitted, env),
|
|
556
|
+
beforeDispatch: async (admittedSeat, lease) => {
|
|
557
|
+
if (!packagedAdmitsCountersign(admittedSeat.role)) return;
|
|
558
|
+
if (!identityDiaristRan || typedTicket !== undefined) {
|
|
559
|
+
await runCountersignCourtDiaristStation(admittedSeat, env, io);
|
|
560
|
+
}
|
|
561
|
+
await relocateAdmittedRunToTicket(admittedSeat, env.principalAuthority, lease);
|
|
562
|
+
Object.assign(turnRequest, buildInstructionSeatTurnRequest(admittedSeat, turnProjection));
|
|
563
|
+
},
|
|
564
|
+
},
|
|
402
565
|
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
403
566
|
});
|
|
567
|
+
await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
|
|
568
|
+
return result;
|
|
569
|
+
});
|
|
570
|
+
} catch (error) {
|
|
571
|
+
const rejected = usageExit(error, io);
|
|
572
|
+
if (rejected !== undefined) return rejected;
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export async function runPublicInstructionSeat(
|
|
578
|
+
argv: readonly string[],
|
|
579
|
+
env: InstructionSeatRunEnv,
|
|
580
|
+
io: CliIo,
|
|
581
|
+
role: PackagedRole,
|
|
582
|
+
parseArgv: (args: readonly string[]) => PublicSeatParse,
|
|
583
|
+
): Promise<SeatRunResult> {
|
|
584
|
+
const record = roleRecord(role);
|
|
585
|
+
let parsed: PublicSeatParse;
|
|
586
|
+
try {
|
|
587
|
+
parsed = parseArgv(argv);
|
|
588
|
+
} catch (error) {
|
|
589
|
+
const rejected = usageExit(error, io);
|
|
590
|
+
if (rejected !== undefined) return rejected;
|
|
591
|
+
throw error;
|
|
592
|
+
}
|
|
593
|
+
if (packagedAdmitsCountersign(role)) {
|
|
594
|
+
return runCountersignBody(parsed, env, io);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if ("parallelLenses" in record && record.parallelLenses === true) {
|
|
598
|
+
if (parsed.baseRevision === undefined) {
|
|
599
|
+
presentStructuralRejection(new CliUsageError("reviewer requires --base"), io);
|
|
600
|
+
return { exitCode: 2 };
|
|
601
|
+
}
|
|
602
|
+
if (parsed.lens === undefined) {
|
|
603
|
+
return runOmittedLensBatch(argv, parsed, env, io);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const projectRoot = parsed.project ?? env.cwd;
|
|
608
|
+
let auditorSubject: "judge" | "doctor" | undefined;
|
|
609
|
+
let auditorSource: string | undefined;
|
|
610
|
+
let auditorTicket: number | undefined;
|
|
611
|
+
if (record.sameParent === "subject-source") {
|
|
612
|
+
if (!isAuditorSoulRole(parsed.subject)) {
|
|
613
|
+
presentStructuralRejection(new CliUsageError("auditor --subject requires judge|doctor"), io);
|
|
614
|
+
return { exitCode: 2 };
|
|
615
|
+
}
|
|
616
|
+
auditorSubject = parsed.subject;
|
|
617
|
+
const source = typeof parsed.sourceRun === "string" ? parsed.sourceRun.trim() : "";
|
|
618
|
+
if (source === "") {
|
|
619
|
+
presentStructuralRejection(new CliUsageError("auditor --source-run requires a run locator"), io);
|
|
620
|
+
return { exitCode: 2 };
|
|
621
|
+
}
|
|
622
|
+
try {
|
|
623
|
+
const resolved = await resolveNotarySourceRunLocator({ projectRoot, sourceRun: source, home: env.home });
|
|
624
|
+
auditorSource = resolved.runDirectory;
|
|
625
|
+
auditorTicket = await readBoardTicketNumber(resolved.runDirectory);
|
|
626
|
+
} catch (error) {
|
|
627
|
+
presentStructuralRejection(new CliUsageError(error instanceof Error ? error.message : String(error)), io);
|
|
628
|
+
return { exitCode: 2 };
|
|
629
|
+
}
|
|
630
|
+
if (auditorSource === undefined) return { exitCode: 2 };
|
|
631
|
+
const sourceDirectory = auditorSource;
|
|
632
|
+
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
633
|
+
const summons: SameTicketSummonsMaterials = {
|
|
634
|
+
...(resumeInstruction === undefined
|
|
635
|
+
? { instruction: parsed.instruction ?? "", instructionEmpty: (parsed.instruction ?? "").trim() === "" }
|
|
636
|
+
: { instruction: resumeInstruction, instructionEmpty: false }),
|
|
637
|
+
attachmentPaths: parsed.attachmentPaths ?? [],
|
|
638
|
+
};
|
|
639
|
+
const resumed = await withAuditorSoulEnv({
|
|
640
|
+
subject: auditorSubject,
|
|
641
|
+
sourceRunDirectory: auditorSource,
|
|
642
|
+
run: () => tryResumeSameTicketSeatRun({
|
|
643
|
+
home: env.home,
|
|
644
|
+
projectRoot,
|
|
645
|
+
role,
|
|
646
|
+
parentRunPath: sourceDirectory,
|
|
647
|
+
freshSummons: env.freshSummons,
|
|
648
|
+
summons,
|
|
649
|
+
resume: (runId, materials) => runPublicInstructionSeatResume(
|
|
650
|
+
{ runId, ...(materials === undefined ? {} : { summons: materials }) },
|
|
651
|
+
env,
|
|
652
|
+
io,
|
|
653
|
+
),
|
|
654
|
+
}),
|
|
655
|
+
});
|
|
656
|
+
if (resumed != null) return resumed;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (record.sameParent === "gate-pointer") {
|
|
660
|
+
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction ?? "");
|
|
661
|
+
if (parentRunPath !== undefined) {
|
|
662
|
+
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
663
|
+
const summons: SameTicketSummonsMaterials = {
|
|
664
|
+
sourceRunPath: parentRunPath,
|
|
665
|
+
...(resumeInstruction === undefined
|
|
666
|
+
? { instruction: parsed.instruction ?? "", instructionEmpty: (parsed.instruction ?? "").trim() === "" }
|
|
667
|
+
: { instruction: resumeInstruction, instructionEmpty: false }),
|
|
668
|
+
attachmentPaths: parsed.attachmentPaths ?? [],
|
|
669
|
+
};
|
|
670
|
+
const resumed = await tryResumeSameTicketSeatRun({
|
|
671
|
+
home: env.home,
|
|
672
|
+
projectRoot,
|
|
673
|
+
role,
|
|
674
|
+
parentRunPath,
|
|
675
|
+
freshSummons: env.freshSummons,
|
|
676
|
+
summons,
|
|
677
|
+
resume: (runId, materials) => runPublicInstructionSeatResume(
|
|
678
|
+
{ runId, ...(materials === undefined ? {} : { summons: materials }) },
|
|
679
|
+
env,
|
|
680
|
+
io,
|
|
681
|
+
),
|
|
682
|
+
});
|
|
683
|
+
if (resumed != null) return resumed;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (record.sameParent === "source-locator") {
|
|
688
|
+
let source;
|
|
689
|
+
try {
|
|
690
|
+
source = await resolveNotarySourceRunLocator({
|
|
691
|
+
projectRoot,
|
|
692
|
+
sourceRun: parsed.sourceRun ?? "",
|
|
693
|
+
home: env.home,
|
|
694
|
+
});
|
|
695
|
+
} catch (error) {
|
|
696
|
+
if (error instanceof NotarySourceRunError) {
|
|
697
|
+
presentStructuralRejection(new CliUsageError(error.message, { cause: error }), io);
|
|
698
|
+
return { exitCode: 2 };
|
|
699
|
+
}
|
|
700
|
+
throw error;
|
|
701
|
+
}
|
|
702
|
+
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
703
|
+
const summons: SameTicketSummonsMaterials = {
|
|
704
|
+
sourceRunPath: source.runDirectory,
|
|
705
|
+
sourceRun: source,
|
|
706
|
+
...(resumeInstruction === undefined ? {} : { instruction: resumeInstruction, instructionEmpty: false }),
|
|
707
|
+
};
|
|
708
|
+
const resumed = await tryResumeSameTicketSeatRun({
|
|
709
|
+
home: env.home,
|
|
710
|
+
projectRoot,
|
|
711
|
+
role,
|
|
712
|
+
parentRunPath: source.runDirectory,
|
|
713
|
+
freshSummons: env.freshSummons,
|
|
714
|
+
summons,
|
|
715
|
+
resume: (runId, materials) => runPublicInstructionSeatResume(
|
|
716
|
+
{ runId, ...(materials === undefined ? {} : { summons: materials }) },
|
|
717
|
+
env,
|
|
718
|
+
io,
|
|
719
|
+
),
|
|
720
|
+
});
|
|
721
|
+
if (resumed != null) return resumed;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
let admitted: AdmittedRoleInvocation;
|
|
725
|
+
try {
|
|
726
|
+
admitted = await admitPublicRole(
|
|
727
|
+
role,
|
|
728
|
+
parsed,
|
|
729
|
+
env,
|
|
730
|
+
auditorTicket === undefined ? undefined : { assertedTicketNumber: auditorTicket },
|
|
731
|
+
);
|
|
732
|
+
} catch (error) {
|
|
733
|
+
const rejected = usageExit(error, io);
|
|
734
|
+
if (rejected !== undefined) return rejected;
|
|
735
|
+
throw error;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (record.sameParent === "gate-pointer") {
|
|
739
|
+
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction ?? "");
|
|
740
|
+
if (parentRunPath !== undefined) {
|
|
741
|
+
await persistAdmittedSourceRunPath(admitted, parentRunPath);
|
|
742
|
+
const sourcePatch = { sourceRunPath: parentRunPath };
|
|
743
|
+
admitted = { ...admitted, ...sourcePatch };
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (record.sameParent === "subject-source" && auditorSource !== undefined) {
|
|
747
|
+
await persistAdmittedSourceRunPath(admitted, auditorSource);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const runAdmitted = async (): Promise<SeatRunResult> => {
|
|
751
|
+
await markRunAdmitted(admitted, env.principalAuthority);
|
|
752
|
+
if (record.sameParent === "court-diarist") {
|
|
753
|
+
const { invokeCourtDiarist } = await import("./countersign-run.ts");
|
|
754
|
+
const outcome = await invokeCourtDiarist({
|
|
755
|
+
instruction: parsed.instruction ?? "",
|
|
756
|
+
projectRoot: admitted.projectRoot,
|
|
757
|
+
failureLabel: "secretariat unbound summons",
|
|
758
|
+
attachmentPaths: admitted.attachments.map((attachment) => attachment.frozenPath),
|
|
759
|
+
correlationId: admitted.runId,
|
|
760
|
+
}, {
|
|
761
|
+
cwd: env.cwd,
|
|
762
|
+
home: env.home,
|
|
763
|
+
agentDir: env.agentDir,
|
|
764
|
+
packageRoot: env.packageRoot,
|
|
765
|
+
...(env.credentials === undefined ? {} : { credentials: env.credentials }),
|
|
766
|
+
...(env.signal === undefined ? {} : { signal: env.signal }),
|
|
767
|
+
...(env.hostAdapters === undefined ? {} : { hostAdapters: env.hostAdapters }),
|
|
768
|
+
}, io);
|
|
769
|
+
if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== undefined) {
|
|
770
|
+
const diagnostic = outcome.identity.kind === "escalate"
|
|
771
|
+
? outcome.identity.diagnostic
|
|
772
|
+
: outcome.failedWithoutEscalate?.diagnostic ?? "";
|
|
773
|
+
return await presentControlledFailure(admitted, {
|
|
774
|
+
timedOut: false,
|
|
775
|
+
code: null,
|
|
776
|
+
stderr: "",
|
|
777
|
+
thrown: new Error(diagnostic),
|
|
778
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
779
|
+
}
|
|
780
|
+
if (outcome.identity.kind === "ticket") {
|
|
781
|
+
try {
|
|
782
|
+
await bindAdmittedTicketNumber(admitted, outcome.identity.ticketNumber);
|
|
783
|
+
await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
|
|
784
|
+
} catch (error) {
|
|
785
|
+
return await presentControlledFailure(admitted, {
|
|
786
|
+
timedOut: false,
|
|
787
|
+
code: null,
|
|
788
|
+
stderr: "",
|
|
789
|
+
thrown: error,
|
|
790
|
+
}, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
return dispatchAdmitted(admitted, env, io);
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
if (record.sameParent === "subject-source") {
|
|
798
|
+
return withAuditorSoulEnv({
|
|
799
|
+
...(auditorSubject === undefined ? {} : { subject: auditorSubject }),
|
|
800
|
+
...(auditorSource === undefined ? {} : { sourceRunDirectory: auditorSource }),
|
|
801
|
+
run: runAdmitted,
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
return runAdmitted();
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
export async function runPublicInstructionSeatResume(
|
|
808
|
+
request: PublicResumeRequest,
|
|
809
|
+
env: InstructionSeatRunEnv,
|
|
810
|
+
io: CliIo,
|
|
811
|
+
): Promise<SeatRunResult> {
|
|
812
|
+
const execution: { cwd?: string } = {
|
|
813
|
+
...(env.executionCwd === undefined ? {} : { cwd: env.executionCwd }),
|
|
814
|
+
};
|
|
815
|
+
return runPostAdmissionSeatResume<AdmittedRoleInvocation>({
|
|
816
|
+
request,
|
|
817
|
+
env,
|
|
818
|
+
io,
|
|
819
|
+
load: async (effective) => {
|
|
820
|
+
const loaded = await loadResumablePublicRole(env.home, effective.runId, env.principalAuthority);
|
|
821
|
+
if (
|
|
822
|
+
packagedRebindSourceOnResume(loaded.admitted.role)
|
|
823
|
+
&& effective.summons?.sourceRunPath !== undefined
|
|
824
|
+
&& effective.summons.sourceRun !== undefined
|
|
825
|
+
) {
|
|
826
|
+
return {
|
|
827
|
+
...loaded,
|
|
828
|
+
admitted: {
|
|
829
|
+
...loaded.admitted,
|
|
830
|
+
sourceRunPath: effective.summons.sourceRunPath,
|
|
831
|
+
sourceRun: effective.summons.sourceRun,
|
|
832
|
+
},
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
return loaded;
|
|
836
|
+
},
|
|
837
|
+
buildTurnRequest: async (admitted, effective) => {
|
|
838
|
+
const activeEnv = execution.cwd === undefined ? env : { ...env, executionCwd: execution.cwd };
|
|
839
|
+
const summonsPrepared = await prepareSummonsResumeMaterials(admitted.runDirectory, effective.summons);
|
|
840
|
+
return buildInstructionSeatTurnRequest(
|
|
841
|
+
admitted,
|
|
842
|
+
{
|
|
843
|
+
...resumeTurnRequestProjectionOptions(admitted, effective, activeEnv, summonsPrepared),
|
|
844
|
+
...(execution.cwd === undefined ? {} : { cwd: execution.cwd }),
|
|
845
|
+
},
|
|
846
|
+
);
|
|
847
|
+
},
|
|
848
|
+
adapters: {
|
|
849
|
+
trySettle: async () => undefined,
|
|
850
|
+
},
|
|
851
|
+
afterAdmittedLoad: (admitted) => {
|
|
852
|
+
const skill = packagedSettleSkill(admitted);
|
|
853
|
+
if (skill === undefined) {
|
|
854
|
+
return Promise.resolve({ kind: "continue" as const, adapters: seatAdapters(admitted, env) });
|
|
855
|
+
}
|
|
856
|
+
const knownCause = packagedMethodLoadFailureCause(admitted.role);
|
|
857
|
+
return resolveResumeMethodMaterialAdapters({
|
|
858
|
+
admitted,
|
|
859
|
+
authority: env.principalAuthority,
|
|
860
|
+
io,
|
|
861
|
+
loadMaterial: () => loadPackagedMethodSkillMaterial(env.packageRoot, skill),
|
|
862
|
+
adaptersWith: (material) => seatAdapters(admitted, env, material),
|
|
863
|
+
emptyAdapters: seatAdapters(admitted, env),
|
|
864
|
+
...(knownCause === undefined ? {} : { knownCause }),
|
|
865
|
+
});
|
|
866
|
+
},
|
|
867
|
+
afterAdmittedPrepare: async (admitted) => {
|
|
868
|
+
if (!wantsFreshExecutionCopy(admitted.role)) return {};
|
|
869
|
+
if (execution.cwd !== undefined) {
|
|
870
|
+
return { env: { ...env, executionCwd: execution.cwd } };
|
|
871
|
+
}
|
|
872
|
+
const { openEphemeralReviewerWorktree } = await import("../public-role-summons.ts");
|
|
873
|
+
const opened = await openEphemeralReviewerWorktree({
|
|
874
|
+
projectRoot: admitted.projectRoot,
|
|
875
|
+
onCleanupDiagnostic: (diagnostic) => {
|
|
876
|
+
io.stderr(`${diagnostic}\n`);
|
|
877
|
+
},
|
|
878
|
+
});
|
|
879
|
+
execution.cwd = opened.executionCwd;
|
|
880
|
+
return {
|
|
881
|
+
env: { ...env, executionCwd: opened.executionCwd },
|
|
882
|
+
cleanup: opened.close,
|
|
883
|
+
};
|
|
404
884
|
},
|
|
885
|
+
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
405
886
|
});
|
|
406
887
|
}
|