@akagilnc/pi-workflow-roles 0.1.5382 → 0.1.5406

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 (51) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/dist/acp-host/production-host.js +2523 -1880
  4. package/dist/archivist-record-pointer.js +38 -0
  5. package/dist/compliance-transport.js +5 -0
  6. package/dist/doctor-auditor.js +1 -0
  7. package/dist/engine-detour-usage.js +6 -6
  8. package/dist/headless-host/production-host.js +1097 -454
  9. package/dist/judge-role.js +14 -1
  10. package/dist/migrate-book-topology.js +190 -74
  11. package/dist/navigator-attendance.js +10 -9
  12. package/dist/navigator-invocation-identity.js +18 -0
  13. package/dist/pi/role-turn-host.js +9 -0
  14. package/dist/public-cli/cli.js +1 -0
  15. package/dist/public-cli/instruction-seat-run.js +250 -44
  16. package/dist/public-cli/main.js +929 -323
  17. package/dist/public-cli/post-admission.js +427 -244
  18. package/dist/public-cli/settlement.js +111 -48
  19. package/dist/public-cli/terminal.js +12 -1
  20. package/dist/public-cli/turn-request.js +3 -0
  21. package/dist/receipt-delivery-policy.js +152 -17
  22. package/dist/submission-errors.js +11 -1
  23. package/dist/submission-gate.js +27 -4
  24. package/package.json +1 -1
  25. package/src/archivist-record-pointer.ts +48 -0
  26. package/src/compliance-transport.ts +10 -2
  27. package/src/doctor-auditor.ts +3 -0
  28. package/src/engine-detour-usage.ts +7 -6
  29. package/src/external-host-turn-loop.ts +24 -12
  30. package/src/gatekeeper-role.ts +2 -2
  31. package/src/host-contracts.ts +7 -0
  32. package/src/judge-role.ts +24 -5
  33. package/src/navigator-attendance.ts +17 -12
  34. package/src/navigator-invocation-identity.ts +31 -0
  35. package/src/pi/adapter.ts +33 -8
  36. package/src/pi/role-turn-host.ts +7 -0
  37. package/src/public-cli/cli.ts +1 -0
  38. package/src/public-cli/instruction-seat-run.ts +283 -49
  39. package/src/public-cli/post-admission.ts +556 -324
  40. package/src/public-cli/settlement.ts +112 -50
  41. package/src/public-cli/terminal.ts +16 -4
  42. package/src/public-cli/turn-request.ts +10 -1
  43. package/src/receipt-delivery-policy.ts +209 -17
  44. package/src/role-envelope.ts +5 -1
  45. package/src/role-runtime-dependencies.ts +1 -0
  46. package/src/role-runtime.ts +65 -21
  47. package/src/submission-correctable-error.ts +5 -2
  48. package/src/submission-errors.ts +12 -1
  49. package/src/submission-gate.ts +34 -4
  50. package/src/worker-role.ts +19 -7
  51. package/src/worker-submission-gates.ts +29 -7
