@akagilnc/pi-workflow-roles 0.1.3572 → 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 (129) hide show
  1. package/dist/acp-host/production-host.js +20239 -10556
  2. package/dist/analyst-gate-cycles-read.js +387 -0
  3. package/dist/archivist-record-entry.js +22 -1
  4. package/dist/audit-escalation.js +6 -0
  5. package/dist/auditor-soul.js +74 -0
  6. package/dist/collector-config.js +86 -0
  7. package/dist/collector-evidence.js +316 -0
  8. package/dist/collector-github.js +527 -0
  9. package/dist/collector-ledger.js +853 -0
  10. package/dist/collector-tool-schemas.js +33 -0
  11. package/dist/compliance-transport.js +104 -52
  12. package/dist/diarist-mechanical.js +411 -0
  13. package/dist/diarist-ticket-resolution.js +177 -0
  14. package/dist/diarist.js +311 -0
  15. package/dist/doctor-auditor.js +25 -0
  16. package/dist/doctor-contracts.js +2 -0
  17. package/dist/doctor-evidence.js +142 -0
  18. package/dist/gatekeeper-role.js +104 -81
  19. package/dist/host-transition-prior-native.js +78 -0
  20. package/dist/institutional-resolution.js +1 -95
  21. package/dist/judge-auditor.js +26 -0
  22. package/dist/ledger-session-read.js +227 -0
  23. package/dist/merger-git-state.js +78 -0
  24. package/dist/navigator-attendance.js +15 -7
  25. package/dist/navigator-public-session.js +170 -0
  26. package/dist/navigator-session-contracts.js +36 -40
  27. package/dist/notary-source-run.js +122 -0
  28. package/dist/package-contracts/auditor-output.js +66 -0
  29. package/dist/package-contracts/evidence-child-output.js +34 -0
  30. package/dist/package-contracts/judge-output.js +2 -0
  31. package/dist/package-contracts/terminating-tools.js +25 -2
  32. package/dist/package-resources/method-skill.js +254 -0
  33. package/dist/packaged-role-registry.js +36 -0
  34. package/dist/pi/durable-principal.js +61 -0
  35. package/dist/pi/in-process-session.js +25 -6
  36. package/dist/pi/known-failure.js +52 -0
  37. package/dist/pi/role-turn-host.js +430 -0
  38. package/dist/public-cli/auto-resume.js +414 -0
  39. package/dist/public-cli/cli-errors.js +8 -0
  40. package/dist/public-cli/cli-io.js +1 -0
  41. package/dist/public-cli/command-renderer.js +5 -0
  42. package/dist/public-cli/doctor-run.js +84 -0
  43. package/dist/public-cli/inspector-run.js +136 -0
  44. package/dist/public-cli/instruction-seat-run.js +256 -0
  45. package/dist/public-cli/invocation.js +2225 -0
  46. package/dist/public-cli/judge-run.js +118 -0
  47. package/dist/public-cli/load-production-acp-host.js +40 -0
  48. package/dist/public-cli/main.js +1140 -652
  49. package/dist/public-cli/notary-run.js +161 -0
  50. package/dist/public-cli/option-definitions.js +1192 -0
  51. package/dist/public-cli/post-admission.js +667 -0
  52. package/dist/public-cli/public-run-credentials.js +49 -0
  53. package/dist/public-cli/registry.js +4 -1
  54. package/dist/public-cli/reviewer-dispatch-rejection.js +77 -0
  55. package/dist/public-cli/run-lifecycle.js +1344 -0
  56. package/dist/public-cli/seat-ticket-binding.js +113 -0
  57. package/dist/public-cli/settlement.js +3441 -0
  58. package/dist/public-cli/terminal.js +135 -0
  59. package/dist/public-cli/turn-request.js +25 -0
  60. package/dist/public-role-summons.js +301 -0
  61. package/dist/receipt-delivery-policy.js +10 -0
  62. package/dist/reviewer-child-executor.js +80 -8
  63. package/dist/reviewer-execution-ledger.js +2 -1
  64. package/dist/run-terminal-artifacts.js +195 -0
  65. package/dist/run-ticket-number.js +40 -0
  66. package/dist/session-assistant-usage.js +107 -0
  67. package/dist/shape-unreadable-failure.js +34 -0
  68. package/dist/submission-errors.js +3 -0
  69. package/dist/submission-ledger.js +388 -0
  70. package/dist/ticket-provenance-contracts.js +115 -0
  71. package/dist/ticket-provenance.js +340 -0
  72. package/extensions/role-runtime.ts +7 -0
  73. package/package.json +1 -1
  74. package/scripts/build-package.mjs +2 -1
  75. package/souls/doctor-auditor.md +1 -0
  76. package/souls/evidence-child.md +1 -0
  77. package/src/acp-host/production-host.ts +3 -0
  78. package/src/acp-host/role-envelope.ts +2 -2
  79. package/src/acp-host/role-turn-host.ts +9 -1
  80. package/src/analyst-gate-cycles-read.ts +37 -2
  81. package/src/archivist-record-entry.ts +45 -1
  82. package/src/audit-escalation.ts +17 -0
  83. package/src/auditor-role.ts +22 -0
  84. package/src/auditor-soul.ts +42 -0
  85. package/src/compliance-transport.ts +177 -66
  86. package/src/doctor-auditor.ts +10 -14
  87. package/src/doctor-contracts.ts +1 -0
  88. package/src/doctor-role.ts +2 -2
  89. package/src/evidence-child-role.ts +22 -0
  90. package/src/gatekeeper-pass-envelope.ts +109 -0
  91. package/src/gatekeeper-role.ts +145 -104
  92. package/src/host-contracts.ts +9 -1
  93. package/src/institutional-resolution.ts +8 -163
  94. package/src/judge-auditor.ts +10 -15
  95. package/src/judge-role.ts +8 -0
  96. package/src/navigator-attendance.ts +25 -9
  97. package/src/navigator-public-session.ts +217 -0
  98. package/src/navigator-session-contracts.ts +61 -54
  99. package/src/notary-source-run.ts +3 -1
  100. package/src/package-contracts/auditor-output.ts +82 -0
  101. package/src/package-contracts/evidence-child-output.ts +51 -0
  102. package/src/package-contracts/judge-output.ts +1 -0
  103. package/src/package-contracts/reviewer-output.ts +2 -2
  104. package/src/package-contracts/terminating-tools.ts +31 -1
  105. package/src/packaged-role-registry.ts +43 -0
  106. package/src/pi/adapter.ts +2 -1
  107. package/src/pi/in-process-session.ts +38 -12
  108. package/src/pi/role-turn-host.ts +34 -0
  109. package/src/public-cli/cli.ts +14 -6
  110. package/src/public-cli/instruction-seat-run.ts +289 -50
  111. package/src/public-cli/invocation.ts +66 -25
  112. package/src/public-cli/option-definitions.ts +61 -0
  113. package/src/public-cli/post-admission.ts +7 -1
  114. package/src/public-cli/registry.ts +4 -1
  115. package/src/public-cli/run-lifecycle.ts +22 -3
  116. package/src/public-cli/settlement.ts +120 -5
  117. package/src/public-cli/terminal.ts +2 -0
  118. package/src/public-role-summons.ts +431 -0
  119. package/src/receipt-delivery-policy.ts +10 -0
  120. package/src/reviewer-agent.ts +1 -1
  121. package/src/reviewer-child-executor.ts +114 -12
  122. package/src/reviewer-execution-ledger.ts +3 -2
  123. package/src/role-runtime.ts +158 -17
  124. package/src/session-assistant-usage.ts +119 -0
  125. package/src/session-opening-materials.ts +1 -1
  126. package/src/shape-unreadable-failure.ts +49 -0
  127. package/src/submission-errors.ts +3 -0
  128. package/dist/evidence-child-executor.js +0 -829
  129. package/src/evidence-child-executor.ts +0 -1140
