@akagilnc/pi-workflow-roles 0.1.3565 → 0.1.3621

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/README.md +4 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/acp-host/production-host.js +18477 -8099
  4. package/dist/analyst-gate-cycles-read.js +387 -0
  5. package/dist/archivist-record-entry.js +22 -1
  6. package/dist/audit-escalation.js +6 -0
  7. package/dist/auditor-soul.js +74 -0
  8. package/dist/collector-config.js +86 -0
  9. package/dist/collector-evidence.js +316 -0
  10. package/dist/collector-github.js +527 -0
  11. package/dist/collector-ledger.js +853 -0
  12. package/dist/collector-tool-schemas.js +33 -0
  13. package/dist/compliance-transport.js +104 -52
  14. package/dist/diarist-contracts.js +72 -0
  15. package/dist/diarist-mechanical.js +411 -0
  16. package/dist/diarist-ticket-resolution.js +177 -0
  17. package/dist/diarist.js +311 -0
  18. package/dist/doctor-auditor.js +25 -0
  19. package/dist/doctor-contracts.js +2 -0
  20. package/dist/doctor-evidence.js +142 -0
  21. package/dist/gatekeeper-role.js +104 -81
  22. package/dist/host-transition-prior-native.js +78 -0
  23. package/dist/institutional-resolution.js +1 -95
  24. package/dist/judge-auditor.js +26 -0
  25. package/dist/ledger-session-read.js +227 -0
  26. package/dist/merger-git-state.js +78 -0
  27. package/dist/navigator-attendance.js +15 -7
  28. package/dist/navigator-public-session.js +170 -0
  29. package/dist/navigator-session-contracts.js +36 -40
  30. package/dist/notary-source-run.js +122 -0
  31. package/dist/package-contracts/auditor-output.js +66 -0
  32. package/dist/package-contracts/evidence-child-output.js +34 -0
  33. package/dist/package-contracts/judge-output.js +2 -0
  34. package/dist/package-contracts/terminating-tools.js +44 -3
  35. package/dist/package-resources/method-skill.js +254 -0
  36. package/dist/packaged-role-registry.js +56 -0
  37. package/dist/pi/durable-principal.js +61 -0
  38. package/dist/pi/in-process-session.js +25 -6
  39. package/dist/pi/known-failure.js +52 -0
  40. package/dist/pi/role-turn-host.js +430 -0
  41. package/dist/public-cli/auto-resume.js +414 -0
  42. package/dist/public-cli/cli-errors.js +8 -0
  43. package/dist/public-cli/cli-io.js +1 -0
  44. package/dist/public-cli/command-renderer.js +5 -0
  45. package/dist/public-cli/doctor-run.js +84 -0
  46. package/dist/public-cli/inspector-run.js +136 -0
  47. package/dist/public-cli/instruction-seat-run.js +256 -0
  48. package/dist/public-cli/invocation.js +2225 -0
  49. package/dist/public-cli/judge-run.js +118 -0
  50. package/dist/public-cli/load-production-acp-host.js +40 -0
  51. package/dist/public-cli/main.js +1511 -1124
  52. package/dist/public-cli/notary-run.js +161 -0
  53. package/dist/public-cli/option-definitions.js +1192 -0
  54. package/dist/public-cli/post-admission.js +667 -0
  55. package/dist/public-cli/public-run-credentials.js +49 -0
  56. package/dist/public-cli/registry.js +8 -2
  57. package/dist/public-cli/reviewer-dispatch-rejection.js +77 -0
  58. package/dist/public-cli/run-lifecycle.js +1344 -0
  59. package/dist/public-cli/seat-ticket-binding.js +113 -0
  60. package/dist/public-cli/settlement.js +3441 -0
  61. package/dist/public-cli/terminal.js +135 -0
  62. package/dist/public-cli/turn-request.js +25 -0
  63. package/dist/public-role-summons.js +301 -0
  64. package/dist/receipt-delivery-policy.js +10 -0
  65. package/dist/reviewer-child-executor.js +80 -8
  66. package/dist/reviewer-execution-ledger.js +2 -1
  67. package/dist/run-terminal-artifacts.js +195 -0
  68. package/dist/run-ticket-number.js +40 -0
  69. package/dist/session-assistant-usage.js +107 -0
  70. package/dist/shape-unreadable-failure.js +34 -0
  71. package/dist/submission-errors.js +3 -0
  72. package/dist/submission-ledger.js +388 -0
  73. package/dist/ticket-provenance-contracts.js +115 -0
  74. package/dist/ticket-provenance.js +340 -0
  75. package/extensions/role-runtime.ts +8 -0
  76. package/package.json +1 -1
  77. package/resources/diarist-collect.md +6 -10
  78. package/scripts/build-package.mjs +2 -1
  79. package/souls/diarist.md +9 -0
  80. package/souls/doctor-auditor.md +1 -0
  81. package/souls/evidence-child.md +1 -0
  82. package/src/acp-host/production-host.ts +4 -0
  83. package/src/acp-host/role-envelope.ts +4 -3
  84. package/src/acp-host/role-turn-host.ts +9 -1
  85. package/src/analyst-gate-cycles-read.ts +37 -2
  86. package/src/archivist-record-entry.ts +45 -1
  87. package/src/audit-escalation.ts +17 -0
  88. package/src/auditor-role.ts +22 -0
  89. package/src/auditor-soul.ts +42 -0
  90. package/src/compliance-transport.ts +177 -66
  91. package/src/diarist-contracts.ts +88 -0
  92. package/src/diarist-role.ts +60 -0
  93. package/src/diarist.ts +253 -179
  94. package/src/doctor-auditor.ts +10 -14
  95. package/src/doctor-contracts.ts +1 -0
  96. package/src/doctor-role.ts +2 -2
  97. package/src/evidence-child-role.ts +22 -0
  98. package/src/gatekeeper-pass-envelope.ts +109 -0
  99. package/src/gatekeeper-role.ts +145 -104
  100. package/src/host-contracts.ts +15 -2
  101. package/src/institutional-resolution.ts +8 -163
  102. package/src/judge-auditor.ts +10 -15
  103. package/src/judge-role.ts +8 -0
  104. package/src/navigator-attendance.ts +25 -9
  105. package/src/navigator-public-session.ts +217 -0
  106. package/src/navigator-session-contracts.ts +61 -54
  107. package/src/notary-source-run.ts +3 -1
  108. package/src/package-contracts/auditor-output.ts +82 -0
  109. package/src/package-contracts/evidence-child-output.ts +51 -0
  110. package/src/package-contracts/judge-output.ts +1 -0
  111. package/src/package-contracts/reviewer-output.ts +2 -2
  112. package/src/package-contracts/terminating-tools.ts +53 -3
  113. package/src/packaged-role-registry.ts +63 -0
  114. package/src/pi/adapter.ts +2 -1
  115. package/src/pi/in-process-session.ts +38 -12
  116. package/src/pi/role-turn-host.ts +42 -0
  117. package/src/public-cli/cli.ts +43 -6
  118. package/src/public-cli/countersign-run.ts +9 -129
  119. package/src/public-cli/diarist-run.ts +312 -0
  120. package/src/public-cli/instruction-seat-run.ts +289 -50
  121. package/src/public-cli/invocation.ts +87 -25
  122. package/src/public-cli/option-definitions.ts +79 -0
  123. package/src/public-cli/post-admission.ts +9 -3
  124. package/src/public-cli/registry.ts +7 -1
  125. package/src/public-cli/run-lifecycle.ts +53 -6
  126. package/src/public-cli/settlement.ts +170 -7
  127. package/src/public-cli/terminal.ts +4 -1
  128. package/src/public-role-summons.ts +431 -0
  129. package/src/receipt-delivery-policy.ts +10 -0
  130. package/src/reviewer-agent.ts +1 -1
  131. package/src/reviewer-child-executor.ts +114 -12
  132. package/src/reviewer-execution-ledger.ts +3 -2
  133. package/src/role-runtime.ts +275 -23
  134. package/src/session-assistant-usage.ts +119 -0
  135. package/src/session-opening-materials.ts +1 -1
  136. package/src/shape-unreadable-failure.ts +49 -0
  137. package/src/submission-errors.ts +3 -0
  138. package/src/ticket-provenance-contracts.ts +1 -0
  139. package/src/ticket-provenance.ts +0 -23
  140. package/dist/evidence-child-executor.js +0 -829
  141. package/src/diarist-llm-collector.ts +0 -324
  142. package/src/evidence-child-executor.ts +0 -1140
