@akagilnc/pi-workflow-roles 0.1.2521 → 0.1.2653-next.71811ca

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 (109) hide show
  1. package/README.md +129 -39
  2. package/README.zh-CN.md +128 -39
  3. package/dist/activation-ledger-topology.js +1 -1
  4. package/dist/archivist-record-entry.js +47 -26
  5. package/dist/auditor-dossier-tool.js +3 -1
  6. package/dist/compliance-transport.js +17 -26
  7. package/dist/doctor-contracts.js +1 -2
  8. package/dist/dossier-resolution.js +4 -8
  9. package/dist/engine-detour-tool.js +33 -8
  10. package/dist/engine-detour.js +1 -0
  11. package/dist/evidence-child-executor.js +277 -424
  12. package/dist/host-contracts.js +22 -0
  13. package/dist/institutional-resolution.js +88 -0
  14. package/dist/merger-contracts.js +1 -2
  15. package/dist/navigator-attendance.js +16 -0
  16. package/dist/notary-contracts.js +2 -3
  17. package/dist/package-contracts/fixer-output.js +1 -2
  18. package/dist/packaged-role-registry.js +102 -9
  19. package/dist/pi/in-process-session.js +671 -0
  20. package/dist/public-cli/config.js +7 -5
  21. package/dist/public-cli/main.js +3767 -4113
  22. package/dist/reviewer-child-executor.js +6 -1
  23. package/dist/session-opening-materials.js +10 -38
  24. package/dist/sitian-appender.js +146 -0
  25. package/dist/sitian-contracts.js +21 -0
  26. package/dist/sitian-facade.js +15 -0
  27. package/dist/sitian-reader.js +52 -0
  28. package/extensions/role-runtime.ts +9 -7
  29. package/package.json +5 -5
  30. package/resources/engines/cursor.md +12 -26
  31. package/resources/engines/hermes.md +2 -23
  32. package/resources/engines/opus.md +1 -16
  33. package/resources/navigator-route-playbook.md +2 -2
  34. package/scripts/build-package.mjs +0 -1
  35. package/souls/quality-law.md +1 -1
  36. package/src/activation-ledger-topology.ts +1 -1
  37. package/src/archivist-record-entry.ts +57 -45
  38. package/src/auditor-dossier-tool.ts +4 -2
  39. package/src/canonical-skill-binding.ts +37 -27
  40. package/src/collector-role.ts +11 -20
  41. package/src/collector-tool-schemas.ts +1 -4
  42. package/src/compliance-transport.ts +19 -44
  43. package/src/doctor-auditor.ts +1 -5
  44. package/src/doctor-contracts.ts +1 -4
  45. package/src/doctor-role.ts +31 -8
  46. package/src/dossier-resolution.ts +8 -8
  47. package/src/engine-detour-tool.ts +48 -19
  48. package/src/engine-detour.ts +3 -0
  49. package/src/evidence-child-executor.ts +277 -485
  50. package/src/factory-board.ts +3 -3
  51. package/src/gatekeeper-role.ts +21 -10
  52. package/src/host-contracts.ts +386 -0
  53. package/src/in-process-session.ts +1 -115
  54. package/src/institutional-resolution.ts +135 -0
  55. package/src/judge-auditor.ts +1 -5
  56. package/src/judge-role.ts +37 -51
  57. package/src/merger-contracts.ts +1 -4
  58. package/src/merger-role.ts +7 -11
  59. package/src/navigator-attendance.ts +20 -1
  60. package/src/notary-contracts.ts +8 -11
  61. package/src/notary-role.ts +7 -23
  62. package/src/notary-source-run.ts +4 -3
  63. package/src/package-contracts/fixer-output.ts +1 -4
  64. package/src/package-resources/method-skill-binding.ts +10 -34
  65. package/src/packaged-role-registry.ts +122 -12
  66. package/src/pi/adapter.ts +192 -0
  67. package/src/pi/durable-principal.ts +98 -0
  68. package/src/pi/in-process-session.ts +819 -0
  69. package/src/pi/known-failure.ts +77 -0
  70. package/src/pi/pi-normalization.ts +284 -0
  71. package/src/pi/role-turn-host.ts +459 -0
  72. package/src/public-cli/auto-resume.ts +42 -44
  73. package/src/public-cli/cli.ts +171 -257
  74. package/src/public-cli/coder-run.ts +115 -433
  75. package/src/public-cli/collector-run.ts +62 -314
  76. package/src/public-cli/config.ts +7 -5
  77. package/src/public-cli/doctor-run.ts +41 -52
  78. package/src/public-cli/fixer-run.ts +122 -427
  79. package/src/public-cli/invocation.ts +287 -96
  80. package/src/public-cli/judge-run.ts +92 -422
  81. package/src/public-cli/merger-run.ts +167 -429
  82. package/src/public-cli/notary-run.ts +41 -47
  83. package/src/public-cli/option-definitions.ts +136 -3
  84. package/src/public-cli/post-admission.ts +497 -0
  85. package/src/public-cli/public-run-credentials.ts +4 -4
  86. package/src/public-cli/reviewer-dispatch-rejection.ts +106 -0
  87. package/src/public-cli/reviewer-run.ts +132 -449
  88. package/src/public-cli/run-lifecycle.ts +339 -327
  89. package/src/public-cli/settlement.ts +251 -134
  90. package/src/public-cli/terminal.ts +3 -9
  91. package/src/public-cli/turn-request.ts +87 -0
  92. package/src/reviewer-child-executor.ts +9 -1
  93. package/src/reviewer-role.ts +11 -20
  94. package/src/role-runtime.ts +129 -78
  95. package/src/session-opening-materials.ts +25 -39
  96. package/src/sitian-appender.ts +171 -0
  97. package/src/sitian-contracts.ts +106 -0
  98. package/src/sitian-facade.ts +18 -0
  99. package/src/sitian-reader.ts +62 -0
  100. package/src/worker-role.ts +42 -40
  101. package/src/worker-submission-gates.ts +33 -0
  102. package/dist/archivist-role-run-coordinates.js +0 -28
  103. package/dist/package-contracts/terminating-infrastructure.js +0 -90
  104. package/resources/engines/sonnet.md +0 -27
  105. package/resources/engines/zcode.md +0 -63
  106. package/src/archivist-role-run-coordinates.ts +0 -45
  107. package/src/package-contracts/terminating-infrastructure.ts +0 -132
  108. package/src/public-cli/explicit-internal.ts +0 -427
  109. package/src/public-cli/one-shot-dispatch.ts +0 -300
@@ -11,12 +11,15 @@ import {
11
11
  readAnalystGateCyclesFromAuditorRoles,
12
12
  type AnalystGateCycleRound,
13
13
  } from "../analyst-gate-cycles-read.ts";
14
+ import { readSitianRecords, resolveSitianRecordPath, sitianReport } from "../sitian-facade.ts";
14
15
 
15
16
  import { isAuditEscalationResult } from "../audit-escalation.ts";
16
17
  import { AUDITOR_SOUL_ROLES } from "../auditor-soul.ts";
17
18
  import { DOCTOR_AUDIT_TOOL_NAME } from "../doctor-auditor.ts";
18
19
  import { JUDGE_AUDIT_TOOL_NAME } from "../judge-auditor.ts";
