@akagilnc/pi-workflow-roles 0.1.3891 → 0.1.3898

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.
@@ -152,8 +152,7 @@ function sealedLedgerHome(admitted: AdmittedRoleInvocation): string {
152
152
  /**
153
153
  * Court-turn settlement scope (#637 same-ticket re-summons).
154
154
  * When courtAttemptId is set, ledger reads only that attempt so a prior seal
155
- * cannot present as this turn's result. Omit for manual resume idempotent
156
- * run-scoped sealed reads (no new court).
155
+ * cannot present as this turn's result. Omit for run-scoped latest sealed read.
157
156
  */
158
157
  export type SettlementCourtScope = {
159
158
  readonly courtAttemptId?: string;
@@ -186,7 +185,7 @@ async function sealedLedgerOutcome(
186
185
  * preserved cause; otherwise allow. Callers present entry-specific terminals;
187
186
  * they must not re-derive this judgment. Ledger projection remains the sole
188
187
  * seal truth — this is disposition over that read, not a second state.
189
- * Always run-scoped (no court attempt filter): any retained seal blocks bare resume.
188
+ * Always run-scoped (no court attempt filter): any retained seal blocks auto-resume redispatch.
190
189
  */
191
190
  export type SealedAcceptanceRedispatchDisposition =
192
191
  | { readonly kind: "allow" }
@@ -2476,8 +2475,9 @@ async function readLawfulSettlementEntries(
2476
2475
  export async function readLawfulJudgeRoleOutcome(
2477
2476
  admitted: AdmittedJudgeInvocation,
2478
2477
  authority: DurablePrincipalAuthority,
2478
+ scope?: SettlementCourtScope,
2479
2479
  ): Promise<LawfulJudgeRoleOutcome | undefined> {
2480
- const sealed = await sealedLedgerOutcome(admitted);
2480
+ const sealed = await sealedLedgerOutcome(admitted, scope);
2481
2481
  if (sealed?.role === "judge") {
2482
2482
  const details = sealed.decisiveFacts as Record<string, unknown>;
2483
2483
  // sealed.status is the sole authority (written by acceptedFacts at seal).
@@ -2490,7 +2490,7 @@ export async function readLawfulJudgeRoleOutcome(
2490
2490
  };
2491
2491
  }
2492
2492
  // Non-final: consume ledger audit-escalation projection (no JSONL accepted rebuild).
2493
- return auditEscalationLedgerOutcome(admitted, "judge");
2493
+ return auditEscalationLedgerOutcome(admitted, "judge", scope);
2494
2494
  }
2495
2495
 
2496
2496
  /**
@@ -2507,8 +2507,9 @@ export async function readLawfulJudgeRoleOutcome(
2507
2507
  async function settleLawfulJudgeTerminalResult(
2508
2508
  admitted: AdmittedJudgeInvocation,
2509
2509
  authority: DurablePrincipalAuthority,
2510
+ scope?: SettlementCourtScope,
2510
2511
  ): Promise<TerminalResult | undefined> {
2511
- const roleOutcome = await readLawfulJudgeRoleOutcome(admitted, authority);
2512
+ const roleOutcome = await readLawfulJudgeRoleOutcome(admitted, authority, scope);
2512
2513
  if (roleOutcome === undefined) return undefined;
2513
2514
  const coordinates = coordinatesFromAdmitted(authority, admitted);
2514
2515
  const entries = await readLawfulSettlementEntries(coordinates.sessionFile) ?? [];
@@ -2538,8 +2539,9 @@ async function settleLawfulJudgeTerminalResult(
2538
2539
  export async function settleJudgeTerminalResult(
2539
2540
  admitted: AdmittedJudgeInvocation,
2540
2541
  authority: DurablePrincipalAuthority,
2542
+ scope?: SettlementCourtScope,
2541
2543
  ): Promise<TerminalResult> {
2542
- const settled = await settleLawfulJudgeTerminalResult(admitted, authority);
2544
+ const settled = await settleLawfulJudgeTerminalResult(admitted, authority, scope);
2543
2545
  if (settled === undefined) {
2544
2546
  throw new Error(
2545
2547
  "Judge Role run completed without a lawful typed terminal result",
@@ -2556,8 +2558,9 @@ export async function settleJudgeTerminalResult(
2556
2558
  export async function trySettleJudgeTerminalResult(
2557
2559
  admitted: AdmittedJudgeInvocation,
2558
2560
  authority: DurablePrincipalAuthority,
2561
+ scope?: SettlementCourtScope,
2559
2562
  ): Promise<TerminalResult | undefined> {
2560
- return settleLawfulJudgeTerminalResult(admitted, authority);
2563
+ return settleLawfulJudgeTerminalResult(admitted, authority, scope);
2561
2564
  }
2562
2565
 
2563
2566
  async function settleLawfulCoderTerminalResult(
@@ -2566,8 +2569,9 @@ async function settleLawfulCoderTerminalResult(
2566
2569
  options: {
2567
2570
  readonly methodProvenance?: PackagedMethodSkillProvenance;
2568
2571
  } = {},
2572
+ scope?: SettlementCourtScope,
2569
2573
  ): Promise<TerminalResult | undefined> {
2570
- const ledgerOutcome = await closedLedgerOutcome(admitted, "coder");
2574
+ const ledgerOutcome = await closedLedgerOutcome(admitted, "coder", scope);
2571
2575
  if (ledgerOutcome === undefined) return undefined;
2572
2576
  // #757: sealed facts pass through — no shape re-project / field drop.
2573
2577
  const roleOutcome: TerminalRoleOutcome = ledgerOutcome;
@@ -2607,8 +2611,9 @@ export async function settleCoderTerminalResult(
2607
2611
  options: {
2608
2612
  readonly methodProvenance?: PackagedMethodSkillProvenance;
2609
2613
  } = {},
2614
+ scope?: SettlementCourtScope,
2610
2615
  ): Promise<TerminalResult> {
2611
- const settled = await settleLawfulCoderTerminalResult(admitted, authority, options);
2616
+ const settled = await settleLawfulCoderTerminalResult(admitted, authority, options, scope);
2612
2617
  if (settled === undefined) {
2613
2618
  throw new Error(
2614
2619
  "Coder Role run completed without a lawful typed terminal result",
@@ -2749,8 +2754,9 @@ async function settleLawfulFixerTerminalResult(
2749
2754
  readonly methodSkillPath: string;
2750
2755
  readonly methodSkillConfiguredPath: string;
2751
2756
  },
2757
+ scope?: SettlementCourtScope,
2752
2758
  ): Promise<TerminalResult | undefined> {
2753
- const ledgerOutcome = await closedLedgerOutcome(admitted, "fixer");
2759
+ const ledgerOutcome = await closedLedgerOutcome(admitted, "fixer", scope);
2754
2760
  if (ledgerOutcome === undefined) return undefined;
2755
2761
  // #757: sealed facts pass through — no shape re-project / field drop.
2756
2762
  const roleOutcome: TerminalRoleOutcome = ledgerOutcome;
@@ -2798,8 +2804,9 @@ export async function settleFixerTerminalResult(
2798
2804
  readonly methodSkillPath: string;
2799
2805
  readonly methodSkillConfiguredPath: string;
2800
2806
  },
2807
+ scope?: SettlementCourtScope,
2801
2808
  ): Promise<TerminalResult> {
2802
- const settled = await settleLawfulFixerTerminalResult(admitted, authority, options);
2809
+ const settled = await settleLawfulFixerTerminalResult(admitted, authority, options, scope);
2803
2810
  if (settled === undefined) {
2804
2811
  throw new Error(
2805
2812
  "Fixer Role run completed without a lawful typed terminal result",
@@ -2877,11 +2884,12 @@ export type LawfulCollectorRoleOutcome = {
2877
2884
  async function settleLawfulCollectorTerminalResult(
2878
2885
  admitted: AdmittedCollectorInvocation,
2879
2886
  authority: DurablePrincipalAuthority,
2887
+ scope?: SettlementCourtScope,
2880
2888
  ): Promise<TerminalResult | undefined> {
2881
2889
  const coordinates = coordinatesFromAdmitted(authority, admitted);
2882
2890
  const { sessionDirectory, sessionFile } = coordinates;
2883
2891
  const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
2884
- const roleOutcome = await sealedLedgerOutcome(admitted);
2892
+ const roleOutcome = await sealedLedgerOutcome(admitted, scope);
2885
2893
  if (roleOutcome?.role !== "collector") {
2886
2894
  // Bounded to the current attempt so multi-attempt resume timeout/no-output
2887
2895
  // is not masked by a prior wait-tool residual (#633).
@@ -2941,8 +2949,9 @@ async function settleLawfulCollectorTerminalResult(
2941
2949
  export async function settleCollectorTerminalResult(
2942
2950
  admitted: AdmittedCollectorInvocation,
2943
2951
  authority: DurablePrincipalAuthority,
2952
+ scope?: SettlementCourtScope,
2944
2953
  ): Promise<TerminalResult> {
2945
- const settled = await settleLawfulCollectorTerminalResult(admitted, authority);
2954
+ const settled = await settleLawfulCollectorTerminalResult(admitted, authority, scope);
2946
2955
  if (settled === undefined) {
2947
2956
  throw new Error(
2948
2957
  "Collector Role run completed without a lawful typed terminal result",
@@ -2955,8 +2964,9 @@ export async function settleCollectorTerminalResult(
2955
2964
  export async function trySettleCollectorTerminalResult(
2956
2965
  admitted: AdmittedCollectorInvocation,
2957
2966
  authority: DurablePrincipalAuthority,
2967
+ scope?: SettlementCourtScope,
2958
2968
  ): Promise<TerminalResult | undefined> {
2959
- return settleLawfulCollectorTerminalResult(admitted, authority);
2969
+ return settleLawfulCollectorTerminalResult(admitted, authority, scope);
2960
2970
  }
2961
2971
 
2962
2972
  export async function publishDoctorArtifacts(
@@ -3034,13 +3044,14 @@ export type LawfulDoctorRoleOutcome =
3034
3044
  async function settleLawfulDoctorTerminalResult(
3035
3045
  admitted: AdmittedDoctorInvocation,
3036
3046
  authority: DurablePrincipalAuthority,
3047
+ scope?: SettlementCourtScope,
3037
3048
  ): Promise<TerminalResult | undefined> {
3038
- const sealed = await sealedLedgerOutcome(admitted);
3049
+ const sealed = await sealedLedgerOutcome(admitted, scope);
3039
3050
  const coordinates = coordinatesFromAdmitted(authority, admitted);
3040
3051
  const { sessionDirectory, sessionFile } = coordinates;
3041
3052
  const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
3042
3053
  if (sealed?.role !== "doctor") {
3043
- const escalation = await auditEscalationLedgerOutcome(admitted, "doctor");
3054
+ const escalation = await auditEscalationLedgerOutcome(admitted, "doctor", scope);
3044
3055
  if (escalation === undefined) return undefined;
3045
3056
  const artifacts = await publishDoctorArtifacts(admitted, escalation, coordinates);
3046
3057
  return withOptionalGateProjection(
@@ -3102,8 +3113,9 @@ async function settleLawfulDoctorTerminalResult(
3102
3113
  export async function settleDoctorTerminalResult(
3103
3114
  admitted: AdmittedDoctorInvocation,
3104
3115
  authority: DurablePrincipalAuthority,
3116
+ scope?: SettlementCourtScope,
3105
3117
  ): Promise<TerminalResult> {
3106
- const settled = await settleLawfulDoctorTerminalResult(admitted, authority);
3118
+ const settled = await settleLawfulDoctorTerminalResult(admitted, authority, scope);
3107
3119
  if (settled === undefined) {
3108
3120
  throw new Error(
3109
3121
  "Doctor Role run completed without a lawful typed terminal result",
@@ -3116,8 +3128,9 @@ export async function settleDoctorTerminalResult(
3116
3128
  export async function trySettleDoctorTerminalResult(
3117
3129
  admitted: AdmittedDoctorInvocation,
3118
3130
  authority: DurablePrincipalAuthority,
3131
+ scope?: SettlementCourtScope,
3119
3132
  ): Promise<TerminalResult | undefined> {
3120
- return settleLawfulDoctorTerminalResult(admitted, authority);
3133
+ return settleLawfulDoctorTerminalResult(admitted, authority, scope);
3121
3134
  }
3122
3135
 
3123
3136
  /**
@@ -3498,8 +3511,9 @@ export async function trySettleCoderTerminalResult(
3498
3511
  options: {
3499
3512
  readonly methodProvenance?: PackagedMethodSkillProvenance;
3500
3513
  } = {},
3514
+ scope?: SettlementCourtScope,
3501
3515
  ): Promise<TerminalResult | undefined> {
3502
- return settleLawfulCoderTerminalResult(admitted, authority, options);
3516
+ return settleLawfulCoderTerminalResult(admitted, authority, options, scope);
3503
3517
  }
3504
3518
 
3505
3519
  /** Try to settle a lawful Fixer Terminal; undefined only for genuine absence. */
@@ -3511,8 +3525,9 @@ export async function trySettleFixerTerminalResult(
3511
3525
  readonly methodSkillPath: string;
3512
3526
  readonly methodSkillConfiguredPath: string;
3513
3527
  },
3528
+ scope?: SettlementCourtScope,
3514
3529
  ): Promise<TerminalResult | undefined> {
3515
- return settleLawfulFixerTerminalResult(admitted, authority, options);
3530
+ return settleLawfulFixerTerminalResult(admitted, authority, options, scope);
3516
3531
  }
3517
3532
 
3518
3533
  /**
@@ -3631,8 +3646,9 @@ async function settleLawfulReviewerTerminalResult(
3631
3646
  readonly methodSkillPath: string;
3632
3647
  readonly methodSkillConfiguredPath: string;
3633
3648
  },
3649
+ scope?: SettlementCourtScope,
3634
3650
  ): Promise<TerminalResult | undefined> {
3635
- const sealed = await sealedLedgerOutcome(admitted);
3651
+ const sealed = await sealedLedgerOutcome(admitted, scope);
3636
3652
  if (sealed?.role !== "reviewer") return undefined;
3637
3653
  const coordinates = coordinatesFromAdmitted(authority, admitted);
3638
3654
  const { sessionDirectory, sessionFile } = coordinates;
@@ -3682,8 +3698,9 @@ export async function settleReviewerTerminalResult(
3682
3698
  readonly methodSkillPath: string;
3683
3699
  readonly methodSkillConfiguredPath: string;
3684
3700
  },
3701
+ scope?: SettlementCourtScope,
3685
3702
  ): Promise<TerminalResult> {
3686
- const settled = await settleLawfulReviewerTerminalResult(admitted, authority, options);
3703
+ const settled = await settleLawfulReviewerTerminalResult(admitted, authority, options, scope);
3687
3704
  if (settled === undefined) {
3688
3705
  throw new Error(
3689
3706
  "Reviewer Role run completed without a lawful typed terminal result",
@@ -3701,8 +3718,9 @@ export async function trySettleReviewerTerminalResult(
3701
3718
  readonly methodSkillPath: string;
3702
3719
  readonly methodSkillConfiguredPath: string;
3703
3720
  },
3721
+ scope?: SettlementCourtScope,
3704
3722
  ): Promise<TerminalResult | undefined> {
3705
- return settleLawfulReviewerTerminalResult(admitted, authority, options);
3723
+ return settleLawfulReviewerTerminalResult(admitted, authority, options, scope);
3706
3724
  }
3707
3725
 
3708
3726
 
@@ -3814,17 +3832,18 @@ async function settleLawfulMergerTerminalResult(
3814
3832
  readonly methodSkillPath: string;
3815
3833
  readonly methodSkillConfiguredPath: string;
3816
3834
  },
3835
+ scope?: SettlementCourtScope,
3817
3836
  ): Promise<TerminalResult | undefined> {
3818
3837
  const coordinates = coordinatesFromAdmitted(authority, admitted);
3819
3838
  const { sessionDirectory, sessionFile } = coordinates;
3820
3839
  const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
3821
- const roleOutcome = await sealedLedgerOutcome(admitted);
3840
+ const roleOutcome = await sealedLedgerOutcome(admitted, scope);
3822
3841
  if (roleOutcome?.role !== "merger") {
3823
3842
  // Ledger owns 0041: a non-sole closed round is not residual-incomplete material.
3824
3843
  const latestOutcome = await readLatestSubmissionOutcome(
3825
3844
  admitted.projectRoot,
3826
3845
  admitted.runId,
3827
- sealedLedgerHome(admitted),
3846
+ ledgerReadScope(admitted, scope),
3828
3847
  );
3829
3848
  if (latestOutcome?.outcome === "correctable-rejection" && latestOutcome.code === "non-sole-round") {
3830
3849
  return undefined;
@@ -3902,8 +3921,9 @@ export async function settleMergerTerminalResult(
3902
3921
  readonly methodSkillPath: string;
3903
3922
  readonly methodSkillConfiguredPath: string;
3904
3923
  },
3924
+ scope?: SettlementCourtScope,
3905
3925
  ): Promise<TerminalResult> {
3906
- const settled = await settleLawfulMergerTerminalResult(admitted, authority, options);
3926
+ const settled = await settleLawfulMergerTerminalResult(admitted, authority, options, scope);
3907
3927
  if (settled === undefined) {
3908
3928
  throw new Error(
3909
3929
  "Merger Role run completed without a lawful typed terminal result",
@@ -3921,8 +3941,9 @@ export async function trySettleMergerTerminalResult(
3921
3941
  readonly methodSkillPath: string;
3922
3942
  readonly methodSkillConfiguredPath: string;
3923
3943
  },
3944
+ scope?: SettlementCourtScope,
3924
3945
  ): Promise<TerminalResult | undefined> {
3925
- return settleLawfulMergerTerminalResult(admitted, authority, options);
3946
+ return settleLawfulMergerTerminalResult(admitted, authority, options, scope);
3926
3947
  }
3927
3948
 
3928
3949
  /** One failed attempt to place a durable failure artifact (path is private layout). */
@@ -29,6 +29,8 @@ export type RoleTurnRequestProjectionOptions = {
29
29
  timeoutMs?: number;
30
30
  correlationId?: string;
31
31
  continuation: RoleTurnRequest["continuation"];
32
+ /** #833 resume-with-message court attempt. */
33
+ courtAttemptId?: string;
32
34
  };
33
35
 
34
36
  export type AdmittedTurnInvocation = {
@@ -69,5 +71,8 @@ export function projectRoleTurnRequest(
69
71
  ? {}
70
72
  : { correlationId: options.correlationId }),
71
73
  ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
74
+ ...(options.courtAttemptId === undefined || options.courtAttemptId.length === 0
75
+ ? {}
76
+ : { courtAttemptId: options.courtAttemptId }),
72
77
  };
73
78
  }
@@ -57,10 +57,10 @@ function runIdentity(context: HostContext): string {
57
57
  }
58
58
 
59
59
  /**
60
- * Court-turn attempt identity (#637 same-ticket re-summons).
61
- * AK_ROLE_COURT_ATTEMPT is injected only for a new court turn on an already-retained
62
- * run (forceContinuation / summons). Manual resume and first mint omit it so the
63
- * session-stable id keeps sole-final + sealed-idempotent semantics.
60
+ * Court-turn attempt identity (#637 same-ticket re-summons / #833 message re-review).
61
+ * AK_ROLE_COURT_ATTEMPT is injected for a new court turn on an already-retained run
62
+ * (summons / message / open-court continue). Bare resume and first mint omit it so
63
+ * the session-stable id keeps sole-final per attempt.
64
64
  */
65
65
  export const COURT_ATTEMPT_ENV = "AK_ROLE_COURT_ATTEMPT" as const;
66
66
 
@@ -149,8 +149,9 @@ function recordsForAttempt<T extends { subject?: unknown; payload?: unknown }>(
149
149
  }
150
150
 
151
151
  /** Settlement read seam: typed sealed projection only, never host session JSONL.
152
- * Omit attemptId for run-scoped latest sealed (manual resume idempotent).
153
- * Pass attemptId for the current court turn so a prior seal cannot wash this turn. */
152
+ * Omit attemptId for run-scoped latest sealed.
153
+ * Pass attemptId for the current court turn so a prior seal cannot wash this turn.
154
+ * post-seal-anomaly is forensic only — later turns must not erase an earlier seal (#833). */
154
155
  export async function readSealedSubmission(
155
156
  cwd: string,
156
157
  runId: string,
@@ -161,7 +162,6 @@ export async function readSealedSubmission(
161
162
  const scoped = recordsForAttempt(owned, scope.attemptId);
162
163
  for (let index = scoped.length - 1; index >= 0; index -= 1) {
163
164
  const record = scoped[index];
164
- if (record?.kind === "post-seal-anomaly") return undefined;
165
165
  if (record?.kind !== "sealed") continue;
166
166
  const payload = record.payload as Partial<Extract<SubmissionLedgerEvent, { type: "sealed" }>> | undefined;
167
167
  if (payload?.type === "sealed" && isAcceptedProjection(payload.projection)) return payload.projection;