@@ -1,33 +1,53 @@
1
1
  /**
2
- * Shared instruction-seat run (#639 repair seam): gatekeeper and navigator are
3
- * the same admit → turn-request → post-admission → settle shape, parameterized
4
- * by seat. Same direction as the settlement one-shot shared skeleton. cli.ts
5
- * calls this parameterized module directly; no per-seat wrappers.
2
+ * Shared instruction-seat run (#639 / #675 / #637): gatekeeper, navigator, auditor,
3
+ * and evidence-child share admit → turn-request → post-admission → settle.
4
+ * Same-ticket re-summons resume the seat's previous run via the shared public
5
+ * tryResumeSameTicketSeatRun seam (inspector/notary/countersign face) — no
6
+ * independent run/rebind/nest path.
6
7
  */
7
8
  import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
8
9
  import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
10
+ import { readRunTicketNumber } from "../run-ticket-number.ts";
9
11
  import { CliUsageError } from "./cli-errors.ts";
10
12
  import {
13
+ admitAuditorInvocation,
14
+ admitEvidenceChildInvocation,
11
15
  admitGatekeeperInvocation,
12
16
  admitNavigatorInvocation,
17
+ bindAdmittedTicketNumber,
13
18
  buildInstructionTransportPrompt,
19
+ type AdmittedAuditorInvocation,
20
+ type AdmittedEvidenceChildInvocation,
14
21
  type AdmittedGatekeeperInvocation,
15
22
  type AdmittedNavigatorInvocation,
16
23
  type ParseInstructionArgvResult,
17
24
  } from "./invocation.ts";