19
- import { knownFailureFromProviderStop, type ExplicitInternalKnownFailure, readReviewerDispatchRejection } from "./explicit-internal.ts";
20
+ import type { RoleTurnKnownFailure } from "../host-contracts.ts";
21
+ import { knownFailureFromProviderStop } from "../pi/known-failure.ts";
22
+ import { readReviewerDispatchRejection } from "./reviewer-dispatch-rejection.ts";
20
23
  import {
21
24
  RESUME_TRANSPORT_ENVELOPE,
22
25
  isV1ResumableProvider,
@@ -32,6 +35,8 @@ import {
32
35
  readComplianceCandidate,
33
36
  type ComplianceDecision,
34
37
  } from "../compliance-transport.ts";
38
+ // COMPLIANCE_RESPONSE_ENTRY_TYPE remains for boundRetainedAuditResponse (call/result
39
+ // interval binding on historical session bytes). Provider-stop retain authority is Sitian.
35
40
  import {
36
41
  COLLECTOR_OBSERVE_TOOL,
37
42
  COLLECTOR_REQUEST_TOOL,
@@ -93,6 +98,12 @@ import {
93
98
  } from "../navigator-invocation-identity.ts";
94
99
  import type { NavigatorPhase } from "../navigator-attendance.ts";
95
100
  import { NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, parseNoReceiptLifecycleFacts, type NoReceiptLifecycleFacts } from "../receipt-delivery-policy.ts";
101
+ import type {
102
+ DurablePrincipal,
103
+ DurablePrincipalAuthority,
104
+ DurablePrincipalCoordinates,
105
+ } from "../host-contracts.ts";
106
+ import { decodePiDurablePrincipal } from "../pi/durable-principal.ts";
96
107
  import {
97
108
  ensureRunArtifactsDir,
98
109
  type AdmittedCoderInvocation,
@@ -105,6 +116,14 @@ import {
105
116
  type AdmittedReviewerInvocation,
106
117
  type AdmittedRoleInvocation,
107
118
  } from "./invocation.ts";
119
+
120
+ /** Settlement path reads go through the host decode accessor only. */
121
+ function coordinatesFromAdmitted(
122
+ authority: DurablePrincipalAuthority,
123
+ admitted: { readonly principal: DurablePrincipal },
124
+ ): DurablePrincipalCoordinates {
125
+ return decodePiDurablePrincipal(authority, admitted.principal);
126
+ }
108
127
  import {
109
128
  exitCodeForTerminalOutcome,
110
129
  formatTerminalResult,
@@ -445,7 +464,7 @@ export function classifyPostAdmissionFailure(input: {
445
464
 
446
465
  /** One projection owner for the four audited public runners. */
447
466
  export function explicitInternalKnownFailureClassificationInput(
448
- failure: ExplicitInternalKnownFailure | undefined,
467
+ failure: RoleTurnKnownFailure | undefined,
449
468
  ) {
450
469
  if (failure === undefined) return {};
451
470
  return {
@@ -634,8 +653,9 @@ export function extractSessionProviderStop(
634
653
  entries: readonly SessionEntry[],
635
654
  ): SessionProviderStop | undefined {
636
655
  // A resumed dispatch appends a typed top-level user turn to the same session.
637
- // Retained audit state from an older attempt must not replace the newer attempt's
638
- // native provider stop. Sessions without a user turn are the initial attempt.
656
+ // Older attempt native stops must not replace the newer attempt's stop.
657
+ // Sessions without a user turn are the initial attempt.
658
+ // Auditor retained responses live in Sitian (kind=auditor); see readSessionProviderStop.
639
659
  let attemptStart = 0;
640
660
  for (let i = entries.length - 1; i >= 0; i -= 1) {
641
661
  const entry = entries[i];
@@ -645,17 +665,6 @@ export function extractSessionProviderStop(
645
665
  }
646
666
  }
647
667
 
648
- // The shared auditor is a nested model turn. Within the current attempt its
649
- // retained typed response is authoritative when failInfrastructure subsequently
650
- // aborts the parent turn.
651
- for (let i = entries.length - 1; i >= attemptStart; i -= 1) {
652
- const entry = entries[i];
653
- if (entry?.type !== "custom" || entry.customType !== COMPLIANCE_RESPONSE_ENTRY_TYPE) continue;
654
- const response = isRecord(entry.data) && isRecord(entry.data.response) ? entry.data.response : undefined;
655
- const stop = sessionProviderStopFromAssistant(response);
656
- if (stop !== undefined) return stop;
657
- break;
658
- }
659
668
  for (let i = entries.length - 1; i >= attemptStart; i -= 1) {
660
669
  const entry = entries[i];
661
670
  if (entry?.type !== "message") continue;
@@ -667,10 +676,46 @@ export function extractSessionProviderStop(
667
676
  return undefined;
668
677
  }
669
678
 
670
- /** Read the bound session principal and extract a typed provider-stop, if any. */
679
+ /**
680
+ * Latest Sitian-retained auditor response stop for this parent session principal.
681
+ * Writer: retainComplianceResponse → sitianReport(kind=auditor, payload={version,response}).
682
+ * Payload stopReason is preserved as retained — aborted stays aborted; no 500/error wash here.
683
+ */
684
+ async function readSitianRetainedAuditorProviderStop(
685
+ sessionFile: string,
686
+ ): Promise<SessionProviderStop | undefined> {
687
+ try {
688
+ const { recordFile } = resolveSitianRecordPath({
689
+ level: "event",
690
+ kind: "auditor",
691
+ sessionParent: sessionFile,
692
+ // Path is driven by sessionParent when under ledger home; cwd is a fallback only.
693
+ cwd: dirname(sessionFile),
694
+ });
695
+ const { records } = await readSitianRecords(recordFile);
696
+ for (let i = records.length - 1; i >= 0; i -= 1) {
697
+ const payload = records[i]?.payload;
698
+ if (!isRecord(payload) || !isRecord(payload.response)) continue;
699
+ // Lifecycle events carry `type` (binding / compliance_failure); retain does not.
700
+ if (typeof payload.type === "string") continue;
701
+ const stop = sessionProviderStopFromAssistant(payload.response as SessionMessage);
702
+ if (stop !== undefined) return stop;
703
+ // Latest retain exists but is not a provider-stop — do not scan older retains
704
+ // (mirrors former session COMPLIANCE_RESPONSE preference break).
705
+ break;
706
+ }
707
+ } catch {
708
+ // Missing volume or unreadable path is absence, not a settlement failure.
709
+ }
710
+ return undefined;
711
+ }
712
+
713
+ /** Read retained auditor stop (Sitian) then native session assistant stop, if any. */
671
714
  export async function readSessionProviderStop(
672
715
  sessionFile: string,
673
716
  ): Promise<SessionProviderStop | undefined> {
717
+ const retained = await readSitianRetainedAuditorProviderStop(sessionFile);
718
+ if (retained !== undefined) return retained;
674
719
  try {
675
720
  const entries = await readBoundSessionEntries(sessionFile);
676
721
  return extractSessionProviderStop(entries);
@@ -686,7 +731,7 @@ export async function readSessionProviderStop(
686
731
  */
687
732
  export async function readBoundEvidenceChildKnownFailure(
688
733
  sessionFile: string,
689
- ): Promise<ExplicitInternalKnownFailure | undefined> {
734
+ ): Promise<RoleTurnKnownFailure | undefined> {
690
735
  const childDirectory = join(dirname(sessionFile), "evidence-children");
691
736
  let names: string[];
692
737
  try {
@@ -796,7 +841,7 @@ async function loadBoundAuditorVolumes(
796
841
 
797
842
  function complianceFailureFromAuditorVolumes(
798
843
  volumes: readonly BoundAuditorVolume[],
799
- ): ExplicitInternalKnownFailure | undefined {
844
+ ): RoleTurnKnownFailure | undefined {
800
845
  for (const { entries, attemptEntryId, parentId, sessionFile } of volumes) {
801
846
  const stop = extractSessionProviderStop(entries);
802
847
  if (stop === undefined) continue;
@@ -823,7 +868,7 @@ function complianceFailureFromAuditorVolumes(
823
868
 
824
869
  function providerStopFallbackFromAuditorVolumes(
825
870
  volumes: readonly BoundAuditorVolume[],
826
- ): ExplicitInternalKnownFailure | undefined {
871
+ ): RoleTurnKnownFailure | undefined {
827
872
  for (const { entries } of volumes) {
828
873
  const stop = extractSessionProviderStop(entries);
829
874
  if (stop === undefined) continue;
@@ -842,7 +887,7 @@ function providerStopFallbackFromAuditorVolumes(
842
887
  /** Recover a provider stop from the auditor child bound to the current parent attempt. */
843
888
  export async function readBoundAuditorKnownFailure(
844
889
  sessionFile: string,
845
- ): Promise<ExplicitInternalKnownFailure | undefined> {
890
+ ): Promise<RoleTurnKnownFailure | undefined> {
846
891
  const volumes = await loadBoundAuditorVolumes(sessionFile);
847
892
  if (volumes === undefined) return undefined;
848
893
  return complianceFailureFromAuditorVolumes(volumes)
@@ -852,7 +897,7 @@ export async function readBoundAuditorKnownFailure(
852
897
  /** Strong auditor tier only — retained compliance-failure entries, no provider-stop fallback. */
853
898
  async function readBoundAuditorComplianceFailure(
854
899
  sessionFile: string,
855
- ): Promise<ExplicitInternalKnownFailure | undefined> {
900
+ ): Promise<RoleTurnKnownFailure | undefined> {
856
901
  const volumes = await loadBoundAuditorVolumes(sessionFile);
857
902
  if (volumes === undefined) return undefined;
858
903
  return complianceFailureFromAuditorVolumes(volumes);
@@ -861,7 +906,7 @@ async function readBoundAuditorComplianceFailure(
861
906
  /** Weaker auditor tier: provider stop without a retained compliance-failure entry. */
862
907
  async function readBoundAuditorProviderStopFallback(
863
908
  sessionFile: string,
864
- ): Promise<ExplicitInternalKnownFailure | undefined> {
909
+ ): Promise<RoleTurnKnownFailure | undefined> {
865
910
  const volumes = await loadBoundAuditorVolumes(sessionFile);
866
911
  if (volumes === undefined) return undefined;
867
912
  return providerStopFallbackFromAuditorVolumes(volumes);
@@ -869,7 +914,7 @@ async function readBoundAuditorProviderStopFallback(
869
914
 
870
915
  function typedFailedTerminatingToolKnownFailure(
871
916
  entries: readonly SessionEntry[],
872
- ): ExplicitInternalKnownFailure | undefined {
917
+ ): RoleTurnKnownFailure | undefined {
873
918
  let attemptStart = 0;
874
919
  for (let i = entries.length - 1; i >= 0; i -= 1) {
875
920
  if (entries[i]?.type === "message" && entries[i]?.message?.role === "user") {
@@ -908,7 +953,7 @@ function typedFailedTerminatingToolKnownFailure(
908
953
  * never re-read the sidecar in presentControlledFailure.
909
954
  */
910
955
  export type AuditedRunnerFailureResolution = {
911
- readonly knownFailure?: ExplicitInternalKnownFailure;
956
+ readonly knownFailure?: RoleTurnKnownFailure;
912
957
  /** Successful sidecar read (not absence). */
913
958
  readonly typedHttpObservation?: TypedProviderHttpObservation;
914
959
  /**
@@ -920,7 +965,7 @@ export type AuditedRunnerFailureResolution = {
920
965
  };
921
966
 
922
967
  function resolutionOf(
923
- knownFailure: ExplicitInternalKnownFailure | undefined,
968
+ knownFailure: RoleTurnKnownFailure | undefined,
924
969
  typedHttp: {
925
970
  readonly settled: boolean;
926
971
  readonly observation?: TypedProviderHttpObservation;
@@ -935,9 +980,9 @@ function resolutionOf(
935
980
 
936
981
  /** Sole evidence-priority owner for public runners with Soul auditors. */
937
982
  export async function resolveAuditedRunnerFailureResolution(input: {
938
- runner: ExplicitInternalKnownFailure | undefined;
983
+ runner: RoleTurnKnownFailure | undefined;
939
984
  sessionFile: string;
940
- credential: ExplicitInternalKnownFailure | undefined;
985
+ credential: RoleTurnKnownFailure | undefined;
941
986
  /** Reviewer only: recover child-written rejection page into knownFailure.details. */
942
987
  runDirectory?: string;
943
988
  }): Promise<AuditedRunnerFailureResolution> {
@@ -1063,12 +1108,12 @@ export async function resolveAuditedRunnerFailureResolution(input: {
1063
1108
 
1064
1109
  /** Sole evidence-priority owner for public runners with Soul auditors. */
1065
1110
  export async function resolveAuditedRunnerKnownFailure(input: {
1066
- runner: ExplicitInternalKnownFailure | undefined;
1111
+ runner: RoleTurnKnownFailure | undefined;
1067
1112
  sessionFile: string;
1068
- credential: ExplicitInternalKnownFailure | undefined;
1113
+ credential: RoleTurnKnownFailure | undefined;
1069
1114
  /** Reviewer only: recover child-written rejection page into knownFailure.details. */
1070
1115
  runDirectory?: string;
1071
- }): Promise<ExplicitInternalKnownFailure | undefined> {
1116
+ }): Promise<RoleTurnKnownFailure | undefined> {
1072
1117
  return (await resolveAuditedRunnerFailureResolution(input)).knownFailure;
1073
1118
  }
1074
1119
 
@@ -1084,7 +1129,7 @@ export async function resolveControlledFailureResumeObservation(input: {
1084
1129
  readonly typedHttpObservation?: TypedProviderHttpObservation;
1085
1130
  }): Promise<{
1086
1131
  readonly typedHttp429?: TypedHttp429Observation;
1087
- readonly observationReadFailure?: ExplicitInternalKnownFailure;
1132
+ readonly observationReadFailure?: RoleTurnKnownFailure;
1088
1133
  }> {
1089
1134
  if (input.typedHttpObservationSettled === true) {
1090
1135
  const observation = input.typedHttpObservation;
@@ -1118,7 +1163,7 @@ export async function resolveControlledFailureResumeObservation(input: {
1118
1163
  export function controlledFailureInputFromResolution(
1119
1164
  resolution: AuditedRunnerFailureResolution,
1120
1165
  ): {
1121
- knownFailure?: ExplicitInternalKnownFailure;
1166
+ knownFailure?: RoleTurnKnownFailure;
1122
1167
  typedHttpObservationSettled?: true;
1123
1168
  typedHttpObservation?: TypedProviderHttpObservation;
1124
1169
  } {
@@ -1815,10 +1860,10 @@ type AttemptHistorySource = {
1815
1860
  * the history entry backing the overwrite did not land (fail closed).
1816
1861
  */
1817
1862
  export async function appendRunAttemptHistory(
1818
- admitted: AttemptHistorySource,
1863
+ source: AttemptHistorySource,
1819
1864
  outcome: AttemptHistoryOutcome,
1820
1865
  ): Promise<void> {
1821
- const entries = await readBoundSessionEntries(admitted.sessionFile);
1866
+ const entries = await readBoundSessionEntries(source.sessionFile);
1822
1867
  let parentId: string | null = null;
1823
1868
  let priorEntries = 0;
1824
1869
  for (const entry of entries) {
@@ -1831,22 +1876,35 @@ export async function appendRunAttemptHistory(
1831
1876
  }
1832
1877
  }
1833
1878
  const timestamp = new Date().toISOString();
1834
- // Shape mirrors pi SessionManager.appendCustomEntry.
1879
+ const attemptData = {
1880
+ sequence: priorEntries + 1,
1881
+ role: source.role,
1882
+ runId: source.runId,
1883
+ recordedAt: timestamp,
1884
+ outcome,
1885
+ };
1835
1886
  const line = `${JSON.stringify({
1836
1887
  type: "custom",
1837
1888
  customType: ATTEMPT_HISTORY_ENTRY_TYPE,
1838
- data: {
1839
- sequence: priorEntries + 1,
1840
- role: admitted.role,
1841
- runId: admitted.runId,
1842
- recordedAt: timestamp,
1843
- outcome,
1844
- },
1889
+ data: attemptData,
1845
1890
  id: randomUUID(),
1846
1891
  parentId,
1847
1892
  timestamp,
1848
1893
  })}\n`;
1849
- await appendFile(admitted.sessionFile, line, "utf8");
1894
+ await appendFile(source.sessionFile, line, "utf8");
1895
+ try {
1896
+ sitianReport({
1897
+ level: "event",
1898
+ kind: "attempt-history",
1899
+ subject: { runId: source.runId },
1900
+ sessionParent: source.sessionFile,
1901
+ payload: {
1902
+ type: ATTEMPT_HISTORY_ENTRY_TYPE,
1903
+ ...attemptData,
1904
+ },
1905
+ source: "settlement",
1906
+ });
1907
+ } catch {}
1850
1908
  }
1851
1909
 
1852
1910
  /** Lawful Judge outcomes extracted from session (never a fabricated failure Receipt). */
@@ -2157,10 +2215,10 @@ export function extractNavigatorFact(
2157
2215
  * so the controlled-failure Terminal itself still settles.
2158
2216
  */
2159
2217
  async function extractNavigatorFactFromAdmittedSession(
2160
- admitted: AdmittedRoleInvocation,
2218
+ sessionFile: string,
2161
2219
  ): Promise<TerminalNavigatorFact> {
2162
2220
  try {
2163
- const entries = await readBoundSessionEntries(admitted.sessionFile);
2221
+ const entries = await readBoundSessionEntries(sessionFile);
2164
2222
  return extractNavigatorFact(entries);
2165
2223
  } catch (error) {
2166
2224
  if (isMissingPathError(error)) {
@@ -2181,11 +2239,11 @@ async function extractNavigatorFactFromAdmittedSession(
2181
2239
  export async function publishJudgeArtifacts(
2182
2240
  admitted: AdmittedJudgeInvocation,
2183
2241
  roleOutcome: TerminalRoleOutcome,
2184
- sessionDirectory: string,
2242
+ coordinates: DurablePrincipalCoordinates,
2185
2243
  ): Promise<TerminalArtifactRef[]> {
2186
2244
  // #419: history first — report/evidence stay last-write-wins views only
2187
2245
  // because every attempt's complete result has already been appended.
2188
- await appendRunAttemptHistory(admitted, roleOutcome);
2246
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
2189
2247
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
2190
2248
  const reportPath = join(artifactsDir, "report.json");
2191
2249
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -2207,8 +2265,8 @@ export async function publishJudgeArtifacts(
2207
2265
  `${JSON.stringify(
2208
2266
  {
2209
2267
  runId: admitted.runId,
2210
- sessionDirectory,
2211
- sessionFile: admitted.sessionFile,
2268
+ sessionDirectory: coordinates.sessionDirectory,
2269
+ sessionFile: coordinates.sessionFile,
2212
2270
  admittedRequestPath: admitted.admittedRequestPath,
2213
2271
  attachments: admitted.attachments.map((a) => ({
2214
2272
  provenancePath: a.provenancePath,
@@ -2235,13 +2293,13 @@ export async function publishJudgeArtifacts(
2235
2293
  export async function publishCoderArtifacts(
2236
2294
  admitted: AdmittedCoderInvocation,
2237
2295
  roleOutcome: TerminalRoleOutcome,
2238
- sessionDirectory: string,
2296
+ coordinates: DurablePrincipalCoordinates,
2239
2297
  options: {
2240
2298
  readonly methodProvenance?: PackagedMethodSkillProvenance;
2241
2299
  readonly coderOutput?: CoderOutput;
2242
2300
  } = {},
2243
2301
  ): Promise<TerminalArtifactRef[]> {
2244
- await appendRunAttemptHistory(admitted, roleOutcome);
2302
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
2245
2303
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
2246
2304
  const reportPath = join(artifactsDir, "report.json");
2247
2305
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -2269,8 +2327,8 @@ export async function publishCoderArtifacts(
2269
2327
  runId: admitted.runId,
2270
2328
  role: "coder",
2271
2329
  phase: admitted.phase,
2272
- sessionDirectory,
2273
- sessionFile: admitted.sessionFile,
2330
+ sessionDirectory: coordinates.sessionDirectory,
2331
+ sessionFile: coordinates.sessionFile,
2274
2332
  admittedRequestPath: admitted.admittedRequestPath,
2275
2333
  taskPath: admitted.taskPath,
2276
2334
  attachments: admitted.attachments.map((a) => ({
@@ -2335,10 +2393,10 @@ export function extractCoderRoleOutcome(
2335
2393
  * Malformed JSONL / other read failures throw with knownCause=session.
2336
2394
  */
2337
2395
  async function readLawfulSettlementEntries(
2338
- admitted: AdmittedRoleInvocation,
2396
+ sessionFile: string,
2339
2397
  ): Promise<SessionEntry[] | undefined> {
2340
2398
  try {
2341
- return await readBoundSessionEntries(admitted.sessionFile);
2399
+ return await readBoundSessionEntries(sessionFile);
2342
2400
  } catch (error) {
2343
2401
  // Missing path is absence of a lawful outcome; callers classify via session inspect.
2344
2402
  if (isMissingPathError(error)) return undefined;
@@ -2357,8 +2415,10 @@ async function readLawfulSettlementEntries(
2357
2415
  */
2358
2416
  export async function readLawfulJudgeRoleOutcome(
2359
2417
  admitted: AdmittedJudgeInvocation,
2418
+ authority: DurablePrincipalAuthority,
2360
2419
  ): Promise<LawfulJudgeRoleOutcome | undefined> {
2361
- const entries = await readLawfulSettlementEntries(admitted);
2420
+ const { sessionFile } = coordinatesFromAdmitted(authority, admitted);
2421
+ const entries = await readLawfulSettlementEntries(sessionFile);
2362
2422
  if (entries === undefined) return undefined;
2363
2423
  return extractJudgeRoleOutcome(entries);
2364
2424
  }
@@ -2370,9 +2430,10 @@ export async function readLawfulJudgeRoleOutcome(
2370
2430
  */
2371
2431
  export async function hasLawfulJudgeTerminalResult(
2372
2432
  admitted: AdmittedJudgeInvocation,
2433
+ authority: DurablePrincipalAuthority,
2373
2434
  ): Promise<boolean> {
2374
2435
  try {
2375
- const outcome = await readLawfulJudgeRoleOutcome(admitted);
2436
+ const outcome = await readLawfulJudgeRoleOutcome(admitted, authority);
2376
2437
  return outcome !== undefined && isLawfulTypedTerminalOutcome(outcome);
2377
2438
  } catch {
2378
2439
  return false;
@@ -2392,8 +2453,10 @@ export async function hasLawfulJudgeTerminalResult(
2392
2453
  */
2393
2454
  async function settleLawfulJudgeTerminalResult(
2394
2455
  admitted: AdmittedJudgeInvocation,
2456
+ authority: DurablePrincipalAuthority,
2395
2457
  ): Promise<TerminalResult | undefined> {
2396
- const entries = await readLawfulSettlementEntries(admitted);
2458
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
2459
+ const entries = await readLawfulSettlementEntries(coordinates.sessionFile);
2397
2460
  if (entries === undefined) return undefined;
2398
2461
  const roleOutcome = extractJudgeRoleOutcome(entries);
2399
2462
  if (roleOutcome === undefined) {
@@ -2404,7 +2467,7 @@ async function settleLawfulJudgeTerminalResult(
2404
2467
  const artifacts = await publishJudgeArtifacts(
2405
2468
  admitted,
2406
2469
  roleOutcome,
2407
- admitted.sessionDirectory,
2470
+ coordinates,
2408
2471
  );
2409
2472
  return withOptionalGateProjection(
2410
2473
  {
@@ -2413,7 +2476,7 @@ async function settleLawfulJudgeTerminalResult(
2413
2476
  artifacts,
2414
2477
  runId: admitted.runId,
2415
2478
  },
2416
- admitted.sessionDirectory,
2479
+ coordinates.sessionDirectory,
2417
2480
  );
2418
2481
  }
2419
2482
 
@@ -2424,8 +2487,9 @@ async function settleLawfulJudgeTerminalResult(
2424
2487
  */
2425
2488
  export async function settleJudgeTerminalResult(
2426
2489
  admitted: AdmittedJudgeInvocation,
2490
+ authority: DurablePrincipalAuthority,
2427
2491
  ): Promise<TerminalResult> {
2428
- const settled = await settleLawfulJudgeTerminalResult(admitted);
2492
+ const settled = await settleLawfulJudgeTerminalResult(admitted, authority);
2429
2493
  if (settled === undefined) {
2430
2494
  throw new Error(
2431
2495
  "Judge Role run completed without a lawful typed terminal result",
@@ -2441,17 +2505,20 @@ export async function settleJudgeTerminalResult(
2441
2505
  */
2442
2506
  export async function trySettleJudgeTerminalResult(
2443
2507
  admitted: AdmittedJudgeInvocation,
2508
+ authority: DurablePrincipalAuthority,
2444
2509
  ): Promise<TerminalResult | undefined> {
2445
- return settleLawfulJudgeTerminalResult(admitted);
2510
+ return settleLawfulJudgeTerminalResult(admitted, authority);
2446
2511
  }
2447
2512
 
2448
2513
  async function settleLawfulCoderTerminalResult(
2449
2514
  admitted: AdmittedCoderInvocation,
2515
+ authority: DurablePrincipalAuthority,
2450
2516
  options: {
2451
2517
  readonly methodProvenance?: PackagedMethodSkillProvenance;
2452
2518
  } = {},
2453
2519
  ): Promise<TerminalResult | undefined> {
2454
- const entries = await readLawfulSettlementEntries(admitted);
2520
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
2521
+ const entries = await readLawfulSettlementEntries(coordinates.sessionFile);
2455
2522
  if (entries === undefined) return undefined;
2456
2523
  const extracted = extractCoderRoleOutcome(entries);
2457
2524
  if (extracted === undefined) return undefined;
@@ -2459,7 +2526,7 @@ async function settleLawfulCoderTerminalResult(
2459
2526
  const artifacts = await publishCoderArtifacts(
2460
2527
  admitted,
2461
2528
  extracted.outcome,
2462
- admitted.sessionDirectory,
2529
+ coordinates,
2463
2530
  {
2464
2531
  coderOutput: extracted.output,
2465
2532
  ...(options.methodProvenance === undefined
@@ -2474,18 +2541,19 @@ async function settleLawfulCoderTerminalResult(
2474
2541
  artifacts,
2475
2542
  runId: admitted.runId,
2476
2543
  },
2477
- admitted.sessionDirectory,
2544
+ coordinates.sessionDirectory,
2478
2545
  );
2479
2546
  }
2480
2547
 
2481
2548
  /** Settle a lawful Coder Terminal from the admitted session (shared #106 success interface). */
2482
2549
  export async function settleCoderTerminalResult(
2483
2550
  admitted: AdmittedCoderInvocation,
2551
+ authority: DurablePrincipalAuthority,
2484
2552
  options: {
2485
2553
  readonly methodProvenance?: PackagedMethodSkillProvenance;
2486
2554
  } = {},
2487
2555
  ): Promise<TerminalResult> {
2488
- const settled = await settleLawfulCoderTerminalResult(admitted, options);
2556
+ const settled = await settleLawfulCoderTerminalResult(admitted, authority, options);
2489
2557
  if (settled === undefined) {
2490
2558
  throw new Error(
2491
2559
  "Coder Role run completed without a lawful typed terminal result",
@@ -2546,14 +2614,14 @@ export function extractFixerMethodInvocations(
2546
2614
  export async function publishFixerArtifacts(
2547
2615
  admitted: AdmittedFixerInvocation,
2548
2616
  roleOutcome: TerminalRoleOutcome,
2549
- sessionDirectory: string,
2617
+ coordinates: DurablePrincipalCoordinates,
2550
2618
  options: {
2551
2619
  readonly methodProvenance: PackagedMethodSkillProvenance;
2552
2620
  readonly methodInvocations?: readonly ObservedPackagedMethodSkillInvocation[];
2553
2621
  readonly fixerOutput?: FixerOutput;
2554
2622
  },
2555
2623
  ): Promise<TerminalArtifactRef[]> {
2556
- await appendRunAttemptHistory(admitted, roleOutcome);
2624
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
2557
2625
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
2558
2626
  const reportPath = join(artifactsDir, "report.json");
2559
2627
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -2581,8 +2649,8 @@ export async function publishFixerArtifacts(
2581
2649
  runId: admitted.runId,
2582
2650
  role: "fixer",
2583
2651
  phase: admitted.phase,
2584
- sessionDirectory,
2585
- sessionFile: admitted.sessionFile,
2652
+ sessionDirectory: coordinates.sessionDirectory,
2653
+ sessionFile: coordinates.sessionFile,
2586
2654
  admittedRequestPath: admitted.admittedRequestPath,
2587
2655
  packetPath: admitted.packetPath,
2588
2656
  ...(admitted.prerequisitesPath === undefined
@@ -2652,13 +2720,16 @@ export function extractFixerRoleOutcome(
2652
2720
 
2653
2721
  async function settleLawfulFixerTerminalResult(
2654
2722
  admitted: AdmittedFixerInvocation,
2723
+ authority: DurablePrincipalAuthority,
2655
2724
  options: {
2656
2725
  readonly methodProvenance: PackagedMethodSkillProvenance;
2657
2726
  readonly methodSkillPath: string;
2658
2727
  readonly methodSkillConfiguredPath: string;
2659
2728
  },
2660
2729
  ): Promise<TerminalResult | undefined> {
2661
- const entries = await readLawfulSettlementEntries(admitted);
2730
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
2731
+ const { sessionDirectory, sessionFile } = coordinates;
2732
+ const entries = await readLawfulSettlementEntries(sessionFile);
2662
2733
  if (entries === undefined) return undefined;
2663
2734
  const extracted = extractFixerRoleOutcome(entries);
2664
2735
  if (extracted === undefined) return undefined;
@@ -2672,7 +2743,7 @@ async function settleLawfulFixerTerminalResult(
2672
2743
  const artifacts = await publishFixerArtifacts(
2673
2744
  admitted,
2674
2745
  extracted.outcome,
2675
- admitted.sessionDirectory,
2746
+ coordinates,
2676
2747
  {
2677
2748
  ...(extracted.output === undefined ? {} : { fixerOutput: extracted.output }),
2678
2749
  methodProvenance: options.methodProvenance,
@@ -2686,20 +2757,21 @@ async function settleLawfulFixerTerminalResult(
2686
2757
  artifacts,
2687
2758
  runId: admitted.runId,
2688
2759
  },
2689
- admitted.sessionDirectory,
2760
+ sessionDirectory,
2690
2761
  );
2691
2762
  }
2692
2763
 
2693
2764
  /** Settle a lawful Fixer Terminal from the admitted session (shared #106 success interface). */
2694
2765
  export async function settleFixerTerminalResult(
2695
2766
  admitted: AdmittedFixerInvocation,
2767
+ authority: DurablePrincipalAuthority,
2696
2768
  options: {
2697
2769
  readonly methodProvenance: PackagedMethodSkillProvenance;
2698
2770
  readonly methodSkillPath: string;
2699
2771
  readonly methodSkillConfiguredPath: string;
2700
2772
  },
2701
2773
  ): Promise<TerminalResult> {
2702
- const settled = await settleLawfulFixerTerminalResult(admitted, options);
2774
+ const settled = await settleLawfulFixerTerminalResult(admitted, authority, options);
2703
2775
  if (settled === undefined) {
2704
2776
  throw new Error(
2705
2777
  "Fixer Role run completed without a lawful typed terminal result",
@@ -2711,12 +2783,12 @@ export async function settleFixerTerminalResult(
2711
2783
  export async function publishCollectorArtifacts(
2712
2784
  admitted: AdmittedCollectorInvocation,
2713
2785
  roleOutcome: TerminalRoleOutcome,
2714
- sessionDirectory: string,
2786
+ coordinates: DurablePrincipalCoordinates,
2715
2787
  options: {
2716
2788
  readonly collectorReceipt?: CollectorReceipt;
2717
2789
  } = {},
2718
2790
  ): Promise<TerminalArtifactRef[]> {
2719
- await appendRunAttemptHistory(admitted, roleOutcome);
2791
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
2720
2792
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
2721
2793
  const reportPath = join(artifactsDir, "report.json");
2722
2794
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -2745,8 +2817,8 @@ export async function publishCollectorArtifacts(
2745
2817
  prNumber: admitted.prNumber,
2746
2818
  repository: admitted.repository.canonical,
2747
2819
  manifestDigest: admitted.manifestDigest,
2748
- sessionDirectory,
2749
- sessionFile: admitted.sessionFile,
2820
+ sessionDirectory: coordinates.sessionDirectory,
2821
+ sessionFile: coordinates.sessionFile,
2750
2822
  admittedRequestPath: admitted.admittedRequestPath,
2751
2823
  attachments: admitted.attachments.map((a) => ({
2752
2824
  provenancePath: a.provenancePath,
@@ -2804,8 +2876,11 @@ export function extractCollectorRoleOutcome(
2804
2876
 
2805
2877
  async function settleLawfulCollectorTerminalResult(
2806
2878
  admitted: AdmittedCollectorInvocation,
2879
+ authority: DurablePrincipalAuthority,
2807
2880
  ): Promise<TerminalResult | undefined> {
2808
- const entries = await readLawfulSettlementEntries(admitted);
2881
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
2882
+ const { sessionDirectory, sessionFile } = coordinates;
2883
+ const entries = await readLawfulSettlementEntries(sessionFile);
2809
2884
  if (entries === undefined) return undefined;
2810
2885
  const extracted = extractCollectorRoleOutcome(entries);
2811
2886
  if (extracted === undefined) {
@@ -2837,7 +2912,7 @@ async function settleLawfulCollectorTerminalResult(
2837
2912
  const artifacts = await publishCollectorArtifacts(
2838
2913
  admitted,
2839
2914
  extracted.outcome,
2840
- admitted.sessionDirectory,
2915
+ coordinates,
2841
2916
  { collectorReceipt: extracted.receipt },
2842
2917
  );
2843
2918
  return withOptionalGateProjection(
@@ -2847,15 +2922,16 @@ async function settleLawfulCollectorTerminalResult(
2847
2922
  artifacts,
2848
2923
  runId: admitted.runId,
2849
2924
  },
2850
- admitted.sessionDirectory,
2925
+ sessionDirectory,
2851
2926
  );
2852
2927
  }
2853
2928
 
2854
2929
  /** Settle a lawful Collector Terminal from the admitted session. */
2855
2930
  export async function settleCollectorTerminalResult(
2856
2931
  admitted: AdmittedCollectorInvocation,
2932
+ authority: DurablePrincipalAuthority,
2857
2933
  ): Promise<TerminalResult> {
2858
- const settled = await settleLawfulCollectorTerminalResult(admitted);
2934
+ const settled = await settleLawfulCollectorTerminalResult(admitted, authority);
2859
2935
  if (settled === undefined) {
2860
2936
  throw new Error(
2861
2937
  "Collector Role run completed without a lawful typed terminal result",
@@ -2867,19 +2943,20 @@ export async function settleCollectorTerminalResult(
2867
2943
  /** Try to settle a lawful Collector Terminal; undefined only for genuine absence. */
2868
2944
  export async function trySettleCollectorTerminalResult(
2869
2945
  admitted: AdmittedCollectorInvocation,
2946
+ authority: DurablePrincipalAuthority,
2870
2947
  ): Promise<TerminalResult | undefined> {
2871
- return settleLawfulCollectorTerminalResult(admitted);
2948
+ return settleLawfulCollectorTerminalResult(admitted, authority);
2872
2949
  }
2873
2950
 
2874
2951
  export async function publishDoctorArtifacts(
2875
2952
  admitted: AdmittedDoctorInvocation,
2876
2953
  roleOutcome: TerminalRoleOutcome,
2877
- sessionDirectory: string,
2954
+ coordinates: DurablePrincipalCoordinates,
2878
2955
  options: {
2879
2956
  readonly doctorOutput?: DoctorOutput;
2880
2957
  } = {},
2881
2958
  ): Promise<TerminalArtifactRef[]> {
2882
- await appendRunAttemptHistory(admitted, roleOutcome);
2959
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
2883
2960
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
2884
2961
  const reportPath = join(artifactsDir, "report.json");
2885
2962
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -2908,8 +2985,8 @@ export async function publishDoctorArtifacts(
2908
2985
  issueNumber: admitted.issueNumber,
2909
2986
  caseRunsPath: admitted.caseRunsPath,
2910
2987
  caseIdentity: admitted.caseIdentity,
2911
- sessionDirectory,
2912
- sessionFile: admitted.sessionFile,
2988
+ sessionDirectory: coordinates.sessionDirectory,
2989
+ sessionFile: coordinates.sessionFile,
2913
2990
  admittedRequestPath: admitted.admittedRequestPath,
2914
2991
  attachments: admitted.attachments.map((a) => ({
2915
2992
  provenancePath: a.provenancePath,
@@ -2992,8 +3069,11 @@ export function extractDoctorRoleOutcome(
2992
3069
 
2993
3070
  async function settleLawfulDoctorTerminalResult(
2994
3071
  admitted: AdmittedDoctorInvocation,
3072
+ authority: DurablePrincipalAuthority,
2995
3073
  ): Promise<TerminalResult | undefined> {
2996
- const entries = await readLawfulSettlementEntries(admitted);
3074
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3075
+ const { sessionDirectory, sessionFile } = coordinates;
3076
+ const entries = await readLawfulSettlementEntries(sessionFile);
2997
3077
  if (entries === undefined) return undefined;
2998
3078
  const extracted = extractDoctorRoleOutcome(entries);
2999
3079
  if (extracted === undefined) return undefined;
@@ -3023,7 +3103,7 @@ async function settleLawfulDoctorTerminalResult(
3023
3103
  const artifacts = await publishDoctorArtifacts(
3024
3104
  admitted,
3025
3105
  extracted.outcome,
3026
- admitted.sessionDirectory,
3106
+ coordinates,
3027
3107
  extracted.output === undefined ? {} : { doctorOutput: extracted.output },
3028
3108
  );
3029
3109
  return withOptionalGateProjection(
@@ -3033,15 +3113,16 @@ async function settleLawfulDoctorTerminalResult(
3033
3113
  artifacts,
3034
3114
  runId: admitted.runId,
3035
3115
  },
3036
- admitted.sessionDirectory,
3116
+ sessionDirectory,
3037
3117
  );
3038
3118
  }
3039
3119
 
3040
3120
  /** Settle a lawful Doctor Terminal from the admitted session. */
3041
3121
  export async function settleDoctorTerminalResult(
3042
3122
  admitted: AdmittedDoctorInvocation,
3123
+ authority: DurablePrincipalAuthority,
3043
3124
  ): Promise<TerminalResult> {
3044
- const settled = await settleLawfulDoctorTerminalResult(admitted);
3125
+ const settled = await settleLawfulDoctorTerminalResult(admitted, authority);
3045
3126
  if (settled === undefined) {
3046
3127
  throw new Error(
3047
3128
  "Doctor Role run completed without a lawful typed terminal result",
@@ -3053,8 +3134,9 @@ export async function settleDoctorTerminalResult(
3053
3134
  /** Try to settle a lawful Doctor Terminal; undefined only for genuine absence. */
3054
3135
  export async function trySettleDoctorTerminalResult(
3055
3136
  admitted: AdmittedDoctorInvocation,
3137
+ authority: DurablePrincipalAuthority,
3056
3138
  ): Promise<TerminalResult | undefined> {
3057
- return settleLawfulDoctorTerminalResult(admitted);
3139
+ return settleLawfulDoctorTerminalResult(admitted, authority);
3058
3140
  }
3059
3141
 
3060
3142
  /** Lawful Notary accepted outcome (pass/bounce). */
@@ -3094,8 +3176,11 @@ export function extractNotaryRoleOutcome(
3094
3176
 
3095
3177
  async function settleLawfulNotaryTerminalResult(
3096
3178
  admitted: AdmittedNotaryInvocation,
3179
+ authority: DurablePrincipalAuthority,
3097
3180
  ): Promise<TerminalResult | undefined> {
3098
- const entries = await readLawfulSettlementEntries(admitted);
3181
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3182
+ const { sessionDirectory, sessionFile } = coordinates;
3183
+ const entries = await readLawfulSettlementEntries(sessionFile);
3099
3184
  if (entries === undefined) return undefined;
3100
3185
  const extracted = extractNotaryRoleOutcome(entries);
3101
3186
  if (extracted === undefined) {
@@ -3116,7 +3201,7 @@ async function settleLawfulNotaryTerminalResult(
3116
3201
  cause: "output",
3117
3202
  diagnostic: residual.diagnostic,
3118
3203
  details: { candidate: residual.candidate, acceptedReceipt: false },
3119
- });
3204
+ }, authority);
3120
3205
  }
3121
3206
  if (
3122
3207
  acceptedNonUsable === undefined &&
@@ -3136,7 +3221,7 @@ async function settleLawfulNotaryTerminalResult(
3136
3221
  cause: "output",
3137
3222
  diagnostic: "符宝郎回执无显式 pass/bounce",
3138
3223
  details: { candidate: acceptedNonUsable, acceptedReceipt: false },
3139
- });
3224
+ }, authority);
3140
3225
  }
3141
3226
  return undefined;
3142
3227
  }
@@ -3148,15 +3233,16 @@ async function settleLawfulNotaryTerminalResult(
3148
3233
  artifacts: [],
3149
3234
  runId: admitted.runId,
3150
3235
  },
3151
- admitted.sessionDirectory,
3236
+ sessionDirectory,
3152
3237
  );
3153
3238
  }
3154
3239
 
3155
3240
  /** Settle a lawful Notary Terminal from the admitted session. */
3156
3241
  export async function settleNotaryTerminalResult(
3157
3242
  admitted: AdmittedNotaryInvocation,
3243
+ authority: DurablePrincipalAuthority,
3158
3244
  ): Promise<TerminalResult> {
3159
- const settled = await settleLawfulNotaryTerminalResult(admitted);
3245
+ const settled = await settleLawfulNotaryTerminalResult(admitted, authority);
3160
3246
  if (settled === undefined) {
3161
3247
  throw new Error(
3162
3248
  "Notary Role run completed without a lawful typed terminal result",
@@ -3168,25 +3254,30 @@ export async function settleNotaryTerminalResult(
3168
3254
  /** Try to settle a lawful Notary Terminal; undefined only for genuine absence. */
3169
3255
  export async function trySettleNotaryTerminalResult(
3170
3256
  admitted: AdmittedNotaryInvocation,
3257
+ authority: DurablePrincipalAuthority,
3171
3258
  ): Promise<TerminalResult | undefined> {
3172
- return settleLawfulNotaryTerminalResult(admitted);
3259
+ return settleLawfulNotaryTerminalResult(admitted, authority);
3173
3260
  }
3174
3261
 
3175
3262
  /** Try to settle a lawful Coder Terminal; undefined only for genuine absence. */
3176
3263
  export async function trySettleCoderTerminalResult(
3177
3264
  admitted: AdmittedCoderInvocation,
3265
+ authority: DurablePrincipalAuthority,
3178
3266
  options: {
3179
3267
  readonly methodProvenance?: PackagedMethodSkillProvenance;
3180
3268
  } = {},
3181
3269
  ): Promise<TerminalResult | undefined> {
3182
- return settleLawfulCoderTerminalResult(admitted, options);
3270
+ return settleLawfulCoderTerminalResult(admitted, authority, options);
3183
3271
  }
3184
3272
 
3185
3273
  export async function hasLawfulCoderTerminalResult(
3186
3274
  admitted: AdmittedCoderInvocation,
3275
+ authority: DurablePrincipalAuthority,
3187
3276
  ): Promise<boolean> {
3277
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3278
+ const { sessionDirectory, sessionFile } = coordinates;
3188
3279
  try {
3189
- const entries = await readLawfulSettlementEntries(admitted);
3280
+ const entries = await readLawfulSettlementEntries(sessionFile);
3190
3281
  if (entries === undefined) return false;
3191
3282
  const extracted = extractCoderRoleOutcome(entries);
3192
3283
  return extracted !== undefined && isLawfulTypedTerminalOutcome(extracted.outcome);
@@ -3198,20 +3289,24 @@ export async function hasLawfulCoderTerminalResult(
3198
3289
  /** Try to settle a lawful Fixer Terminal; undefined only for genuine absence. */
3199
3290
  export async function trySettleFixerTerminalResult(
3200
3291
  admitted: AdmittedFixerInvocation,
3292
+ authority: DurablePrincipalAuthority,
3201
3293
  options: {
3202
3294
  readonly methodProvenance: PackagedMethodSkillProvenance;
3203
3295
  readonly methodSkillPath: string;
3204
3296
  readonly methodSkillConfiguredPath: string;
3205
3297
  },
3206
3298
  ): Promise<TerminalResult | undefined> {
3207
- return settleLawfulFixerTerminalResult(admitted, options);
3299
+ return settleLawfulFixerTerminalResult(admitted, authority, options);
3208
3300
  }
3209
3301
 
3210
3302
  export async function hasLawfulFixerTerminalResult(
3211
3303
  admitted: AdmittedFixerInvocation,
3304
+ authority: DurablePrincipalAuthority,
3212
3305
  ): Promise<boolean> {
3306
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3307
+ const { sessionDirectory, sessionFile } = coordinates;
3213
3308
  try {
3214
- const entries = await readLawfulSettlementEntries(admitted);
3309
+ const entries = await readLawfulSettlementEntries(sessionFile);
3215
3310
  if (entries === undefined) return false;
3216
3311
  const extracted = extractFixerRoleOutcome(entries);
3217
3312
  return extracted !== undefined && isLawfulTypedTerminalOutcome(extracted.outcome);
@@ -3254,14 +3349,14 @@ export function extractReviewerMethodInvocations(
3254
3349
  export async function publishReviewerArtifacts(
3255
3350
  admitted: AdmittedReviewerInvocation,
3256
3351
  roleOutcome: TerminalRoleOutcome,
3257
- sessionDirectory: string,
3352
+ coordinates: DurablePrincipalCoordinates,
3258
3353
  options: {
3259
3354
  readonly methodProvenance: PackagedMethodSkillProvenance;
3260
3355
  readonly methodInvocations?: readonly ObservedPackagedMethodSkillInvocation[];
3261
3356
  readonly reviewerReceipt?: RuntimeReviewerReceiptV2;
3262
3357
  },
3263
3358
  ): Promise<TerminalArtifactRef[]> {
3264
- await appendRunAttemptHistory(admitted, roleOutcome);
3359
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
3265
3360
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
3266
3361
  const reportPath = join(artifactsDir, "report.json");
3267
3362
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -3287,8 +3382,8 @@ export async function publishReviewerArtifacts(
3287
3382
  {
3288
3383
  runId: admitted.runId,
3289
3384
  role: "reviewer",
3290
- sessionDirectory,
3291
- sessionFile: admitted.sessionFile,
3385
+ sessionDirectory: coordinates.sessionDirectory,
3386
+ sessionFile: coordinates.sessionFile,
3292
3387
  admittedRequestPath: admitted.admittedRequestPath,
3293
3388
  baseRevision: admitted.baseRevision,
3294
3389
  authorityRefs: [...admitted.authorityRefs],
@@ -3361,13 +3456,16 @@ export function extractReviewerRoleOutcome(
3361
3456
 
3362
3457
  async function settleLawfulReviewerTerminalResult(
3363
3458
  admitted: AdmittedReviewerInvocation,
3459
+ authority: DurablePrincipalAuthority,
3364
3460
  options: {
3365
3461
  readonly methodProvenance: PackagedMethodSkillProvenance;
3366
3462
  readonly methodSkillPath: string;
3367
3463
  readonly methodSkillConfiguredPath: string;
3368
3464
  },
3369
3465
  ): Promise<TerminalResult | undefined> {
3370
- const entries = await readLawfulSettlementEntries(admitted);
3466
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3467
+ const { sessionDirectory, sessionFile } = coordinates;
3468
+ const entries = await readLawfulSettlementEntries(sessionFile);
3371
3469
  if (entries === undefined) return undefined;
3372
3470
  const extracted = extractReviewerRoleOutcome(entries);
3373
3471
  if (extracted === undefined) return undefined;
@@ -3381,7 +3479,7 @@ async function settleLawfulReviewerTerminalResult(
3381
3479
  const artifacts = await publishReviewerArtifacts(
3382
3480
  admitted,
3383
3481
  extracted.outcome,
3384
- admitted.sessionDirectory,
3482
+ coordinates,
3385
3483
  {
3386
3484
  ...(extracted.receipt === undefined ? {} : { reviewerReceipt: extracted.receipt }),
3387
3485
  methodProvenance: options.methodProvenance,
@@ -3395,20 +3493,21 @@ async function settleLawfulReviewerTerminalResult(
3395
3493
  artifacts,
3396
3494
  runId: admitted.runId,
3397
3495
  },
3398
- admitted.sessionDirectory,
3496
+ sessionDirectory,
3399
3497
  );
3400
3498
  }
3401
3499
 
3402
3500
  /** Settle a lawful Reviewer Terminal from the admitted session (shared #106 success interface). */
3403
3501
  export async function settleReviewerTerminalResult(
3404
3502
  admitted: AdmittedReviewerInvocation,
3503
+ authority: DurablePrincipalAuthority,
3405
3504
  options: {
3406
3505
  readonly methodProvenance: PackagedMethodSkillProvenance;
3407
3506
  readonly methodSkillPath: string;
3408
3507
  readonly methodSkillConfiguredPath: string;
3409
3508
  },
3410
3509
  ): Promise<TerminalResult> {
3411
- const settled = await settleLawfulReviewerTerminalResult(admitted, options);
3510
+ const settled = await settleLawfulReviewerTerminalResult(admitted, authority, options);
3412
3511
  if (settled === undefined) {
3413
3512
  throw new Error(
3414
3513
  "Reviewer Role run completed without a lawful typed terminal result",
@@ -3420,20 +3519,24 @@ export async function settleReviewerTerminalResult(
3420
3519
  /** Try to settle a lawful Reviewer Terminal; undefined only for genuine absence. */
3421
3520
  export async function trySettleReviewerTerminalResult(
3422
3521
  admitted: AdmittedReviewerInvocation,
3522
+ authority: DurablePrincipalAuthority,
3423
3523
  options: {
3424
3524
  readonly methodProvenance: PackagedMethodSkillProvenance;
3425
3525
  readonly methodSkillPath: string;
3426
3526
  readonly methodSkillConfiguredPath: string;
3427
3527
  },
3428
3528
  ): Promise<TerminalResult | undefined> {
3429
- return settleLawfulReviewerTerminalResult(admitted, options);
3529
+ return settleLawfulReviewerTerminalResult(admitted, authority, options);
3430
3530
  }
3431
3531
 
3432
3532
  export async function hasLawfulReviewerTerminalResult(
3433
3533
  admitted: AdmittedReviewerInvocation,
3534
+ authority: DurablePrincipalAuthority,
3434
3535
  ): Promise<boolean> {
3536
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3537
+ const { sessionDirectory, sessionFile } = coordinates;
3435
3538
  try {
3436
- const entries = await readLawfulSettlementEntries(admitted);
3539
+ const entries = await readLawfulSettlementEntries(sessionFile);
3437
3540
  if (entries === undefined) return false;
3438
3541
  const extracted = extractReviewerRoleOutcome(entries);
3439
3542
  return extracted !== undefined && isLawfulTypedTerminalOutcome(extracted.outcome);
@@ -3493,14 +3596,14 @@ export function extractMergerMethodInvocations(
3493
3596
  export async function publishMergerArtifacts(
3494
3597
  admitted: AdmittedMergerInvocation,
3495
3598
  roleOutcome: TerminalRoleOutcome,
3496
- sessionDirectory: string,
3599
+ coordinates: DurablePrincipalCoordinates,
3497
3600
  options: {
3498
3601
  readonly methodProvenance: PackagedMethodSkillProvenance;
3499
3602
  readonly methodInvocations?: readonly ObservedPackagedMethodSkillInvocation[];
3500
3603
  readonly mergerOutput?: MergerOutput;
3501
3604
  },
3502
3605
  ): Promise<TerminalArtifactRef[]> {
3503
- await appendRunAttemptHistory(admitted, roleOutcome);
3606
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
3504
3607
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
3505
3608
  const reportPath = join(artifactsDir, "report.json");
3506
3609
  const evidencePath = join(artifactsDir, "evidence.json");
@@ -3526,8 +3629,8 @@ export async function publishMergerArtifacts(
3526
3629
  {
3527
3630
  runId: admitted.runId,
3528
3631
  role: "merger",
3529
- sessionDirectory,
3530
- sessionFile: admitted.sessionFile,
3632
+ sessionDirectory: coordinates.sessionDirectory,
3633
+ sessionFile: coordinates.sessionFile,
3531
3634
  admittedRequestPath: admitted.admittedRequestPath,
3532
3635
  mergerInputPath: admitted.mergerInputPath,
3533
3636
  derived: admitted.derived,
@@ -3589,13 +3692,16 @@ export function extractMergerRoleOutcome(
3589
3692
 
3590
3693
  async function settleLawfulMergerTerminalResult(
3591
3694
  admitted: AdmittedMergerInvocation,
3695
+ authority: DurablePrincipalAuthority,
3592
3696
  options: {
3593
3697
  readonly methodProvenance: PackagedMethodSkillProvenance;
3594
3698
  readonly methodSkillPath: string;
3595
3699
  readonly methodSkillConfiguredPath: string;
3596
3700
  },
3597
3701
  ): Promise<TerminalResult | undefined> {
3598
- const entries = await readLawfulSettlementEntries(admitted);
3702
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3703
+ const { sessionDirectory, sessionFile } = coordinates;
3704
+ const entries = await readLawfulSettlementEntries(sessionFile);
3599
3705
  if (entries === undefined) return undefined;
3600
3706
  const extracted = extractMergerRoleOutcome(entries);
3601
3707
  if (extracted === undefined) {
@@ -3650,7 +3756,7 @@ async function settleLawfulMergerTerminalResult(
3650
3756
  const artifacts = await publishMergerArtifacts(
3651
3757
  admitted,
3652
3758
  extracted.outcome,
3653
- admitted.sessionDirectory,
3759
+ coordinates,
3654
3760
  {
3655
3761
  mergerOutput: extracted.output,
3656
3762
  methodProvenance: options.methodProvenance,
@@ -3664,20 +3770,21 @@ async function settleLawfulMergerTerminalResult(
3664
3770
  artifacts,
3665
3771
  runId: admitted.runId,
3666
3772
  },
3667
- admitted.sessionDirectory,
3773
+ sessionDirectory,
3668
3774
  );
3669
3775
  }
3670
3776
 
3671
3777
  /** Settle a lawful Merger Terminal from the admitted session (shared #106 success interface). */
3672
3778
  export async function settleMergerTerminalResult(
3673
3779
  admitted: AdmittedMergerInvocation,
3780
+ authority: DurablePrincipalAuthority,
3674
3781
  options: {
3675
3782
  readonly methodProvenance: PackagedMethodSkillProvenance;
3676
3783
  readonly methodSkillPath: string;
3677
3784
  readonly methodSkillConfiguredPath: string;
3678
3785
  },
3679
3786
  ): Promise<TerminalResult> {
3680
- const settled = await settleLawfulMergerTerminalResult(admitted, options);
3787
+ const settled = await settleLawfulMergerTerminalResult(admitted, authority, options);
3681
3788
  if (settled === undefined) {
3682
3789
  throw new Error(
3683
3790
  "Merger Role run completed without a lawful typed terminal result",
@@ -3689,20 +3796,24 @@ export async function settleMergerTerminalResult(
3689
3796
  /** Try to settle a lawful Merger Terminal; undefined only for genuine absence. */
3690
3797
  export async function trySettleMergerTerminalResult(
3691
3798
  admitted: AdmittedMergerInvocation,
3799
+ authority: DurablePrincipalAuthority,
3692
3800
  options: {
3693
3801
  readonly methodProvenance: PackagedMethodSkillProvenance;
3694
3802
  readonly methodSkillPath: string;
3695
3803
  readonly methodSkillConfiguredPath: string;
3696
3804
  },
3697
3805
  ): Promise<TerminalResult | undefined> {
3698
- return settleLawfulMergerTerminalResult(admitted, options);
3806
+ return settleLawfulMergerTerminalResult(admitted, authority, options);
3699
3807
  }
3700
3808
 
3701
3809
  export async function hasLawfulMergerTerminalResult(
3702
3810
  admitted: AdmittedMergerInvocation,
3811
+ authority: DurablePrincipalAuthority,
3703
3812
  ): Promise<boolean> {
3813
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
3814
+ const { sessionDirectory, sessionFile } = coordinates;
3704
3815
  try {
3705
- const entries = await readLawfulSettlementEntries(admitted);
3816
+ const entries = await readLawfulSettlementEntries(sessionFile);
3706
3817
  if (entries === undefined) return false;
3707
3818
  const extracted = extractMergerRoleOutcome(entries);
3708
3819
  return extracted !== undefined && isLawfulTypedTerminalOutcome(extracted.outcome);
@@ -3832,7 +3943,9 @@ async function writeFailureJsonRetainingCause(
3832
3943
  export async function publishFailureArtifacts(
3833
3944
  admitted: AdmittedRoleInvocation,
3834
3945
  failure: ControlledFailure,
3946
+ authority: DurablePrincipalAuthority,
3835
3947
  ): Promise<TerminalArtifactRef[]> {
3948
+ const { sessionDirectory, sessionFile } = coordinatesFromAdmitted(authority, admitted);
3836
3949
  const { baseDir, attempt: baseAttempt } = await resolveFailureArtifactsBase(
3837
3950
  admitted.runDirectory,
3838
3951
  );
@@ -3843,13 +3956,13 @@ export async function publishFailureArtifacts(
3843
3956
  // strand the original controlled failure outside settlement — it rides
3844
3957
  // publicationIssues instead of aborting durability.
3845
3958
  try {
3846
- await appendRunAttemptHistory(admitted, {
3959
+ await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile }, {
3847
3960
  kind: "failure",
3848
3961
  role: admitted.role,
3849
3962
  ...failure,
3850
3963
  });
3851
3964
  } catch (error) {
3852
- priorIssues.push(publicationAttemptFromError(admitted.sessionFile, error));
3965
+ priorIssues.push(publicationAttemptFromError(sessionFile, error));
3853
3966
  }
3854
3967
 
3855
3968
  // Prefer conventional names; unique fallback dirs keep colliding fixed paths
@@ -3901,8 +4014,8 @@ export async function publishFailureArtifacts(
3901
4014
 
3902
4015
  const evidencePayload: Record<string, unknown> = {
3903
4016
  runId: admitted.runId,
3904
- sessionDirectory: admitted.sessionDirectory,
3905
- sessionFile: admitted.sessionFile,
4017
+ sessionDirectory: sessionDirectory,
4018
+ sessionFile: sessionFile,
3906
4019
  admittedRequestPath: admitted.admittedRequestPath,
3907
4020
  attachments: admitted.attachments.map((a) => ({
3908
4021
  provenancePath: a.provenancePath,
@@ -3995,13 +4108,16 @@ function redactNavigatorFactForPublicTerminal(
3995
4108
  export async function settleFailureTerminalResult(
3996
4109
  admitted: AdmittedRoleInvocation,
3997
4110
  failure: ControlledFailure,
4111
+ authority: DurablePrincipalAuthority,
3998
4112
  options: { readonly resume?: TerminalResume } = {},
3999
4113
  ): Promise<TerminalResult> {
4114
+ const coordinates = coordinatesFromAdmitted(authority, admitted);
4115
+ const { sessionDirectory, sessionFile } = coordinates;
4000
4116
  // #288 is lawful only when the lifecycle owner persisted an exhausted,
4001
4117
  // current-attempt fact. Transcript reconstruction must not turn arbitrary output
4002
4118
  // failures (or bytes retained from a prior resume attempt) into exit zero.
4003
4119
  if (failure.cause === "output") {
4004
- const entries = await readBoundSessionEntries(admitted.sessionFile).catch(() => undefined);
4120
+ const entries = await readBoundSessionEntries(sessionFile).catch(() => undefined);
4005
4121
  if (entries !== undefined) {
4006
4122
  let attemptStart = 0;
4007
4123
  for (let index = entries.length - 1; index >= 0; index -= 1) {
@@ -4019,11 +4135,11 @@ export async function settleFailureTerminalResult(
4019
4135
  return withOptionalGateProjection(
4020
4136
  {
4021
4137
  roleOutcome: { kind: "no_receipt", role: admitted.role, status: "no-accepted-receipt", ...facts, decisiveFacts },
4022
- navigator: await extractNavigatorFactFromAdmittedSession(admitted),
4138
+ navigator: await extractNavigatorFactFromAdmittedSession(sessionFile),
4023
4139
  artifacts: [],
4024
4140
  runId: admitted.runId,
4025
4141
  },
4026
- admitted.sessionDirectory,
4142
+ sessionDirectory,
4027
4143
  );
4028
4144
  }
4029
4145
  } catch { /* malformed lifecycle bytes remain the existing nonzero output failure */ }
@@ -4031,9 +4147,9 @@ export async function settleFailureTerminalResult(
4031
4147
  }
4032
4148
  }
4033
4149
  // Exact-session attendance only — never infer no-advice from caller omission.
4034
- const navigator = await extractNavigatorFactFromAdmittedSession(admitted);
4150
+ const navigator = await extractNavigatorFactFromAdmittedSession(sessionFile);
4035
4151
  // Private durable artifacts retain the original diagnostic identity (including run ID).
4036
- const artifacts = await publishFailureArtifacts(admitted, failure);
4152
+ const artifacts = await publishFailureArtifacts(admitted, failure, authority);
4037
4153
  const decisiveFacts: Record<string, unknown> = {
4038
4154
  cause: failure.cause,
4039
4155
  diagnostic: failure.diagnostic,
@@ -4072,7 +4188,7 @@ export async function settleFailureTerminalResult(
4072
4188
  artifacts: [],
4073
4189
  resume: options.resume,
4074
4190
  },
4075
- admitted.sessionDirectory,
4191
+ sessionDirectory,
4076
4192
  );
4077
4193
  }
4078
4194
  const roleOutcome: TerminalRoleOutcome = {
@@ -4090,7 +4206,7 @@ export async function settleFailureTerminalResult(
4090
4206
  artifacts,
4091
4207
  runId: admitted.runId,
4092
4208
  },
4093
- admitted.sessionDirectory,
4209
+ sessionDirectory,
4094
4210
  );
4095
4211
  }
4096
4212
 
@@ -4098,9 +4214,10 @@ export async function settleFailureTerminalResult(
4098
4214
  export async function settleJudgeFailureTerminalResult(
4099
4215
  admitted: AdmittedJudgeInvocation,
4100
4216
  failure: ControlledFailure,
4217
+ authority: DurablePrincipalAuthority,
4101
4218
  options: { readonly resume?: TerminalResume } = {},
4102
4219
  ): Promise<TerminalResult> {
4103
- return settleFailureTerminalResult(admitted, failure, options);
4220
+ return settleFailureTerminalResult(admitted, failure, authority, options);
4104
4221
  }
4105
4222
 
4106
4223
  /**