@akagilnc/pi-workflow-roles 0.1.2383 → 0.1.2402

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 (57) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/audit-escalation.js +0 -13
  4. package/dist/compliance-transport.js +28 -5
  5. package/dist/doctor-contracts.js +2 -9
  6. package/dist/dossier-resolution.js +21 -2
  7. package/dist/engine-detour-tool.js +10 -35
  8. package/dist/evidence-child-executor.js +12 -4
  9. package/dist/merger-contracts.js +2 -8
  10. package/dist/navigator-attendance.js +1 -9
  11. package/dist/navigator-invocation-identity.js +16 -4
  12. package/dist/notary-contracts.js +7 -25
  13. package/dist/package-contracts/judge-output.js +1 -4
  14. package/dist/package-contracts/reviewer-output.js +1 -7
  15. package/dist/package-contracts/terminating-tools.js +6 -11
  16. package/dist/public-cli/main.js +125 -475
  17. package/package.json +1 -1
  18. package/scripts/build-package.mjs +1 -2
  19. package/src/analyst-gate-cycles-read.ts +5 -8
  20. package/src/analyst-metric-families/acceptance-success-rework.ts +3 -6
  21. package/src/audit-escalation.ts +0 -25
  22. package/src/collector-role.ts +1 -8
  23. package/src/compliance-transport.ts +38 -6
  24. package/src/doctor-auditor.ts +3 -3
  25. package/src/doctor-contracts.ts +3 -18
  26. package/src/doctor-role.ts +1 -5
  27. package/src/dossier-resolution.ts +25 -4
  28. package/src/engine-detour-tool.ts +16 -51
  29. package/src/evidence-child-executor.ts +12 -4
  30. package/src/factory-board.ts +2 -4
  31. package/src/gatekeeper-role.ts +33 -43
  32. package/src/judge-auditor.ts +3 -3
  33. package/src/judge-role.ts +1 -8
  34. package/src/merger-contracts.ts +3 -17
  35. package/src/merger-role.ts +1 -8
  36. package/src/navigator-attendance.ts +1 -14
  37. package/src/navigator-invocation-identity.ts +34 -13
  38. package/src/notary-contracts.ts +9 -43
  39. package/src/notary-role.ts +3 -5
  40. package/src/package-contracts/judge-output.ts +2 -17
  41. package/src/package-contracts/reviewer-output.ts +2 -21
  42. package/src/package-contracts/terminating-tools.ts +5 -14
  43. package/src/package-contracts/worker-output.ts +2 -10
  44. package/src/public-cli/doctor-run.ts +0 -2
  45. package/src/public-cli/fixer-run.ts +0 -15
  46. package/src/public-cli/judge-run.ts +0 -16
  47. package/src/public-cli/notary-run.ts +1 -1
  48. package/src/public-cli/one-shot-dispatch.ts +1 -1
  49. package/src/public-cli/reviewer-run.ts +0 -15
  50. package/src/public-cli/settlement.ts +110 -368
  51. package/src/public-cli/terminal.ts +3 -71
  52. package/src/reviewer-auditor.ts +3 -3
  53. package/src/reviewer-role.ts +2 -11
  54. package/src/role-runtime.ts +43 -37
  55. package/src/worker-role.ts +2 -14
  56. package/dist/engine-labor-fallback.js +0 -136
  57. package/src/engine-labor-fallback.ts +0 -270
@@ -6,7 +6,6 @@
6
6
  * extra rows or shift column boundaries (note / fix.summary / decision question / reason).
7
7
  */
8
8
  import { renderPublicAkRoleCommand } from "./command-renderer.ts";
9
- import type { ComplianceAuditIncomplete } from "../compliance-transport.ts";
10
9
  import type { NavigatorPhase } from "../navigator-attendance.ts";
11
10
  import type { NoReceiptLifecycleFacts } from "../receipt-delivery-policy.ts";
12
11
 
@@ -41,9 +40,10 @@ export type TerminalRoleName =
41
40
  | "merger"
42
41
  | "notary";
43
42
 