18
25
  import {
26
+ prepareSummonsResumeMaterials,
19
27
  runPostAdmissionOneShot,
20
28
  runPostAdmissionSeatResume,
21
29
  resumeTurnRequestProjectionOptions,
30
+ type PostAdmissionAdapters,
22
31
  type PostAdmissionEnv,
23
32
  } from "./post-admission.ts";
24
33
  import {
25
34
  loadResumableInstructionSeatRun,
26
35
  markRunAdmitted,
27
36
  type PublicResumeRequest,
37
+ type SameTicketSummonsMaterials,
28
38
  } from "./run-lifecycle.ts";
39
+ import {
40
+ applyInstructionTicketProbe,
41
+ probeInstructionTicket,
42
+ ticketNumberFromProbe,
43
+ tryResumeSameTicketSeatRun,
44
+ type InstructionTicketProbe,
45
+ } from "./seat-ticket-binding.ts";
29
46
  import {
30
47
  presentStructuralRejection,
48
+ readEngineDetourInfrastructureFailure,
49
+ trySettleAuditorTerminalResult,
50
+ trySettleEvidenceChildTerminalResult,
31
51
  trySettleGatekeeperTerminalResult,
32
52
  trySettleNavigatorTerminalResult,
33
53
  } from "./settlement.ts";
@@ -38,11 +58,17 @@ import {
38
58
  type RoleTurnRequestProjectionOptions,
39
59
  } from "./turn-request.ts";
40
60
 
41
- export type InstructionSeatRole = "gatekeeper" | "navigator";
61
+ export type InstructionSeatRole =
62
+ | "gatekeeper"
63
+ | "navigator"
64
+ | "auditor"
65
+ | "evidence-child";
42
66
 
43
67
  export type AdmittedInstructionSeatInvocation =
44
68
  | AdmittedGatekeeperInvocation
45
- | AdmittedNavigatorInvocation;
69
+ | AdmittedNavigatorInvocation
70
+ | AdmittedAuditorInvocation
71
+ | AdmittedEvidenceChildInvocation;
46
72
 
47
73
  export type InstructionSeatRunEnv = PostAdmissionEnv & {
48
74
  principalAuthority: DurablePrincipalAuthority;
@@ -65,26 +91,81 @@ export function buildInstructionSeatTurnRequest(
65
91
  );
66
92
  }
67
93
 
68
- function instructionSeatAdapters() {
94
+ function instructionSeatAdapters(options?: {
95
+ beforeDispatch?: (
96
+ admitted: AdmittedInstructionSeatInvocation,
97
+ ) => void | Promise<void>;
98
+ }): PostAdmissionAdapters<AdmittedInstructionSeatInvocation> {
69
99
  return {
70
100
  trySettle: (
71
101
  admitted: AdmittedInstructionSeatInvocation,
72
102
  authority: DurablePrincipalAuthority,
73
103
  scope?: { readonly courtAttemptId?: string },
74
- ) =>
75
- admitted.role === "gatekeeper"
76
- ? trySettleGatekeeperTerminalResult(admitted, authority, scope)
77
- : trySettleNavigatorTerminalResult(admitted, authority, scope),
104
+ ) => {
105
+ switch (admitted.role) {
106
+ case "gatekeeper":
107
+ return trySettleGatekeeperTerminalResult(admitted, authority, scope);
108
+ case "navigator":
109
+ return trySettleNavigatorTerminalResult(admitted, authority, scope);
110
+ case "auditor":
111
+ return trySettleAuditorTerminalResult(admitted, authority, scope);
112
+ case "evidence-child":
113
+ return trySettleEvidenceChildTerminalResult(admitted, authority, scope);
114
+ }
115
+ },
78
116
  // Accepted receipts and failure terminals both present via shared path.
79
117
  shouldPresentSettled: () => true,
118
+ // #675 / #357 T2: failInfrastructure abort after engine-detour tool failure must not
119
+ // wash the durable toolResult diagnostic (same seam as reviewer-run / judge-run).
120
+ resolveRunnerKnownFailure: async ({
121
+ result,
122
+ sessionFile,
123
+ }: {
124
+ result: { knownFailure?: import("../host-contracts.ts").RoleTurnKnownFailure };
125
+ sessionFile: string;
126
+ }) => {
127
+ const infrastructureFailure = await readEngineDetourInfrastructureFailure(sessionFile);
128
+ return infrastructureFailure === undefined
129
+ ? result.knownFailure
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 }),
80
141
  };