@@ -1828,6 +1828,9 @@ ${serializeReceipt(result.submission)}`;
1828
1828
  }
1829
1829
  return `\u95E8\u4E0B\u7701 ${result.status}\uFF08${result.stage}\uFF09\uFF1A${result.reason}`;
1830
1830
  }
1831
+ function isOneShotWorkerReminderCode(code) {
1832
+ return code === "worker_commit_reminder" || code === "worker_prefix_reminder";
1833
+ }
1831
1834
  function unreadableDiscriminatorNotice(field, received) {
1832
1835
  if (received === void 0) return `\u8BFB\u4E0D\u51FA ${field}`;
1833
1836
  return `\u8BFB\u4E0D\u51FA ${field}\uFF1A${readableGateItem(received)}`;
@@ -1868,7 +1871,7 @@ var init_submission_errors = __esm({
1868
1871
  WorkerUnfinishedReasonReminderError = class extends Error {
1869
1872
  code = "worker_unfinished_reason_reminder";
1870
1873
  constructor() {
1871
- super("\u672C\u6B21 unfinished \u56DE\u6267\u672A\u542B reason\uFF1B\u672C\u63A5\u7F1D\u7F3A\u7531\u81F3\u591A\u6253\u56DE\u4E24\u6B21\u3002");
1874
+ super("\u672C\u6B21 unfinished \u56DE\u6267\u672A\u542B reason\uFF1B\u8BF7\u8865\u4E0A reason \u540E\u518D\u4EA4\u3002");
1872
1875
  this.name = "WorkerUnfinishedReasonReminderError";
1873
1876
  }
1874
1877
  };
@@ -2526,6 +2529,23 @@ function markerMatchesExpectedIdentity(marker, expected) {
2526
2529
  }
2527
2530
  return true;
2528
2531
  }
2532
+ function packagedRoleOutputRejectionReason(message) {
2533
+ if (typeof message.toolName !== "string") return void 0;
2534
+ if (!PACKAGED_ROLE_OUTPUT_TOOLS.has(message.toolName) && message.toolName !== "ak_submission_output") {
2535
+ return void 0;
2536
+ }
2537
+ if (message.isError !== true) return void 0;
2538
+ if (classifyPackagedRoleTerminalResult(message).kind !== "nonterminal") return void 0;
2539
+ const content = message.content;
2540
+ if (typeof content === "string") return content.trim();
2541
+ if (!Array.isArray(content)) return "";
2542
+ return content.map((part) => {
2543
+ if (isRecord(part) && part.type === "text" && typeof part.text === "string") {
2544
+ return part.text;
2545
+ }
2546
+ return "";
2547
+ }).join("").trim();
2548
+ }
2529
2549
  function classifyPackagedRoleTerminalResult(message) {
2530
2550
  if (typeof message.toolName !== "string") return { kind: "nonterminal" };
2531
2551
  if (!PACKAGED_ROLE_OUTPUT_TOOLS.has(message.toolName) && message.toolName !== "ak_submission_output") return { kind: "nonterminal" };
@@ -4553,6 +4573,13 @@ function formatTerminalResult(result) {
4553
4573
  `diagnostic ${encodeTerminalField(result.roleOutcome.diagnostic)}`
4554
4574
  );
4555
4575
  }
4576
+ if (result.roleOutcome.kind === "accepted" && result.roleOutcome.decisiveFacts?.directionUnsettled === true) {
4577
+ lines.push("fact directionUnsettled true");
4578
+ const subsequent = result.roleOutcome.decisiveFacts.subsequentAudit;
4579
+ if (typeof subsequent === "string") {
4580
+ lines.push(`fact subsequentAudit ${encodeTerminalField(subsequent)}`);
4581
+ }
4582
+ }
4556
4583
  if (result.roleOutcome.kind === "failure" || result.roleOutcome.kind === "no_receipt" || result.roleOutcome.kind === "audit_escalation" || result.roleOutcome.decisiveFacts?.failedAttempts !== void 0) {
4557
4584
  const facts = result.roleOutcome.kind === "accepted" ? { failedAttempts: result.roleOutcome.decisiveFacts?.failedAttempts } : result.roleOutcome.decisiveFacts ?? {};
4558
4585
  for (const [key, value] of Object.entries(facts)) {
@@ -4611,7 +4638,7 @@ function formatTerminalResult(result) {
4611
4638
  lines.push(`recorded-submission ${encodeTerminalField(rendered)}`);
4612
4639
  }
4613
4640
  } else {
4614
- const payloads = result.roleOutcome.kind === "accepted" || result.roleOutcome.kind === "audit_escalation" ? coalesceSubmissionRows(result.roleOutcome.payloads, result.submissions) : result.submissions ?? [];
4641
+ const payloads = result.roleOutcome.kind === "accepted" || result.roleOutcome.kind === "audit_escalation" ? coalesceSubmissionRows(result.submissions, result.roleOutcome.payloads) : result.submissions ?? [];
4615
4642
  for (let i = payloads.length - 1; i >= 0; i -= 1) {
4616
4643
  const payload = payloads[i];
4617
4644
  const rendered = typeof payload === "string" ? payload : JSON.stringify(payload);
@@ -4627,6 +4654,230 @@ var init_terminal = __esm({
4627
4654
  }
4628
4655
  });
4629
4656
 
4657
+ // src/receipt-delivery-policy.ts
4658
+ function receiptAttemptPointer(runPointer, invocationScopeId) {
4659
+ const scope = invocationScopeId?.trim() ?? "";
4660
+ if (scope.length > 0) return `invocation:${scope}`;
4661
+ return `current:${runPointer}`;
4662
+ }
4663
+ function deliveryLimitFromConfig(value) {
4664
+ return parseAutoResumeLimit(value ?? AUTO_RESUME_LIMIT);
4665
+ }
4666
+ function deliveryLimitFromEnv(env) {
4667
+ const raw = env[RECEIPT_DELIVERY_LIMIT_ENV];
4668
+ if (raw === void 0 || raw.trim() === "") return deliveryLimitFromConfig(void 0);
4669
+ const parsed = Number(raw);
4670
+ if (!Number.isInteger(parsed)) return deliveryLimitFromConfig(void 0);
4671
+ return deliveryLimitFromConfig(parsed);
4672
+ }
4673
+ function deliveryTurnsFact(value) {
4674
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
4675
+ throw new TypeError("deliveryTurns must be a non-negative integer");
4676
+ }
4677
+ return value;
4678
+ }
4679
+ function parseNoReceiptLifecycleFacts(input) {
4680
+ if (!isRecord(input) || typeof input.terminalToolCalled !== "boolean" || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord(item) && typeof item.reason === "string")) {
4681
+ throw new TypeError("malformed no-receipt lifecycle facts");
4682
+ }
4683
+ return {
4684
+ terminalToolCalled: input.terminalToolCalled,
4685
+ rejectedReceipts: input.rejectedReceipts.map((item) => ({
4686
+ reason: item.reason,
4687
+ diagnosticAvailable: item.reason.trim() !== ""
4688
+ })),
4689
+ deliveryTurns: deliveryTurnsFact(input.deliveryTurns),
4690
+ sessionCompletion: "settled-without-accepted-receipt",
4691
+ runPointer: input.runPointer,
4692
+ attemptPointer: input.attemptPointer,
4693
+ acceptedReceipt: false
4694
+ };
4695
+ }
4696
+ function noReceiptLifecycleFacts(input) {
4697
+ return {
4698
+ terminalToolCalled: input.terminalToolCalled,
4699
+ rejectedReceipts: input.rejectedReceipts.map(({ reason }) => ({
4700
+ reason,
4701
+ diagnosticAvailable: reason.trim() !== ""
4702
+ })),
4703
+ deliveryTurns: deliveryTurnsFact(input.deliveryTurns),
4704
+ sessionCompletion: "settled-without-accepted-receipt",
4705
+ runPointer: input.runPointer,
4706
+ attemptPointer: input.attemptPointer,
4707
+ acceptedReceipt: false
4708
+ };
4709
+ }
4710
+ function createReceiptDeliveryPolicy(limit) {
4711
+ const deliveryLimit = deliveryLimitFromConfig(limit);
4712
+ let accepted = false;
4713
+ let closed = false;
4714
+ let terminalToolCalled = false;
4715
+ let deliveryTurns = 0;
4716
+ let budgetSpent = 0;
4717
+ const rejectedReceipts = [];
4718
+ const spend = () => {
4719
+ if (budgetSpent < deliveryLimit) budgetSpent += 1;
4720
+ };
4721
+ return {
4722
+ /** The effective ceiling this budget spends (#1132 — never re-read). */
4723
+ limit: deliveryLimit,
4724
+ recordAccepted() {
4725
+ accepted = true;
4726
+ terminalToolCalled = true;
4727
+ },
4728
+ /** Infrastructure owns terminality and must never trigger receipt催交. */
4729
+ stopForInfrastructure() {
4730
+ accepted = true;
4731
+ },
4732
+ /**
4733
+ * Record the rejection this turn already produced.
4734
+ * The fact does not spend a budget. The seam that sends the next prompt
4735
+ * owns that count.
4736
+ */
4737
+ recordRejected(reason) {
4738
+ terminalToolCalled = true;
4739
+ rejectedReceipts.push({ reason, diagnosticAvailable: reason.trim() !== "" });
4740
+ },
4741
+ recordDeliveryRequest() {
4742
+ deliveryTurns += 1;
4743
+ spend();
4744
+ },
4745
+ /**
4746
+ * Stop asking. The issued count stays whatever was actually sent (#1132 —
4747
+ * do not fill the remainder up to the ceiling).
4748
+ */
4749
+ closeBudget() {
4750
+ closed = true;
4751
+ },
4752
+ /**
4753
+ * A nested session settled without an accepted receipt. Close so this layer
4754
+ * does not open another prompt on that session. The issued count stays the
4755
+ * larger of the two seams: a nested zero must not wipe prompts this layer
4756
+ * already sent, and adding the two counts would bill one send twice.
4757
+ */
4758
+ recordNestedNoReceipt(facts) {
4759
+ terminalToolCalled = terminalToolCalled || facts.terminalToolCalled;
4760
+ rejectedReceipts.push(...facts.rejectedReceipts);
4761
+ deliveryTurns = Math.max(deliveryTurns, facts.deliveryTurns);
4762
+ closed = true;
4763
+ },
4764
+ nextAction() {
4765
+ if (accepted) return "accepted";
4766
+ if (closed) return "no-receipt";
4767
+ return budgetSpent < deliveryLimit ? "request-delivery" : "no-receipt";
4768
+ },
4769
+ /** Delivery requests actually issued so far (#1132). */
4770
+ issuedDeliveryRequests() {
4771
+ return deliveryTurns;
4772
+ },
4773
+ /** Current typed delivery facts. No prose. */
4774
+ deliveryState() {
4775
+ return {
4776
+ terminalToolCalled,
4777
+ rejectedReceipts: rejectedReceipts.map((item) => ({ ...item })),
4778
+ deliveryTurns,
4779
+ acceptedReceipt: false
4780
+ };
4781
+ },
4782
+ facts(binding) {
4783
+ return noReceiptLifecycleFacts({ terminalToolCalled, rejectedReceipts: [...rejectedReceipts], deliveryTurns, ...binding });
4784
+ },
4785
+ /**
4786
+ * Continue a public call after the in-memory policy was rebuilt.
4787
+ * Sends already issued spend the same budget; copied rejections keep
4788
+ * the fact and do not spend again.
4789
+ */
4790
+ continueIssued(prior) {
4791
+ for (const receipt of prior.rejectedReceipts) {
4792
+ this.recordRejected(receipt.reason);
4793
+ }
4794
+ if (prior.terminalToolCalled === true) terminalToolCalled = true;
4795
+ for (let index = 0; index < prior.deliveryTurns; index += 1) {
4796
+ this.recordDeliveryRequest();
4797
+ }
4798
+ }
4799
+ };
4800
+ }
4801
+ function entryRecord(entry) {
4802
+ return isRecord(entry) ? entry : void 0;
4803
+ }
4804
+ function customTypeOf(record, message) {
4805
+ return record.customType ?? message?.customType;
4806
+ }
4807
+ function dataOf(record, message) {
4808
+ return record.data ?? message?.details;
4809
+ }
4810
+ function scopeTag(record) {
4811
+ const message = isRecord(record.message) ? record.message : void 0;
4812
+ const customType = customTypeOf(record, message);
4813
+ const data = dataOf(record, message);
4814
+ if ((customType === RECEIPT_DELIVERY_REQUEST_ENTRY || customType === RECEIPT_REJECTION_ENTRY) && isRecord(data) && typeof data.invocationScopeId === "string" && data.invocationScopeId.trim() !== "") {
4815
+ return data.invocationScopeId;
4816
+ }
4817
+ if (customType !== NO_RECEIPT_LIFECYCLE_ENTRY_TYPE) return void 0;
4818
+ try {
4819
+ const facts = parseNoReceiptLifecycleFacts(data);
4820
+ const prefix = "invocation:";
4821
+ if (!facts.attemptPointer.startsWith(prefix)) return void 0;
4822
+ const scope = facts.attemptPointer.slice(prefix.length);
4823
+ return scope.trim() === "" ? void 0 : scope;
4824
+ } catch {
4825
+ return void 0;
4826
+ }
4827
+ }
4828
+ function priorReceiptContinuation(entries, invocationScopeId) {
4829
+ const pointer = receiptAttemptPointer("", invocationScopeId);
4830
+ let entryTurns = 0;
4831
+ let factTurns = 0;
4832
+ let rejectedReceipts = [];
4833
+ let snapshotTerminal = false;
4834
+ for (const entry of entries) {
4835
+ const record = entryRecord(entry);
4836
+ if (record === void 0) continue;
4837
+ const tagged = scopeTag(record);
4838
+ if (tagged !== void 0) {
4839
+ const message = isRecord(record.message) ? record.message : void 0;
4840
+ const customType = customTypeOf(record, message);
4841
+ if (tagged !== invocationScopeId) continue;
4842
+ if (customType === RECEIPT_DELIVERY_REQUEST_ENTRY) entryTurns += 1;
4843
+ if (customType === RECEIPT_REJECTION_ENTRY) {
4844
+ const data = dataOf(record, message);
4845
+ if (isRecord(data) && typeof data.reason === "string") rejectedReceipts.push({ reason: data.reason });
4846
+ }
4847
+ if (customType !== NO_RECEIPT_LIFECYCLE_ENTRY_TYPE) continue;
4848
+ try {
4849
+ const facts = parseNoReceiptLifecycleFacts(dataOf(record, message));
4850
+ if (facts.attemptPointer !== pointer) continue;
4851
+ factTurns = Math.max(factTurns, facts.deliveryTurns);
4852
+ if (facts.rejectedReceipts.length >= rejectedReceipts.length) {
4853
+ rejectedReceipts = facts.rejectedReceipts.map(({ reason }) => ({ reason }));
4854
+ }
4855
+ snapshotTerminal ||= facts.terminalToolCalled;
4856
+ } catch {
4857
+ }
4858
+ continue;
4859
+ }
4860
+ }
4861
+ return {
4862
+ deliveryTurns: Math.max(entryTurns, factTurns),
4863
+ rejectedReceipts,
4864
+ terminalToolCalled: snapshotTerminal || rejectedReceipts.length > 0
4865
+ };
4866
+ }
4867
+ var NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_REQUEST_ENTRY, RECEIPT_REJECTION_ENTRY, RECEIPT_DELIVERY_LIMIT_ENV;
4868
+ var init_receipt_delivery_policy = __esm({
4869
+ "src/receipt-delivery-policy.ts"() {
4870
+ "use strict";
4871
+ init_run_lifecycle();
4872
+ init_config();
4873
+ init_unknown_value();
4874
+ NO_RECEIPT_LIFECYCLE_ENTRY_TYPE = "ak-no-receipt-lifecycle";
4875
+ RECEIPT_DELIVERY_REQUEST_ENTRY = "ak-receipt-delivery-request";
4876
+ RECEIPT_REJECTION_ENTRY = "ak-receipt-rejection";
4877
+ RECEIPT_DELIVERY_LIMIT_ENV = "AK_ROLE_RECEIPT_DELIVERY_LIMIT";
4878
+ }
4879
+ });
4880
+
4630
4881
  // src/session-assistant-usage.ts
4631
4882
  var session_assistant_usage_exports = {};
4632
4883
  __export(session_assistant_usage_exports, {
@@ -4636,10 +4887,10 @@ __export(session_assistant_usage_exports, {
4636
4887
  });
4637
4888
  import { join as join14 } from "node:path";
4638
4889
  async function readAssistantUsageFromSessionFile(sessionFile) {
4639
- const { readFile: readFile25 } = await import("node:fs/promises");
4890
+ const { readFile: readFile26 } = await import("node:fs/promises");
4640
4891
  let text;
4641
4892
  try {
4642
- text = await readFile25(sessionFile, "utf8");
4893
+ text = await readFile26(sessionFile, "utf8");
4643
4894
  } catch (error) {
4644
4895
  if (error?.code === "ENOENT") return void 0;
4645
4896
  throw error;
@@ -5144,6 +5395,8 @@ function createPiRoleTurnHost(config) {
5144
5395
  else env.AK_ROLE_INVOCATION_SCOPE = request.invocationScopeId;
5145
5396
  if (request.host === void 0 || request.host.trim() === "") delete env.AK_ROLE_HOST;
5146
5397
  else env.AK_ROLE_HOST = request.host.trim();
5398
+ if (request.deliveryRequestLimit === void 0) delete env[RECEIPT_DELIVERY_LIMIT_ENV];
5399
+ else env[RECEIPT_DELIVERY_LIMIT_ENV] = String(request.deliveryRequestLimit);
5147
5400
  applyEngineChildEnv(env, request.engine);
5148
5401
  if (typeof process.env.AK_ROLE_AUDITOR_SOURCE_RUN === "string" && process.env.AK_ROLE_AUDITOR_SOURCE_RUN.trim() !== "") {
5149
5402
  env.AK_ROLE_AUDITOR_SOURCE_RUN = process.env.AK_ROLE_AUDITOR_SOURCE_RUN;
@@ -5203,6 +5456,7 @@ var init_role_turn_host = __esm({
5203
5456
  init_engine_detour();
5204
5457
  init_role_activation_flags();
5205
5458
  init_user_dialogue_stdin();
5459
+ init_receipt_delivery_policy();
5206
5460
  init_sitian_facade();
5207
5461
  INTERNAL_ROLE_ENTRYPOINT_RELATIVE2 = "extensions/role-runtime.ts";
5208
5462
  EXPLICIT_INTERNAL_LOAD_PROBE_ARGS = [
@@ -9284,10 +9538,10 @@ function pairGateRounds(volumes) {
9284
9538
  return rounds.sort((a, b) => a.officerStartedAt.localeCompare(b.officerStartedAt)).map((round, index) => ({ ...round, roundIndex: index + 1 }));
9285
9539
  }
9286
9540
  async function resolveOfficerSessionFromPointerFile(pointerPath) {
9287
- const { readFile: readFile25 } = await import("node:fs/promises");
9541
+ const { readFile: readFile26 } = await import("node:fs/promises");
9288
9542
  let raw;
9289
9543
  try {
9290
- raw = JSON.parse(await readFile25(pointerPath, "utf8"));
9544
+ raw = JSON.parse(await readFile26(pointerPath, "utf8"));
9291
9545
  } catch (error) {
9292
9546
  throw new Error(
9293
9547
  `direct officer run pointer unreadable in ${pointerPath}: ${errorText(error)}`,
@@ -10167,9 +10421,7 @@ function runDirectoryFromSessionDirectory(sessionDirectory) {
10167
10421
  function sessionFileFromSessionDirectory(sessionDirectory) {
10168
10422
  return join26(sessionDirectory, "session.jsonl");
10169
10423
  }
10170
- function mintEngineDetourInvocationScope(input) {
10171
- const engine = input.effectiveEngine?.trim();
10172
- if (engine === void 0 || engine.length === 0) return void 0;
10424
+ function mintEngineDetourInvocationScope(_input) {
10173
10425
  return randomUUID4();
10174
10426
  }
10175
10427
  function withEngineDetourInvocationScope(request, invocationScopeId) {
@@ -10259,101 +10511,6 @@ var init_dossier_resolution = __esm({
10259
10511
  }
10260
10512
  });
10261
10513
 
10262
- // src/receipt-delivery-policy.ts
10263
- function parseNoReceiptLifecycleFacts(input) {
10264
- if (!isRecord(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord(item) && typeof item.reason === "string")) {
10265
- throw new TypeError("malformed no-receipt lifecycle facts");
10266
- }
10267
- return {
10268
- terminalToolCalled: input.terminalToolCalled,
10269
- rejectedReceipts: input.rejectedReceipts.map((item) => ({
10270
- reason: item.reason,
10271
- diagnosticAvailable: item.reason.trim() !== ""
10272
- })),
10273
- deliveryTurns: RECEIPT_DELIVERY_TURN_LIMIT,
10274
- sessionCompletion: "settled-without-accepted-receipt",
10275
- runPointer: input.runPointer,
10276
- attemptPointer: input.attemptPointer,
10277
- acceptedReceipt: false
10278
- };
10279
- }
10280
- function noReceiptLifecycleFacts(input) {
10281
- if (input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT) {
10282
- throw new TypeError("no-receipt lifecycle requires an exhausted delivery budget");
10283
- }
10284
- return {
10285
- terminalToolCalled: input.terminalToolCalled,
10286
- rejectedReceipts: input.rejectedReceipts.map(({ reason }) => ({
10287
- reason,
10288
- diagnosticAvailable: reason.trim() !== ""
10289
- })),
10290
- deliveryTurns: RECEIPT_DELIVERY_TURN_LIMIT,
10291
- sessionCompletion: "settled-without-accepted-receipt",
10292
- runPointer: input.runPointer,
10293
- attemptPointer: input.attemptPointer,
10294
- acceptedReceipt: false
10295
- };
10296
- }
10297
- function createReceiptDeliveryPolicy() {
10298
- let accepted = false;
10299
- let terminalToolCalled = false;
10300
- let deliveryTurns = 0;
10301
- const rejectedReceipts = [];
10302
- return {
10303
- recordAccepted() {
10304
- accepted = true;
10305
- terminalToolCalled = true;
10306
- },
10307
- /** Infrastructure owns terminality and must never trigger receipt催交. */
10308
- stopForInfrastructure() {
10309
- accepted = true;
10310
- },
10311
- recordRejected(reason) {
10312
- terminalToolCalled = true;
10313
- rejectedReceipts.push({ reason, diagnosticAvailable: reason.trim() !== "" });
10314
- deliveryTurns = Math.min(RECEIPT_DELIVERY_TURN_LIMIT, deliveryTurns + 1);
10315
- },
10316
- recordDeliveryRequest() {
10317
- deliveryTurns = Math.min(RECEIPT_DELIVERY_TURN_LIMIT, deliveryTurns + 1);
10318
- },
10319
- /**
10320
- * A nested session settled without an accepted receipt after spending its own
10321
- * delivery budget. Adopt its facts and close this budget: another prompt would
10322
- * open an independent session, not a delivery request on the settled one.
10323
- */
10324
- recordNestedNoReceipt(facts) {
10325
- terminalToolCalled = terminalToolCalled || facts.terminalToolCalled;
10326
- rejectedReceipts.push(...facts.rejectedReceipts);
10327
- deliveryTurns = RECEIPT_DELIVERY_TURN_LIMIT;
10328
- },
10329
- nextAction() {
10330
- if (accepted) return "accepted";
10331
- return deliveryTurns < RECEIPT_DELIVERY_TURN_LIMIT ? "request-delivery" : "no-receipt";
10332
- },
10333
- /** Current typed delivery facts. No prose. */
10334
- deliveryState() {
10335
- return {
10336
- terminalToolCalled,
10337
- rejectedReceipts: rejectedReceipts.map((item) => ({ ...item })),
10338
- deliveryTurns,
10339
- acceptedReceipt: false
10340
- };
10341
- },
10342
- facts(binding) {
10343
- return noReceiptLifecycleFacts({ terminalToolCalled, rejectedReceipts: [...rejectedReceipts], deliveryTurns, ...binding });
10344
- }
10345
- };
10346
- }
10347
- var RECEIPT_DELIVERY_TURN_LIMIT, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE;
10348
- var init_receipt_delivery_policy = __esm({
10349
- "src/receipt-delivery-policy.ts"() {
10350
- "use strict";
10351
- init_unknown_value();
10352
- RECEIPT_DELIVERY_TURN_LIMIT = 2;
10353
- NO_RECEIPT_LIFECYCLE_ENTRY_TYPE = "ak-no-receipt-lifecycle";
10354
- }
10355
- });
10356
-
10357
10514
  // src/public-cli/settlement.ts
10358
10515
  var settlement_exports = {};
10359
10516
  __export(settlement_exports, {
@@ -10496,13 +10653,76 @@ async function attachRecordedSubmissions(admitted, terminal, scope) {
10496
10653
  if (errorPath !== void 0) privateFailureErrorPaths.set(result, errorPath);
10497
10654
  return result;
10498
10655
  }
10499
- async function settleHostEndedNoReceipt(admitted, authority, scope) {
10656
+ function lifecycleFactsFromEntry(entry) {
10657
+ const customType = entry.customType ?? entry.message?.customType;
10658
+ if (customType !== NO_RECEIPT_LIFECYCLE_ENTRY_TYPE) return void 0;
10659
+ return entry.data ?? entry.message?.details;
10660
+ }
10661
+ async function readCurrentAttemptNoReceiptFacts(admitted, authority, scope) {
10662
+ const { sessionFile } = coordinatesFromAdmitted(authority, admitted);
10663
+ const entries = await readBoundSessionEntries(sessionFile).catch(() => void 0);
10664
+ if (entries === void 0) return void 0;
10665
+ const scopeId = scope?.invocationScopeId?.trim() ?? "";
10666
+ if (scopeId.length > 0) {
10667
+ const pointer = receiptAttemptPointer(admitted.runDirectory, scopeId);
10668
+ let selected;
10669
+ for (const entry of entries) {
10670
+ const raw2 = lifecycleFactsFromEntry(entry);
10671
+ if (raw2 === void 0) continue;
10672
+ try {
10673
+ const facts2 = parseNoReceiptLifecycleFacts(raw2);
10674
+ if (facts2.runPointer !== admitted.runDirectory) continue;
10675
+ if (facts2.attemptPointer !== pointer) continue;
10676
+ if (selected === void 0 || facts2.deliveryTurns >= selected.deliveryTurns) {
10677
+ selected = facts2;
10678
+ }
10679
+ } catch {
10680
+ }
10681
+ }
10682
+ return selected;
10683
+ }
10684
+ let attemptStart = 0;
10685
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
10686
+ if (entries[index]?.type === "message" && entries[index]?.message?.role === "user") {
10687
+ attemptStart = index;
10688
+ break;
10689
+ }
10690
+ }
10691
+ const lifecycleEntry = entries.slice(attemptStart).reverse().find((entry) => lifecycleFactsFromEntry(entry) !== void 0);
10692
+ const raw = lifecycleEntry === void 0 ? void 0 : lifecycleFactsFromEntry(lifecycleEntry);
10693
+ if (raw === void 0) return void 0;
10694
+ let facts;
10695
+ try {
10696
+ facts = parseNoReceiptLifecycleFacts(raw);
10697
+ } catch {
10698
+ return void 0;
10699
+ }
10700
+ if (facts.runPointer !== admitted.runDirectory) return void 0;
10701
+ if (facts.attemptPointer !== receiptAttemptPointer(admitted.runDirectory)) return void 0;
10702
+ return facts;
10703
+ }
10704
+ async function settleHostEndedNoReceipt(admitted, authority, scope, issuedDeliveryRequests = 0) {
10705
+ const scopeId = scope?.invocationScopeId?.trim() ?? "";
10706
+ const persisted = scopeId.length > 0 ? void 0 : await readCurrentAttemptNoReceiptFacts(admitted, authority, scope);
10707
+ let terminalToolCalled = persisted?.terminalToolCalled ?? false;
10708
+ let rejectedReceipts = persisted?.rejectedReceipts ?? [];
10709
+ let recordedTurns = persisted?.deliveryTurns ?? 0;
10710
+ if (scopeId.length > 0) {
10711
+ const { sessionFile } = coordinatesFromAdmitted(authority, admitted);
10712
+ const entries = await readBoundSessionEntries(sessionFile).catch(() => void 0);
10713
+ if (entries !== void 0) {
10714
+ const prior = priorReceiptContinuation(entries, scopeId);
10715
+ terminalToolCalled = prior.terminalToolCalled;
10716
+ rejectedReceipts = prior.rejectedReceipts;
10717
+ recordedTurns = prior.deliveryTurns;
10718
+ }
10719
+ }
10500
10720
  const facts = noReceiptLifecycleFacts({
10501
- terminalToolCalled: false,
10502
- rejectedReceipts: [],
10503
- deliveryTurns: RECEIPT_DELIVERY_TURN_LIMIT,
10721
+ terminalToolCalled,
10722
+ rejectedReceipts,
10723
+ deliveryTurns: Math.max(issuedDeliveryRequests, recordedTurns),
10504
10724
  runPointer: admitted.runDirectory,
10505
- attemptPointer: `current:${admitted.runDirectory}`
10725
+ attemptPointer: receiptAttemptPointer(admitted.runDirectory, scope?.invocationScopeId)
10506
10726
  });
10507
10727
  const coordinates = coordinatesFromAdmitted(authority, admitted);
10508
10728
  await clearOppositeTerminalArtifactFace(admitted.runDirectory);
@@ -12075,44 +12295,26 @@ async function settleFailureTerminalResult(admitted, failure, authority, options
12075
12295
  const coordinates = coordinatesFromAdmitted(authority, admitted);
12076
12296
  const { sessionDirectory, sessionFile } = coordinates;
12077
12297
  if (failure.cause === "output") {
12078
- const entries = await readBoundSessionEntries(sessionFile).catch(() => void 0);
12079
- if (entries !== void 0) {
12080
- let attemptStart = 0;
12081
- for (let index = entries.length - 1; index >= 0; index -= 1) {
12082
- if (entries[index]?.type === "message" && entries[index]?.message?.role === "user") {
12083
- attemptStart = index;
12084
- break;
12085
- }
12086
- }
12087
- const lifecycleEntry = entries.slice(attemptStart).reverse().find((entry) => entry.customType === NO_RECEIPT_LIFECYCLE_ENTRY_TYPE || entry.message?.customType === NO_RECEIPT_LIFECYCLE_ENTRY_TYPE);
12088
- const raw = lifecycleEntry?.data ?? lifecycleEntry?.message?.details;
12089
- if (raw !== void 0) {
12090
- let facts;
12091
- try {
12092
- facts = parseNoReceiptLifecycleFacts(raw);
12093
- } catch {
12094
- }
12095
- if (facts !== void 0 && facts.runPointer === admitted.runDirectory && facts.attemptPointer === `current:${admitted.runDirectory}`) {
12096
- let decisiveFacts2 = facts;
12097
- await clearOppositeTerminalArtifactFace(admitted.runDirectory);
12098
- return withOptionalGateProjection(
12099
- {
12100
- roleOutcome: {
12101
- kind: "no_receipt",
12102
- role: admitted.role,
12103
- status: "no-accepted-receipt",
12104
- ...facts,
12105
- decisiveFacts: decisiveFacts2
12106
- },
12107
- navigator: await extractNavigatorFactFromAdmittedSession(sessionFile),
12108
- artifacts: [],
12109
- runId: admitted.runId
12110
- },
12111
- sessionDirectory,
12112
- detourGateContext(admitted, options)
12113
- );
12114
- }
12115
- }
12298
+ const facts = await readCurrentAttemptNoReceiptFacts(admitted, authority, options);
12299
+ if (facts !== void 0) {
12300
+ const decisiveFacts2 = facts;
12301
+ await clearOppositeTerminalArtifactFace(admitted.runDirectory);
12302
+ return withOptionalGateProjection(
12303
+ {
12304
+ roleOutcome: {
12305
+ kind: "no_receipt",
12306
+ role: admitted.role,
12307
+ status: "no-accepted-receipt",
12308
+ ...facts,
12309
+ decisiveFacts: decisiveFacts2
12310
+ },
12311
+ navigator: await extractNavigatorFactFromAdmittedSession(sessionFile),
12312
+ artifacts: [],
12313
+ runId: admitted.runId
12314
+ },
12315
+ sessionDirectory,
12316
+ detourGateContext(admitted, options)
12317
+ );
12116
12318
  }
12117
12319
  }
12118
12320
  const navigator = await extractNavigatorFactFromAdmittedSession(sessionFile);
@@ -12282,16 +12484,19 @@ var init_settlement = __esm({
12282
12484
 
12283
12485
  // src/archivist-record-pointer.ts
12284
12486
  import { mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
12487
+ import { readFile as readFile17 } from "node:fs/promises";
12285
12488
  import { dirname as dirname17, join as join28 } from "node:path";
12286
12489
  function bookDirectOfficerRunPointer(options) {
12287
12490
  const nest = join28(dirname17(options.parentSessionFile), "auditor-roles");
12288
12491
  mkdirSync2(nest, { recursive: true });
12492
+ const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
12289
12493
  const pointer = {
12290
12494
  version: 1,
12291
12495
  kind: DIRECT_OFFICER_RUN_POINTER_KIND,
12292
12496
  officer: options.officer,
12293
12497
  sessionFile: options.sessionFile,
12294
- ...options.runDirectory !== void 0 && options.runDirectory.trim() !== "" ? { runDirectory: options.runDirectory } : {}
12498
+ ...options.runDirectory !== void 0 && options.runDirectory.trim() !== "" ? { runDirectory: options.runDirectory } : {},
12499
+ ...submissionToolCallId === "" ? {} : { submissionToolCallId }
12295
12500
  };
12296
12501
  writeFileSync(
12297
12502
  join28(nest, `${options.officer}.pointer.json`),
@@ -12301,10 +12506,36 @@ function bookDirectOfficerRunPointer(options) {
12301
12506
  );
12302
12507
  return pointer;
12303
12508
  }
12509
+ async function readDirectOfficerRunPointer(parentSessionFile, officer) {
12510
+ try {
12511
+ const raw = JSON.parse(await readFile17(
12512
+ join28(dirname17(parentSessionFile), "auditor-roles", `${officer}.pointer.json`),
12513
+ "utf8"
12514
+ ));
12515
+ if (!isRecord(raw) || raw.kind !== DIRECT_OFFICER_RUN_POINTER_KIND || raw.version !== 1) {
12516
+ return void 0;
12517
+ }
12518
+ if (raw.officer !== officer) return void 0;
12519
+ if (typeof raw.sessionFile !== "string" || raw.sessionFile.trim() === "") return void 0;
12520
+ const runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== "" ? raw.runDirectory : void 0;
12521
+ const submissionToolCallId = typeof raw.submissionToolCallId === "string" && raw.submissionToolCallId.trim() !== "" ? raw.submissionToolCallId : void 0;
12522
+ return {
12523
+ version: 1,
12524
+ kind: DIRECT_OFFICER_RUN_POINTER_KIND,
12525
+ officer,
12526
+ sessionFile: raw.sessionFile,
12527
+ ...runDirectory === void 0 ? {} : { runDirectory },
12528
+ ...submissionToolCallId === void 0 ? {} : { submissionToolCallId }
12529
+ };
12530
+ } catch {
12531
+ return void 0;
12532
+ }
12533
+ }
12304
12534
  var DIRECT_OFFICER_RUN_POINTER_KIND;
12305
12535
  var init_archivist_record_pointer = __esm({
12306
12536
  "src/archivist-record-pointer.ts"() {
12307
12537
  "use strict";
12538
+ init_unknown_value();
12308
12539
  DIRECT_OFFICER_RUN_POINTER_KIND = "direct-officer-run-pointer";
12309
12540
  }
12310
12541
  });
@@ -12322,6 +12553,7 @@ function createPiDoctorAuditor() {
12322
12553
  submission: options.submission,
12323
12554
  ...auditorRunDirectory(options.context) === void 0 ? {} : { runDirectory: auditorRunDirectory(options.context) },
12324
12555
  ...options.signal === void 0 ? {} : { signal: options.signal },
12556
+ ...options.autoResumeLimit === void 0 ? {} : { autoResumeLimit: options.autoResumeLimit },
12325
12557
  ...options.summonAuditor === void 0 ? {} : { summonAuditor: options.summonAuditor }
12326
12558
  });
12327
12559
  };
@@ -12369,10 +12601,23 @@ async function runJudgeGates(input) {
12369
12601
  if (await input.gateAlreadyConverged(subject)) continue;
12370
12602
  const pass = await input.runGate(subject);
12371
12603
  const received = pass?.status;
12372
- if (pass === void 0 || typeof received !== "string" || !REVIEW_QUEUE_STATUSES.has(received)) {
12604
+ if (pass === void 0 || (typeof received !== "string" || !REVIEW_QUEUE_STATUSES.has(received) && received !== "needs_reask")) {
12373
12605
  throw new Error("judge gate returned no conclusion");
12374
12606
  }
12375
12607
  const status = received;
12608
+ if (status === "needs_reask") {
12609
+ return {
12610
+ status,
12611
+ passes: [{
12612
+ subject,
12613
+ status,
12614
+ receipt: pass.receipt,
12615
+ ...pass.runId === void 0 ? {} : { runId: pass.runId },
12616
+ ...pass.runDirectory === void 0 ? {} : { runDirectory: pass.runDirectory },
12617
+ ...pass.terminal === void 0 ? {} : { terminal: pass.terminal }
12618
+ }]
12619
+ };
12620
+ }
12376
12621
  passes.push({
12377
12622
  subject,
12378
12623
  status,
@@ -12477,7 +12722,7 @@ function createDefaultGateOfficerSummon(options) {
12477
12722
  });
12478
12723
  };
12479
12724
  }
12480
- function bookDirectOfficerPointer(context, officer, result, summoned) {
12725
+ function bookDirectOfficerPointer(context, officer, result, summoned, toolCallId) {
12481
12726
  if (result.status !== "converged" && result.status !== "continue" && result.status !== "escalate" && result.status !== "needs_reask" && result.status !== "transport_failure") {
12482
12727
  return;
12483
12728
  }
@@ -12491,11 +12736,14 @@ function bookDirectOfficerPointer(context, officer, result, summoned) {
12491
12736
  parentSessionFile: parentFile,
12492
12737
  officer,
12493
12738
  sessionFile,
12494
- ...typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== "" ? { runDirectory: summoned.runDirectory } : {}
12739
+ ...typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== "" ? { runDirectory: summoned.runDirectory } : {},
12740
+ ...toolCallId.trim() === "" ? {} : { submissionToolCallId: toolCallId }
12495
12741
  });
12496
12742
  }
12497
12743
  async function requireSubmissionGate(options) {
12498
12744
  let reask;
12745
+ let reasksSpent = 0;
12746
+ const reaskLimit = deliveryLimitFromConfig(options.autoResumeLimit);
12499
12747
  const summonOfficer = options.summonOfficer ?? createDefaultGateOfficerSummon({
12500
12748
  cwd: options.context.cwd ?? process.cwd()
12501
12749
  });
@@ -12515,7 +12763,8 @@ async function requireSubmissionGate(options) {
12515
12763
  options.context,
12516
12764
  projected.officer,
12517
12765
  gatekeeper,
12518
- projected.summoned
12766
+ projected.summoned,
12767
+ options.toolCallId
12519
12768
  );
12520
12769
  } catch (error) {
12521
12770
  options.hostActions.failInfrastructure(error, options.context, options.toolCallId);
@@ -12538,6 +12787,17 @@ async function requireSubmissionGate(options) {
12538
12787
  };
12539
12788
  }
12540
12789
  if (gatekeeper.status === "needs_reask") {
12790
+ if (reasksSpent >= reaskLimit) {
12791
+ return {
12792
+ status: "needs_reask",
12793
+ officer: projected.officer,
12794
+ receipt: gatekeeper.receipt,
12795
+ ...typeof gatekeeper.runId === "string" && gatekeeper.runId.trim() !== "" ? { runId: gatekeeper.runId } : {},
12796
+ ...typeof projected.summoned?.runDirectory === "string" && projected.summoned.runDirectory.trim() !== "" ? { runDirectory: projected.summoned.runDirectory } : {},
12797
+ ...projected.summoned?.terminal === void 0 ? {} : { terminal: projected.summoned.terminal }
12798
+ };
12799
+ }
12800
+ reasksSpent += 1;
12541
12801
  reask = officerConclusionReask(gatekeeper.receivedStatus);
12542
12802
  continue;
12543
12803
  }
@@ -12567,6 +12827,7 @@ var init_submission_gate = __esm({
12567
12827
  init_archivist_record_pointer();
12568
12828
  init_gatekeeper_role();
12569
12829
  init_submission_errors();
12830
+ init_receipt_delivery_policy();
12570
12831
  init_session_assistant_usage();
12571
12832
  init_unknown_value();
12572
12833
  }
@@ -12746,7 +13007,8 @@ function projectRoleTurnRequest(admitted, roleDetails, options) {
12746
13007
  ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
12747
13008
  ...options.courtAttemptId === void 0 || options.courtAttemptId.length === 0 ? {} : { courtAttemptId: options.courtAttemptId },
12748
13009
  ...options.invocationScopeId === void 0 || options.invocationScopeId.length === 0 ? {} : { invocationScopeId: options.invocationScopeId },
12749
- ...options.stationChild === void 0 ? {} : { stationChild: options.stationChild }
13010
+ ...options.stationChild === void 0 ? {} : { stationChild: options.stationChild },
13011
+ ...options.deliveryRequestLimit === void 0 ? {} : { deliveryRequestLimit: options.deliveryRequestLimit }
12750
13012
  };
12751
13013
  }
12752
13014
  function packagedSettleSkill(admitted) {
@@ -12824,7 +13086,7 @@ var init_turn_request = __esm({
12824
13086
  });
12825
13087
 
12826
13088
  // src/session-identity.ts
12827
- import { mkdir as mkdir3, readFile as readFile17, rename as rename3, writeFile as writeFile6 } from "node:fs/promises";
13089
+ import { mkdir as mkdir3, readFile as readFile18, rename as rename3, writeFile as writeFile6 } from "node:fs/promises";
12828
13090
  import { dirname as dirname18, join as join30 } from "node:path";
12829
13091
  function createSessionIdentityAuthority(authority, sessionBindingFile) {
12830
13092
  const bindingPath = (principal) => join30(authority.decode(principal).sessionDirectory, sessionBindingFile);
@@ -12834,7 +13096,7 @@ function createSessionIdentityAuthority(authority, sessionBindingFile) {
12834
13096
  },
12835
13097
  async load(principal) {
12836
13098
  try {
12837
- const value = JSON.parse(await readFile17(bindingPath(principal), "utf8"));
13099
+ const value = JSON.parse(await readFile18(bindingPath(principal), "utf8"));
12838
13100
  if (typeof value !== "object" || value === null || typeof value.sessionId !== "string") {
12839
13101
  throw new Error("durable session binding is invalid");
12840
13102
  }
@@ -13631,47 +13893,242 @@ async function presentControlledFailure2(admitted, failureInput, adapters, autho
13631
13893
  if (io.omitFailureStderrDiagnostic && publishedErrorPath !== void 0) {
13632
13894
  writeResumeFailurePointer(io, publishedErrorPath);
13633
13895
  }
13634
- throw error;
13896
+ throw error;
13897
+ }
13898
+ presentFailureTerminal(terminal, io);
13899
+ return {
13900
+ exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome),
13901
+ admitted,
13902
+ terminal
13903
+ };
13904
+ }
13905
+ async function settleAfterTurnStarted(admitted, failureInput, adapters, authority, io, persistRunState) {
13906
+ try {
13907
+ return await presentControlledFailure2(
13908
+ admitted,
13909
+ failureInput,
13910
+ adapters,
13911
+ authority,
13912
+ io,
13913
+ persistRunState
13914
+ );
13915
+ } catch (error) {
13916
+ throw new TurnDispatchedFailure(error);
13917
+ }
13918
+ }
13919
+ async function settleDeferredPersist(admitted, authority, adapters, io, result) {
13920
+ if (result.needsPersist !== true || result.terminal === void 0) return result;
13921
+ const { needsPersist: _needsPersist, ...settledResult } = result;
13922
+ const lawful = isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
13923
+ try {
13924
+ await persistReturnedRunState(admitted, lawful ? { lawful: true } : void 0);
13925
+ return settledResult;
13926
+ } catch (error) {
13927
+ const failed = await settleAfterTurnStarted(
13928
+ admitted,
13929
+ { timedOut: false, code: null, stderr: "", thrown: error, skipRunStateWrite: true },
13930
+ adapters,
13931
+ authority,
13932
+ io,
13933
+ true
13934
+ );
13935
+ return {
13936
+ ...failed,
13937
+ turnDispatched: true,
13938
+ skipAutoResume: true
13939
+ };
13940
+ }
13941
+ }
13942
+ function settlementScopeForTurn(request) {
13943
+ const hasCourt = request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0;
13944
+ const hasScope = request.invocationScopeId !== void 0 && request.invocationScopeId.length > 0;
13945
+ if (!hasCourt && !hasScope) return void 0;
13946
+ return {
13947
+ ...hasCourt ? { courtAttemptId: request.courtAttemptId } : {},
13948
+ ...hasScope ? { invocationScopeId: request.invocationScopeId } : {}
13949
+ };
13950
+ }
13951
+ async function buildReceiptDeliveryRequest(input) {
13952
+ const { admitted, env, request, receiptDelivery } = input;
13953
+ const hostSessionId = await readStoredHostSessionId(
13954
+ env.host,
13955
+ env.principalAuthority,
13956
+ admitted.principal
13957
+ );
13958
+ return {
13959
+ ...request,
13960
+ continuation: {
13961
+ kind: "resume",
13962
+ prompt: JSON.stringify({
13963
+ ...receiptDelivery.deliveryState(),
13964
+ deliveryTurns: receiptDelivery.issuedDeliveryRequests() + 1
13965
+ }),
13966
+ ...hostSessionId === void 0 ? {} : { hostSessionId }
13967
+ },
13968
+ deliveryRequestLimit: receiptDelivery.limit
13969
+ };
13970
+ }
13971
+ async function settleCompletedHostTurn(input) {
13972
+ const { admitted, env, io, adapters, shouldPresent, request, result, persistRunState, deferredPersist } = input;
13973
+ const finishAfterTurn = input.finishAfterTurn;
13974
+ let stderrLogWriteFailure;
13975
+ try {
13976
+ await writeFile7(
13977
+ join33(admitted.runDirectory, "stderr.log"),
13978
+ result.stderr,
13979
+ "utf8"
13980
+ );
13981
+ } catch (error) {
13982
+ stderrLogWriteFailure = error;
13983
+ await recordBestEffortPostDispatchDiagnostic(
13984
+ admitted,
13985
+ env,
13986
+ `stderr.log write failed (best-effort continue): ${describeErrorIdentity(error)}`,
13987
+ io
13988
+ );
13989
+ }
13990
+ const courtScope = settlementScopeForTurn(request);
13991
+ let settled;
13992
+ let settledOutcome;
13993
+ let hostSignalFailed = false;
13994
+ let resolution;
13995
+ try {
13996
+ const sessionFile = admitted.principal !== void 0 ? env.principalAuthority.decode(admitted.principal).sessionFile : "";
13997
+ const runnerKnownFailure = adapters.resolveRunnerKnownFailure !== void 0 && sessionFile !== "" ? await adapters.resolveRunnerKnownFailure({ result, sessionFile }) : result.knownFailure;
13998
+ resolution = await resolveAuditedRunnerFailureResolution({
13999
+ runner: runnerKnownFailure,
14000
+ sessionFile,
14001
+ credential: void 0,
14002
+ runDirectory: admitted.runDirectory
14003
+ });
14004
+ const processCancelName = processCancelSignalName(env.signal);
14005
+ const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || processCancelName !== void 0;
14006
+ hostSignalFailed = directHostFailureSignal || result.code !== null && result.code !== 0 || resolution.knownFailure !== void 0;
14007
+ settled = await adapters.trySettle(admitted, env.principalAuthority, courtScope);
14008
+ if (settled !== void 0) {
14009
+ settled = await attachRecordedSubmissions(admitted, settled, courtScope);
14010
+ }
14011
+ const settledIsFreshThisAttempt = settled === void 0 || settled.roleOutcome.kind !== "accepted" && settled.roleOutcome.kind !== "audit_escalation" ? true : await attemptProducedFreshSubmission(admitted, courtScope);
14012
+ const staleAcceptanceOutranksRealFailure = !settledIsFreshThisAttempt && hostSignalFailed;
14013
+ const cancelAfterSettle = processCancelSignalName(env.signal);
14014
+ if (settled !== void 0 && shouldPresent(settled) && !directHostFailureSignal && !staleAcceptanceOutranksRealFailure && stderrLogWriteFailure === void 0 && cancelAfterSettle === void 0) {
14015
+ if (settled.roleOutcome.kind === "accepted" && request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0) {
14016
+ try {
14017
+ await clearCurrentCourt(admitted.runDirectory, request.courtAttemptId);
14018
+ } catch (error) {
14019
+ await recordBestEffortPostDispatchDiagnostic(
14020
+ admitted,
14021
+ env,
14022
+ `current-court cleanup failed after accepted settlement (best-effort continue): ${describeErrorIdentity(error)}`,
14023
+ io
14024
+ );
14025
+ }
14026
+ }
14027
+ settledOutcome = {
14028
+ exitCode: exitCodeForTerminalOutcome(settled.roleOutcome),
14029
+ admitted,
14030
+ terminal: settled,
14031
+ turnDispatched: true
14032
+ };
14033
+ }
14034
+ } catch (error) {
14035
+ const settledFailure = await settleAfterTurnStarted(
14036
+ admitted,
14037
+ withEngineDetourInvocationScope({
14038
+ timedOut: false,
14039
+ code: result.code,
14040
+ stderr: result.stderr,
14041
+ thrown: error
14042
+ }, request.invocationScopeId),
14043
+ adapters,
14044
+ env.principalAuthority,
14045
+ io,
14046
+ persistRunState
14047
+ );
14048
+ return { kind: "settled", outcome: await finishAfterTurn({ ...settledFailure, turnDispatched: true, ...deferredPersist }) };
14049
+ }
14050
+ if (settledOutcome !== void 0) {
14051
+ const lateCancel = processCancelSignalName(env.signal);
14052
+ if (lateCancel !== void 0) {
14053
+ return { kind: "settled", outcome: await finishAfterTurn(
14054
+ await settleProcessCancelAfterTurn({
14055
+ admitted,
14056
+ cancelName: lateCancel,
14057
+ result,
14058
+ adapters,
14059
+ env,
14060
+ io,
14061
+ persistRunState,
14062
+ deferredPersist,
14063
+ invocationScopeId: request.invocationScopeId
14064
+ })
14065
+ ) };
14066
+ }
14067
+ if (persistRunState) {
14068
+ try {
14069
+ await persistReturnedRunState(admitted, { lawful: true });
14070
+ } catch (error) {
14071
+ await recordBestEffortPostDispatchDiagnostic(
14072
+ admitted,
14073
+ env,
14074
+ `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
14075
+ io
14076
+ );
14077
+ }
14078
+ }
14079
+ return { kind: "settled", outcome: await finishAfterTurn({ ...settledOutcome, ...deferredPersist }) };
13635
14080
  }