@@ -34,6 +34,8 @@ export type OptionOwner =
34
34
  | "inspector"
35
35
  | "gatekeeper"
36
36
  | "navigator"
37
+ | "auditor"
38
+ | "evidence-child"
37
39
  | "diarist"
38
40
  | "analyst";
39
41
 
@@ -423,6 +425,44 @@ const NAVIGATOR_OPTIONS = [
423
425
  bindOwner("navigator", SHARED_ATTACH_SEMANTICS),
424
426
  ] as const satisfies readonly PublicOptionDefinition[];
425
427
 
428
+ const AUDITOR_OPTIONS = [
429
+ bindOwner("auditor", SHARED_PROJECT_SEMANTICS),
430
+ bindOwner("auditor", SHARED_ATTACH_SEMANTICS),
431
+ {
432
+ id: "subject",
433
+ owner: "auditor",
434
+ canonical: "--subject",
435
+ aliases: [],
436
+ valueMetavar: "judge|doctor",
437
+ required: true,
438
+ repeatable: false,
439
+ form: "option",
440
+ description: {
441
+ en: "Required audited subject: judge or doctor (selects judge-auditor.md / doctor-auditor.md).",
442
+ zh: "必填受审对象:judge 或 doctor(装 judge-auditor.md / doctor-auditor.md)。",
443
+ },
444
+ },
445
+ {
446
+ id: "source-run",
447
+ owner: "auditor",
448
+ canonical: "--source-run",
449
+ aliases: [],
450
+ valueMetavar: "runId@role|path",
451
+ required: true,
452
+ repeatable: false,
453
+ form: "option",
454
+ description: {
455
+ en: "Required source run locator of the audited subject volume (same input for direct and nested summons).",
456
+ zh: "必填受审卷宗 locator(直调与传召同一输入面)。",
457
+ },
458
+ },
459
+ ] as const satisfies readonly PublicOptionDefinition[];
460
+
461
+ const EVIDENCE_CHILD_OPTIONS = [
462
+ bindOwner("evidence-child", SHARED_PROJECT_SEMANTICS),
463
+ bindOwner("evidence-child", SHARED_ATTACH_SEMANTICS),
464
+ ] as const satisfies readonly PublicOptionDefinition[];
465
+
426
466
  const COUNTERSIGN_OPTIONS = [
427
467
  bindOwner("countersign", SHARED_PROJECT_SEMANTICS),
428
468
  bindOwner("countersign", SHARED_ATTACH_SEMANTICS),
@@ -790,6 +830,8 @@ export const PUBLIC_OPTION_TABLE = {
790
830
  inspector: INSPECTOR_OPTIONS,
791
831
  gatekeeper: GATEKEEPER_OPTIONS,
792
832
  navigator: NAVIGATOR_OPTIONS,
833
+ auditor: AUDITOR_OPTIONS,
834
+ "evidence-child": EVIDENCE_CHILD_OPTIONS,
793
835
  diarist: DIARIST_OPTIONS,
794
836
  analyst: ANALYST_OPTIONS,
795
837
  } as const satisfies Record<OptionOwner, readonly PublicOptionDefinition[]>;
@@ -811,6 +853,8 @@ export const PUBLIC_ROLE_OPTION_OWNERS = [
811
853
  "inspector",
812
854
  "gatekeeper",
813
855
  "navigator",
856
+ "auditor",
857
+ "evidence-child",
814
858
  "diarist",
815
859
  "analyst",
816
860
  ] as const satisfies readonly PublicRoleOptionOwner[];
@@ -1209,6 +1253,23 @@ const ROLE_COMMAND_HELP = {
1209
1253
  'ak-role navigator "刚完成 coder apply 收敛,下一步?"',
1210
1254
  ],
1211
1255
  },
