@akagilnc/pi-workflow-roles 0.1.5406 → 0.1.5475

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 (93) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +42 -55
  3. package/README.zh-CN.md +59 -73
  4. package/THIRD_PARTY_NOTICES.md +4 -7
  5. package/dist/acp-host/production-host.js +8261 -9073
  6. package/dist/collector-tool-schemas.js +1 -1
  7. package/dist/compliance-transport.js +2 -5
  8. package/dist/engine-detour-usage.js +3 -30
  9. package/dist/gatekeeper-role.js +4 -18
  10. package/dist/headless-host/description.js +0 -209
  11. package/dist/headless-host/production-host.js +6973 -8035
  12. package/dist/host-contracts.js +8 -0
  13. package/dist/migrate-book-topology.js +30 -27
  14. package/dist/packaged-role-registry.js +1 -9
  15. package/dist/pi/role-turn-host.js +37 -19
  16. package/dist/public-cli/auto-resume.js +29 -66
  17. package/dist/public-cli/countersign-run.js +4 -18
  18. package/dist/public-cli/instruction-seat-run.js +59 -76
  19. package/dist/public-cli/main.js +9844 -10720
  20. package/dist/public-cli/option-definitions.js +1 -1
  21. package/dist/public-cli/post-admission.js +204 -285
  22. package/dist/public-cli/process-cancel.js +8 -0
  23. package/dist/public-cli/run-lifecycle.js +24 -94
  24. package/dist/public-cli/settlement.js +614 -1524
  25. package/dist/public-cli/terminal.js +23 -53
  26. package/dist/public-role-summons.js +3 -8
  27. package/dist/receipt-delivery-policy.js +11 -12
  28. package/dist/run-terminal-artifacts.js +19 -14
  29. package/dist/serialize-thrown-value.js +7 -1
  30. package/dist/submission-ledger.js +21 -89
  31. package/package.json +1 -1
  32. package/packets/fixer-repair.md +3 -1
  33. package/packets/judge-apply.md +7 -16
  34. package/packets/judge-authority.md +7 -17
  35. package/packets/judge-plan.md +7 -18
  36. package/packets/judge-review.md +8 -22
  37. package/packets/judge-submission.md +4 -7
  38. package/resources/collector-bot-handbook.md +2 -2
  39. package/resources/diarist-collect.md +2 -2
  40. package/resources/engine-dispatch.md +2 -2
  41. package/resources/navigator-route-playbook.md +1 -1
  42. package/resources/secretariat-ticket-identity.md +1 -1
  43. package/scripts/build-package.mjs +0 -2
  44. package/souls/coder-output-guide.md +3 -3
  45. package/souls/coder.md +2 -3
  46. package/souls/doctor-auditor.md +0 -3
  47. package/souls/fixer-auditor.md +0 -2
  48. package/souls/fixer-output-guide.md +3 -3
  49. package/souls/fixer.md +2 -2
  50. package/souls/gate-output-guide.md +1 -1
  51. package/souls/quality-law.md +2 -0
  52. package/src/acp-host/role-turn-host.ts +168 -75
  53. package/src/collector-tool-schemas.ts +1 -1
  54. package/src/compliance-transport.ts +3 -6
  55. package/src/engine-detour-usage.ts +3 -33
  56. package/src/external-host-turn-loop.ts +81 -36
  57. package/src/gatekeeper-role.ts +5 -20
  58. package/src/headless-host/description.ts +4 -214
  59. package/src/headless-host/production-host.ts +2 -1
  60. package/src/headless-host/role-turn-host.ts +153 -186
  61. package/src/host-contracts.ts +13 -10
  62. package/src/navigator-public-session.ts +1 -1
  63. package/src/navigator-session-contracts.ts +1 -1
  64. package/src/package-contracts/gatekeeper-output.ts +1 -1
  65. package/src/package-contracts/navigator-output.ts +1 -1
  66. package/src/package-contracts/terminating-infrastructure.ts +1 -1
  67. package/src/packaged-role-registry.ts +2 -10
  68. package/src/pi/adapter.ts +0 -3
  69. package/src/pi/role-turn-host.ts +42 -28
  70. package/src/prepared-role-turn.ts +2 -0
  71. package/src/public-cli/auto-resume.ts +27 -66
  72. package/src/public-cli/countersign-run.ts +4 -22
  73. package/src/public-cli/instruction-seat-run.ts +79 -80
  74. package/src/public-cli/option-definitions.ts +1 -1
  75. package/src/public-cli/post-admission.ts +264 -340
  76. package/src/public-cli/process-cancel.ts +9 -0
  77. package/src/public-cli/run-lifecycle.ts +25 -126
  78. package/src/public-cli/settlement.ts +792 -1912
  79. package/src/public-cli/terminal.ts +29 -69
  80. package/src/public-role-summons.ts +3 -8
  81. package/src/receipt-delivery-policy.ts +11 -12
  82. package/src/role-envelope.ts +16 -9
  83. package/src/role-runtime.ts +14 -81
  84. package/src/run-terminal-artifacts.ts +21 -17
  85. package/src/serialize-thrown-value.ts +7 -1
  86. package/src/submission-ledger.ts +30 -116
  87. package/dist/audit-escalation.js +0 -7
  88. package/dist/pi/known-failure.js +0 -51
  89. package/dist/typed-provider-http.js +0 -57
  90. package/dist/upstream-error-testimony.js +0 -19
  91. package/src/pi/known-failure.ts +0 -76
  92. package/src/typed-provider-http.ts +0 -89
  93. package/src/upstream-error-testimony.ts +0 -45