81
142
  }
82
143
 
144
+ async function admitInstructionSeat(
145
+ role: InstructionSeatRole,
146
+ options: Parameters<typeof admitGatekeeperInvocation>[0],
147
+ ): Promise<AdmittedInstructionSeatInvocation> {
148
+ switch (role) {
149
+ case "gatekeeper":
150
+ return admitGatekeeperInvocation(options);
151
+ case "navigator":
152
+ return admitNavigatorInvocation(options);
153
+ case "auditor":
154
+ return admitAuditorInvocation(options);
155
+ case "evidence-child":
156
+ return admitEvidenceChildInvocation(options);
157
+ }
158
+ }
159
+
83
160
  export async function runPublicInstructionSeatResume(
84
161
  request: PublicResumeRequest,
85
162
  env: InstructionSeatRunEnv,
86
163
  io: CliIo,
87
- ): Promise<{ exitCode: number; terminal?: TerminalResult }> {
164
+ ): Promise<{
165
+ exitCode: number;
166
+ admitted?: AdmittedInstructionSeatInvocation;
167
+ terminal?: TerminalResult;
168
+ }> {
88
169
  return await runPostAdmissionSeatResume({
89
170
  request,
90
171
  env,
@@ -94,15 +175,62 @@ export async function runPublicInstructionSeatResume(
94
175
  effective.runId,
95
176
  env.principalAuthority,
96
177
  ),
97
- buildTurnRequest: (admitted, effective) => buildInstructionSeatTurnRequest(
98
- admitted,
99
- resumeTurnRequestProjectionOptions(admitted, effective, env),
100
- ),
178
+ buildTurnRequest: async (admitted, effective) => {
179
+ const summonsPrepared = await prepareSummonsResumeMaterials(
180
+ admitted.runDirectory,
181
+ effective.summons,
182
+ );
183
+ return buildInstructionSeatTurnRequest(
184
+ admitted,
185
+ resumeTurnRequestProjectionOptions(
186
+ admitted,
187
+ effective,
188
+ env,
189
+ summonsPrepared,
190
+ ),
191
+ );
192
+ },
101
193
  adapters: instructionSeatAdapters(),
102
194
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
103
195
  });
104
196
  }
105
197
 