1256
+ auditor: {
1257
+ command: "auditor",
1258
+ summary: "Direct Auditor (审刑院) compliance audit: pass, revise, or escalate.",
1259
+ usage: ["ak-role auditor --subject <judge|doctor> --source-run <runId@role|path> [options] [instruction]"],
1260
+ examples: [
1261
+ 'ak-role auditor --subject judge --source-run 01abc…@judge --attach ./dossier "审:本 run 是否合规。"',
1262
+ 'ak-role auditor --subject doctor --source-run 01abc…@doctor "审:太医候选是否合规。"',
1263
+ ],
1264
+ },
1265
+ "evidence-child": {
1266
+ command: "evidence-child",
1267
+ summary: "Direct evidence-child fact gathering; submit one report.",
1268
+ usage: ["ak-role evidence-child [options] [instruction]"],
1269
+ examples: [
1270
+ 'ak-role evidence-child "查:本工作树 diff 与票面是否一致。"',
1271
+ ],
1272
+ },
1212
1273
  diarist: {
1213
1274
  command: "diarist",
1214
1275
  summary:
@@ -110,6 +110,12 @@ export type PostAdmissionEnv = {
110
110
  sessionAppender: SessionCustomEntryAppender;
111
111
  autoResumeLimit?: number;
112
112
  createRunId?: () => string;
113
+ /**
114
+ * Parent cancellation for a nested public summon (#675). Every dispatched turn
115
+ * carries it so an aborted parent terminates the nested activation; a CLI
116
+ * process has no parent and leaves it absent.
117
+ */
118
+ signal?: AbortSignal;
113
119
  /**
114
120
  * #724 explicit fresh summons (`ak-role new <role>`): skip same-ticket auto-resume
115
121
  * and mint a new run. Absent on ordinary role commands and on `ak-role resume`.
@@ -302,7 +308,7 @@ export async function dispatchPostAdmissionTurn<
302
308
  piSessionFile: principalCoordinates.sessionFile,
303
309
  })
304
310
  : undefined;
305
- turnRequest = request;
311
+ turnRequest = env.signal === undefined ? request : { ...request, signal: env.signal };
306
312
  if (hostTransition !== undefined) {
307
313
  turnRequest = { ...turnRequest, hostTransition };
308
314
  }
@@ -99,13 +99,16 @@ const STARTUP_CANDIDATES: Record<PublicConfigurableSeat, readonly ModelRef[]> =
99
99
  // #620: subordinate officers inherit gatekeeper; no package startup model.
100
100
  notary: [],
101
101
  // #453/#620/#639: gatekeeper callable but no package startup model — caller
102
- // configures it or the institutional resolution applies on the province path.
102
+ // configures it or inherits on the province path.
103
103
  gatekeeper: [],
104
104
  inspector: [],
105
105
  navigator: [
106
106
  { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "medium" },
107
107
  { provider: "xai", model: "grok-4.5", thinking: "high" },
108
108
  ],
109
+ // #675: auditor / evidence-child public seats — no package startup; caller configures.
110
+ auditor: [],
111
+ "evidence-child": [],
109
112
  // #708 `diarist-seat-default`: owner-set initial value; changed in the seat
110
113
  // table like any other seat. No engine axis, package-default host.
111
114
  diarist: [{ provider: "xai", model: "grok-4.5", thinking: "medium" }],
@@ -97,6 +97,8 @@ export type RoleRunRecord = {
97
97
  | "inspector"
98
98
  | "gatekeeper"
99
99
  | "navigator"
100
+ | "auditor"
101
+ | "evidence-child"
100
102
  | "diarist";
101
103
  readonly state: RoleRunState;
102
104
  readonly bookKey: string;
@@ -351,6 +353,8 @@ async function readRoleRunStateDisk(
351
353
  record.role !== "inspector" &&
352
354
  record.role !== "gatekeeper" &&
353
355
  record.role !== "navigator" &&
356
+ record.role !== "auditor" &&
357
+ record.role !== "evidence-child" &&
354
358
  record.role !== "diarist"
355
359
  ) {
356
360
  return undefined;
@@ -1454,7 +1458,11 @@ export type LoadedResumableDiaristRun = {
1454
1458
  };
1455
1459
 
1456
1460
  export type LoadedResumableInstructionSeatRun = {
1457
- readonly admitted: AdmittedGatekeeperInvocation | AdmittedNavigatorInvocation;
1461
+ readonly admitted:
1462
+ | AdmittedGatekeeperInvocation
1463
+ | AdmittedNavigatorInvocation
1464
+ | import("./invocation.ts").AdmittedAuditorInvocation
1465
+ | import("./invocation.ts").AdmittedEvidenceChildInvocation;
1458
1466
  readonly run: RoleRunRecord;
1459
1467
  readonly observation?: TypedHttp429Observation;
1460
1468
  };
@@ -1676,7 +1684,12 @@ export async function loadResumableInstructionSeatRun(
1676
1684
  authority: DurablePrincipalAuthority,
1677
1685
  ): Promise<LoadedResumableInstructionSeatRun> {
1678
1686
  const loaded = await loadResumableRunRecord(home, runId, authority);
1679
- if (loaded.run.role !== "gatekeeper" && loaded.run.role !== "navigator") {
1687
+ if (
1688
+ loaded.run.role !== "gatekeeper"
1689
+ && loaded.run.role !== "navigator"
1690
+ && loaded.run.role !== "auditor"
1691
+ && loaded.run.role !== "evidence-child"
1692
+ ) {
1680
1693
  throw new CliUsageError(
1681
1694
  `role run ${runId} belongs to ${loaded.run.role}, not an instruction seat`,
1682
1695
  );
@@ -1684,7 +1697,11 @@ export async function loadResumableInstructionSeatRun(
1684
1697
  const admitted = {
1685
1698
  role: loaded.run.role,
1686
1699
  ...resumedBaseAdmitted(loaded),
1687
- } as AdmittedGatekeeperInvocation | AdmittedNavigatorInvocation;
1700
+ } as
1701
+ | AdmittedGatekeeperInvocation
1702
+ | AdmittedNavigatorInvocation
1703
+ | import("./invocation.ts").AdmittedAuditorInvocation
1704
+ | import("./invocation.ts").AdmittedEvidenceChildInvocation;
1688
1705
  return seatLoadedResult(loaded, admitted);
1689
1706
  }
1690
1707
 
@@ -1956,6 +1973,8 @@ export async function peekRoleRunRole(
1956
1973
  | "inspector"
1957
1974
  | "gatekeeper"
1958
1975
  | "navigator"
1976
+ | "auditor"
1977
+ | "evidence-child"
1959
1978
  | "diarist"
1960
1979
  | undefined
1961
1980
  > {
@@ -24,6 +24,7 @@ import { AUDITOR_SOUL_ROLES } from "../auditor-soul.ts";
24
24
  import { DOCTOR_AUDIT_TOOL_NAME } from "../doctor-auditor.ts";
25
25
  import { JUDGE_AUDIT_TOOL_NAME } from "../judge-auditor.ts";
26
26
  import type { RoleTurnKnownFailure } from "../host-contracts.ts";
27
+ import { stampShapeUnreadableDetails } from "../shape-unreadable-failure.ts";
27
28
  import { knownFailureFromProviderStop } from "../pi/known-failure.ts";
28
29
  import { readReviewerDispatchRejection } from "./reviewer-dispatch-rejection.ts";
29
30
  import {
@@ -118,6 +119,17 @@ import {
118
119
  navigatorDecisiveFacts,
119
120
  validateRecordedNavigatorOutput,
120
121
  } from "../package-contracts/navigator-output.ts";
122
+ import {
123
+ AUDITOR_OUTPUT_TOOL_NAME,
124
+ auditorDecisiveFacts,
125
+ projectLawfulAuditorOutput,
126
+ validateRecordedAuditorOutput,
127
+ } from "../package-contracts/auditor-output.ts";
128
+ import {
129
+ EVIDENCE_CHILD_OUTPUT_TOOL_NAME,
130
+ evidenceChildDecisiveFacts,
131
+ validateRecordedEvidenceChildOutput,
132
+ } from "../package-contracts/evidence-child-output.ts";
121
133
  import {
122
134
  observePackagedMethodSkillInvocation,
123
135
  type ObservedPackagedMethodSkillInvocation,
@@ -1223,9 +1235,11 @@ function typedFailedTerminatingToolKnownFailure(
1223
1235
  const diagnostic = isRecord(textPart) ? textPart.text : undefined;
1224
1236
  // Durable details already carry fact + typed evidence from envelope one-shot projection (#475).
1225
1237
  // Do not re-parse retained compliance responses here.
1238
+ // Host infrastructure must NOT map to cause=output — that cause is reserved for
1239
+ // shape-unreadable retained candidates (ADR 0055 / #675 producer→consumer diversion).
1226
1240
  const details = isRecord(message.details) ? message.details : classification.fact;
1227
1241
  return {
1228
- cause: "output",
1242
+ cause: "activation",
1229
1243
  identity: { name: message.toolName, code: message.toolCallId },
1230
1244
  ...(typeof diagnostic === "string" && diagnostic.trim() !== "" ? { diagnostic } : {}),
1231
1245
  details,
@@ -1489,6 +1503,16 @@ function auditNoReceiptDecisiveFact(candidate: object): Record<string, unknown>
1489
1503
  }
1490
1504
  }
1491
1505
 
1506
+ /** Typed unreadable audit leg beside accepted parent candidate (ADR 0055 / #675). */
1507
+ function auditUnreadableDecisiveFact(candidate: object): Record<string, unknown> {
1508
+ const projected = safelyRead(candidate, "auditUnreadable");
1509
+ if (!projected.readable || projected.value === undefined) return {};
1510
+ if (typeof projected.value !== "object" || projected.value === null || Array.isArray(projected.value)) {
1511
+ return { auditUnreadable: projected.value };
1512
+ }
1513
+ return { auditUnreadable: projected.value as Record<string, unknown> };
1514
+ }
1515
+
1492
1516
  /** Countersign terminal projection — escalate keeps decisionGate; continue keeps fix (#572 / ADR 0074). */
1493
1517
  function countersignDecisiveFacts(
1494
1518
  verdict: object,
@@ -1531,6 +1555,7 @@ function judgeDecisiveFacts(
1531
1555
  const facts: Record<string, unknown> = {
1532
1556
  judgeStatus,
1533
1557
  ...auditNoReceiptDecisiveFact(verdict),
1558
+ ...auditUnreadableDecisiveFact(verdict),
1534
1559
  };
1535
1560
  const statusBase = judgeStatus;
1536
1561
  if (statusBase === "continue") {
@@ -1695,7 +1720,10 @@ function collectorDecisiveFacts(
1695
1720
  function doctorDecisiveFacts(output: DoctorOutput): Record<string, unknown> {
1696
1721
  const candidate = output as unknown as object;
1697
1722
  const status = safelyRead(candidate, "status");
1698
- const facts: Record<string, unknown> = { ...auditNoReceiptDecisiveFact(candidate) };
1723
+ const facts: Record<string, unknown> = {
1724
+ ...auditNoReceiptDecisiveFact(candidate),
1725
+ ...auditUnreadableDecisiveFact(candidate),
1726
+ };
1699
1727
  if (status.readable && typeof status.value === "string") facts.doctorStatus = status.value;
1700
1728
  const statusBase =
1701
1729
  status.readable && typeof status.value === "string"
@@ -3367,6 +3395,8 @@ type SeatAcceptedSettlementSpec = {
3367
3395
  | "inspector"
3368
3396
  | "gatekeeper"
3369
3397
  | "navigator"
3398
+ | "auditor"
3399
+ | "evidence-child"
3370
3400
  | "diarist";
3371
3401
  readonly toolName: string;
3372
3402
  readonly nonUsableDiagnostic: string;
@@ -3395,6 +3425,8 @@ async function settleLawfulSeatAcceptedTerminalResult(
3395
3425
  | AdmittedInspectorInvocation
3396
3426
  | AdmittedGatekeeperInvocation
3397
3427
  | AdmittedNavigatorInvocation
3428
+ | import("./invocation.ts").AdmittedAuditorInvocation
3429
+ | import("./invocation.ts").AdmittedEvidenceChildInvocation
3398
3430
  | AdmittedDiaristInvocation,
3399
3431
  authority: DurablePrincipalAuthority,
3400
3432
  spec: SeatAcceptedSettlementSpec,
@@ -3436,7 +3468,7 @@ async function settleLawfulSeatAcceptedTerminalResult(
3436
3468
  return settleFailureTerminalResult(admitted, {
3437
3469
  cause: "output",
3438
3470
  diagnostic: residual.diagnostic,
3439
- details: { candidate: residual.candidate, acceptedReceipt: false },
3471
+ details: stampShapeUnreadableDetails(residual.candidate),
3440
3472
  }, authority);
3441
3473
  }
3442
3474
  if (
@@ -3454,7 +3486,7 @@ async function settleLawfulSeatAcceptedTerminalResult(
3454
3486
  return settleFailureTerminalResult(admitted, {
3455
3487
  cause: "output",
3456
3488
  diagnostic: spec.nonUsableDiagnostic,
3457
- details: { candidate: acceptedNonUsable, acceptedReceipt: false },
3489
+ details: stampShapeUnreadableDetails(acceptedNonUsable),
3458
3490
  }, authority);
3459
3491
  }
3460
3492
  return undefined;
@@ -3465,7 +3497,7 @@ async function settleLawfulSeatAcceptedTerminalResult(
3465
3497
  {
3466
3498
  cause: "output",
3467
3499
  diagnostic: spec.nonUsableDiagnostic,
3468
- details: { candidate: roleOutcome.decisiveFacts, acceptedReceipt: false },
3500
+ details: stampShapeUnreadableDetails(roleOutcome.decisiveFacts),
3469
3501
  },
3470
3502
  authority,
3471
3503
  );
@@ -3818,6 +3850,89 @@ export async function trySettleNavigatorTerminalResult(
3818
3850
  return settleLawfulNavigatorTerminalResult(admitted, authority, scope);
3819
3851
  }
3820
3852
 
3853
+ /** Lawful Auditor accepted outcome (pass/revise/escalate, #675). */
3854
+ export type LawfulAuditorRoleOutcome = {
3855
+ kind: "accepted";
3856
+ role: "auditor";
3857
+ status: string;
3858
+ decisiveFacts: Readonly<Record<string, unknown>>;
3859
+ };
3860
+
3861
+ async function settleLawfulAuditorTerminalResult(
3862
+ admitted: import("./invocation.ts").AdmittedAuditorInvocation,
3863
+ authority: DurablePrincipalAuthority,
3864
+ scope?: SettlementCourtScope,
3865
+ ): Promise<TerminalResult | undefined> {
3866
+ return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
3867
+ role: "auditor",
3868
+ toolName: AUDITOR_OUTPUT_TOOL_NAME,
3869
+ nonUsableDiagnostic: "审刑院回执无显式 pass/revise/escalate",
3870
+ // Only pass/revise/escalate are lawful releases. Unreadable mystery status
3871
+ // fails closed with candidate retained for parent ComplianceCandidateUnreadableError.
3872
+ tryAcceptDetails: (details) => projectLawfulAuditorOutput(details) !== undefined,
3873
+ projectAccepted: (sealed) => {
3874
+ const lawful = projectLawfulAuditorOutput(sealed.decisiveFacts);
3875
+ if (lawful === undefined) {
3876
+ throw new Error("auditor projectAccepted requires lawful pass/revise/escalate");
3877
+ }
3878
+ const accepted: LawfulAuditorRoleOutcome = {
3879
+ kind: "accepted",
3880
+ role: "auditor",
3881
+ status: lawful.status,
3882
+ decisiveFacts: auditorDecisiveFacts(lawful),
3883
+ };
3884
+ return accepted;
3885
+ },
3886
+ }, scope);
3887
+ }
3888
+
3889
+ export async function trySettleAuditorTerminalResult(
3890
+ admitted: import("./invocation.ts").AdmittedAuditorInvocation,
3891
+ authority: DurablePrincipalAuthority,
3892
+ scope?: SettlementCourtScope,
3893
+ ): Promise<TerminalResult | undefined> {
3894
+ return settleLawfulAuditorTerminalResult(admitted, authority, scope);
3895
+ }
3896
+
3897
+ /** Lawful Evidence-Child accepted outcome (#675). */
3898
+ export type LawfulEvidenceChildRoleOutcome = {
3899
+ kind: "accepted";
3900
+ role: "evidence-child";
3901
+ status: string;
3902
+ decisiveFacts: Readonly<Record<string, unknown>>;
3903
+ };
3904
+
3905
+ async function settleLawfulEvidenceChildTerminalResult(
3906
+ admitted: import("./invocation.ts").AdmittedEvidenceChildInvocation,
3907
+ authority: DurablePrincipalAuthority,
3908
+ scope?: SettlementCourtScope,
3909
+ ): Promise<TerminalResult | undefined> {
3910
+ return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
3911
+ role: "evidence-child",
3912
+ toolName: EVIDENCE_CHILD_OUTPUT_TOOL_NAME,
3913
+ nonUsableDiagnostic: "取证回执无报告正文",
3914
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedEvidenceChildOutput),
3915
+ projectAccepted: (sealed) => {
3916
+ const output = validateRecordedEvidenceChildOutput(sealed.decisiveFacts);
3917
+ const accepted: LawfulEvidenceChildRoleOutcome = {
3918
+ kind: "accepted",
3919
+ role: "evidence-child",
3920
+ status: "report",
3921
+ decisiveFacts: evidenceChildDecisiveFacts(output),
3922
+ };
3923
+ return accepted;
3924
+ },
3925
+ }, scope);
3926
+ }
3927
+
3928
+ export async function trySettleEvidenceChildTerminalResult(
3929
+ admitted: import("./invocation.ts").AdmittedEvidenceChildInvocation,
3930
+ authority: DurablePrincipalAuthority,
3931
+ scope?: SettlementCourtScope,
3932
+ ): Promise<TerminalResult | undefined> {
3933
+ return settleLawfulEvidenceChildTerminalResult(admitted, authority, scope);
3934
+ }
3935
+
3821
3936
  /** Try to settle a lawful Coder Terminal; undefined only for genuine absence. */
3822
3937
  export async function trySettleCoderTerminalResult(
3823
3938
  admitted: AdmittedCoderInvocation,
@@ -41,6 +41,8 @@ export type TerminalRoleName =
41
41
  | "inspector"
42
42
  | "gatekeeper"
43
43
  | "navigator"
44
+ | "auditor"
45
+ | "evidence-child"
44
46
  | "diarist";
45
47
 
46
48
  /** Merger/Collector residual only — Notary/audit residual abolished (#475). */