@@ -57,6 +57,7 @@ import {
57
57
  } from "./invocation.ts";
58
58
  import {
59
59
  presentControlledFailure,
60
+ packageFaultNoteFor,
60
61
  prepareSummonsResumeMaterials,
61
62
  roleTurnOptions,
62
63
  runPostAdmissionOneShot,
@@ -67,6 +68,7 @@ import {
67
68
  type PostAdmissionAdapters,
68
69
  type PostAdmissionEnv,
69
70
  } from "./post-admission.ts";
71
+ import { presentTerminal } from "./auto-resume.ts";
70
72
  import {
71
73
  buildAutoResumeContinuationPrompt,
72
74
  loadResumablePublicRole,
@@ -81,18 +83,16 @@ import { tryResumeSameTicketSeatRun } from "./seat-ticket-binding.ts";
81
83
  import {
82
84
  presentStructuralRejection,
83
85
  readBoundSessionEntries,
84
- seatKnownFailureResolver,
85
86
  attachPostAuditProjection,
86
87
  trySettlePublicSeat,
88
+ type SettlementCourtScope,
87
89
  } from "./settlement.ts";
88
90
  import type { CliIo } from "./cli-io.ts";
89
91
  import { warnMissingMethodSkills } from "./machine-method-skills.ts";
90
92
  import {
91
- coalesceSubmissionRows,
92
93
  formatTerminalResult,
93
94
  isLawfulTypedTerminalOutcome,
94
95
  type TerminalResult,
95
- type TerminalRoleName,
96
96
  } from "./terminal.ts";
97
97
  import {
98
98
  admittedSeatTurnDetails,
@@ -190,21 +190,20 @@ function isUnreadableReaskExhausted(
190
190
  return value === UNREADABLE_REASK_EXHAUSTED;
191
191
  }
192
192
 
193
- function presentOriginalVolume(
193
+ async function presentOriginalVolume(
194
194
  held: readonly string[],
195
195
  terminal: TerminalResult | undefined,
196
196
  io: CliIo,
197
- ): void {
198
- // The held buffer was formatted before direction facts were attached.
199
- if (terminal?.roleOutcome.decisiveFacts?.directionUnsettled === true) {
200
- io.stdout(formatTerminalResult(terminal));
197
+ runDirectory?: string,
198
+ ): Promise<void> {
199
+ if (terminal !== undefined && runDirectory !== undefined) {
200
+ // Direction facts were attached after the held volume was formatted.
201
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, runDirectory,
202
+ terminal.roleOutcome.decisiveFacts?.directionUnsettled === true ? undefined : held);
201
203
  return;
202
204
  }
203
- if (held.length > 0) {
204
- for (const value of held) io.stdout(value);
205
- return;
206
- }
207
- if (terminal !== undefined) io.stdout(formatTerminalResult(terminal));
205
+ // No settled host report exists to preserve at this pre-result boundary.
206
+ for (const value of held) io.stdout(value);
208
207
  }
209
208
 
210
209
  /** Runtime fact beside the original volume. Payloads stay as submitted. */
@@ -215,12 +214,12 @@ function withUnsettledDirection(
215
214
  const outcome = parent.roleOutcome;
216
215
  if (outcome.kind !== "accepted" && outcome.kind !== "audit_escalation") return parent;
217
216
  const officerOutcome = officer?.roleOutcome;
218
- const officerPayloads = coalesceSubmissionRows(
219
- officer?.submissions,
220
- officerOutcome !== undefined && officerOutcome.kind !== "no_receipt"
221
- ? officerOutcome.payloads
222
- : undefined,
223
- );
217
+ const officerPayloads = officer?.submissions !== undefined && officer.submissions.length > 0
218
+ ? officer.submissions
219
+ : officerOutcome !== undefined && officerOutcome.kind !== "no_receipt"
220
+ ? officerOutcome.payloads ?? []
221
+ : [];
222
+
224
223
  return {
225
224
  ...parent,
226
225
  roleOutcome: {
@@ -244,14 +243,15 @@ function heldUnreadableTerminal(terminal: TerminalResult | undefined): boolean {
244
243
  return typeof status !== "string" || !REVIEW_QUEUE_STATUSES.has(status);
245
244
  }
246
245
 
247
- function presentUnsettledAudit(
246
+ async function presentUnsettledAudit(
248
247
  parent: TerminalResult,
249
248
  officer: TerminalResult | undefined,
250
249
  io: CliIo,
251
- ): TerminalResult {
250
+ runDirectory: string,
251
+ ): Promise<TerminalResult> {
252
252
  const terminal = withUnsettledDirection(parent, officer);
253
- io.stdout(formatTerminalResult(terminal));
254
- if (officer !== undefined) io.stdout(formatTerminalResult(officer));
253
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, runDirectory);
254
+ if (officer !== undefined) await presentTerminal(officer, { ...io, omitFailureStderrDiagnostic: true }, runDirectory);
255
255
  return terminal;
256
256
  }
257
257
 
@@ -266,7 +266,7 @@ async function reaskUnreadablePostSubmissionStatus(
266
266
  const next = withUnreadableReask(env);
267
267
  if (next === undefined) return UNREADABLE_REASK_EXHAUSTED;
268
268
  return runPublicInstructionSeatResume(
269
- { runId: admitted.runId, message },
269
+ { runId: admitted.runId, summons: { instruction: message } },
270
270
  next,
271
271
  io,
272
272
  );
@@ -310,11 +310,6 @@ function initialPrompt(
310
310
  );
311
311
  }
312
312
 
313
- function infraFailure(role: PackagedRole) {
314
- const resolveRunnerKnownFailure = seatKnownFailureResolver(role);
315
- return resolveRunnerKnownFailure === undefined ? {} : { resolveRunnerKnownFailure };
316
- }
317
-
318
313
  function isBoardTicketSeat(
319
314
  seat: AdmittedRoleInvocation,
320
315
  ): seat is AdmittedRoleInvocation & { role: "diarist" } {
@@ -334,6 +329,14 @@ async function bindAndRelocateDiarist(
334
329
  return await relocateAdmittedRunToTicket(admitted, authority, lease);
335
330
  }
336
331
 
332
+ function packageFaultScope(
333
+ admitted: Pick<AdmittedRoleInvocation, "runDirectory" | "principal">,
334
+ env: InstructionSeatRunEnv,
335
+ io: CliIo,
336
+ ): SettlementCourtScope {
337
+ return { notePackageFault: packageFaultNoteFor(admitted, env, io) };
338
+ }
339
+
337
340
  function seatAdapters(
338
341
  admitted: AdmittedRoleInvocation,
339
342
  env: InstructionSeatRunEnv,
@@ -347,7 +350,6 @@ function seatAdapters(
347
350
  ...(present === "typed"
348
351
  ? { shouldPresentSettled: (terminal: TerminalResult) => isLawfulTypedTerminalOutcome(terminal.roleOutcome) }
349
352
  : {}),
350
- ...infraFailure(admitted.role),
351
353
  ...(packagedBindsBoardTicket(admitted.role)
352
354
  ? {
353
355
  beforeDispatch: async (seat: AdmittedRoleInvocation, lease?: RunWriterLease) => {
@@ -467,14 +469,14 @@ async function dispatchAdmitted(
467
469
  const terminal = result.terminal === undefined
468
470
  ? undefined
469
471
  : withUnsettledDirection(result.terminal);
470
- presentOriginalVolume(held, terminal, io);
472
+ await presentOriginalVolume(held, terminal, io, admitted.runDirectory);
471
473
  return terminal === undefined ? result : { ...result, terminal };
472
474
  }
473
475
  if (unreadableReask !== undefined) return unreadableReask;
474
476
  if (AUDITED_ROLES.has(admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
475
477
  return auditSubmittedRole(result, env, io);
476
478
  }
477
- for (const value of held) io.stdout(value);
479
+ await presentOriginalVolume(held, result.terminal, io, admitted.runDirectory);
478
480
  return result;
479
481
  }
480
482
 
@@ -551,7 +553,9 @@ async function runOmittedLensBatch(
551
553
  },
552
554
  artifacts: terminals.flatMap((item) => item.artifacts),
553
555
  };
554
- io.stdout(formatTerminalResult(terminal));
556
+ const childRunDirectory = children.completeness.admitted?.runDirectory ?? children.correctness.admitted?.runDirectory;
557
+ if (childRunDirectory !== undefined) await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, childRunDirectory);
558
+ else io.stdout(formatTerminalResult(terminal));
555
559
  return { exitCode: failed ? 1 : 0, terminal };
556
560
  }
557
561
 
@@ -715,7 +719,7 @@ export async function runPublicInstructionSeat(
715
719
  stdout: (value) => held.push(value), stderr: io.stderr,
716
720
  });
717
721
  if (result.terminal?.roleOutcome.kind === "accepted") return auditSubmittedRole(result, env, io);
718
- for (const value of held) io.stdout(value);
722
+ await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
719
723
  return result;
720
724
  }
721
725
 
@@ -880,7 +884,8 @@ export async function runPublicInstructionSeat(
880
884
  } catch (error) {
881
885
  return await presentControlledFailure(admitted, {
882
886
  timedOut: false, code: null, stderr: "", thrown: error,
883
- }, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
887
+ }, seatAdapters(admitted, env), env.principalAuthority, io, true,
888
+ packageFaultNoteFor(admitted, env, io)) as SeatRunResult;
884
889
  }
885
890
  if (outcome.admitted !== undefined && isUnboundRunDirectory(outcome.admitted.runDirectory)) {
886
891
  await recordChildDiaristRun(admitted, outcome.admitted.runId);
@@ -889,12 +894,13 @@ export async function runPublicInstructionSeat(
889
894
  return await presentControlledFailure(admitted, {
890
895
  timedOut: false, code: null, stderr: "",
891
896
  thrown: new Error(outcome.failedWithoutEscalate.diagnostic),
892
- }, seatAdapters(admitted, env), env.principalAuthority, io) as SeatRunResult;
897
+ }, seatAdapters(admitted, env), env.principalAuthority, io, true,
898
+ packageFaultNoteFor(admitted, env, io)) as SeatRunResult;
893
899
  }
894
900
  // The diarist's escalation pauses only the diarist's own run; call order
895
901
  // belongs to the caller, so the Secretariat still takes its own turn.
896
902
  if (outcome.identity.kind === "escalate" && outcome.terminal !== undefined) {
897
- io.stdout(formatTerminalResult(outcome.terminal));
903
+ await presentTerminal(outcome.terminal, { ...io, omitFailureStderrDiagnostic: true }, outcome.admitted?.runDirectory ?? admitted.runDirectory);
898
904
  }
899
905
  }
900
906
  return dispatchAdmitted(admitted, env, io);
@@ -958,27 +964,7 @@ export async function runPublicInstructionSeatResume(
958
964
  },
959
965
  afterAdmittedLoad: async (admitted) => {
960
966
  await warnMissingMethodSkills(env.home, env.host, admitted.role, requiredMethodSkills(admitted), io.stdout);
961
- const adapters = seatAdapters(admitted, env);
962
- if ((env.unreadableReasksSpent ?? 0) === 0 && env.reviewReask === undefined) {
963
- return { kind: "continue" as const, adapters };
964
- }
965
- const original = await adapters.trySettle(
966
- admitted, env.principalAuthority, await readCurrentCourt(admitted.runDirectory),
967
- );
968
- const unsettled = POST_SUBMISSION_ROUTING[admitted.role] === undefined
969
- ? heldUnreadableTerminal(original)
970
- : unreadablePostSubmissionStatus(admitted, original) !== undefined;
971
- // Select this reask's existing subject before dispatch. The common
972
- // settlement then keeps it only when no fresh receipt supersedes it;
973
- // actual failures still take their normal failure path.
974
- return {
975
- kind: "continue" as const,
976
- adapters: original === undefined || !unsettled ? adapters : {
977
- ...adapters,
978
- trySettle: async (seat, authority, scope) =>
979
- await adapters.trySettle(seat, authority, scope) ?? original,
980
- },
981
- };
967
+ return { kind: "continue" as const, adapters: seatAdapters(admitted, env) };
982
968
  },
983
969
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
984
970
  });
@@ -994,7 +980,7 @@ export async function runPublicInstructionSeatResume(
994
980
  const terminal = result.terminal === undefined
995
981
  ? undefined
996
982
  : withUnsettledDirection(result.terminal);
997
- presentOriginalVolume(held, terminal, io);
983
+ await presentOriginalVolume(held, terminal, io, result.admitted?.runDirectory);
998
984
  return terminal === undefined ? result : { ...result, terminal };
999
985
  }
1000
986
  if (unreadableReask !== undefined) return unreadableReask;
@@ -1002,7 +988,7 @@ export async function runPublicInstructionSeatResume(
1002
988
  && result.terminal?.roleOutcome.kind === "accepted") {
1003
989
  return auditSubmittedRole(result, env, io);
1004
990
  }
1005
- for (const value of held) io.stdout(value);
991
+ await presentOriginalVolume(held, result.terminal, io, result.admitted?.runDirectory);
1006
992
  return result;
1007
993
  };
1008
994
  let binding: Awaited<ReturnType<typeof readAuditorResumeBinding>>;
@@ -1046,7 +1032,7 @@ async function queueConclusionFromChild(
1046
1032
  if (!GATE_CHILD_ROLES.has(child.role)) return undefined;
1047
1033
  if (child.role === "countersign") {
1048
1034
  const terminal = await trySettlePublicSeat(
1049
- child, env.principalAuthority, await readCurrentCourt(child.runDirectory),
1035
+ child, env.principalAuthority, { ...await readCurrentCourt(child.runDirectory), ...packageFaultScope(child, env, io) },
1050
1036
  );
1051
1037
  const status = latestQueueStatus(terminal);
1052
1038
  if (terminal !== undefined && typeof status === "string" && REVIEW_QUEUE_STATUSES.has(status)) {
@@ -1063,7 +1049,7 @@ async function queueConclusionFromChild(
1063
1049
  const terminal = await trySettlePublicSeat(
1064
1050
  current,
1065
1051
  env.principalAuthority,
1066
- await readCurrentCourt(current.runDirectory),
1052
+ { ...await readCurrentCourt(current.runDirectory), ...packageFaultScope(current, env, io) },
1067
1053
  );
1068
1054
  const status = latestQueueStatus(terminal);
1069
1055
  if (terminal !== undefined && typeof status === "string" && REVIEW_QUEUE_STATUSES.has(status)) {
@@ -1115,7 +1101,7 @@ export async function continueParentAfterChild(
1115
1101
  parentTerminal?.roleOutcome.kind === "accepted"
1116
1102
  || parentTerminal?.roleOutcome.kind === "audit_escalation"
1117
1103
  ) {
1118
- const terminal = presentUnsettledAudit(parentTerminal, stopped.terminal, io);
1104
+ const terminal = await presentUnsettledAudit(parentTerminal, stopped.terminal, io, admitted.runDirectory);
1119
1105
  return { exitCode: 0, admitted, terminal };
1120
1106
  }
1121
1107
  }
@@ -1126,13 +1112,17 @@ export async function continueParentAfterChild(
1126
1112
  }
1127
1113
  if (resolved !== undefined && (resolved.status === "continue" || resolved.status === "converged")) {
1128
1114
  if (AUDITED_ROLES.has(admitted.role) && resolved.status === "converged") {
1129
- const terminal = await trySettlePublicSeat(admitted, env.principalAuthority, undefined);
1115
+ const terminal = await trySettlePublicSeat(
1116
+ admitted,
1117
+ env.principalAuthority,
1118
+ packageFaultScope(admitted, env, io),
1119
+ );
1130
1120
  if (terminal?.roleOutcome.kind !== "accepted") throw new Error("pending submission is not recorded");
1131
1121
  return auditSubmittedRole({ exitCode: 0, admitted, terminal }, env, io, resolved.admitted, latestQueuePayload(resolved.terminal));
1132
1122
  }
1133
1123
  return runPublicInstructionSeatResume({
1134
1124
  runId: parentRunId,
1135
- message: readableGateItem(latestQueuePayload(resolved.terminal)),
1125
+ summons: { instruction: readableGateItem(latestQueuePayload(resolved.terminal)) },
1136
1126
  }, { ...env, unreadableReasksSpent: 0 }, io);
1137
1127
  }
1138
1128
  const result = await dispatchAdmitted(admitted, env, { ...io, omitFailureStderrDiagnostic: true });
@@ -1200,20 +1190,20 @@ async function auditSubmittedRole(
1200
1190
  const next = withUnreadableReask(env);
1201
1191
  if (next === undefined) {
1202
1192
  const terminal = withUnsettledDirection(turn.terminal);
1203
- io.stdout(formatTerminalResult(terminal));
1193
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
1204
1194
  return { ...turn, terminal };
1205
1195
  }
1206
- return runPublicInstructionSeatResume({ runId: admitted.runId, message: SECRETARIAT_STATUS_REASK }, next, io);
1196
+ return runPublicInstructionSeatResume({ runId: admitted.runId, summons: { instruction: SECRETARIAT_STATUS_REASK } }, next, io);
1207
1197
  }
1208
1198
  if (admitted.role === "countersign" && (typeof status !== "string" || !REVIEW_QUEUE_STATUSES.has(status))) {
1209
1199
  if (gateOwnsStatusReask) return turn;
1210
1200
  const next = withUnreadableReask(env);
1211
1201
  if (next === undefined) {
1212
1202
  const terminal = withUnsettledDirection(turn.terminal);
1213
- io.stdout(formatTerminalResult(terminal));
1203
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
1214
1204
  return { ...turn, terminal };
1215
1205
  }
1216
- return runPublicInstructionSeatResume({ runId: admitted.runId, message: officerConclusionReask(status) }, next, io);
1206
+ return runPublicInstructionSeatResume({ runId: admitted.runId, summons: { instruction: officerConclusionReask(status) } }, next, io);
1217
1207
  }
1218
1208
  // Self-escalation is a valid open routing state for these seats only.
1219
1209
  // Doctor's declared domain is completed|refused — an open "escalate" must
@@ -1225,7 +1215,7 @@ async function auditSubmittedRole(
1225
1215
  || ((admitted.role === "fixer" || admitted.role === "coder")
1226
1216
  && (typeof status !== "string" || !WORKER_DONE_STATUSES.has(status)));
1227
1217
  if (skipAudit) {
1228
- io.stdout(formatTerminalResult(turn.terminal));
1218
+ await presentTerminal(turn.terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
1229
1219
  return turn;
1230
1220
  }
1231
1221
  const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, env.home);
@@ -1233,7 +1223,9 @@ async function auditSubmittedRole(
1233
1223
  const toolCallId = acceptedRow?.toolCallId;
1234
1224
  if (toolCallId === undefined) throw new Error("accepted submission has no tool call identity");
1235
1225
  const sessionFile = env.principalAuthority.decode(admitted.principal).sessionFile;
1236
- const entries = admitted.role === "doctor" ? await readBoundSessionEntries(sessionFile) : [];
1226
+ const entries = admitted.role === "doctor"
1227
+ ? await readBoundSessionEntries(sessionFile)
1228
+ : [];
1237
1229
  const context: HostContext = {
1238
1230
  cwd: admitted.projectRoot,
1239
1231
  mode: "print",
@@ -1290,7 +1282,7 @@ async function auditSubmittedRole(
1290
1282
  });
1291
1283
  if (decision.status === "continue") {
1292
1284
  return runPublicInstructionSeatResume({
1293
- runId: admitted.runId, message: readableGateItem(decision.receipt ?? decision.violations),
1285
+ runId: admitted.runId, summons: { instruction: readableGateItem(decision.receipt ?? decision.violations) },
1294
1286
  }, { ...env, unreadableReasksSpent: 0 }, io);
1295
1287
  }
1296
1288
  if (decision.status === "received") {
@@ -1298,12 +1290,12 @@ async function auditSubmittedRole(
1298
1290
  throw new Error("doctor audit kept an unreadable reply with no terminal");
1299
1291
  }
1300
1292
  if (turn.terminal === undefined) throw new Error("doctor submission has no terminal");
1301
- const terminal = presentUnsettledAudit(turn.terminal, lastSummon.terminal, io);
1293
+ const terminal = await presentUnsettledAudit(turn.terminal, lastSummon.terminal, io, admitted.runDirectory);
1302
1294
  return { exitCode: 0, admitted, terminal };
1303
1295
  }
1304
1296
  if (decision.status !== "converged") {
1305
1297
  if (lastSummon?.terminal !== undefined) {
1306
- io.stdout(formatTerminalResult(lastSummon.terminal));
1298
+ await presentTerminal(lastSummon.terminal, { ...io, omitFailureStderrDiagnostic: true }, lastSummon.admitted?.runDirectory ?? admitted.runDirectory);
1307
1299
  return { exitCode: lastSummon.exitCode,
1308
1300
  ...(lastSummon.admitted === undefined ? {} : { admitted: lastSummon.admitted }),
1309
1301
  terminal: lastSummon.terminal };
@@ -1370,7 +1362,7 @@ async function auditSubmittedRole(
1370
1362
  const officerTerminal = chain.passes.at(-1)?.terminal;
1371
1363
  if (officerTerminal === undefined) throw new Error("unreadable audit has no terminal result");
1372
1364
  if (turn.terminal === undefined) throw new Error("audited submission has no terminal");
1373
- const terminal = presentUnsettledAudit(turn.terminal, officerTerminal, io);
1365
+ const terminal = await presentUnsettledAudit(turn.terminal, officerTerminal, io, admitted.runDirectory);
1374
1366
  return { exitCode: 0, admitted, terminal };
1375
1367
  }
1376
1368
  if (chain.status === "escalate") {
@@ -1381,16 +1373,18 @@ async function auditSubmittedRole(
1381
1373
  if (escalatedRunId === undefined) throw new Error("escalated audit has no resumable run identity");
1382
1374
  const officer = await loadResumablePublicRole(env.home, escalatedRunId, env.principalAuthority);
1383
1375
  const terminal = await trySettlePublicSeat(
1384
- officer.admitted, env.principalAuthority, await readCurrentCourt(officer.admitted.runDirectory),
1376
+ officer.admitted,
1377
+ env.principalAuthority,
1378
+ { ...await readCurrentCourt(officer.admitted.runDirectory), ...packageFaultScope(officer.admitted, env, io) },
1385
1379
  );
1386
1380
  if (terminal === undefined) throw new Error("escalated audit has no terminal result");
1387
- io.stdout(formatTerminalResult(terminal));
1381
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, officer.admitted.runDirectory);
1388
1382
  return { exitCode: 0, admitted: officer.admitted, terminal };
1389
1383
  }
1390
1384
  if (chain.status === "continue") {
1391
1385
  return runPublicInstructionSeatResume({
1392
1386
  runId: admitted.runId,
1393
- message: readableGateItem(chain.passes.at(-1)?.receipt),
1387
+ summons: { instruction: readableGateItem(chain.passes.at(-1)?.receipt) },
1394
1388
  }, { ...env, unreadableReasksSpent: 0 }, io);
1395
1389
  }
1396
1390
  if (admitted.role === "secretariat") {
@@ -1408,8 +1402,13 @@ async function auditSubmittedRole(
1408
1402
  // Audit only adds gate rounds and, for 中书省, the officer fact. A second
1409
1403
  // settle would republish the same attempt.
1410
1404
  if (turn.terminal === undefined) throw new Error(`audited ${admitted.role} submission did not settle`);
1411
- const terminal = await attachPostAuditProjection(admitted, env.principalAuthority, turn.terminal);
1405
+ const terminal = await attachPostAuditProjection(
1406
+ admitted,
1407
+ env.principalAuthority,
1408
+ turn.terminal,
1409
+ packageFaultScope(admitted, env, io),
1410
+ );
1412
1411
  turn = { ...turn, terminal };
1413
- io.stdout(formatTerminalResult(terminal));
1412
+ await presentTerminal(terminal, { ...io, omitFailureStderrDiagnostic: true }, admitted.runDirectory);
1414
1413
  return turn;
1415
1414
  }
@@ -1236,7 +1236,7 @@ const ROLE_COMMAND_HELP = {
1236
1236
  },
1237
1237
  notary: {
1238
1238
  command: "notary",
1239
- summary: "Direct Notary document check (quote fidelity + ticket alignment); zero prompt/attachment.",
1239
+ summary: "Direct Notary summons; duties: souls/notary.md. Zero prompt/attachment.",
1240
1240
  usage: ["ak-role notary --source-run <runId@role|path> [options]"],
1241
1241
  examples: [
1242
1242
  "ak-role notary --source-run 01a034f1-75bf-71a6-bcf5-d1299145b1a5@judge",