43
+ /** Merger/Collector residual only — Notary/audit residual abolished (#475). */
44
44
  export type ResidualIncompleteTerminalOutcome = {
45
45
  kind: "incomplete";
46
- role: "merger" | "collector" | "notary";
46
+ role: "merger" | "collector";
47
47
  status: "incomplete";
48
48
  decision: "no-usable-result";
49
49
  candidate: unknown;
@@ -52,35 +52,6 @@ export type ResidualIncompleteTerminalOutcome = {
52
52
  decisiveFacts: Readonly<Record<string, unknown>>;
53
53
  };
54
54
 
55
- export type AuditIncompleteTerminalOutcome = {
56
- kind: "audit_incomplete";
57
- role: TerminalRoleName;
58
- status: "audit-incomplete";
59
- decision: "no-usable-decision";
60
- /** The original role submission arguments, retained independently. */
61
- roleCandidate: unknown;
62
- /** The malformed auditor candidate and observation retained by compliance transport. */
63
- audit: ComplianceAuditIncomplete;
64
- acceptedReceipt: false;
65
- decisiveFacts: Readonly<Record<string, unknown>>;
66
- };
67
-
68
- /** JSON-safe public stand-in for an omitted tool-call `arguments` member. */
69
- export const JSON_SAFE_UNDEFINED_ARGUMENT = Object.freeze({
70
- kind: "json-safe-sentinel",
71
- type: "undefined",
72
- } as const);
73
-
74
- export type AuditIncompleteResidual = {
75
- readonly roleCandidate: unknown;
76
- readonly audit: ComplianceAuditIncomplete;
77
- readonly acceptedReceipt: false;
78
- };
79
-
80
- export function jsonSafeComplianceCandidate(value: unknown): unknown {
81
- return value === undefined ? JSON_SAFE_UNDEFINED_ARGUMENT : value;
82
- }
83
-
84
55
  export type NoReceiptTerminalOutcome = NoReceiptLifecycleFacts & {
85
56
  kind: "no_receipt";
86
57
  role: TerminalRoleName;
@@ -102,7 +73,6 @@ export type TerminalRoleOutcome =
102
73
  status: "audit_escalation";
103
74
  decisiveFacts: Readonly<Record<string, unknown>>;
104
75
  }
105
- | AuditIncompleteTerminalOutcome
106
76
  | ResidualIncompleteTerminalOutcome
107
77
  | NoReceiptTerminalOutcome
108
78
  | {
@@ -113,8 +83,6 @@ export type TerminalRoleOutcome =
113
83
  /** Original diagnostic identity retained for the caller. */
114
84
  diagnostic: string;
115
85
  decisiveFacts: Readonly<Record<string, unknown>>;
116
- /** Retained audit residual when publication itself failed. */
117
- auditResidual?: AuditIncompleteResidual;
118
86
  };
119
87
 
120
88
  /** Lawful typed terminal results exit zero (including audit_escalation). */
@@ -131,7 +99,7 @@ export function exitCodeForTerminalOutcome(
131
99
  }
132
100
 
133
101
  export function buildResidualIncompleteTerminalOutcome(input: {
134
- role: "merger" | "collector" | "notary";
102
+ role: "merger" | "collector";
135
103
  candidate: unknown;
136
104
  diagnostic: string;
137
105
  }): ResidualIncompleteTerminalOutcome {
@@ -152,42 +120,6 @@ export function buildResidualIncompleteTerminalOutcome(input: {
152
120
  };
153
121
  }
154
122
 
155
- export function buildAuditIncompleteTerminalOutcome(input: {
156
- role: TerminalRoleName;
157
- roleCandidate: unknown;
158
- audit: ComplianceAuditIncomplete;
159
- }): AuditIncompleteTerminalOutcome {
160
- const roleCandidate = jsonSafeComplianceCandidate(input.roleCandidate);
161
- const audit = {
162
- ...input.audit,
163
- candidate: jsonSafeComplianceCandidate(input.audit.candidate),
164
- };
165
- return {
166
- kind: "audit_incomplete",
167
- role: input.role,
168
- status: "audit-incomplete",
169
- decision: "no-usable-decision",
170
- roleCandidate,
171
- audit,
172
- acceptedReceipt: false,
173
- decisiveFacts: {
174
- decision: "no-usable-decision",
175
- roleCandidate,
176
- auditCandidate: audit.candidate,
177
- auditObservation: audit.observation,
178
- observationKind: audit.observation.kind,
179
- observationType: audit.observation.kind === "non-object-arguments"
180
- ? audit.observation.type
181
- : audit.observation.kind === "object-status-unreadable"
182
- ? audit.observation.status
183
- : audit.observation.kind === "missing-subject"
184
- ? audit.observation.subject
185
- : audit.observation.kind,
186
- acceptedReceipt: false,
187
- },
188
- };
189
- }
190
-
191
123
  export type TerminalNavigatorFact =
192
124
  | {
193
125
  disposition: "recommendation";
@@ -10,8 +10,8 @@ import {
10
10
  } from "./compliance-transport.ts";
11
11
  import {
12
12
  readReviewerAuditSubjects,
13
+ requireAuditMaterials,
13
14
  resolveAuditDossier,
14
- toAuditIncomplete,
15
15
  } from "./dossier-resolution.ts";
16
16
 
17
17
  export const REVIEWER_AUDIT_TOOL_NAME = "ak_reviewer_audit_decision";
@@ -35,9 +35,9 @@ export function createPiReviewerAuditor(
35
35
  ): (options: ReviewerAuditOptions) => Promise<ComplianceDecision> {
36
36
  return async (options) => {
37
37
  const dossier = resolveAuditDossier();
38
- if (dossier.status === "incomplete") return toAuditIncomplete(dossier.observation);
38
+ requireAuditMaterials(dossier);
39
39
  const subjects = readReviewerAuditSubjects(options.context);
40
- if (subjects.status === "incomplete") return toAuditIncomplete(subjects.observation);
40
+ requireAuditMaterials(subjects);
41
41
 
42
42
  return runComplianceAudit({
43
43
  tool: reviewerDecisionTool,
@@ -7,10 +7,6 @@ export type { CanonicalSkillBinding };
7
7
  import { disposeComplianceDecision } from "./audit-escalation.ts";
8
8
  import type { ComplianceDecision } from "./compliance-transport.ts";
9
9
  import { appendActiveSessionCustomEntry } from "./compliance-transport.ts";
10
- import {
11
- readActivationEngineLaborFallbackField,
12
- withEngineLaborFallbackField,
13
- } from "./engine-labor-fallback.ts";
14
10
  import { REVIEWER_CANDIDATE_ENTRY_TYPE } from "./dossier-resolution.ts";
15
11
  import { type ReviewerSpecDisposition } from "./reviewer-construction.ts";
16
12
  import { createReviewerDispatcher, type AcceptedReviewerDispatch, type AcceptedReviewerExecution, type ReviewerIssueFetcher, type ReviewerPinnedGitReader } from "./reviewer-dispatch.ts";
@@ -160,15 +156,11 @@ export function createReviewerRoleRuntime(
160
156
  const output = validateReviewerIntent(parameters);
161
157
  let record: ReviewerExecutionRecord;
162
158
  try { record = ledger.recordForAudit(output.status); } catch (error) { if ((error as any)?.fatalReviewerInfrastructure) hostActions.failInfrastructure(error, toolCtx, id); throw error; }
163
- const candidate = withEngineLaborFallbackField(
164
- assembleRuntimeReviewerReceipt({
159
+ const candidate = assembleRuntimeReviewerReceipt({
165
160
  intent: output,
166
161
  record,
167
162
  canonicalSkillText: binding.snapshot.raw,
168
- }),
169
- // #380: sole-built declaration when any leg detour fell back to seat labor.
170
- readActivationEngineLaborFallbackField(),
171
- );
163
+ });
172
164
  // First-record-then-audit: candidate lands on the parent session books
173
165
  // before the auditor is spawned (zero hand-delivery).
174
166
  try {
@@ -210,7 +202,6 @@ export function createReviewerRoleRuntime(
210
202
  try { await dependencies.shutdownAgent?.(); } catch (error) { hostActions.failInfrastructure(ledger.recordInfrastructureFailure(error), toolCtx, id); }
211
203
  return result;
212
204
  },
213
- auditIncomplete: (result) => result,
214
205
  },
215
206
  candidate,
216
207
  );
@@ -23,13 +23,6 @@ import {
23
23
  } from "./tool-execution-observation.ts";
24
24
  import { ENGINE_DETOUR_TOOL_NAME } from "./engine-detour.ts";
25
25
  import { registerEngineDetourTool } from "./engine-detour-tool.ts";
26
- import {
27
- createEngineLaborFallbackLatch,
28
- installActivationEngineLaborFallbackLatch,
29
- restoreEngineLaborFallbackFromSessionEntries,
30
- seatFallbackBaseStatus,
31
- seatFallbackStatusHasLawfulEvidence,
32
- } from "./engine-labor-fallback.ts";
33
26
  import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_PROMPT } from "./receipt-delivery-policy.ts";
34
27
  import { createOAuthKeepalive, type OAuthKeepaliveOptions } from "./oauth-keepalive.ts";
35
28
 
@@ -50,6 +43,7 @@ import { decorateSettlementWithNavigation, formatNavigatorReport, NAVIGATOR_EVEN
50
43
  import {
51
44
  buildNavigatorInfrastructureFailureFact,
52
45
  classifyPackagedRoleTerminalResult,
46
+ NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
53
47
  NAVIGATOR_INVOCATION_ENTRY,
54
48
  resolveLifecycleInvocationPrincipal,
55
49
  } from "./navigator-invocation-identity.ts";
@@ -220,9 +214,11 @@ import { createMergerRoleRuntime, type MergerRoleDependencies } from "./merger-r
220
214
  export {
221
215
  buildNavigatorInfrastructureFailureFact,
222
216
  classifyPackagedRoleTerminalResult,
217
+ hasNavigatorInfrastructureFailureBase,
223
218
  isAcceptedPackagedRoleTerminalResult,
224
219
  isDurablePackagedRoleTerminalResult,
225
220
  isNavigatorInfrastructureFailureFact,
221
+ NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
226
222
  NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND,
227
223
  type NavigatorInfrastructureFailureFact,
228
224
  type PackagedRoleTerminalClassification,
@@ -550,6 +546,35 @@ function failInfrastructure(error: unknown, ctx: ExtensionContext): never {
550
546
  throw error;
551
547
  }
552
548
 
549
+ /**
550
+ * Envelope-owned pending infrastructure failure: closed fact + original Error evidence.
551
+ * tool_result projects once from this record; settlement consumes durable details as-is.
552
+ */
553
+ type PendingInfrastructureFailure = {
554
+ readonly details: Record<string, unknown>;
555
+ };
556
+
557
+ function extractInfrastructureFailureEvidence(error: unknown): Record<string, unknown> {
558
+ if (typeof error !== "object" || error === null) return {};
559
+ const record = error as Record<string, unknown>;
560
+ const evidence: Record<string, unknown> = {};
561
+ for (const key of NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS) {
562
+ if (!Object.hasOwn(record, key)) continue;
563
+ // undefined → null so JSON durable details retain the empty-candidate key.
564
+ evidence[key] = record[key] === undefined ? null : record[key];
565
+ }
566
+ return evidence;
567
+ }
568
+
569
+ function buildPendingInfrastructureFailure(error: unknown): PendingInfrastructureFailure {
570
+ return {
571
+ details: {
572
+ ...buildNavigatorInfrastructureFailureFact(),
573
+ ...extractInfrastructureFailureEvidence(error),
574
+ },
575
+ };
576
+ }
577
+
553
578
  function navigatorPhase(pi: ExtensionAPI, role: string): NavigatorPhase {
554
579
  const metadata = packagedRoleMetadata(role);
555
580
  if (metadata === undefined || metadata.phases[0] === null) return null;
@@ -582,12 +607,7 @@ export function publicNavigatorSettlement(role: string, phase: NavigatorPhase, e
582
607
  const status = typeof details.status === "string"
583
608
  ? details.status
584
609
  : typeof details.judgeStatus === "string" ? details.judgeStatus : undefined;
585
- // ADR 0071: `-by-fallback` without latch-shaped evidence is not a lawful terminal.
586
- if (status !== undefined && !seatFallbackStatusHasLawfulEvidence(status, event.details)) {
587
- return undefined;
588
- }
589
- // Seat-fallback taint keeps escalate semantics (base) while preserving the polluted token.
590
- if (status !== undefined && seatFallbackBaseStatus(status) === "escalate") {
610
+ if (status !== undefined && status === "escalate") {
591
611
  return { kind: "human_decision", role, phase, status };
592
612
  }
593
613
  return { kind: "accepted", role, phase, ...(status === undefined ? {} : { status }) };
@@ -616,12 +636,11 @@ export function createRoleRuntimeExtension(
616
636
  let pendingNavigatorPresentation: { event: import("./navigator-attendance.ts").NavigatorEvent; report: import("./navigator-attendance.ts").NavigatorReport } | undefined;
617
637
  let pendingNavigatorSettlement: Promise<void> | undefined;
618
638
  let navigatorWorkContext: NavigatorWorkContext | undefined;
619
- const pendingInfrastructureToolCallIds = new Set<string>();
639
+ /** toolCallId → fact+evidence; one-shot projected onto durable tool_result (#475). */
640
+ const pendingInfrastructureFailures = new Map<string, PendingInfrastructureFailure>();
620
641
  // Envelope-owned execute→tool_result bridge for Gatekeeper non-pass (ADR 0018).
621
642
  const pendingGatekeeperNonPassByToolCallId = new Map<string, GatekeeperNonPassResult>();
622
- // #357 T2 / #378 / #380 / #391: engine detour once-latch + seat-fallback latch (any role+engine).
623
643
  let engineDetourRegistration: ReturnType<typeof registerEngineDetourTool> | undefined;
624
- let engineLaborFallbackLatch = createEngineLaborFallbackLatch();
625
644
  // #288 primary-session thin adapter. The policy is the sole budget owner;
626
645
  // terminating-tool rejections and mechanical delivery requests share two turns.
627
646
  let receiptDelivery = createReceiptDeliveryPolicy();
@@ -705,11 +724,11 @@ export function createRoleRuntimeExtension(
705
724
  pi.on("tool_result", async (event) => {
706
725
  const role = selectedRole;
707
726
  if (role === undefined) return;
708
- const isRoleInfrastructureFailure = pendingInfrastructureToolCallIds.delete(event.toolCallId);
709
- // Overlay typed infra fact so live settlement and durable session entry agree.
710
- const infrastructureDetails = isRoleInfrastructureFailure
711
- ? buildNavigatorInfrastructureFailureFact()
712
- : undefined;
727
+ const pendingInfra = pendingInfrastructureFailures.get(event.toolCallId);
728
+ const isRoleInfrastructureFailure = pendingInfra !== undefined;
729
+ if (pendingInfra !== undefined) pendingInfrastructureFailures.delete(event.toolCallId);
730
+ // One-shot project fact + typed evidence so live settlement and durable session agree.
731
+ const infrastructureDetails = pendingInfra?.details;
713
732
  const classified = infrastructureDetails === undefined
714
733
  ? event
715
734
  : { ...event, details: infrastructureDetails };
@@ -878,7 +897,7 @@ export function createRoleRuntimeExtension(
878
897
  navigatorAttendance?.dispose();
879
898
  navigatorAttendance = undefined;
880
899
  pendingNavigatorSettlement = undefined;
881
- pendingInfrastructureToolCallIds.clear();
900
+ pendingInfrastructureFailures.clear();
882
901
  pendingGatekeeperNonPassByToolCallId.clear();
883
902
  observationFace.reset();
884
903
  });
@@ -886,7 +905,7 @@ export function createRoleRuntimeExtension(
886
905
  const hostActions = {
887
906
  failInfrastructure(error: unknown, ctx: ExtensionContext, toolCallId?: string): never {
888
907
  if (toolCallId !== undefined) {
889
- pendingInfrastructureToolCallIds.add(toolCallId);
908
+ pendingInfrastructureFailures.set(toolCallId, buildPendingInfrastructureFailure(error));
890
909
  }
891
910
  failInfrastructure(error, ctx);
892
911
  },
@@ -1105,20 +1124,8 @@ export function createRoleRuntimeExtension(
1105
1124
  observationFace.reset();
1106
1125
  pendingNavigatorPresentation = undefined;
1107
1126
  pendingNavigatorSettlement = undefined;
1108
- pendingInfrastructureToolCallIds.clear();
1127
+ pendingInfrastructureFailures.clear();
1109
1128
  pendingGatekeeperNonPassByToolCallId.clear();
1110
- engineLaborFallbackLatch = createEngineLaborFallbackLatch();
1111
- // #380 resume: restore sole-built fallback from durable same-session detour results.
1112
- const sessionEntries =
1113
- typeof ctx.sessionManager?.getEntries === "function"
1114
- ? ctx.sessionManager.getEntries()
1115
- : [];
1116
- restoreEngineLaborFallbackFromSessionEntries(
1117
- engineLaborFallbackLatch,
1118
- sessionEntries,
1119
- ENGINE_DETOUR_TOOL_NAME,
1120
- );
1121
- installActivationEngineLaborFallbackLatch(engineLaborFallbackLatch);
1122
1129
  engineDetourRegistration?.resetLatch();
1123
1130
  navigatorWorkContext = undefined;
1124
1131
  // #351: OAuth keepalive is orthogonal to --ak-role; start before role early-return
@@ -1234,7 +1241,6 @@ export function createRoleRuntimeExtension(
1234
1241
  await executeActivationStage(entry.role, activationStage(entry.role, runtime), { clock, writeTrace });
1235
1242
  // #357 T2 / #378 / #380 / #391: any role+engine activation registers the package detour tool once.
1236
1243
  // Gate is env presence only — no per-engine execute branch; no role-module spawn.
1237
- // Seat-fallback latch is activation-scoped (installed at session_start) so legs share it.
1238
1244
  if (engineDetourRegistration === undefined) {
1239
1245
  engineDetourRegistration = registerEngineDetourTool(pi, hostActions);
1240
1246
  if (!engineDetourRegistration.registered) {
@@ -6,10 +6,6 @@ import type {
6
6
  } from "@earendil-works/pi-coding-agent";
7
7
  import { Type, type Static } from "typebox";
8
8
  import { openToolObjectFromUnion } from "./open-tool-schema.ts";
9
- import {
10
- readActivationEngineLaborFallbackField,
11
- withEngineLaborFallbackField,
12
- } from "./engine-labor-fallback.ts";
13
9
 
14
10
  import type {
15
11
  AnyCanonicalSkillBinding,
@@ -299,11 +295,7 @@ export function createFixerRoleRuntime(
299
295
  toolCallId,
300
296
  });
301
297
  }
302
- // #391: attach sole-built engineLaborFallback when detour fell back to seat labor.
303
- const acceptedDetails = withEngineLaborFallbackField(
304
- output,
305
- readActivationEngineLaborFallbackField(),
306
- );
298
+ const acceptedDetails = output;
307
299
  return {
308
300
  content: [{ type: "text" as const, text: "Fixer report accepted" }],
309
301
  details: acceptedDetails,
@@ -452,11 +444,7 @@ export function createCoderRoleRuntime(
452
444
  toolCallId,
453
445
  });
454
446
  }
455
- // #391: attach sole-built engineLaborFallback when detour fell back to seat labor.
456
- const acceptedDetails = withEngineLaborFallbackField(
457
- output,
458
- readActivationEngineLaborFallbackField(),
459
- );
447
+ const acceptedDetails = output;
460
448
  return {
461
449
  content: [{ type: "text" as const, text: "Coder report accepted" }],
462
450
  details: acceptedDetails,
@@ -1,136 +0,0 @@
1
- let activationLatch;
2
- function buildEngineLaborFallbackField(input) {
3
- return Object.freeze({
4
- engineLaborFallback: Object.freeze({
5
- engine: input.engine,
6
- failure: input.failure,
7
- laborBy: "seat"
8
- })
9
- });
10
- }
11
- const SEAT_FALLBACK_STATUS_SUFFIX = "-by-fallback";
12
- function isSeatFallbackTaintedStatus(status) {
13
- return status.endsWith(SEAT_FALLBACK_STATUS_SUFFIX);
14
- }
15
- function seatFallbackBaseStatus(status) {
16
- return isSeatFallbackTaintedStatus(status) ? status.slice(0, -SEAT_FALLBACK_STATUS_SUFFIX.length) : status;
17
- }
18
- function seatFallbackStatusHasLawfulEvidence(status, source) {
19
- if (!isSeatFallbackTaintedStatus(status)) return true;
20
- return readEngineLaborFallbackFieldFrom(source) !== void 0;
21
- }
22
- function taintStatusForSeatFallback(status) {
23
- if (status.length === 0 || isSeatFallbackTaintedStatus(status)) return status;
24
- return `${status}${SEAT_FALLBACK_STATUS_SUFFIX}`;
25
- }
26
- const STATUS_DISCRIMINATOR_KEYS = ["judgeStatus", "status"];
27
- function taintReceiptStatusDiscriminators(receipt) {
28
- let next;
29
- for (const key of STATUS_DISCRIMINATOR_KEYS) {
30
- if (!Object.prototype.hasOwnProperty.call(receipt, key)) continue;
31
- let value;
32
- try {
33
- value = receipt[key];
34
- } catch {
35
- continue;
36
- }
37
- if (typeof value !== "string" || value.length === 0) continue;
38
- const tainted = taintStatusForSeatFallback(value);
39
- if (tainted === value) continue;
40
- if (next === void 0) {
41
- next = { ...receipt };
42
- }
43
- next[key] = tainted;
44
- }
45
- return next === void 0 ? receipt : next;
46
- }
47
- function createEngineLaborFallbackLatch() {
48
- return { field: void 0 };
49
- }
50
- function recordEngineLaborFallback(latch, input) {
51
- const field = buildEngineLaborFallbackField(input);
52
- if (latch.field === void 0) latch.field = field;
53
- return latch.field;
54
- }
55
- function readEngineLaborFallbackField(latch) {
56
- return latch?.field;
57
- }
58
- function withEngineLaborFallbackField(receipt, field) {
59
- if (field !== void 0) {
60
- const taintedReceipt = taintReceiptStatusDiscriminators(receipt);
61
- return { ...taintedReceipt, ...field };
62
- }
63
- if (!Object.prototype.hasOwnProperty.call(receipt, "engineLaborFallback")) {
64
- return receipt;
65
- }
66
- const { engineLaborFallback: _forged, ...rest } = receipt;
67
- return rest;
68
- }
69
- function installActivationEngineLaborFallbackLatch(latch) {
70
- activationLatch = latch;
71
- }
72
- function clearActivationEngineLaborFallbackLatch() {
73
- activationLatch = void 0;
74
- }
75
- function activationEngineLaborFallbackLatch() {
76
- return activationLatch;
77
- }
78
- function readActivationEngineLaborFallbackField() {
79
- return readEngineLaborFallbackField(activationLatch);
80
- }
81
- function readEngineLaborFallbackFieldFrom(source) {
82
- if (typeof source !== "object" || source === null || Array.isArray(source)) {
83
- return void 0;
84
- }
85
- let raw;
86
- try {
87
- raw = source.engineLaborFallback;
88
- } catch {
89
- return void 0;
90
- }
91
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
92
- const rec = raw;
93
- if (typeof rec.engine !== "string" || typeof rec.failure !== "string" || rec.laborBy !== "seat") {
94
- return void 0;
95
- }
96
- return buildEngineLaborFallbackField({
97
- engine: rec.engine,
98
- failure: rec.failure
99
- });
100
- }
101
- function restoreEngineLaborFallbackFromSessionEntries(latch, entries, toolName) {
102
- for (const entry of entries) {
103
- if (typeof entry !== "object" || entry === null) continue;
104
- const row = entry;
105
- if (row.type !== "message") continue;
106
- const message = row.message;
107
- if (typeof message !== "object" || message === null) continue;
108
- const msg = message;
109
- if (msg.role !== "toolResult") continue;
110
- if (msg.toolName !== toolName) continue;
111
- const field = readEngineLaborFallbackFieldFrom(msg.details);
112
- if (field === void 0) continue;
113
- recordEngineLaborFallback(latch, {
114
- engine: field.engineLaborFallback.engine,
115
- failure: field.engineLaborFallback.failure
116
- });
117
- }
118
- }
119
- export {
120
- SEAT_FALLBACK_STATUS_SUFFIX,
121
- activationEngineLaborFallbackLatch,
122
- buildEngineLaborFallbackField,
123
- clearActivationEngineLaborFallbackLatch,
124
- createEngineLaborFallbackLatch,
125
- installActivationEngineLaborFallbackLatch,
126
- isSeatFallbackTaintedStatus,
127
- readActivationEngineLaborFallbackField,
128
- readEngineLaborFallbackField,
129
- readEngineLaborFallbackFieldFrom,
130
- recordEngineLaborFallback,
131
- restoreEngineLaborFallbackFromSessionEntries,
132
- seatFallbackBaseStatus,
133
- seatFallbackStatusHasLawfulEvidence,
134
- taintStatusForSeatFallback,
135
- withEngineLaborFallbackField
136
- };