13636
- presentFailureTerminal(terminal, io);
13637
- return {
13638
- exitCode: exitCodeForTerminalOutcome(terminal.roleOutcome),
13639
- admitted,
13640
- terminal
13641
- };
13642
- }
13643
- async function settleAfterTurnStarted(admitted, failureInput, adapters, authority, io, persistRunState) {
13644
- try {
13645
- return await presentControlledFailure2(
14081
+ if (hostSignalFailed) {
14082
+ const resolutionInput = controlledFailureInputFromResolution(resolution);
14083
+ const processCancelName = processCancelSignalName(env.signal);
14084
+ const stderrLogWriteDetails = stderrLogWriteFailure === void 0 ? void 0 : { stderrLogWriteFailure: describeCaughtError(stderrLogWriteFailure) };
14085
+ const failed = await settleAfterTurnStarted(
13646
14086
  admitted,
13647
- failureInput,
14087
+ withEngineDetourInvocationScope({
14088
+ timedOut: result.timedOut,
14089
+ code: result.code,
14090
+ stderr: result.stderr,
14091
+ ...resolutionInput,
14092
+ ...processCancelName === void 0 ? {} : { knownDiagnostic: processCancelDiagnostic(processCancelName) },
14093
+ // Secondary fact only — never the cause. Rides on whichever channel
14094
+ // classification actually reads (knownFailure.details owns it when
14095
+ // a knownFailure exists; the top-level knownDetails otherwise).
14096
+ ...stderrLogWriteDetails === void 0 ? {} : resolutionInput.knownFailure !== void 0 ? {
14097
+ knownFailure: {
14098
+ ...resolutionInput.knownFailure,
14099
+ details: { ...resolutionInput.knownFailure.details ?? {}, ...stderrLogWriteDetails }
14100
+ }
14101
+ } : { knownDetails: stderrLogWriteDetails }
14102
+ }, request.invocationScopeId),
13648
14103
  adapters,
13649
- authority,
14104
+ env.principalAuthority,
13650
14105
  io,
13651
14106
  persistRunState
13652
14107
  );
13653
- } catch (error) {
13654
- throw new TurnDispatchedFailure(error);
14108
+ return { kind: "settled", outcome: await finishAfterTurn(
14109
+ withProcessCancelSkipAutoResume(
14110
+ { ...failed, turnDispatched: true, ...deferredPersist },
14111
+ env.signal
14112
+ )
14113
+ ) };
13655
14114
  }
13656
- }
13657
- async function settleDeferredPersist(admitted, authority, adapters, io, result) {
13658
- if (result.needsPersist !== true || result.terminal === void 0) return result;
13659
- const { needsPersist: _needsPersist, ...settledResult } = result;
13660
- const lawful = isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
13661
- try {
13662
- await persistReturnedRunState(admitted, lawful ? { lawful: true } : void 0);
13663
- return settledResult;
13664
- } catch (error) {
14115
+ if (stderrLogWriteFailure !== void 0) {
13665
14116
  const failed = await settleAfterTurnStarted(
13666
14117
  admitted,
13667
- { timedOut: false, code: null, stderr: "", thrown: error, skipRunStateWrite: true },
14118
+ withEngineDetourInvocationScope({
14119
+ timedOut: false,
14120
+ code: result.code,
14121
+ stderr: result.stderr,
14122
+ thrown: stderrLogWriteFailure
14123
+ }, request.invocationScopeId),
13668
14124
  adapters,
13669
- authority,
14125
+ env.principalAuthority,
13670
14126
  io,
13671
- true
14127
+ persistRunState
13672
14128
  );
13673
- return { ...failed, turnDispatched: true, skipAutoResume: true };
14129
+ return { kind: "settled", outcome: await finishAfterTurn({ ...failed, turnDispatched: true, ...deferredPersist }) };
13674
14130
  }
14131
+ return { kind: "still-missing" };
13675
14132
  }
13676
14133
  async function dispatchPostAdmissionTurn(input) {
13677
14134
  const { admitted, env, io, request, lease, adapters, effectiveEngine } = input;
@@ -13679,6 +14136,9 @@ async function dispatchPostAdmissionTurn(input) {
13679
14136
  const deferredPersist = persistRunState ? {} : { needsPersist: true };
13680
14137
  const shouldPresent = adapters.shouldPresentSettled ?? ((terminal) => isLawfulTypedTerminalOutcome(terminal.roleOutcome));
13681
14138
  let afterDispatchApplied = false;
14139
+ const receiptDelivery = input.receiptDelivery ?? createReceiptDeliveryPolicy(env.autoResumeLimit);
14140
+ let turnDispatched = false;
14141
+ const akSeamDeliversReceipt = env.host !== void 0 && env.host !== "" && env.host !== DEFAULT_ROLE_TURN_HOST;
13682
14142
  const finishAfterTurn = async (result) => {
13683
14143
  if (afterDispatchApplied) return result;
13684
14144
  afterDispatchApplied = true;
@@ -13776,7 +14236,7 @@ async function dispatchPostAdmissionTurn(input) {
13776
14236
  return { exitCode: 0, admitted, terminal: paused, skipAutoResume: true };
13777
14237
  }
13778
14238
  } catch (error) {
13779
- const settled2 = await presentControlledFailure2(
14239
+ const settled = await presentControlledFailure2(
13780
14240
  admitted,
13781
14241
  withEngineDetourInvocationScope({
13782
14242
  timedOut: false,
@@ -13789,7 +14249,7 @@ async function dispatchPostAdmissionTurn(input) {
13789
14249
  io,
13790
14250
  persistRunState
13791
14251
  );
13792
- return { ...settled2, ...deferredPersist };
14252
+ return { ...settled, ...deferredPersist };
13793
14253
  }
13794
14254
  }
13795
14255
  let turnRequest = {
@@ -13813,10 +14273,11 @@ async function dispatchPostAdmissionTurn(input) {
13813
14273
  let result;
13814
14274
  try {
13815
14275
  recordRunStart(admitted.runDirectory);
14276
+ turnDispatched = true;
13816
14277
  result = await env.roleTurnHost.executeTurn(turnRequest);
13817
14278
  } catch (error) {
13818
14279
  const processCancelName = processCancelSignalName(env.signal);
13819
- const settled2 = await settleAfterTurnStarted(
14280
+ const settled = await settleAfterTurnStarted(
13820
14281
  admitted,
13821
14282
  withEngineDetourInvocationScope({
13822
14283
  timedOut: false,
@@ -13831,175 +14292,111 @@ async function dispatchPostAdmissionTurn(input) {
13831
14292
  );
13832
14293
  return await finishAfterTurn(
13833
14294
  withProcessCancelSkipAutoResume(
13834
- { ...settled2, turnDispatched: true, ...deferredPersist },
14295
+ { ...settled, turnDispatched: true, ...deferredPersist },
13835
14296
  env.signal
13836
14297
  )
13837
14298
  );
13838
14299
  }
13839
- let stderrLogWriteFailure;
13840
- try {
13841
- await writeFile7(
13842
- join33(admitted.runDirectory, "stderr.log"),
13843
- result.stderr,
13844
- "utf8"
13845
- );
13846
- } catch (error) {
13847
- stderrLogWriteFailure = error;
13848
- await recordBestEffortPostDispatchDiagnostic(
14300
+ const settledTurn = await settleCompletedHostTurn({
14301
+ admitted,
14302
+ env,
14303
+ io,
14304
+ adapters,
14305
+ shouldPresent,
14306
+ request,
14307
+ result,
14308
+ persistRunState,
14309
+ deferredPersist,
14310
+ finishAfterTurn
14311
+ });
14312
+ if (settledTurn.kind === "settled") return settledTurn.outcome;
14313
+ while (akSeamDeliversReceipt && receiptDelivery.nextAction() === "request-delivery") {
14314
+ let deliveryResult;
14315
+ let deliveryTurnRequest;
14316
+ try {
14317
+ const deliveryRequest = await buildReceiptDeliveryRequest({
14318
+ admitted,
14319
+ env,
14320
+ // Host and the other axes already selected on this turn ride the
14321
+ // shared projection. The pre-projection request does not have them.
14322
+ request: turnRequest,
14323
+ receiptDelivery
14324
+ });
14325
+ deliveryTurnRequest = {
14326
+ ...deliveryRequest,
14327
+ principal: admitted.principal,
14328
+ runDirectory: admitted.runDirectory,
14329
+ ...env.signal === void 0 ? {} : { signal: env.signal }
14330
+ };
14331
+ receiptDelivery.recordDeliveryRequest();
14332
+ deliveryResult = await env.roleTurnHost.executeTurn(deliveryTurnRequest);
14333
+ } catch (error) {
14334
+ const settled = await settleAfterTurnStarted(
14335
+ admitted,
14336
+ withEngineDetourInvocationScope(
14337
+ { timedOut: false, code: null, stderr: "", thrown: error },
14338
+ request.invocationScopeId
14339
+ ),
14340
+ adapters,
14341
+ env.principalAuthority,
14342
+ io,
14343
+ persistRunState
14344
+ );
14345
+ return await finishAfterTurn(
14346
+ withProcessCancelSkipAutoResume(
14347
+ {
14348
+ ...settled,
14349
+ turnDispatched: true,
14350
+ ...deferredPersist
14351
+ },
14352
+ env.signal
14353
+ )
14354
+ );
14355
+ }
14356
+ const deliveryTurn = await settleCompletedHostTurn({
13849
14357
  admitted,
13850
14358
  env,
13851
- `stderr.log write failed (best-effort continue): ${describeErrorIdentity(error)}`,
13852
- io
13853
- );
13854
- }
13855
- const courtScope = (request.courtAttemptId === void 0 || request.courtAttemptId.length === 0) && (request.invocationScopeId === void 0 || request.invocationScopeId.length === 0) ? void 0 : {
13856
- ...request.courtAttemptId === void 0 || request.courtAttemptId.length === 0 ? {} : { courtAttemptId: request.courtAttemptId },
13857
- ...request.invocationScopeId === void 0 || request.invocationScopeId.length === 0 ? {} : { invocationScopeId: request.invocationScopeId }
13858
- };
13859
- let settled;
13860
- let settledOutcome;
13861
- let hostSignalFailed = false;
13862
- let resolution;
13863
- try {
13864
- const sessionFile = admitted.principal !== void 0 ? env.principalAuthority.decode(admitted.principal).sessionFile : "";
13865
- const runnerKnownFailure = adapters.resolveRunnerKnownFailure !== void 0 && sessionFile !== "" ? await adapters.resolveRunnerKnownFailure({ result, sessionFile }) : result.knownFailure;
13866
- resolution = await resolveAuditedRunnerFailureResolution({
13867
- runner: runnerKnownFailure,
13868
- sessionFile,
13869
- credential: void 0,
13870
- runDirectory: admitted.runDirectory
14359
+ // Only the final Terminal presents; intermediate delivery attempts stay quiet.
14360
+ io: { ...io, stdout: () => {
14361
+ } },
14362
+ adapters,
14363
+ shouldPresent,
14364
+ request: deliveryTurnRequest,
14365
+ result: deliveryResult,
14366
+ // Run-state terminal write belongs to the OUTERMOST turn only, so a
14367
+ // still-silent delivery attempt never makes the run look lawfully terminal.
14368
+ persistRunState: false,
14369
+ deferredPersist,
14370
+ finishAfterTurn
13871
14371
  });
13872
- const processCancelName = processCancelSignalName(env.signal);
13873
- const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || processCancelName !== void 0;
13874
- hostSignalFailed = directHostFailureSignal || result.code !== null && result.code !== 0 || resolution.knownFailure !== void 0;
13875
- settled = await adapters.trySettle(admitted, env.principalAuthority, courtScope);
13876
- if (settled !== void 0) {
13877
- settled = await attachRecordedSubmissions(admitted, settled, courtScope);
13878
- }
13879
- const settledIsFreshThisAttempt = settled === void 0 || settled.roleOutcome.kind !== "accepted" && settled.roleOutcome.kind !== "audit_escalation" ? true : await attemptProducedFreshSubmission(admitted, courtScope);
13880
- const staleAcceptanceOutranksRealFailure = !settledIsFreshThisAttempt && hostSignalFailed;
13881
- const cancelAfterSettle = processCancelSignalName(env.signal);
13882
- if (settled !== void 0 && shouldPresent(settled) && !directHostFailureSignal && !staleAcceptanceOutranksRealFailure && stderrLogWriteFailure === void 0 && cancelAfterSettle === void 0) {
13883
- if (settled.roleOutcome.kind === "accepted" && request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0) {
14372
+ if (deliveryTurn.kind === "settled") {
14373
+ if (persistRunState && deliveryTurn.outcome.terminal !== void 0) {
13884
14374
  try {
13885
- await clearCurrentCourt(admitted.runDirectory, request.courtAttemptId);
14375
+ await persistReturnedRunState(admitted, {
14376
+ lawful: isLawfulTypedTerminalOutcome(deliveryTurn.outcome.terminal.roleOutcome)
14377
+ });
13886
14378
  } catch (error) {
13887
14379
  await recordBestEffortPostDispatchDiagnostic(
13888
14380
  admitted,
13889
14381
  env,
13890
- `current-court cleanup failed after accepted settlement (best-effort continue): ${describeErrorIdentity(error)}`,
14382
+ `run-state persistence failed beside\u50AC\u4EA4 terminal (best-effort continue): ${describeErrorIdentity(error)}`,
13891
14383
  io
13892
14384
  );
13893
14385
  }
13894
14386
  }
13895
- settledOutcome = {
13896
- exitCode: exitCodeForTerminalOutcome(settled.roleOutcome),
13897
- admitted,
13898
- terminal: settled,
13899
- turnDispatched: true
13900
- };
13901
- }
13902
- } catch (error) {
13903
- const settledFailure = await settleAfterTurnStarted(
13904
- admitted,
13905
- withEngineDetourInvocationScope({
13906
- timedOut: false,
13907
- code: result.code,
13908
- stderr: result.stderr,
13909
- thrown: error
13910
- }, request.invocationScopeId),
13911
- adapters,
13912
- env.principalAuthority,
13913
- io,
13914
- persistRunState
13915
- );
13916
- return await finishAfterTurn({ ...settledFailure, turnDispatched: true, ...deferredPersist });
13917
- }
13918
- if (settledOutcome !== void 0) {
13919
- const lateCancel = processCancelSignalName(env.signal);
13920
- if (lateCancel !== void 0) {
13921
- return await finishAfterTurn(
13922
- await settleProcessCancelAfterTurn({
13923
- admitted,
13924
- cancelName: lateCancel,
13925
- result,
13926
- adapters,
13927
- env,
13928
- io,
13929
- persistRunState,
13930
- deferredPersist,
13931
- invocationScopeId: request.invocationScopeId
13932
- })
13933
- );
13934
- }
13935
- if (persistRunState) {
13936
- try {
13937
- await persistReturnedRunState(admitted, { lawful: true });
13938
- } catch (error) {
13939
- await recordBestEffortPostDispatchDiagnostic(
13940
- admitted,
13941
- env,
13942
- `run-state persistence failed beside host terminal (best-effort continue): ${describeErrorIdentity(error)}`,
13943
- io
13944
- );
13945
- }
14387
+ return await finishAfterTurn(deliveryTurn.outcome);
13946
14388
  }
13947
- return await finishAfterTurn({ ...settledOutcome, ...deferredPersist });
13948
- }
13949
- if (hostSignalFailed) {
13950
- const resolutionInput = controlledFailureInputFromResolution(resolution);
13951
- const processCancelName = processCancelSignalName(env.signal);
13952
- const stderrLogWriteDetails = stderrLogWriteFailure === void 0 ? void 0 : { stderrLogWriteFailure: describeCaughtError(stderrLogWriteFailure) };
13953
- const failed = await settleAfterTurnStarted(
13954
- admitted,
13955
- withEngineDetourInvocationScope({
13956
- timedOut: result.timedOut,
13957
- code: result.code,
13958
- stderr: result.stderr,
13959
- ...resolutionInput,
13960
- ...processCancelName === void 0 ? {} : { knownDiagnostic: processCancelDiagnostic(processCancelName) },
13961
- // Secondary fact only — never the cause. Rides on whichever channel
13962
- // classification actually reads (knownFailure.details owns it when
13963
- // a knownFailure exists; the top-level knownDetails otherwise).
13964
- ...stderrLogWriteDetails === void 0 ? {} : resolutionInput.knownFailure !== void 0 ? {
13965
- knownFailure: {
13966
- ...resolutionInput.knownFailure,
13967
- details: { ...resolutionInput.knownFailure.details ?? {}, ...stderrLogWriteDetails }
13968
- }
13969
- } : { knownDetails: stderrLogWriteDetails }
13970
- }, request.invocationScopeId),
13971
- adapters,
13972
- env.principalAuthority,
13973
- io,
13974
- persistRunState
13975
- );
13976
- return await finishAfterTurn(
13977
- withProcessCancelSkipAutoResume(
13978
- { ...failed, turnDispatched: true, ...deferredPersist },
13979
- env.signal
13980
- )
13981
- );
13982
- }
13983
- if (stderrLogWriteFailure !== void 0) {
13984
- const failed = await settleAfterTurnStarted(
13985
- admitted,
13986
- withEngineDetourInvocationScope({
13987
- timedOut: false,
13988
- code: result.code,
13989
- stderr: result.stderr,
13990
- thrown: stderrLogWriteFailure
13991
- }, request.invocationScopeId),
13992
- adapters,
13993
- env.principalAuthority,
13994
- io,
13995
- persistRunState
13996
- );
13997
- return await finishAfterTurn({ ...failed, turnDispatched: true, ...deferredPersist });
13998
14389
  }
14390
+ const noReceiptScope = settlementScopeForTurn(request);
13999
14391
  const noReceipt = await attachRecordedSubmissions(
14000
14392
  admitted,
14001
- await settleHostEndedNoReceipt(admitted, env.principalAuthority, courtScope),
14002
- courtScope
14393
+ await settleHostEndedNoReceipt(
14394
+ admitted,
14395
+ env.principalAuthority,
14396
+ noReceiptScope,
14397
+ receiptDelivery.issuedDeliveryRequests()
14398
+ ),
14399
+ noReceiptScope
14003
14400
  );
14004
14401
  const noReceiptCancel = processCancelSignalName(env.signal);
14005
14402
  if (noReceiptCancel !== void 0) {
@@ -14036,6 +14433,11 @@ async function dispatchPostAdmissionTurn(input) {
14036
14433
  turnDispatched: true,
14037
14434
  ...deferredPersist
14038
14435
  });
14436
+ } catch (error) {
14437
+ if (turnDispatched && !(error instanceof TurnDispatchedFailure)) {
14438
+ throw new TurnDispatchedFailure(error);
14439
+ }
14440
+ throw error;
14039
14441
  } finally {
14040
14442
  if (lease !== void 0) {
14041
14443
  try {
@@ -14081,7 +14483,9 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
14081
14483
  prompt
14082
14484
  },
14083
14485
  ...request.message === void 0 ? {} : { courtAttemptId: randomUUID7() },
14084
- ...env.stationChild === void 0 ? {} : { stationChild: env.stationChild }
14486
+ ...env.stationChild === void 0 ? {} : { stationChild: env.stationChild },
14487
+ // #1132: one configured ceiling, already resolved by the caller (#422).
14488
+ deliveryRequestLimit: deliveryLimitFromConfig(env.autoResumeLimit)
14085
14489
  };
14086
14490
  }
14087
14491
  function roleTurnOptions(env, admitted, continuation) {
@@ -14091,7 +14495,9 @@ function roleTurnOptions(env, admitted, continuation) {
14091
14495
  ...env.host === void 0 ? {} : { host: env.host },
14092
14496
  ...correlationId === void 0 || correlationId.trim() === "" ? {} : { correlationId },
14093
14497
  continuation,
14094
- ...env.stationChild === void 0 ? {} : { stationChild: env.stationChild }
14498
+ ...env.stationChild === void 0 ? {} : { stationChild: env.stationChild },
14499
+ // #1132: one configured ceiling, already resolved by the caller (#422).
14500
+ deliveryRequestLimit: deliveryLimitFromConfig(env.autoResumeLimit)
14095
14501
  };
14096
14502
  }
14097
14503
  async function dispatchAfterWriterLease(input) {
@@ -14109,6 +14515,7 @@ async function dispatchAfterWriterLease(input) {
14109
14515
  async function runSettledAutoResumeLoop(input) {
14110
14516
  const adapters = withOnceSuccessfulBeforeDispatch(input.adapters);
14111
14517
  const dispatchEnv = input.dispatchEnv ?? input.env;
14518
+ const receiptDelivery = createReceiptDeliveryPolicy(input.env.autoResumeLimit);
14112
14519
  return runWithAutoResumeLoop({
14113
14520
  admitted: input.admitted,
14114
14521
  principalAuthority: input.env.principalAuthority,
@@ -14130,6 +14537,7 @@ async function runSettledAutoResumeLoop(input) {
14130
14537
  ...lease === void 0 ? {} : { lease },
14131
14538
  adapters,
14132
14539
  persistRunState: false,
14540
+ receiptDelivery,
14133
14541
  ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine }
14134
14542
  });
14135
14543
  return settleDeferredPersist(
@@ -14492,12 +14900,14 @@ var init_post_admission = __esm({
14492
14900
  init_activation_ledger_topology();
14493
14901
  init_engine_material();
14494
14902
  init_session_identity();
14903
+ init_receipt_delivery_policy();
14495
14904
  init_role_run_relocation();
14496
14905
  init_packaged_role_registry();
14497
14906
  init_engine_detour_usage();
14498
14907
  init_run_lifecycle();
14499
14908
  init_process_cancel();
14500
14909
  init_activation_ledger_topology();
14910
+ init_host_descriptions();
14501
14911
  init_host_session_record();
14502
14912
  init_settlement();
14503
14913
  init_terminal();
@@ -14646,12 +15056,67 @@ function unreadablePostSubmissionStatus(admitted, terminal) {
14646
15056
  const status = receivedDiscriminator(payload, "status");
14647
15057
  return typeof status === "string" && route.statuses.has(status) ? void 0 : route.reask ?? officerConclusionReask(status);
14648
15058
  }
14649
- async function reaskUnreadablePostSubmissionStatus(admitted, terminal, env, io) {
14650
- const message = unreadablePostSubmissionStatus(admitted, terminal);
15059
+ function withUnreadableReask(env) {
15060
+ const spent = env.unreadableReasksSpent ?? 0;
15061
+ if (spent >= deliveryLimitFromConfig(env.autoResumeLimit)) return void 0;
15062
+ return { ...env, unreadableReasksSpent: spent + 1 };
15063
+ }
15064
+ function isUnreadableReaskExhausted(value) {
15065
+ return value === UNREADABLE_REASK_EXHAUSTED;
15066
+ }
15067
+ function presentOriginalVolume(held, terminal, io) {
15068
+ if (terminal?.roleOutcome.decisiveFacts?.directionUnsettled === true) {
15069
+ io.stdout(formatTerminalResult(terminal));
15070
+ return;
15071
+ }
15072
+ if (held.length > 0) {
15073
+ for (const value of held) io.stdout(value);
15074
+ return;
15075
+ }
15076
+ if (terminal !== void 0) io.stdout(formatTerminalResult(terminal));
15077
+ }
15078
+ function withUnsettledDirection(parent, officer) {
15079
+ const outcome = parent.roleOutcome;
15080
+ if (outcome.kind !== "accepted" && outcome.kind !== "audit_escalation") return parent;
15081
+ const officerOutcome = officer?.roleOutcome;
15082
+ const officerPayloads = coalesceSubmissionRows(
15083
+ officer?.submissions,
15084
+ officerOutcome !== void 0 && officerOutcome.kind !== "no_receipt" ? officerOutcome.payloads : void 0
15085
+ );
15086
+ return {
15087
+ ...parent,
15088
+ roleOutcome: {
15089
+ ...outcome,
15090
+ decisiveFacts: {
15091
+ ...outcome.decisiveFacts ?? {},
15092
+ directionUnsettled: true,
15093
+ subsequentAudit: "incomplete",
15094
+ ...officerOutcome === void 0 ? {} : { officerRole: officerOutcome.role },
15095
+ ...officer?.runId === void 0 ? {} : { officerRunId: officer.runId },
15096
+ ...officerPayloads.length === 0 ? {} : { officerPayloads }
15097
+ }
15098
+ }
15099
+ };
15100
+ }
15101
+ function heldUnreadableTerminal(terminal) {
15102
+ if (terminal?.roleOutcome.kind !== "accepted") return false;
15103
+ if (latestPayloadEscalated(terminal.roleOutcome)) return false;
15104
+ const status = latestQueueStatus(terminal);
15105
+ return typeof status !== "string" || !REVIEW_QUEUE_STATUSES.has(status);
15106
+ }
15107
+ function presentUnsettledAudit(parent, officer, io) {
15108
+ const terminal = withUnsettledDirection(parent, officer);
15109
+ io.stdout(formatTerminalResult(terminal));
15110
+ if (officer !== void 0) io.stdout(formatTerminalResult(officer));
15111
+ return terminal;
15112
+ }
15113
+ async function reaskUnreadablePostSubmissionStatus(admitted, terminal, env, io, message = unreadablePostSubmissionStatus(admitted, terminal)) {
14651
15114
  if (message === void 0) return void 0;
15115
+ const next = withUnreadableReask(env);
15116
+ if (next === void 0) return UNREADABLE_REASK_EXHAUSTED;
14652
15117
  return runPublicInstructionSeatResume(
14653
15118
  { runId: admitted.runId, message },
14654
- { ...env, autoResumeLimit: 0 },
15119
+ next,
14655
15120
  io
14656
15121
  );
14657
15122
  }
@@ -14805,6 +15270,11 @@ async function dispatchAdmitted(admitted, env, io) {
14805
15270
  env,
14806
15271
  io
14807
15272
  );
15273
+ if (isUnreadableReaskExhausted(unreadableReask)) {
15274
+ const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
15275
+ presentOriginalVolume(held, terminal, io);
15276
+ return terminal === void 0 ? result : { ...result, terminal };
15277
+ }
14808
15278
  if (unreadableReask !== void 0) return unreadableReask;
14809
15279
  if (AUDITED_ROLES.has(admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
14810
15280
  return auditSubmittedRole(result, env, io);
@@ -14936,20 +15406,16 @@ async function runCountersignBody(parsed, env, io) {
14936
15406
  await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
14937
15407
  admitted = { ...admitted, sourceRunPath: gateParentRunPath };
14938
15408
  }
14939
- const turnProjection = {
14940
- ...projectPublicTurnAxes(env),
14941
- ...env.correlationId === void 0 || env.correlationId.trim() === "" ? {} : { correlationId: env.correlationId },
14942
- continuation: {
14943
- kind: "initial",
14944
- prompt: env.reviewReask ?? env.gateReviewInstruction ?? buildInstructionTransportPrompt(
14945
- admitted,
14946
- engineSessionMaterialFromOptions({
14947
- ...pickEngineAxis(env),
14948
- packageRoot: env.packageRoot
14949
- })
14950
- )
14951
- }
14952
- };
15409
+ const turnProjection = roleTurnOptions(env, admitted, {
15410
+ kind: "initial",
15411
+ prompt: env.reviewReask ?? env.gateReviewInstruction ?? buildInstructionTransportPrompt(
15412
+ admitted,
15413
+ engineSessionMaterialFromOptions({
15414
+ ...pickEngineAxis(env),
15415
+ packageRoot: env.packageRoot
15416
+ })
15417
+ )
15418
+ });
14953
15419
  const turnRequest = buildInstructionSeatTurnRequest(admitted, turnProjection);
14954
15420
  const result = await runPostAdmissionOneShot({
14955
15421
  admitted,
@@ -15218,7 +15684,23 @@ async function runPublicInstructionSeatResume(request, env, io) {
15218
15684
  },
15219
15685
  afterAdmittedLoad: async (admitted) => {
15220
15686
  await warnMissingMethodSkills(env.home, env.host, admitted.role, requiredMethodSkills(admitted), io.stdout);
15221
- return { kind: "continue", adapters: seatAdapters(admitted, env) };
15687
+ const adapters = seatAdapters(admitted, env);
15688
+ if ((env.unreadableReasksSpent ?? 0) === 0 && env.reviewReask === void 0) {
15689
+ return { kind: "continue", adapters };
15690
+ }
15691
+ const original = await adapters.trySettle(
15692
+ admitted,
15693
+ env.principalAuthority,
15694
+ await readCurrentCourt(admitted.runDirectory)
15695
+ );
15696
+ const unsettled = POST_SUBMISSION_ROUTING[admitted.role] === void 0 ? heldUnreadableTerminal(original) : unreadablePostSubmissionStatus(admitted, original) !== void 0;
15697
+ return {
15698
+ kind: "continue",
15699
+ adapters: original === void 0 || !unsettled ? adapters : {
15700
+ ...adapters,
15701
+ trySettle: async (seat, authority, scope) => await adapters.trySettle(seat, authority, scope) ?? original
15702
+ }
15703
+ };
15222
15704
  },
15223
15705
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
15224
15706
  });
@@ -15228,6 +15710,11 @@ async function runPublicInstructionSeatResume(request, env, io) {
15228
15710
  env,
15229
15711
  io
15230
15712
  );
15713
+ if (isUnreadableReaskExhausted(unreadableReask)) {
15714
+ const terminal = result.terminal === void 0 ? void 0 : withUnsettledDirection(result.terminal);
15715
+ presentOriginalVolume(held, terminal, io);
15716
+ return terminal === void 0 ? result : { ...result, terminal };
15717
+ }
15231
15718
  if (unreadableReask !== void 0) return unreadableReask;
15232
15719
  if (result.admitted !== void 0 && AUDITED_ROLES.has(result.admitted.role) && result.terminal?.roleOutcome.kind === "accepted") {
15233
15720
  return auditSubmittedRole(result, env, io);
@@ -15253,22 +15740,42 @@ async function runPublicInstructionSeatResume(request, env, io) {
15253
15740
  }
15254
15741
  async function queueConclusionFromChild(child, env, io) {
15255
15742
  if (!GATE_CHILD_ROLES.has(child.role)) return void 0;
15743
+ if (child.role === "countersign") {
15744
+ const terminal = await trySettlePublicSeat(
15745
+ child,
15746
+ env.principalAuthority,
15747
+ await readCurrentCourt(child.runDirectory)
15748
+ );
15749
+ const status = latestQueueStatus(terminal);
15750
+ if (terminal !== void 0 && typeof status === "string" && REVIEW_QUEUE_STATUSES.has(status)) {
15751
+ return { admitted: child, terminal, status };
15752
+ }
15753
+ return { stop: { exitCode: 0, ...terminal === void 0 ? {} : { terminal } } };
15754
+ }
15256
15755
  let current = child;
15756
+ let budgetEnv = { ...env, unreadableReasksSpent: 0 };
15257
15757
  for (; ; ) {
15258
15758
  const terminal = await trySettlePublicSeat(
15259
15759
  current,
15260
15760
  env.principalAuthority,
15261
- void 0
15761
+ await readCurrentCourt(current.runDirectory)
15262
15762
  );
15263
15763
  const status = latestQueueStatus(terminal);
15264
15764
  if (terminal !== void 0 && typeof status === "string" && REVIEW_QUEUE_STATUSES.has(status)) {
15265
15765
  return { admitted: current, terminal, status };
15266
15766
  }
15267
- const reasked = await runPublicInstructionSeatResume({
15268
- runId: current.runId,
15269
- message: officerConclusionReask(status)
15270
- }, env, io);
15271
- if (reasked.exitCode !== 0 || reasked.admitted === void 0 || reasked.terminal === void 0) {
15767
+ const reasked = await reaskUnreadablePostSubmissionStatus(
15768
+ current,
15769
+ terminal,
15770
+ budgetEnv,
15771
+ io,
15772
+ officerConclusionReask(status)
15773
+ );
15774
+ if (reasked === void 0 || isUnreadableReaskExhausted(reasked)) {
15775
+ return { stop: { exitCode: 0, ...terminal === void 0 ? {} : { terminal } } };
15776
+ }
15777
+ budgetEnv = withUnreadableReask(budgetEnv);
15778
+ if (reasked.exitCode !== 0 || reasked.admitted === void 0 || reasked.terminal === void 0 || reasked.terminal.roleOutcome.kind === "no_receipt" || reasked.terminal.roleOutcome.decisiveFacts?.directionUnsettled === true) {
15272
15779
  return { stop: reasked };
15273
15780
  }
15274
15781
  const reaskedStatus = latestQueueStatus(reasked.terminal);
@@ -15286,7 +15793,17 @@ async function continueParentAfterChild(parentRunId, child, env, io) {
15286
15793
  }
15287
15794
  const admitted = loaded.admitted;
15288
15795
  const resolved = await queueConclusionFromChild(child, env, io);
15289
- if (resolved !== void 0 && "stop" in resolved) return resolved.stop;
15796
+ if (resolved !== void 0 && "stop" in resolved) {
15797
+ const stopped = resolved.stop;
15798
+ if (stopped.exitCode === 0 && heldUnreadableTerminal(stopped.terminal) && stopped.terminal !== void 0) {
15799
+ const parentTerminal = await trySettlePublicSeat(admitted, env.principalAuthority, void 0);
15800
+ if (parentTerminal?.roleOutcome.kind === "accepted" || parentTerminal?.roleOutcome.kind === "audit_escalation") {
15801
+ const terminal = presentUnsettledAudit(parentTerminal, stopped.terminal, io);
15802
+ return { exitCode: 0, admitted, terminal };
15803
+ }
15804
+ }
15805
+ return stopped;
15806
+ }
15290
15807
  if (resolved !== void 0 && resolved.status === "escalate") {
15291
15808
  return { exitCode: 0, admitted: resolved.admitted, terminal: resolved.terminal };
15292
15809
  }
@@ -15294,37 +15811,67 @@ async function continueParentAfterChild(parentRunId, child, env, io) {
15294
15811
  if (AUDITED_ROLES.has(admitted.role) && resolved.status === "converged") {
15295
15812
  const terminal = await trySettlePublicSeat(admitted, env.principalAuthority, void 0);
15296
15813
  if (terminal?.roleOutcome.kind !== "accepted") throw new Error("pending submission is not recorded");
15297
- return auditSubmittedRole({ exitCode: 0, admitted, terminal }, env, io, resolved.admitted.role, latestQueuePayload(resolved.terminal), resolved.admitted.runId);
15814
+ return auditSubmittedRole({ exitCode: 0, admitted, terminal }, env, io, resolved.admitted, latestQueuePayload(resolved.terminal));
15298
15815
  }
15299
15816
  return runPublicInstructionSeatResume({
15300
15817
  runId: parentRunId,
15301
15818
  message: readableGateItem(latestQueuePayload(resolved.terminal))
15302
- }, { ...env, autoResumeLimit: 0 }, io);
15819
+ }, { ...env, unreadableReasksSpent: 0 }, io);
15303
15820
  }
15304
15821
  const result = await dispatchAdmitted(admitted, env, { ...io, omitFailureStderrDiagnostic: true });
15305
15822
  showResumeErrorPointer(io, result.exitCode, result.terminal);
15306
15823
  return result;
15307
15824
  }
15308
- async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, passedRunId) {
15825
+ async function officerPassedCurrentSubmission(input) {
15826
+ const { env, officer } = input;
15827
+ const pointer = await readDirectOfficerRunPointer(input.parentSessionFile, officer);
15828
+ if (pointer?.runDirectory === void 0) return false;
15829
+ if (pointer.submissionToolCallId !== input.toolCallId) return false;
15830
+ const officerRunId = runIdFromRunDirectory(pointer.runDirectory);
15831
+ if (officerRunId === void 0) return false;
15832
+ let admitted;
15833
+ try {
15834
+ const loaded = await loadResumablePublicRole(
15835
+ env.home,
15836
+ officerRunId,
15837
+ env.principalAuthority
15838
+ );
15839
+ admitted = loaded.admitted;
15840
+ } catch {
15841
+ return false;
15842
+ }
15843
+ if (admitted.role !== officer) return false;
15844
+ const court = await readCurrentCourt(admitted.runDirectory);
15845
+ const terminal = await trySettlePublicSeat(admitted, env.principalAuthority, court);
15846
+ return latestQueueStatus(terminal) === "converged";
15847
+ }
15848
+ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt) {
15309
15849
  const admitted = turn.admitted;
15310
15850
  if (admitted === void 0 || !AUDITED_ROLES.has(admitted.role) || turn.terminal?.roleOutcome.kind !== "accepted") return turn;
15311
15851
  const accepted = turn.terminal.roleOutcome.payloads?.at(-1);
15312
15852
  if (accepted === void 0) throw new Error("accepted submission has no payload");
15313
15853
  const record = isRecord(accepted) ? accepted : void 0;
15314
15854
  const status = admitted.role === "secretariat" ? record?.secretariatStatus : record?.status;
15855
+ const gateOwnsStatusReask = typeof env.parentRunPath === "string" && env.parentRunPath.trim() !== "";
15315
15856
  if (admitted.role === "secretariat" && status !== "converged" && status !== "escalate") {
15316
- return runPublicInstructionSeatResume(
15317
- { runId: admitted.runId, message: SECRETARIAT_STATUS_REASK },
15318
- { ...env, autoResumeLimit: 0 },
15319
- io
15320
- );
15857
+ if (gateOwnsStatusReask) return turn;
15858
+ const next = withUnreadableReask(env);
15859
+ if (next === void 0) {
15860
+ const terminal2 = withUnsettledDirection(turn.terminal);
15861
+ io.stdout(formatTerminalResult(terminal2));
15862
+ return { ...turn, terminal: terminal2 };
15863
+ }
15864
+ return runPublicInstructionSeatResume({ runId: admitted.runId, message: SECRETARIAT_STATUS_REASK }, next, io);
15321
15865
  }
15322
15866
  if (admitted.role === "countersign" && (typeof status !== "string" || !REVIEW_QUEUE_STATUSES.has(status))) {
15323
- return runPublicInstructionSeatResume(
15324
- { runId: admitted.runId, message: officerConclusionReask(status) },
15325
- { ...env, autoResumeLimit: 0 },
15326
- io
15327
- );
15867
+ if (gateOwnsStatusReask) return turn;
15868
+ const next = withUnreadableReask(env);
15869
+ if (next === void 0) {
15870
+ const terminal2 = withUnsettledDirection(turn.terminal);
15871
+ io.stdout(formatTerminalResult(terminal2));
15872
+ return { ...turn, terminal: terminal2 };
15873
+ }
15874
+ return runPublicInstructionSeatResume({ runId: admitted.runId, message: officerConclusionReask(status) }, next, io);
15328
15875
  }
15329
15876
  const selfEscalationSkipsAudit = status === "escalate" && (admitted.role === "judge" || admitted.role === "secretariat" || admitted.role === "countersign");
15330
15877
  const skipAudit = selfEscalationSkipsAudit || (admitted.role === "fixer" || admitted.role === "coder") && (typeof status !== "string" || !WORKER_DONE_STATUSES.has(status));
@@ -15354,12 +15901,19 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15354
15901
  abort() {
15355
15902
  }
15356
15903
  };
15904
+ const passedThisSubmission = (officer) => officerPassedCurrentSubmission({
15905
+ env,
15906
+ parentSessionFile: sessionFile,
15907
+ officer,
15908
+ toolCallId
15909
+ });
15357
15910
  if (admitted.role === "doctor") {
15358
- if (passedOfficer !== "auditor") {
15911
+ if (!await passedThisSubmission("auditor")) {
15359
15912
  let lastSummon;
15360
15913
  const decision = await createPiDoctorAuditor()({
15361
15914
  context,
15362
15915
  submission: accepted,
15916
+ ...env.autoResumeLimit === void 0 ? {} : { autoResumeLimit: env.autoResumeLimit },
15363
15917
  ...env.signal === void 0 ? {} : { signal: env.signal },
15364
15918
  summonAuditor: async (subject, sourceRunDirectory, signal, reask, submission) => {
15365
15919
  const summoned = await summonPublicRole({
@@ -15388,6 +15942,7 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15388
15942
  parentSessionFile: sessionFile,
15389
15943
  officer: "auditor",
15390
15944
  sessionFile: officerSession,
15945
+ submissionToolCallId: toolCallId,
15391
15946
  ...summoned.runDirectory === void 0 ? {} : { runDirectory: summoned.runDirectory }
15392
15947
  });
15393
15948
  }
@@ -15399,7 +15954,15 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15399
15954
  return runPublicInstructionSeatResume({
15400
15955
  runId: admitted.runId,
15401
15956
  message: readableGateItem(decision.receipt ?? decision.violations)
15402
- }, { ...env, autoResumeLimit: 0 }, io);
15957
+ }, { ...env, unreadableReasksSpent: 0 }, io);
15958
+ }
15959
+ if (decision.status === "received") {
15960
+ if (lastSummon?.terminal === void 0) {
15961
+ throw new Error("doctor audit kept an unreadable reply with no terminal");
15962
+ }
15963
+ if (turn.terminal === void 0) throw new Error("doctor submission has no terminal");
15964
+ const terminal2 = presentUnsettledAudit(turn.terminal, lastSummon.terminal, io);
15965
+ return { exitCode: 0, admitted, terminal: terminal2 };
15403
15966
  }
15404
15967
  if (decision.status !== "converged") {
15405
15968
  if (lastSummon?.terminal !== void 0) {
@@ -15422,13 +15985,14 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15422
15985
  ...env.hostAdapters === void 0 ? {} : { hostAdapters: env.hostAdapters }
15423
15986
  });
15424
15987
  let chain;
15425
- let officerRunId = passedRunId;
15988
+ let officerRunId = resumedOfficer?.runId;
15426
15989
  const runGate = (subject) => requireSubmissionGate({
15427
15990
  context,
15428
15991
  subject,
15429
15992
  toolCallId,
15430
15993
  submission: accepted,
15431
15994
  summonOfficer,
15995
+ ...env.autoResumeLimit === void 0 ? {} : { autoResumeLimit: env.autoResumeLimit },
15432
15996
  ...env.signal === void 0 ? {} : { signal: env.signal },
15433
15997
  hostActions: {
15434
15998
  failInfrastructure(error) {
@@ -15440,13 +16004,13 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15440
16004
  });
15441
16005
  if (admitted.role === "judge") {
15442
16006
  chain = await runJudgeGates({
15443
- gateAlreadyConverged: async (subject) => passedOfficer === "auditor" || passedOfficer === "notary" && subject.kind === "judge_draft",
16007
+ gateAlreadyConverged: async (subject) => passedThisSubmission(gateOfficerForSubject(subject)),
15444
16008
  runGate
15445
16009
  });
15446
16010
  } else {
15447
16011
  const subject = admitted.role === "fixer" || admitted.role === "coder" ? { kind: "worker_completion" } : admitted.role === "secretariat" ? { kind: "secretariat_verdict" } : { kind: "countersign_verdict" };
15448
16012
  const officer = gateOfficerForSubject(subject);
15449
- if (passedOfficer === officer) {
16013
+ if (await passedThisSubmission(officer)) {
15450
16014
  chain = { status: "converged", passes: [] };
15451
16015
  } else {
15452
16016
  const pass = await runGate(subject);
@@ -15459,17 +16023,29 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15459
16023
  status: pass.status,
15460
16024
  receipt: pass.receipt,
15461
16025
  ...pass.runId === void 0 ? {} : { runId: pass.runId },
15462
- ...pass.runDirectory === void 0 ? {} : { runDirectory: pass.runDirectory }
16026
+ ...pass.runDirectory === void 0 ? {} : { runDirectory: pass.runDirectory },
16027
+ ...pass.terminal === void 0 ? {} : { terminal: pass.terminal }
15463
16028
  }]
15464
16029
  };
15465
16030
  }
15466
16031
  }
16032
+ if (chain.status === "needs_reask") {
16033
+ const officerTerminal = chain.passes.at(-1)?.terminal;
16034
+ if (officerTerminal === void 0) throw new Error("unreadable audit has no terminal result");
16035
+ if (turn.terminal === void 0) throw new Error("audited submission has no terminal");
16036
+ const terminal2 = presentUnsettledAudit(turn.terminal, officerTerminal, io);
16037
+ return { exitCode: 0, admitted, terminal: terminal2 };
16038
+ }
15467
16039
  if (chain.status === "escalate") {
15468
16040
  const escalation = chain.passes.at(-1);
15469
16041
  const escalatedRunId = escalation?.runId ?? (escalation?.runDirectory === void 0 ? void 0 : runIdFromRunDirectory(escalation.runDirectory));
15470
16042
  if (escalatedRunId === void 0) throw new Error("escalated audit has no resumable run identity");
15471
16043
  const officer = await loadResumablePublicRole(env.home, escalatedRunId, env.principalAuthority);
15472
- const terminal2 = await trySettlePublicSeat(officer.admitted, env.principalAuthority, void 0);
16044
+ const terminal2 = await trySettlePublicSeat(
16045
+ officer.admitted,
16046
+ env.principalAuthority,
16047
+ await readCurrentCourt(officer.admitted.runDirectory)
16048
+ );
15473
16049
  if (terminal2 === void 0) throw new Error("escalated audit has no terminal result");
15474
16050
  io.stdout(formatTerminalResult(terminal2));
15475
16051
  return { exitCode: 0, admitted: officer.admitted, terminal: terminal2 };
@@ -15478,7 +16054,7 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15478
16054
  return runPublicInstructionSeatResume({
15479
16055
  runId: admitted.runId,
15480
16056
  message: readableGateItem(chain.passes.at(-1)?.receipt)
15481
- }, { ...env, autoResumeLimit: 0 }, io);
16057
+ }, { ...env, unreadableReasksSpent: 0 }, io);
15482
16058
  }
15483
16059
  if (admitted.role === "secretariat") {
15484
16060
  const pass = chain.passes.at(-1);
@@ -15498,7 +16074,7 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15498
16074
  io.stdout(formatTerminalResult(terminal));
15499
16075
  return turn;
15500
16076
  }
15501
- var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STATUS_REASK, DOCTOR_ROUTING_STATUSES, DOCTOR_STATUS_REASK, POST_SUBMISSION_ROUTING, GATE_CHILD_ROLES;
16077
+ var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, WORKER_ROUTING_STATUSES, WORKER_STATUS_REASK, DOCTOR_ROUTING_STATUSES, DOCTOR_STATUS_REASK, POST_SUBMISSION_ROUTING, UNREADABLE_REASK_EXHAUSTED, GATE_CHILD_ROLES;
15502
16078
  var init_instruction_seat_run = __esm({
15503
16079
  "src/public-cli/instruction-seat-run.ts"() {
15504
16080
  "use strict";
@@ -15513,6 +16089,7 @@ var init_instruction_seat_run = __esm({
15513
16089
  init_worker_submission_contracts();
15514
16090
  init_secretariat_contracts();
15515
16091
  init_readable_gate_item();
16092
+ init_receipt_delivery_policy();
15516
16093
  init_run_terminal_artifacts();
15517
16094
  init_submission_gate();
15518
16095
  init_submission_ledger();
@@ -15570,6 +16147,7 @@ var init_instruction_seat_run = __esm({
15570
16147
  reask: DOCTOR_STATUS_REASK
15571
16148
  }
15572
16149
  };
16150
+ UNREADABLE_REASK_EXHAUSTED = { unreadableReaskExhausted: true };
15573
16151
  GATE_CHILD_ROLES = /* @__PURE__ */ new Set(["notary", "auditor", "inspector", "countersign"]);
15574
16152
  }
15575
16153
  });
@@ -15609,7 +16187,7 @@ var init_analyst_book_key = __esm({
15609
16187
  });
15610
16188
 
15611
16189
  // src/analyst-index.ts
15612
- import { open as open2, readFile as readFile18, unlink as unlink4 } from "node:fs/promises";
16190
+ import { open as open2, readFile as readFile19, unlink as unlink4 } from "node:fs/promises";
15613
16191
  import { dirname as dirname21, join as join34 } from "node:path";
15614
16192
  import { setTimeout as sleep } from "node:timers/promises";
15615
16193
  async function withAnalystLibraryIndexLock(ledgerHome, fn) {
@@ -15733,7 +16311,7 @@ async function readAnalystLibraryIndexPage(ledgerHome) {
15733
16311
  const path = analystLibraryIndexPath(ledgerHome);
15734
16312
  let raw;
15735
16313
  try {
15736
- raw = await readFile18(path, "utf8");
16314
+ raw = await readFile19(path, "utf8");
15737
16315
  } catch (error) {
15738
16316
  if (isMissingPathError(error)) return void 0;
15739
16317
  throw error;
@@ -15936,7 +16514,7 @@ var init_analyst_cohort = __esm({
15936
16514
  });
15937
16515
 
15938
16516
  // src/analyst-ledger.ts
15939
- import { readdir as readdir6, readFile as readFile19 } from "node:fs/promises";
16517
+ import { readdir as readdir6, readFile as readFile20 } from "node:fs/promises";
15940
16518
  import { basename as basename9, join as join35 } from "node:path";
15941
16519
  async function readExistingRunLifecycleState(runDirectory) {
15942
16520
  return (await readRoleRunIdentity(runDirectory))?.state;
@@ -15986,7 +16564,7 @@ async function listLedgerBookNames(booksRoot) {
15986
16564
  async function readInvocationScopeFields(runDirectory) {
15987
16565
  let raw;
15988
16566
  try {
15989
- raw = await readFile19(join35(runDirectory, "invocation.json"), "utf8");
16567
+ raw = await readFile20(join35(runDirectory, "invocation.json"), "utf8");
15990
16568
  } catch (error) {
15991
16569
  if (isMissingPathError(error)) return void 0;
15992
16570
  throw error;
@@ -16019,7 +16597,7 @@ function decideIssueScope(input) {
16019
16597
  }
16020
16598
  async function resolveSessionFile(runDirectory) {
16021
16599
  try {
16022
- const raw = await readFile19(join35(runDirectory, "invocation.json"), "utf8");
16600
+ const raw = await readFile20(join35(runDirectory, "invocation.json"), "utf8");
16023
16601
  const parsed = JSON.parse(raw);
16024
16602
  if (isRecord(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
16025
16603
  return parsed.sessionFile;
@@ -17279,7 +17857,7 @@ var init_analyst_model_groups = __esm({
17279
17857
  });
17280
17858
 
17281
17859
  // src/analyst-entry.ts
17282
- import { readFile as readFile20 } from "node:fs/promises";
17860
+ import { readFile as readFile21 } from "node:fs/promises";
17283
17861
  import { Type as Type18 } from "typebox";
17284
17862
  function cachedPageMatchesRequestedScope(page, input) {
17285
17863
  if (page.bookKey !== input.bookKey) return false;
@@ -17307,7 +17885,7 @@ async function readOrComputeAnalystIssuePage(input, options) {
17307
17885
  ...issueNumber === void 0 && input.bookKey === void 0 ? { scopeRootIdentity: projectRoot } : {}
17308
17886
  });
17309
17887
  try {
17310
- const raw = await readFile20(pagePath, "utf8");
17888
+ const raw = await readFile21(pagePath, "utf8");
17311
17889
  const page = JSON.parse(raw);
17312
17890
  if (cachedPageMatchesRequestedScope(page, { bookKey, ...input })) {
17313
17891
  const ghostScan = await scanAnalystIssueRuns({
@@ -17408,7 +17986,7 @@ async function runAnalystModelGroupsMode(input, home) {
17408
17986
  scopeRootIdentity: projectRoot
17409
17987
  });
17410
17988
  try {
17411
- const raw = await readFile20(pagePath, "utf8");
17989
+ const raw = await readFile21(pagePath, "utf8");
17412
17990
  JSON.parse(raw);
17413
17991
  } catch (error) {
17414
17992
  if (!isMissingPathError(error)) {
@@ -17505,7 +18083,7 @@ var init_analyst_entry = __esm({
17505
18083
  });
17506
18084
 
17507
18085
  // src/public-cli/analyst-run.ts
17508
- import { readFile as readFile21 } from "node:fs/promises";
18086
+ import { readFile as readFile22 } from "node:fs/promises";
17509
18087
  import { isAbsolute as isAbsolute9, resolve as resolve15 } from "node:path";
17510
18088
  import { Value as Value3 } from "typebox/value";
17511
18089
  function resolveAnalystIssueBookKeyFromCwd(cwd = process.cwd()) {
@@ -17559,7 +18137,7 @@ async function buildAnalystSweepModeInputFromAttachmentPaths(attachmentPaths) {
17559
18137
  const absolute = isAbsolute9(sourcePath) ? sourcePath : resolve15(sourcePath);
17560
18138
  let bytes;
17561
18139
  try {
17562
- bytes = await readFile21(absolute);
18140
+ bytes = await readFile22(absolute);
17563
18141
  } catch (error) {
17564
18142
  throw new CliUsageError(
17565
18143
  `analyst sweep attachment is not a readable regular file: ${sourcePath}`,
@@ -18447,7 +19025,7 @@ async function runAkRole(argv, env) {
18447
19025
  io
18448
19026
  );
18449
19027
  let current = result;
18450
- while (current.exitCode === 0 && current.admitted?.correlationId !== void 0 && current.terminal?.roleOutcome.kind === "accepted" && !latestPayloadEscalated(current.terminal.roleOutcome)) {
19028
+ while (current.exitCode === 0 && current.admitted?.correlationId !== void 0 && current.terminal?.roleOutcome.kind === "accepted" && current.terminal.roleOutcome.decisiveFacts?.directionUnsettled !== true && !latestPayloadEscalated(current.terminal.roleOutcome)) {
18451
19029
  const parentRunId = current.admitted.correlationId;
18452
19030
  resumeFailureContext = {
18453
19031
  home,
@@ -19193,10 +19771,14 @@ async function runComplianceAudit(options) {
19193
19771
  });
19194
19772
  });
19195
19773
  let reask;
19774
+ let reasksSpent = 0;
19775
+ const reaskLimit = deliveryLimitFromConfig(options.autoResumeLimit);
19196
19776
  for (; ; ) {
19197
19777
  const summoned = await summon(subject, runDirectory, options.signal, reask, submission);
19198
19778
  const decision = await projectAuditorTerminal(summoned);
19199
19779
  if (decision.status === "received") {
19780
+ if (reasksSpent >= reaskLimit) return decision;
19781
+ reasksSpent += 1;
19200
19782
  reask = officerConclusionReask(receivedDiscriminator(decision.reply, "status"));
19201
19783
  continue;
19202
19784
  }
@@ -19212,6 +19794,7 @@ var init_compliance_transport = __esm({
19212
19794
  init_submission_errors();
19213
19795
  init_terminal();
19214
19796
  init_readable_gate_item();
19797
+ init_receipt_delivery_policy();
19215
19798
  init_unknown_value();
19216
19799
  AUDITOR_DOSSIER_PROMPT = "\u5377\u5B97\u6307\u9488\uFF1A";
19217
19800
  AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE = "ak_auditor_parent_attempt_binding";
@@ -19351,7 +19934,7 @@ __export(run_lifecycle_exports, {
19351
19934
  renderResumeCommand: () => renderResumeCommand,
19352
19935
  writeRoleRunState: () => writeRoleRunState
19353
19936
  });
19354
- import { chmod, lstat as lstat6, open as open3, readdir as readdir7, readFile as readFile22, unlink as unlink5, writeFile as writeFile8 } from "node:fs/promises";
19937
+ import { chmod, lstat as lstat6, open as open3, readdir as readdir7, readFile as readFile23, unlink as unlink5, writeFile as writeFile8 } from "node:fs/promises";
19355
19938
  import { basename as basename10, join as join39 } from "node:path";
19356
19939
  function buildAutoResumeContinuationPrompt(options) {
19357
19940
  return appendEngineSessionMaterial(
@@ -19428,7 +20011,7 @@ function parseCurrentCourtState(raw) {
19428
20011
  async function readRoleRunStateRaw(runDirectory) {
19429
20012
  let raw;
19430
20013
  try {
19431
- raw = JSON.parse(await readFile22(join39(runDirectory, RUN_STATE_FILE), "utf8"));
20014
+ raw = JSON.parse(await readFile23(join39(runDirectory, RUN_STATE_FILE), "utf8"));
19432
20015
  } catch (error) {
19433
20016
  if (errorCodeOf(error) === "ENOENT") return void 0;
19434
20017
  throw error;
@@ -19686,7 +20269,7 @@ function isProcessAlive(pid) {
19686
20269
  async function autopsyWriterLock(lockPath) {
19687
20270
  let content;
19688
20271
  try {
19689
- content = await readFile22(lockPath, "utf8");
20272
+ content = await readFile23(lockPath, "utf8");
19690
20273
  } catch (error) {
19691
20274
  if (errorCodeOf(error) === "ENOENT") return { verdict: "absent" };
19692
20275
  return { verdict: "unknown", reason: "unreadable", readFailure: error };
@@ -19883,7 +20466,7 @@ async function readRunParentPath(runDirectory) {
19883
20466
  let raw;
19884
20467
  try {
19885
20468
  raw = JSON.parse(
19886
- await readFile22(join39(runDirectory, "admitted-request.json"), "utf8")
20469
+ await readFile23(join39(runDirectory, "admitted-request.json"), "utf8")
19887
20470
  );
19888
20471
  } catch (error) {
19889
20472
  if (errorCodeOf(error) === "ENOENT") return void 0;
@@ -19998,7 +20581,7 @@ async function loadResumableRunRecord(home, runId, authority) {
19998
20581
  let sourceRun;
19999
20582
  try {
20000
20583
  const raw = JSON.parse(
20001
- await readFile22(run.admittedRequestPath, "utf8")
20584
+ await readFile23(run.admittedRequestPath, "utf8")
20002
20585
  );
20003
20586
  if (isRecord(raw)) {
20004
20587
  const record = raw;
@@ -20120,7 +20703,7 @@ async function loadResumableRunRecord(home, runId, authority) {
20120
20703
  let model;
20121
20704
  try {
20122
20705
  const invocationRaw = JSON.parse(
20123
- await readFile22(join39(run.runDirectory, "invocation.json"), "utf8")
20706
+ await readFile23(join39(run.runDirectory, "invocation.json"), "utf8")
20124
20707
  );
20125
20708
  if (isRecord(invocationRaw)) {
20126
20709
  const rec = invocationRaw;
@@ -20871,7 +21454,7 @@ init_host_descriptions();
20871
21454
  import { randomUUID as randomUUID11 } from "node:crypto";
20872
21455
 
20873
21456
  // src/role-runtime-dependencies.ts
20874
- import { readFile as readFile24 } from "node:fs/promises";
21457
+ import { readFile as readFile25 } from "node:fs/promises";
20875
21458
  init_doctor_evidence();
20876
21459
 
20877
21460
  // src/navigator-attendance.ts
@@ -21598,8 +22181,8 @@ function createNavigatorAttendance(options) {
21598
22181
  try {
21599
22182
  try {
21600
22183
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
21601
- const delivery = createReceiptDeliveryPolicy();
21602
- const promptAllowingRejectedPrepare = async (text, deliveryRequest) => {
22184
+ const delivery = createReceiptDeliveryPolicy(options.deliveryRequestLimit);
22185
+ const promptAllowingRejectedPrepare = async (text) => {
21603
22186
  await persistNavigatorWorkBase(activeSession.recordPointer(), { subject, authority });
21604
22187
  const entryStart = activeSession.entries().length;
21605
22188
  prepareBatchRejected = false;
@@ -21626,17 +22209,15 @@ function createNavigatorAttendance(options) {
21626
22209
  delivery.recordNestedNoReceipt(sessionNoReceipt);
21627
22210
  return;
21628
22211
  }
21629
- if (deliveryRequest && output === void 0) delivery.recordDeliveryRequest();
21630
22212
  };
21631
- await promptAllowingRejectedPrepare(request, false);
22213
+ await promptAllowingRejectedPrepare(request);
21632
22214
  if (boundSettlement !== void 0) {
21633
22215
  while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
21634
- await promptAllowingRejectedPrepare(JSON.stringify(delivery.deliveryState()), true);
22216
+ delivery.recordDeliveryRequest();
22217
+ await promptAllowingRejectedPrepare(JSON.stringify(delivery.deliveryState()));
21635
22218
  }
21636
22219
  if (output === void 0 && delivery.nextAction() === "request-delivery") {
21637
- while (delivery.nextAction() === "request-delivery") {
21638
- delivery.recordDeliveryRequest();
21639
- }
22220
+ delivery.closeBudget();
21640
22221
  }
21641
22222
  if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
21642
22223
  const facts = delivery.facts({ runPointer: activeSession.recordPointer(), attemptPointer: invocationId });
@@ -21834,7 +22415,7 @@ function createNavigatorAttendance(options) {
21834
22415
  init_doctor_evidence();
21835
22416
  init_unknown_value();
21836
22417
  init_host_contracts();
21837
- import { readFile as readFile23 } from "node:fs/promises";
22418
+ import { readFile as readFile24 } from "node:fs/promises";
21838
22419
  import { resolve as resolve18 } from "node:path";
21839
22420
  init_notary_source_run();
21840
22421
  init_packaged_role_registry();
@@ -21848,7 +22429,7 @@ function navigatorInputReference(getFlag, role) {
21848
22429
  async function loadNavigatorWorkContext(options) {
21849
22430
  const reference = navigatorInputReference(options.getFlag, options.role);
21850
22431
  const subjectMode = packagedNavigatorSubject(options.role);
21851
- const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile23(reference, "utf8");
22432
+ const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile24(reference, "utf8");
21852
22433
  const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
21853
22434
  let subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
21854
22435
  let subject = input ?? `work subject: ${subjectKey}`;
@@ -21905,7 +22486,7 @@ async function loadNavigatorWorkContext(options) {
21905
22486
  let authorityMaterial;
21906
22487
  for (const path of authorityFiles) {
21907
22488
  try {
21908
- const content = await readFile23(path, "utf8");
22489
+ const content = await readFile24(path, "utf8");
21909
22490
  if (content.trim() !== "") {
21910
22491
  authorityMaterial = content;
21911
22492
  break;
@@ -22657,6 +23238,7 @@ init_archivist_record_entry();
22657
23238
  init_sitian_facade();
22658
23239
  init_submission_errors();
22659
23240
  init_worker_submission_contracts();
23241
+ init_receipt_delivery_policy();
22660
23242
  init_unknown_value();
22661
23243
  init_submission_errors();
22662
23244
  init_worker_submission_contracts();
@@ -22667,11 +23249,11 @@ var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
22667
23249
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
22668
23250
  var WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE = "commit-reminder-bounce";
22669
23251
  var WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE = "prefix-reminder-bounce";
23252
+ var WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE = "unfinished-reason-bounce";
22670
23253
  var HOOK_MARKER = "ak-roles: worker-submission-gates reference-transaction";
22671
23254
  var HOOKS_DIR = "ak-roles-hooks";
22672
23255
  var HOOK_FILE = "reference-transaction";
22673
23256
  var PLATFORM_PREFIX = /^[A-Za-z][A-Za-z0-9_-]*:/;
22674
- var UNFINISHED_REASON_BOUNCE_LIMIT = 2;
22675
23257
  function git2(cwd, args) {
22676
23258
  return execFileSync3("git", args, {
22677
23259
  cwd,
@@ -22771,10 +23353,11 @@ function unfinishedReasonPresent(details) {
22771
23353
  if (!isRecord(details)) return false;
22772
23354
  return containsWrittenReason(details.reason);
22773
23355
  }
22774
- function readGateState(session) {
23356
+ function readGateState(session, invocationScopeId) {
22775
23357
  let baseline;
22776
23358
  let reminded = false;
22777
23359
  let prefixReminded = false;
23360
+ let unfinishedReasonBounces = 0;
22778
23361
  for (const entry of session.getEntries()) {
22779
23362
  if (entry.type !== "custom") continue;
22780
23363
  if (entry.customType === WORKER_COMMIT_BASELINE_ENTRY_TYPE) {
@@ -22786,9 +23369,11 @@ function readGateState(session) {
22786
23369
  reminded = true;
22787
23370
  } else if (entry.customType === WORKER_PREFIX_REMINDER_BOUNCE_ENTRY_TYPE) {
22788
23371
  prefixReminded = true;
23372
+ } else if (entry.customType === WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE && invocationScopeId !== void 0 && isRecord(entry.data) && entry.data.invocationScopeId === invocationScopeId) {
23373
+ unfinishedReasonBounces += 1;
22789
23374
  }
22790
23375
  }
22791
- return { baseline, reminded, prefixReminded };
23376
+ return { baseline, reminded, prefixReminded, unfinishedReasonBounces };
22792
23377
  }
22793
23378
  function isAncestor(cwd, ancestor, descendant) {
22794
23379
  try {
@@ -22819,9 +23404,11 @@ function createWorkerSubmissionGate(options = {}) {
22819
23404
  let reminded = false;
22820
23405
  let prefixReminded = false;
22821
23406
  let unfinishedReasonBounces = 0;
23407
+ let invocationScopeId;
22822
23408
  let record;
22823
23409
  let sessionParent;
22824
23410
  const explicitHome = typeof options.home === "string" && options.home.length > 0 ? options.home : void 0;
23411
+ const unfinishedReasonBounceLimit = deliveryLimitFromConfig(options.unfinishedReasonBounceLimit);
22825
23412
  const head = (cwd) => {
22826
23413
  try {
22827
23414
  return git2(cwd, ["rev-parse", "HEAD"]);
@@ -22842,7 +23429,8 @@ function createWorkerSubmissionGate(options = {}) {
22842
23429
  });
22843
23430
  };
22844
23431
  return {
22845
- arm(cwd, parent) {
23432
+ arm(cwd, parent, scope) {
23433
+ invocationScopeId = scope;
22846
23434
  uninstallPackageWorkerHooks(cwd);
22847
23435
  root = cwd;
22848
23436
  sessionParent = parent.getSessionFile();
@@ -22851,7 +23439,8 @@ function createWorkerSubmissionGate(options = {}) {
22851
23439
  kind: WORKER_SUBMISSION_GATE_RECORD_KIND,
22852
23440
  parent
22853
23441
  });
22854
- const prior = readGateState(record);
23442
+ const prior = readGateState(record, invocationScopeId);
23443
+ unfinishedReasonBounces = prior.unfinishedReasonBounces;
22855
23444
  if (prior.baseline !== void 0) {
22856
23445
  baseline = prior.baseline;
22857
23446
  reminded = prior.reminded;
@@ -22873,7 +23462,11 @@ function createWorkerSubmissionGate(options = {}) {
22873
23462
  },
22874
23463
  assertAcceptable(status, details) {
22875
23464
  if (status === "unfinished" && !unfinishedReasonPresent(details)) {
22876
- if (unfinishedReasonBounces < UNFINISHED_REASON_BOUNCE_LIMIT) {
23465
+ if (unfinishedReasonBounces < unfinishedReasonBounceLimit) {
23466
+ record?.appendCustomEntry(WORKER_UNFINISHED_REASON_BOUNCE_ENTRY_TYPE, {
23467
+ version: 1,
23468
+ invocationScopeId
23469
+ });
22877
23470
  unfinishedReasonBounces += 1;
22878
23471
  throw new WorkerUnfinishedReasonReminderError();
22879
23472
  }
@@ -22907,6 +23500,9 @@ function createWorkerSubmissionGate(options = {}) {
22907
23500
  };
22908
23501
  }
22909
23502
 
23503
+ // src/worker-role.ts
23504
+ init_receipt_delivery_policy();
23505
+
22910
23506
  // src/fixer-bash-seatbelt.ts
22911
23507
  var FIXER_BASH_FORBIDDEN_LITERALS = [
22912
23508
  "rm -rf",
@@ -22995,14 +23591,16 @@ function assertAcceptableThroughHost(submissionGate, status, details, hostAction
22995
23591
  hostActions.failInfrastructure(error, ctx, toolCallId);
22996
23592
  }
22997
23593
  }
22998
- function createFixerRoleRuntime(pi, dependencies, hostActions) {
23594
+ function createFixerRoleRuntime(pi, dependencies, hostActions, options) {
22999
23595
  let soul;
23000
23596
  let packet;
23001
23597
  let packetPath;
23002
23598
  let prerequisitesPath;
23003
23599
  let phase;
23004
23600
  let lifecycleRegistered = false;
23005
- const submissionGate = createWorkerSubmissionGate();
23601
+ const submissionGate = createWorkerSubmissionGate({
23602
+ unfinishedReasonBounceLimit: options?.unfinishedReasonBounceLimit ?? deliveryLimitFromEnv(process.env)
23603
+ });
23006
23604
  pi.registerFlag(
23007
23605
  FIXER_FLAG_DEFINITIONS.packet.name,
23008
23606
  FIXER_FLAG_DEFINITIONS.packet.definition
@@ -23091,17 +23689,19 @@ ${packetPath}
23091
23689
  });
23092
23690
  }
23093
23691
  },
23094
- armSubmissionGate(cwd, parent) {
23095
- submissionGate.arm(cwd, parent);
23692
+ armSubmissionGate(cwd, parent, invocationScopeId) {
23693
+ submissionGate.arm(cwd, parent, invocationScopeId);
23096
23694
  }
23097
23695
  };
23098
23696
  }
23099
- function createCoderRoleRuntime(pi, dependencies, hostActions) {
23697
+ function createCoderRoleRuntime(pi, dependencies, hostActions, options) {
23100
23698
  let soul;
23101
23699
  let task;
23102
23700
  let phase;
23103
23701
  let lifecycleRegistered = false;
23104
- const submissionGate = createWorkerSubmissionGate();
23702
+ const submissionGate = createWorkerSubmissionGate({
23703
+ unfinishedReasonBounceLimit: options?.unfinishedReasonBounceLimit ?? deliveryLimitFromEnv(process.env)
23704
+ });
23105
23705
  pi.registerFlag("ak-coder-task", {
23106
23706
  description: "Markdown task assigned to the coder role",
23107
23707
  type: "string"
@@ -23157,8 +23757,8 @@ ${task ?? ""}
23157
23757
  });
23158
23758
  }
23159
23759
  },
23160
- armSubmissionGate(cwd, parent) {
23161
- submissionGate.arm(cwd, parent);
23760
+ armSubmissionGate(cwd, parent, invocationScopeId) {
23761
+ submissionGate.arm(cwd, parent, invocationScopeId);
23162
23762
  }
23163
23763
  };
23164
23764
  }
@@ -23749,7 +24349,8 @@ function lastAssistantProse(messages) {
23749
24349
  }
23750
24350
  return void 0;
23751
24351
  }
23752
- function createRoleRuntimeExtension(dependencies) {
24352
+ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
24353
+ const deliveryLimit = deliveryRequestLimit === void 0 ? deliveryLimitFromEnv(process.env) : deliveryLimitFromConfig(deliveryRequestLimit);
23753
24354
  return (envelopeHost) => {
23754
24355
  let projectClosedSubmission = async () => {
23755
24356
  throw new Error("\u89D2\u8272\u7EC8\u5C40\u6295\u5C04\u63A5\u7F1D\u5C1A\u672A\u521D\u59CB\u5316");
@@ -23806,7 +24407,7 @@ function createRoleRuntimeExtension(dependencies) {
23806
24407
  const pendingInfrastructureFailures = /* @__PURE__ */ new Map();
23807
24408
  const pendingSubmissionNonPassByToolCallId = /* @__PURE__ */ new Map();
23808
24409
  let engineDetourRegistered = false;
23809
- let receiptDelivery = createReceiptDeliveryPolicy();
24410
+ let receiptDelivery = createReceiptDeliveryPolicy(deliveryLimit);
23810
24411
  let noReceiptRecorded = false;
23811
24412
  let priorFetch;
23812
24413
  let fetchWrapped = false;
@@ -23969,7 +24570,7 @@ function createRoleRuntimeExtension(dependencies) {
23969
24570
  }
23970
24571
  };
23971
24572
  });
23972
- roleHost.on("tool_result", async (event) => {
24573
+ roleHost.on("tool_result", async (event, ctx) => {
23973
24574
  const role = selectedRole;
23974
24575
  if (role === void 0) return;
23975
24576
  const pendingInfra = pendingInfrastructureFailures.get(event.toolCallId);
@@ -23981,9 +24582,17 @@ function createRoleRuntimeExtension(dependencies) {
23981
24582
  const outputClassification = isOutputTool ? classifyPackagedRoleTerminalResult(classified) : void 0;
23982
24583
  if (isRoleInfrastructureFailure || outputClassification?.kind === "infrastructure") {
23983
24584
  receiptDelivery.stopForInfrastructure();
23984
- } else if (isOutputTool && outputClassification?.kind === "nonterminal" && event.isError) {
23985
- const reason = (event.content ?? []).map((part) => part.type === "text" && "text" in part ? part.text : "").join("").trim();
23986
- receiptDelivery.recordRejected(reason);
24585
+ } else if (isOutputTool) {
24586
+ const reason = packagedRoleOutputRejectionReason(classified);
24587
+ if (reason !== void 0) {
24588
+ receiptDelivery.recordRejected(reason);
24589
+ if (ctx.invocationScopeId !== void 0) {
24590
+ envelopeHost.appendEntry(RECEIPT_REJECTION_ENTRY, {
24591
+ invocationScopeId: ctx.invocationScopeId,
24592
+ reason
24593
+ });
24594
+ }
24595
+ }
23987
24596
  }
23988
24597
  const settlement = isRoleInfrastructureFailure || outputClassification?.kind === "infrastructure" ? publicNavigatorSettlement(role, navigatorPhase(roleHost, role), classified) : void 0;
23989
24598
  await settleNavigatorProjection(settlement);
@@ -24025,10 +24634,11 @@ function createRoleRuntimeExtension(dependencies) {
24025
24634
  const runPointer = runDirectoryFromHostContext(ctx);
24026
24635
  if (runPointer !== void 0) {
24027
24636
  noReceiptRecorded = true;
24028
- while (receiptDelivery.nextAction() === "request-delivery") {
24029
- receiptDelivery.recordDeliveryRequest();
24030
- }
24031
- const facts = receiptDelivery.facts({ runPointer, attemptPointer: `current:${runPointer}` });
24637
+ receiptDelivery.closeBudget();
24638
+ const facts = receiptDelivery.facts({
24639
+ runPointer,
24640
+ attemptPointer: receiptAttemptPointer(runPointer, ctx.invocationScopeId)
24641
+ });
24032
24642
  envelopeHost.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
24033
24643
  try {
24034
24644
  sitianReport({
@@ -24047,7 +24657,11 @@ function createRoleRuntimeExtension(dependencies) {
24047
24657
  }
24048
24658
  if (receiptDelivery.nextAction() === "request-delivery") {
24049
24659
  receiptDelivery.recordDeliveryRequest();
24050
- envelopeHost.appendEntry("ak-receipt-delivery-request");
24660
+ const scopeId = ctx.invocationScopeId?.trim() ?? "";
24661
+ envelopeHost.appendEntry(
24662
+ RECEIPT_DELIVERY_REQUEST_ENTRY,
24663
+ scopeId.length > 0 ? { invocationScopeId: scopeId } : void 0
24664
+ );
24051
24665
  try {
24052
24666
  sitianReport({
24053
24667
  level: "event",
@@ -24068,7 +24682,10 @@ function createRoleRuntimeExtension(dependencies) {
24068
24682
  const runPointer = runDirectoryFromHostContext(ctx);
24069
24683
  if (runPointer !== void 0) {
24070
24684
  noReceiptRecorded = true;
24071
- const facts = receiptDelivery.facts({ runPointer, attemptPointer: `current:${runPointer}` });
24685
+ const facts = receiptDelivery.facts({
24686
+ runPointer,
24687
+ attemptPointer: receiptAttemptPointer(runPointer, ctx.invocationScopeId)
24688
+ });
24072
24689
  envelopeHost.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
24073
24690
  try {
24074
24691
  sitianReport({
@@ -24155,7 +24772,8 @@ function createRoleRuntimeExtension(dependencies) {
24155
24772
  return dependencies.loadFixPacket(path);
24156
24773
  }
24157
24774
  },
24158
- hostActions
24775
+ hostActions,
24776
+ { unfinishedReasonBounceLimit: deliveryLimit }
24159
24777
  );
24160
24778
  const coder = createCoderRoleRuntime(
24161
24779
  roleHost,
@@ -24168,7 +24786,8 @@ function createRoleRuntimeExtension(dependencies) {
24168
24786
  return dependencies.loadCoderTask(path);
24169
24787
  }
24170
24788
  },
24171
- hostActions
24789
+ hostActions,
24790
+ { unfinishedReasonBounceLimit: deliveryLimit }
24172
24791
  );
24173
24792
  const reviewer = createReviewerRoleRuntime(
24174
24793
  roleHost,
@@ -24351,7 +24970,7 @@ function createRoleRuntimeExtension(dependencies) {
24351
24970
  roleReferenceMaterials = "";
24352
24971
  activeReviewerParent = void 0;
24353
24972
  activeCollector = void 0;
24354
- receiptDelivery = createReceiptDeliveryPolicy();
24973
+ receiptDelivery = createReceiptDeliveryPolicy(deliveryLimit);
24355
24974
  noReceiptRecorded = false;
24356
24975
  pendingNavigatorPresentation = void 0;
24357
24976
  navigatorActivation += 1;
@@ -24397,6 +25016,12 @@ function createRoleRuntimeExtension(dependencies) {
24397
25016
  try {
24398
25017
  resolveBookKeyFromGit(ctx.cwd);
24399
25018
  durableSessionPointer(ctx.sessionManager);
25019
+ const scopeId = ctx.invocationScopeId?.trim() ?? "";
25020
+ if (scopeId.length > 0) {
25021
+ receiptDelivery.continueIssued(
25022
+ priorReceiptContinuation(ctx.sessionManager.getEntries(), scopeId)
25023
+ );
25024
+ }
24400
25025
  const isStationChild = roleHost.getFlag(STATION_CHILD_FLAG.name) === true;
24401
25026
  if (dependencies.createNavigatorAttendance !== void 0 && entry.outputTool !== NAVIGATOR_TOOL_SPEC.name && !isStationChild) {
24402
25027
  navigatorSessionParent = ctx.sessionManager.getSessionFile();
@@ -24460,6 +25085,7 @@ function createRoleRuntimeExtension(dependencies) {
24460
25085
  subject: work.subject,
24461
25086
  authority: work.authority,
24462
25087
  invocationId,
25088
+ deliveryRequestLimit: deliveryLimit,
24463
25089
  ...contextError === void 0 ? {} : { contextError },
24464
25090
  onEvent: (navigatorEvent, report) => {
24465
25091
  if (activation === navigatorActivation && !navigatorDeliveryClosed) {
@@ -24483,7 +25109,7 @@ function createRoleRuntimeExtension(dependencies) {
24483
25109
  }
24484
25110
  if ("worker" in entry && entry.worker === true) {
24485
25111
  const workerArms = { coder, fixer };
24486
- workerArms[entry.role].armSubmissionGate(ctx.cwd, ctx.sessionManager);
25112
+ workerArms[entry.role].armSubmissionGate(ctx.cwd, ctx.sessionManager, ctx.invocationScopeId);
24487
25113
  }
24488
25114
  admitted = true;
24489
25115
  } catch (error) {
@@ -24513,11 +25139,11 @@ function createRoleRuntimeDependencies(packageRoot) {
24513
25139
  packageRoot,
24514
25140
  loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
24515
25141
  loadRoleSoul: loadRegisteredRoleSoul,
24516
- loadFixPacket: (path) => readFile24(path, "utf8"),
24517
- loadCoderTask: (path) => readFile24(path, "utf8"),
25142
+ loadFixPacket: (path) => readFile25(path, "utf8"),
25143
+ loadCoderTask: (path) => readFile25(path, "utf8"),
24518
25144
  loadDoctorCase,
24519
25145
  loadNotarySourceRun: loadNotarySourceRunLocator,
24520
- loadMergerInput: async (path) => JSON.parse(await readFile24(path, "utf8")),
25146
+ loadMergerInput: async (path) => JSON.parse(await readFile25(path, "utf8")),
24521
25147
  loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
24522
25148
  context: options.context,
24523
25149
  role: options.role,
@@ -24532,6 +25158,7 @@ function createRoleRuntimeDependencies(packageRoot) {
24532
25158
  authority: options.authority,
24533
25159
  invocationId: options.invocationId,
24534
25160
  createSession: navigatorSessionFactory,
25161
+ ...options.deliveryRequestLimit === void 0 ? {} : { deliveryRequestLimit: options.deliveryRequestLimit },
24535
25162
  ...options.contextError === void 0 ? {} : { contextError: options.contextError },
24536
25163
  onEvent: options.onEvent
24537
25164
  })
@@ -24541,6 +25168,7 @@ function createRoleRuntimeDependencies(packageRoot) {
24541
25168
  // src/role-envelope.ts
24542
25169
  init_engine_detour();
24543
25170
  init_packaged_role_registry();
25171
+ init_receipt_delivery_policy();
24544
25172
  import { randomUUID as randomUUID9 } from "node:crypto";
24545
25173
  import { appendFile as appendFile3, mkdir as mkdir5, writeFile as writeFile9 } from "node:fs/promises";
24546
25174
  import { createServer } from "node:net";
@@ -24726,7 +25354,10 @@ async function prepareRoleEnvelope(options) {
24726
25354
  stopKeepalive() {
24727
25355
  }
24728
25356
  };
24729
- createRoleRuntimeExtension(options.dependencies)(envelope);
25357
+ createRoleRuntimeExtension(
25358
+ options.dependencies,
25359
+ deliveryLimitFromConfig(options.request.deliveryRequestLimit)
25360
+ )(envelope);
24730
25361
  const token = randomUUID9();
24731
25362
  const server = createServer((socket) => serveSocket(socket));
24732
25363
  function rememberProjectedRejection(details, toolCallId, content) {
@@ -25118,8 +25749,9 @@ import { writeFile as writeFile10 } from "node:fs/promises";
25118
25749
  import { dirname as dirname26, isAbsolute as isAbsolute12, join as join45, resolve as resolve21 } from "node:path";
25119
25750
 
25120
25751
  // src/external-host-turn-loop.ts
25752
+ init_receipt_delivery_policy();
25753
+ init_submission_errors();
25121
25754
  init_unknown_value();
25122
- var EXTERNAL_ROLE_TURN_ROUND_LIMIT = 8;
25123
25755
  function mergeRoleTurnAbortSignals(prepared, request) {
25124
25756
  if (request === void 0) return prepared;
25125
25757
  if (prepared === void 0) return request;
@@ -25168,7 +25800,10 @@ async function driveExternalRoleTurnRounds(prepared, request, driver) {
25168
25800
  let prompt = prepared.prompt;
25169
25801
  const abortSignal = mergeRoleTurnAbortSignals(prepared.abortSignal, request.signal);
25170
25802
  let stderr = "";
25171
- for (let attempt = 0; attempt < EXTERNAL_ROLE_TURN_ROUND_LIMIT; attempt += 1) {
25803
+ const countedReaskLimit = deliveryLimitFromConfig(request.deliveryRequestLimit);
25804
+ const exemptReminders = /* @__PURE__ */ new Set();
25805
+ let countedReasks = 0;
25806
+ for (let attempt = 0; ; attempt += 1) {
25172
25807
  if (abortSignal?.aborted) return settleHostAborted(prepared, driver.currentSessionId());
25173
25808
  let round;
25174
25809
  try {
@@ -25189,14 +25824,22 @@ async function driveExternalRoleTurnRounds(prepared, request, driver) {
25189
25824
  return { code: 0, stderr, timedOut: false };
25190
25825
  }
25191
25826
  if ("failure" in closure) return asFailure(closure.failure, stderr);
25827
+ const reminderCode = closure.retry.code;
25828
+ const exempt = isOneShotWorkerReminderCode(reminderCode) && !exemptReminders.has(reminderCode);
25829
+ if (exempt) exemptReminders.add(reminderCode);
25830
+ else {
25831
+ countedReasks += 1;
25832
+ if (countedReasks > countedReaskLimit) {
25833
+ return asFailure({
25834
+ cause: "output",
25835
+ identity: { name: driver.roundLimitName, code: "round-retry-limit" },
25836
+ ...driver.currentSessionId() === void 0 ? {} : { details: { sessionId: driver.currentSessionId() } }
25837
+ });
25838
+ }
25839
+ }
25192
25840
  prompt = closure.retry.message;
25193
25841
  driver.afterRetry?.();
25194
25842
  }
25195
- return asFailure({
25196
- cause: "output",
25197
- identity: { name: driver.roundLimitName, code: "round-retry-limit" },
25198
- ...driver.currentSessionId() === void 0 ? {} : { details: { sessionId: driver.currentSessionId() } }
25199
- });
25200
25843
  }
25201
25844
  function createSerializedRoleTurnHost(execute) {
25202
25845
  let serial = Promise.resolve();