198
+ /** Scope auditor subject/source-run env for the duration of one seat turn. */
199
+ async function withAuditorSoulEnv<
200
+ T,
201
+ >(options: {
202
+ readonly subject?: "judge" | "doctor";
203
+ readonly sourceRunDirectory?: string;
204
+ readonly run: () => Promise<T>;
205
+ }): Promise<T> {
206
+ if (options.subject === undefined && options.sourceRunDirectory === undefined) {
207
+ return options.run();
208
+ }
209
+ const { AK_ROLE_AUDITOR_SUBJECT_ENV, AK_ROLE_AUDITOR_SOURCE_RUN_ENV } = await import(
210
+ "../auditor-soul.ts"
211
+ );
212
+ const priorSubject = process.env[AK_ROLE_AUDITOR_SUBJECT_ENV];
213
+ const priorSource = process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV];
214
+ if (options.subject !== undefined) {
215
+ process.env[AK_ROLE_AUDITOR_SUBJECT_ENV] = options.subject;
216
+ }
217
+ if (options.sourceRunDirectory !== undefined) {
218
+ process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV] = options.sourceRunDirectory;
219
+ }
220
+ try {
221
+ return await options.run();
222
+ } finally {
223
+ if (options.subject !== undefined) {
224
+ if (priorSubject === undefined) delete process.env[AK_ROLE_AUDITOR_SUBJECT_ENV];
225
+ else process.env[AK_ROLE_AUDITOR_SUBJECT_ENV] = priorSubject;
226
+ }
227
+ if (options.sourceRunDirectory !== undefined) {
228
+ if (priorSource === undefined) delete process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV];
229
+ else process.env[AK_ROLE_AUDITOR_SOURCE_RUN_ENV] = priorSource;
230
+ }
231
+ }
232
+ }
233
+
106
234
  export async function runPublicInstructionSeat(
107
235
  argv: readonly string[],
108
236
  env: InstructionSeatRunEnv,
@@ -114,10 +242,106 @@ export async function runPublicInstructionSeat(
114
242
  admitted?: AdmittedInstructionSeatInvocation;
115
243
  terminal?: TerminalResult;
116
244
  }> {
245
+ let parsed: ParseInstructionArgvResult;
246
+ try {
247
+ parsed = parseArgv(argv);
248
+ } catch (error) {
249
+ if (error instanceof CliUsageError) {
250
+ presentStructuralRejection(error, io);
251
+ return { exitCode: 2 };
252
+ }
253
+ throw error;
254
+ }
255
+
256
+ let auditorSubject: "judge" | "doctor" | undefined;
257
+ let auditorSourceRun: string | undefined;
258
+ let auditorSourceTicket: number | undefined;
259
+ let ticketProbe: InstructionTicketProbe | undefined;
260
+
261
+ // #637: same ticket → resume prior seat run with this summons' materials.
262
+ // Auditor inherits ticket from source-run (notary face); other instruction seats
263
+ // probe instruction (inspector face). No bare catch→fresh: lookup/resume failures
264
+ // surface; only true absence of a prior run mints new.
265
+ const projectRoot = parsed.project ?? env.cwd;
266
+ if (role === "auditor") {
267
+ if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
268
+ presentStructuralRejection(
269
+ new CliUsageError("auditor --subject requires judge|doctor"),
270
+ io,
271
+ );
272
+ return { exitCode: 2 };
273
+ }
274
+ auditorSubject = parsed.subject;
275
+ const source = typeof parsed.sourceRun === "string" ? parsed.sourceRun.trim() : "";
276
+ if (source === "") {
277
+ presentStructuralRejection(
278
+ new CliUsageError("auditor --source-run requires a run locator"),
279
+ io,
280
+ );
281
+ return { exitCode: 2 };
282
+ }
283
+ try {
284
+ const { resolveNotarySourceRunLocator } = await import("../notary-source-run.ts");
285
+ const resolved = await resolveNotarySourceRunLocator({
286
+ projectRoot,
287
+ sourceRun: source,
288
+ home: env.home,
289
+ });
290
+ auditorSourceRun = resolved.runDirectory;
291
+ auditorSourceTicket = await readRunTicketNumber(resolved.runDirectory);
292
+ } catch (error) {
293
+ presentStructuralRejection(
294
+ new CliUsageError(error instanceof Error ? error.message : String(error)),
295
+ io,
296
+ );
297
+ return { exitCode: 2 };
298
+ }
299
+ } else {
300
+ // Inspector face: unconditional probe (same seam as inspector-run.ts).
301
+ ticketProbe = await probeInstructionTicket(
302
+ parsed.instruction,
303
+ projectRoot,
304
+ env,
305
+ );
306
+ }
307
+
308
+ const probedTicketNumber =
309
+ auditorSourceTicket
310
+ ?? (ticketProbe === undefined ? undefined : ticketNumberFromProbe(ticketProbe));
311
+
312
+ if (probedTicketNumber !== undefined) {
313
+ const summons: SameTicketSummonsMaterials = {
314
+ instruction: parsed.instruction,
315
+ instructionEmpty: parsed.instruction.trim() === "",
316
+ attachmentPaths: parsed.attachmentPaths,
317
+ };
318
+ const resumed = await withAuditorSoulEnv({
319
+ ...(auditorSubject === undefined ? {} : { subject: auditorSubject }),
320
+ ...(auditorSourceRun === undefined
321
+ ? {}
322
+ : { sourceRunDirectory: auditorSourceRun }),
323
+ run: () =>
324
+ tryResumeSameTicketSeatRun({
325
+ home: env.home,
326
+ projectRoot,
327
+ role,
328
+ ticketNumber: probedTicketNumber,
329
+ freshSummons: env.freshSummons,
330
+ summons,
331
+ resume: (runId, materials) =>
332
+ runPublicInstructionSeatResume(
333
+ { runId, ...(materials === undefined ? {} : { summons: materials }) },
334
+ env,
335
+ io,
336
+ ),
337
+ }),
338
+ });
339
+ if (resumed !== undefined) return resumed;
340
+ }
341
+
117
342
  let admitted: AdmittedInstructionSeatInvocation;
118
343
  try {
119
- const parsed = parseArgv(argv);
120
- const options = {
344
+ admitted = await admitInstructionSeat(role, {
121
345
  home: env.home,
122
346
  principalAuthority: env.principalAuthority,
123
347
  cwd: env.cwd,
@@ -127,11 +351,7 @@ export async function runPublicInstructionSeat(
127
351
  ...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
128
352
  ...(env.model === undefined ? {} : { model: env.model }),
129
353
  ...(env.correlationId === undefined ? {} : { correlationId: env.correlationId }),
130
- };
131
- admitted =
132
- role === "gatekeeper"
133
- ? await admitGatekeeperInvocation(options)
134
- : await admitNavigatorInvocation(options);
354
+ });
135
355
  } catch (error) {
136
356
  if (error instanceof CliUsageError) {
137
357
  presentStructuralRejection(error, io);
@@ -140,36 +360,55 @@ export async function runPublicInstructionSeat(
140
360
  throw error;
141
361
  }
142
362
 
143
- await markRunAdmitted(admitted, env.principalAuthority);
144
-
145
- const turnRequest = buildInstructionSeatTurnRequest(admitted, {
146
- packageRoot: env.packageRoot,
147
- home: env.home,
148
- agentDir: env.agentDir,
149
- ...(env.model === undefined ? {} : { model: env.model }),
150
- ...(env.engine === undefined ? {} : { engine: env.engine }),
151
- ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
152
- ...(env.correlationId === undefined || env.correlationId.trim() === ""
363
+ return await withAuditorSoulEnv({
364
+ ...(auditorSubject === undefined ? {} : { subject: auditorSubject }),
365
+ ...(auditorSourceRun === undefined
153
366
  ? {}
154
- : { correlationId: env.correlationId }),
155
- continuation: {
156
- kind: "initial",
157
- prompt: buildInstructionTransportPrompt(
367
+ : { sourceRunDirectory: auditorSourceRun }),
368
+ run: async () => {
369
+ await markRunAdmitted(admitted, env.principalAuthority);
370
+
371
+ const turnRequest = buildInstructionSeatTurnRequest(admitted, {
372
+ packageRoot: env.packageRoot,
373
+ home: env.home,
374
+ agentDir: env.agentDir,
375
+ ...(env.model === undefined ? {} : { model: env.model }),
376
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
377
+ ...(env.timeoutMs === undefined ? {} : { timeoutMs: env.timeoutMs }),
378
+ ...(env.correlationId === undefined || env.correlationId.trim() === ""
379
+ ? {}
380
+ : { correlationId: env.correlationId }),
381
+ continuation: {
382
+ kind: "initial",
383
+ prompt: buildInstructionTransportPrompt(
384
+ admitted,
385
+ engineSessionMaterialFromOptions({
386
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
387
+ packageRoot: env.packageRoot,
388
+ }),
389
+ ),
390
+ },
391
+ });
392
+
393
+ return await runPostAdmissionOneShot({
158
394
  admitted,
159
- engineSessionMaterialFromOptions({
160
- ...(env.engine === undefined ? {} : { engine: env.engine }),
161
- packageRoot: env.packageRoot,
395
+ env,
396
+ io,
397
+ request: turnRequest,
398
+ adapters: instructionSeatAdapters({
399
+ beforeDispatch: async (admittedSeat) => {
400
+ // #635/#637: ticket bind inside controlled-failure boundary.
401
+ // Auditor inherits source-run ticket (notary face).
402
+ // Other seats: same applyInstructionTicketProbe as inspector-run.
403
+ if (auditorSourceTicket !== undefined) {
404
+ await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
405
+ } else if (ticketProbe !== undefined) {
406
+ await applyInstructionTicketProbe(admittedSeat, ticketProbe);
407
+ }
408
+ },
162
409
  }),
163
- ),
410
+ ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
411
+ });
164
412
  },
165
413
  });
166
-
167
- return await runPostAdmissionOneShot({
168
- admitted,
169
- env,
170
- io,
171
- request: turnRequest,
172
- adapters: instructionSeatAdapters(),
173
- ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
174
- });
175
414
  }
@@ -73,12 +73,7 @@ import {
73
73
  type OptionOwner,
74
74
  type PublicOptionDefinition,
75
75
  } from "./option-definitions.ts";
76
- import { loadPublicCliConfig } from "./config.ts";
77
76
  import type { PublicThinkingLevel } from "./registry.ts";
78
- import {
79
- resolveInstitutionalSeatSelections,
80
- writeInstitutionalResolutionPage,
81
- } from "../institutional-resolution.ts";
82
77
 
83
78
  export type FrozenAttachment = {
84
79
  /** Original caller path retained only as provenance. */
@@ -151,6 +146,18 @@ export type AdmittedNavigatorInvocation = AdmittedRoleInvocationBase & {
151
146
  readonly role: "navigator";
152
147
  };
153
148
 
149
+ export type AdmittedAuditorInvocation = AdmittedRoleInvocationBase & {
150
+ readonly role: "auditor";
151
+ };
152
+
153
+ export type AdmittedEvidenceChildInvocation = AdmittedRoleInvocationBase & {
154
+ readonly role: "evidence-child";
155
+ };
156
+
157
+ export type AdmittedDiaristInvocation = AdmittedRoleInvocationBase & {
158
+ readonly role: "diarist";
159
+ };
160
+
154
161
  export type CoderPhase = "plan" | "apply";
155
162
 
156
163
  export type AdmittedCoderInvocation = AdmittedRoleInvocationBase & {
@@ -234,6 +241,9 @@ export type AdmittedRoleInvocation =
234
241
  | AdmittedInspectorInvocation
235
242
  | AdmittedGatekeeperInvocation
236
243
  | AdmittedNavigatorInvocation
244
+ | AdmittedAuditorInvocation
245
+ | AdmittedEvidenceChildInvocation
246
+ | AdmittedDiaristInvocation
237
247
  | AdmittedCoderInvocation
238
248
  | AdmittedFixerInvocation
239
249
  | AdmittedCollectorInvocation
@@ -362,10 +372,6 @@ async function writeRoleInvocationLedger(
362
372
  `${JSON.stringify(identity, null, 2)}\n`,
363
373
  "utf8",
364
374
  );
365
- const home = homeFromRunDirectory(source.runDirectory);
366
- const config = await loadPublicCliConfig(home);
367
- const institutionalPage = resolveInstitutionalSeatSelections(config, effectiveModel);
368
- await writeInstitutionalResolutionPage(source.runDirectory, institutionalPage);
369
375
  }
370
376
 
371
377
  /**
@@ -412,20 +418,6 @@ export async function recordEffectiveInvocationModel(
412
418
  `${JSON.stringify(next, null, 2)}\n`,
413
419
  "utf8",
414
420
  );
415
- const effectiveModel: InvocationEffectiveModel | undefined =
416
- typeof next.provider === "string" && typeof next.model === "string"
417
- ? {
418
- provider: next.provider,
419
- model: next.model,
420
- ...(typeof next.thinking === "string"
421
- ? { thinking: next.thinking }
422
- : {}),
423
- }
424
- : undefined;
425
- const home = homeFromRunDirectory(runDirectory);
426
- const config = await loadPublicCliConfig(home);
427
- const institutionalPage = resolveInstitutionalSeatSelections(config, effectiveModel);
428
- await writeInstitutionalResolutionPage(runDirectory, institutionalPage);
429
421
  }
430
422
 
431
423
  /** Merge observed launch-time fields into the single existing invocation.json identity page. */
@@ -578,6 +570,10 @@ export type ParseInstructionArgvResult = {
578
570
  instruction: string;
579
571
  attachmentPaths: string[];
580
572
  project?: string;
573
+ /** Auditor only — audited subject selecting soul materials (#675 owner). */
574
+ subject?: "judge" | "doctor";
575
+ /** Auditor source-run locator — same input surface for direct and nested (#675). */
576
+ sourceRun?: string;
581
577
  };
582
578
 
583
579
  /** Judge/Countersign 命令面同形:--project/--attach/opaque instruction。 */
@@ -586,6 +582,7 @@ export type ParseCountersignArgvResult = ParseInstructionArgvResult;
586
582
  export type ParseInspectorArgvResult = ParseInstructionArgvResult;
587
583
  export type ParseGatekeeperArgvResult = ParseInstructionArgvResult;
588
584
  export type ParseNavigatorArgvResult = ParseInstructionArgvResult;
585
+ export type ParseDiaristArgvResult = ParseInstructionArgvResult;
589
586
 
590
587
  /** Positive ticket number for analyst query-scope face (and shared integer parse). */
591
588
  export function parsePositiveTicketNumber(
@@ -606,10 +603,12 @@ export function parsePositiveTicketNumber(
606
603
  /** 共享解析体:同形 owner 的 argv → instruction/attachments/project。 */
607
604
  function parseInstructionArgv(
608
605
  args: readonly string[],
609
- owner: "judge" | "countersign" | "inspector" | "gatekeeper" | "navigator",
606
+ owner: "judge" | "countersign" | "inspector" | "gatekeeper" | "navigator" | "auditor" | "evidence-child" | "diarist",
610
607
  ): ParseInstructionArgvResult {
611
608
  const attachmentPaths: string[] = [];
612
609
  let project: string | undefined;
610
+ let subject: "judge" | "doctor" | undefined;
611
+ let sourceRun: string | undefined;
613
612
  const positional: string[] = [];
614
613
  const tokens = [...args];
615
614
  const definitions = roleOptions(owner);
@@ -631,6 +630,24 @@ function parseInstructionArgv(
631
630
  project = requireOptionPath(taken.def.canonical, taken.value);
632
631
  continue;
633
632
  }
633
+ if (taken.def.id === "subject") {
634
+ const raw = typeof taken.value === "string" ? taken.value.trim() : "";
635
+ if (raw !== "judge" && raw !== "doctor") {
636
+ throw new CliUsageError(
637
+ `auditor --subject must be judge|doctor, got ${taken.value ?? "(missing)"}`,
638
+ );
639
+ }
640
+ subject = raw;
641
+ continue;
642
+ }
643
+ if (taken.def.id === "source-run") {
644
+ const raw = typeof taken.value === "string" ? taken.value.trim() : "";
645
+ if (raw === "") {
646
+ throw new CliUsageError("auditor --source-run requires a run locator");
647
+ }
648
+ sourceRun = raw;
649
+ continue;
650
+ }
634
651
  throw new CliUsageError(`unknown ${owner} option: ${taken.def.canonical}`);
635
652
  }
636
653
  const token = tokens.shift()!;
@@ -645,6 +662,8 @@ function parseInstructionArgv(
645
662
  instruction: positional.join(" "),
646
663
  attachmentPaths,
647
664
  ...(project === undefined ? {} : { project }),
665
+ ...(subject === undefined ? {} : { subject }),
666
+ ...(sourceRun === undefined ? {} : { sourceRun }),
648
667
  };
649
668
  }
650
669
 
@@ -846,6 +865,21 @@ export function parseNavigatorArgv(args: readonly string[]): ParseNavigatorArgvR
846
865
  return parseInstructionArgv(args, "navigator");
847
866
  }
848
867
 
868
+ export type ParseAuditorArgvResult = ParseInstructionArgvResult;
869
+ export type ParseEvidenceChildArgvResult = ParseInstructionArgvResult;
870
+
871
+ export function parseAuditorArgv(args: readonly string[]): ParseAuditorArgvResult {
872
+ return parseInstructionArgv(args, "auditor");
873
+ }
874
+
875
+ export function parseEvidenceChildArgv(args: readonly string[]): ParseEvidenceChildArgvResult {
876
+ return parseInstructionArgv(args, "evidence-child");
877
+ }
878
+
879
+ export function parseDiaristArgv(args: readonly string[]): ParseDiaristArgvResult {
880
+ return parseInstructionArgv(args, "diarist");
881
+ }
882
+
849
883
  /**
850
884
  * Parse Coder-specific argv after the `coder` token.
851
885
  * Phase defaults to apply; spellings from PUBLIC_OPTION_TABLE.coder (#342).
@@ -1045,6 +1079,7 @@ export type AdmitInspectorInvocationOptions = AdmitJudgeInvocationOptions & {
1045
1079
 
1046
1080
  export type AdmitGatekeeperInvocationOptions = AdmitInspectorInvocationOptions;
1047
1081
  export type AdmitNavigatorInvocationOptions = AdmitInspectorInvocationOptions;
1082
+ export type AdmitDiaristInvocationOptions = AdmitInspectorInvocationOptions;
1048
1083
 
1049
1084
  /**
1050
1085
  * Shared instruction-seat admission for Judge and Inspector: project check,
@@ -1053,7 +1088,7 @@ export type AdmitNavigatorInvocationOptions = AdmitInspectorInvocationOptions;
1053
1088
  * Ticket binding is post-admission via shared seat LLM path (#635).
1054
1089
  */
1055
1090
  async function admitStandardMaterialInvocation<
1056
- R extends "judge" | "inspector" | "gatekeeper" | "navigator",
1091
+ R extends "judge" | "inspector" | "gatekeeper" | "navigator" | "auditor" | "evidence-child" | "diarist",
1057
1092
  >(
1058
1093
  role: R,
1059
1094
  options: AdmitJudgeInvocationOptions & { correlationId?: string },
@@ -1173,6 +1208,33 @@ export async function admitNavigatorInvocation(
1173
1208
  return admitStandardMaterialInvocation("navigator", options);
1174
1209
  }
1175
1210
 
1211
+ export type AdmitAuditorInvocationOptions = AdmitInspectorInvocationOptions;
1212
+ export type AdmitEvidenceChildInvocationOptions = AdmitInspectorInvocationOptions;
1213
+
1214
+ /** Admit a public 审刑院 run (#675). */
1215
+ export async function admitAuditorInvocation(
1216
+ options: AdmitAuditorInvocationOptions,
1217
+ ): Promise<AdmittedAuditorInvocation> {
1218
+ return admitStandardMaterialInvocation("auditor", options);
1219
+ }
1220
+
1221
+ /** Admit a public evidence-child run (#675). */
1222
+ export async function admitEvidenceChildInvocation(
1223
+ options: AdmitEvidenceChildInvocationOptions,
1224
+ ): Promise<AdmittedEvidenceChildInvocation> {
1225
+ return admitStandardMaterialInvocation("evidence-child", options);
1226
+ }
1227
+
1228
+ /**
1229
+ * Admit a direct Diarist (起居郎) run (#708): freeze attachments, persist the
1230
+ * request, reserve session placement — same instruction-seat face.
1231
+ */
1232
+ export async function admitDiaristInvocation(
1233
+ options: AdmitDiaristInvocationOptions,
1234
+ ): Promise<AdmittedDiaristInvocation> {
1235
+ return admitStandardMaterialInvocation("diarist", options);
1236
+ }
1237
+
1176
1238
  /** Shared prompt transport for instruction-seat roles (judge/countersign/inspector). */
1177
1239
  export function buildInstructionTransportPrompt(
1178
1240
  admitted: { instruction: string; instructionEmpty: boolean; attachments: readonly { frozenPath: string }[] },