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