@akagilnc/pi-workflow-roles 0.1.4586 → 0.1.4631

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 (63) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +3 -3
  3. package/dist/acp-host/production-host.js +1184 -717
  4. package/dist/activation-ledger-topology.js +0 -4
  5. package/dist/archivist-record-topology.js +27 -35
  6. package/dist/headless-host/description.js +7 -4
  7. package/dist/headless-host/production-host.js +998 -595
  8. package/dist/migrate-book-topology.js +3 -6
  9. package/dist/navigator-attendance.js +146 -241
  10. package/dist/navigator-public-session.js +81 -15
  11. package/dist/package-contracts/navigator-output.js +30 -12
  12. package/dist/pi/role-turn-host.js +0 -3
  13. package/dist/public-cli/auto-resume.js +26 -0
  14. package/dist/public-cli/judge-run.js +2 -2
  15. package/dist/public-cli/main.js +1119 -870
  16. package/dist/public-cli/option-definitions.js +1 -1
  17. package/dist/public-cli/post-admission.js +103 -9
  18. package/dist/public-cli/process-cancel.js +57 -0
  19. package/dist/public-cli/run-lifecycle.js +29 -7
  20. package/dist/public-cli/settlement.js +46 -32
  21. package/dist/public-cli/terminal.js +8 -27
  22. package/dist/public-role-summons.js +22 -4
  23. package/dist/submission-ledger.js +56 -23
  24. package/package.json +1 -1
  25. package/resources/836-deleted-machine-instruction-inventory.md +2 -0
  26. package/resources/navigator-route-playbook.md +9 -0
  27. package/scripts/build-package.mjs +6 -2
  28. package/src/acp-host/role-turn-host.ts +129 -13
  29. package/src/activation-ledger-topology.ts +1 -6
  30. package/src/activation-ledger.ts +5 -236
  31. package/src/analyst-entry.ts +19 -2
  32. package/src/analyst-ledger.ts +111 -6
  33. package/src/archivist-record-entry.ts +1 -1
  34. package/src/headless-host/description.ts +17 -7
  35. package/src/headless-host/role-turn-host.ts +42 -11
  36. package/src/navigator-attendance.ts +290 -425
  37. package/src/navigator-public-session.ts +126 -25
  38. package/src/navigator-role.ts +2 -2
  39. package/src/package-contracts/navigator-output.ts +41 -25
  40. package/src/pi/role-turn-host.ts +0 -3
  41. package/src/public-cli/auto-resume.ts +34 -0
  42. package/src/public-cli/cli.ts +30 -0
  43. package/src/public-cli/coder-run.ts +2 -2
  44. package/src/public-cli/fixer-run.ts +2 -2
  45. package/src/public-cli/judge-run.ts +2 -2
  46. package/src/public-cli/main.ts +25 -3
  47. package/src/public-cli/merger-run.ts +2 -2
  48. package/src/public-cli/option-definitions.ts +1 -1
  49. package/src/public-cli/post-admission.ts +175 -7
  50. package/src/public-cli/process-cancel.ts +75 -0
  51. package/src/public-cli/run-lifecycle.ts +37 -7
  52. package/src/public-cli/settlement.ts +42 -33
  53. package/src/public-cli/terminal.ts +12 -37
  54. package/src/public-role-summons.ts +34 -5
  55. package/src/role-envelope.ts +89 -4
  56. package/src/role-runtime.ts +78 -65
  57. package/src/submission-ledger.ts +63 -21
  58. package/dist/activation-reconciliation.js +0 -61
  59. package/dist/public-cli/command-renderer.js +0 -5
  60. package/dist/public-command-renderer.js +0 -29
  61. package/src/activation-reconciliation.ts +0 -163
  62. package/src/public-cli/command-renderer.ts +0 -9
  63. package/src/public-command-renderer.ts +0 -55
@@ -417,7 +417,7 @@ function normalizeReviewComment(raw) {
417
417
  function createGhApiRunner(options = {}) {
418
418
  const spawnImpl = options.spawnImpl ?? spawn;
419
419
  return async (args, runOptions = {}) => {
420
- return await new Promise((resolve22, reject) => {
420
+ return await new Promise((resolve21, reject) => {
421
421
  const signal = runOptions.signal;
422
422
  if (signal?.aborted) {
423
423
  reject(signal.reason ?? new Error("aborted"));
@@ -490,11 +490,11 @@ function createGhApiRunner(options = {}) {
490
490
  const value = line2.slice(idx + 1).trim();
491
491
  headers[name] = value;
492
492
  }
493
- resolve22({ status, headers, bodyText });
493
+ resolve21({ status, headers, bodyText });
494
494
  return;
495
495
  }
496
496
  if (code === 0) {
497
- resolve22({ status: 200, headers: {}, bodyText: stdout });
497
+ resolve21({ status: 200, headers: {}, bodyText: stdout });
498
498
  return;
499
499
  }
500
500
  const failure2 = new Error(
@@ -691,7 +691,6 @@ var activation_ledger_topology_exports = {};
691
691
  __export(activation_ledger_topology_exports, {
692
692
  ActivationLedgerError: () => ActivationLedgerError,
693
693
  activationBookDirectory: () => activationBookDirectory,
694
- activationWaitingLedgerPath: () => activationWaitingLedgerPath,
695
694
  assertLedgerFileInsideHome: () => assertLedgerFileInsideHome,
696
695
  ensureRealDirectoryTree: () => ensureRealDirectoryTree,
697
696
  errnoCode: () => errnoCode,
@@ -754,9 +753,6 @@ function resolveActivationLedgerHomeForPath(path) {
754
753
  function activationBookDirectory(ledgerHome, bookKey) {
755
754
  return join(ledgerHome, "books", bookKey);
756
755
  }
757
- function activationWaitingLedgerPath(ledgerHome, bookKey) {
758
- return join(activationBookDirectory(ledgerHome, bookKey), "waiting.jsonl");
759
- }
760
756
  function pathContainedIn(root, candidate) {
761
757
  const rel = relative(root, candidate);
762
758
  return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
@@ -1964,7 +1960,7 @@ async function spawnEngineDetourOnce(input) {
1964
1960
  }
1965
1961
  const command = input.argv[0];
1966
1962
  const args = input.argv.slice(1);
1967
- return await new Promise((resolve22, reject) => {
1963
+ return await new Promise((resolve21, reject) => {
1968
1964
  let settled = false;
1969
1965
  const signal = input.signal;
1970
1966
  const child = spawn2(command, args, {
@@ -1994,7 +1990,7 @@ async function spawnEngineDetourOnce(input) {
1994
1990
  if (signal !== void 0) {
1995
1991
  signal.removeEventListener("abort", onAbort);
1996
1992
  }
1997
- resolve22(result);
1993
+ resolve21(result);
1998
1994
  };
1999
1995
  const onAbort = () => {
2000
1996
  fail4(signal !== void 0 ? abortReasonError(signal) : new Error("aborted"));
@@ -2110,7 +2106,48 @@ var init_collector_output = __esm({
2110
2106
  });
2111
2107
 
2112
2108
  // src/package-contracts/navigator-output.ts
2109
+ var navigator_output_exports = {};
2110
+ __export(navigator_output_exports, {
2111
+ NAVIGATOR_ACCEPTED_TEXT: () => NAVIGATOR_ACCEPTED_TEXT,
2112
+ NAVIGATOR_OUTPUT_TOOL_NAME: () => NAVIGATOR_OUTPUT_TOOL_NAME,
2113
+ navigatorOutputSchema: () => navigatorOutputSchema,
2114
+ navigatorProseFromUnknown: () => navigatorProseFromUnknown,
2115
+ projectLawfulNavigatorOutput: () => projectLawfulNavigatorOutput,
2116
+ validateRecordedNavigatorOutput: () => validateRecordedNavigatorOutput
2117
+ });
2113
2118
  import { Type as Type5 } from "typebox";
2119
+ function projectLawfulNavigatorOutput(value) {
2120
+ if (value === void 0 || value === null) return void 0;
2121
+ if (typeof value === "string") return { prose: value };
2122
+ if (typeof value === "object" && !Array.isArray(value)) {
2123
+ const record4 = value;
2124
+ if (typeof record4.prose === "string") return { prose: record4.prose };
2125
+ if (record4.prose !== void 0 && record4.prose !== null) {
2126
+ return { prose: typeof record4.prose === "string" ? record4.prose : String(record4.prose) };
2127
+ }
2128
+ const keys = Object.keys(record4);
2129
+ if (keys.length === 0) return { prose: "" };
2130
+ try {
2131
+ return { prose: JSON.stringify(record4) };
2132
+ } catch {
2133
+ return { prose: String(record4) };
2134
+ }
2135
+ }
2136
+ return { prose: String(value) };
2137
+ }
2138
+ function validateRecordedNavigatorOutput(value) {
2139
+ const projected = projectLawfulNavigatorOutput(value);
2140
+ if (projected === void 0) {
2141
+ throw new Error("Navigator output is empty");
2142
+ }
2143
+ return projected;
2144
+ }
2145
+ function navigatorProseFromUnknown(value) {
2146
+ const projected = projectLawfulNavigatorOutput(value);
2147
+ if (projected === void 0) return void 0;
2148
+ const trimmed = projected.prose.trim();
2149
+ return trimmed === "" ? void 0 : projected.prose;
2150
+ }
2114
2151
  var NAVIGATOR_OUTPUT_TOOL_NAME, NAVIGATOR_ACCEPTED_TEXT, navigatorOutputSchema;
2115
2152
  var init_navigator_output = __esm({
2116
2153
  "src/package-contracts/navigator-output.ts"() {
@@ -2122,11 +2159,8 @@ var init_navigator_output = __esm({
2122
2159
  navigatorOutputSchema = withTerminatingOutputDeclarations(
2123
2160
  openToolObject(
2124
2161
  Type5.Object({
2125
- status: Type5.Unknown({
2126
- description: "advice \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
2127
- }),
2128
- candidates: Type5.Unknown({
2129
- description: "\u6392\u597D\u5E8F\u7684\u8DEF\u7EBF\u5EFA\u8BAE\u6570\u7EC4\uFF0C\u5143\u7D20\u542B next/phase/reason \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
2162
+ prose: Type5.Unknown({
2163
+ description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
2130
2164
  })
2131
2165
  })
2132
2166
  )
@@ -3708,9 +3742,6 @@ ${paths.join("\n")}`
3708
3742
  if (typeof process.env.AK_ROLE_AUDITOR_SUBJECT === "string" && process.env.AK_ROLE_AUDITOR_SUBJECT.trim() !== "") {
3709
3743
  env.AK_ROLE_AUDITOR_SUBJECT = process.env.AK_ROLE_AUDITOR_SUBJECT;
3710
3744
  }
3711
- if (request.correlationId !== void 0 && request.correlationId.trim() !== "") {
3712
- env.AK_CORRELATION_ID = request.correlationId;
3713
- }
3714
3745
  if (config.recordLaunchedRolePackageIdentity !== void 0 && config.observeLaunchedRolePackageIdentity !== void 0) {
3715
3746
  await config.recordLaunchedRolePackageIdentity(
3716
3747
  request.runDirectory,
@@ -4912,6 +4943,56 @@ var init_typed_provider_http = __esm({
4912
4943
  });
4913
4944
 
4914
4945
  // src/public-cli/run-lifecycle.ts
4946
+ var run_lifecycle_exports = {};
4947
+ __export(run_lifecycle_exports, {
4948
+ AUTO_RESUME_LIMIT: () => AUTO_RESUME_LIMIT,
4949
+ GATE_DOSSIER_POINTER_PREFIX: () => GATE_DOSSIER_POINTER_PREFIX,
4950
+ RESUME_TRANSPORT_ENVELOPE: () => RESUME_TRANSPORT_ENVELOPE,
4951
+ RunWriterLeaseHeldError: () => RunWriterLeaseHeldError,
4952
+ V1_RESUMABLE_PROVIDERS: () => V1_RESUMABLE_PROVIDERS,
4953
+ acquireRunWriterLease: () => acquireRunWriterLease,
4954
+ autopsyWriterLock: () => autopsyWriterLock,
4955
+ buildAutoResumeContinuationPrompt: () => buildAutoResumeContinuationPrompt,
4956
+ buildResumeContinuationPrompt: () => buildResumeContinuationPrompt,
4957
+ clearCurrentCourt: () => clearCurrentCourt,
4958
+ clearTypedProviderHttpObservation: () => clearTypedProviderHttpObservation,
4959
+ describeErrorIdentity: () => describeErrorIdentity,
4960
+ findLatestRunIdForSeatTicket: () => findLatestRunIdForSeatTicket,
4961
+ findRunDirectoryById: () => findRunDirectoryById,
4962
+ isDurablePrincipalAvailable: () => isDurablePrincipalAvailable,
4963
+ isV1ResumableProvider: () => isV1ResumableProvider,
4964
+ loadResumableCoderRun: () => loadResumableCoderRun,
4965
+ loadResumableCollectorRun: () => loadResumableCollectorRun,
4966
+ loadResumableCountersignRun: () => loadResumableCountersignRun,
4967
+ loadResumableDiaristRun: () => loadResumableDiaristRun,
4968
+ loadResumableDoctorRun: () => loadResumableDoctorRun,
4969
+ loadResumableFixerRun: () => loadResumableFixerRun,
4970
+ loadResumableGleanerLeftRun: () => loadResumableGleanerLeftRun,
4971
+ loadResumableInspectorRun: () => loadResumableInspectorRun,
4972
+ loadResumableInstructionSeatRun: () => loadResumableInstructionSeatRun,
4973
+ loadResumableJudgeRun: () => loadResumableJudgeRun,
4974
+ loadResumableMergerRun: () => loadResumableMergerRun,
4975
+ loadResumableNotaryRun: () => loadResumableNotaryRun,
4976
+ loadResumableReviewerRun: () => loadResumableReviewerRun,
4977
+ loadResumableSecretariatRun: () => loadResumableSecretariatRun,
4978
+ markRunAdmitted: () => markRunAdmitted,
4979
+ markRunResumable: () => markRunResumable,
4980
+ markRunRunning: () => markRunRunning,
4981
+ markRunTerminal: () => markRunTerminal,
4982
+ parentRunPathFromGatePointerInstruction: () => parentRunPathFromGatePointerInstruction,
4983
+ peekRoleRunRole: () => peekRoleRunRole,
4984
+ readCurrentCourt: () => readCurrentCourt,
4985
+ readLatestTypedProviderHttpObservation: () => readLatestTypedProviderHttpObservation,
4986
+ readRoleRunIdentity: () => readRoleRunIdentity,
4987
+ readRoleRunState: () => readRoleRunState,
4988
+ readRunParentPath: () => readRunParentPath,
4989
+ readTypedHttp429Observation: () => readTypedHttp429Observation,
4990
+ recordCurrentCourt: () => recordCurrentCourt,
4991
+ recordTypedProviderHttpStatus: () => recordTypedProviderHttpStatus,
4992
+ renderResumeCommand: () => renderResumeCommand,
4993
+ selectResumeContinuationPrompt: () => selectResumeContinuationPrompt,
4994
+ writeRoleRunState: () => writeRoleRunState
4995
+ });
4915
4996
  import { chmod, lstat as lstat2, open, readdir as readdir4, readFile as readFile10, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
4916
4997
  import { basename as basename4, join as join13 } from "node:path";
4917
4998
  function selectResumeContinuationPrompt(message, engineMaterial) {
@@ -4927,6 +5008,15 @@ function buildResumeContinuationPrompt(options) {
4927
5008
  })
4928
5009
  );
4929
5010
  }
5011
+ function buildAutoResumeContinuationPrompt(options) {
5012
+ return selectResumeContinuationPrompt(
5013
+ RESUME_TRANSPORT_ENVELOPE,
5014
+ engineSessionMaterialFromOptions({
5015
+ packageRoot: options.packageRoot,
5016
+ ...pickEngineAxis(options)
5017
+ })
5018
+ );
5019
+ }
4930
5020
  function isV1ResumableProvider(provider) {
4931
5021
  return V1_RESUMABLE_PROVIDERS.includes(provider);
4932
5022
  }
@@ -5090,6 +5180,11 @@ function materializeRoleRunFromDisk(disk, authority) {
5090
5180
  return void 0;
5091
5181
  }
5092
5182
  }
5183
+ async function readRoleRunState(runDirectory, authority) {
5184
+ const disk = await readRoleRunStateDisk(runDirectory);
5185
+ if (disk === void 0) return void 0;
5186
+ return materializeRoleRunFromDisk(disk, authority)?.run;
5187
+ }
5093
5188
  async function readRoleRunIdentity(runDirectory) {
5094
5189
  const disk = await readRoleRunStateDisk(runDirectory);
5095
5190
  if (disk === void 0) return void 0;
@@ -5823,6 +5918,75 @@ async function loadResumableJudgeRun(home, runId, authority) {
5823
5918
  };
5824
5919
  return seatLoadedResult(loaded, admitted);
5825
5920
  }
5921
+ async function loadResumableCoderRun(home, runId, authority) {
5922
+ const loaded = await loadResumableRunRecord(home, runId, authority);
5923
+ if (loaded.run.role !== "coder") {
5924
+ throw new CliUsageError(
5925
+ `role run ${runId} belongs to ${loaded.run.role}, not coder`
5926
+ );
5927
+ }
5928
+ const phase = loaded.admittedFields.phase ?? loaded.run.phase;
5929
+ if (phase !== "plan" && phase !== "apply") {
5930
+ throw new CliUsageError(
5931
+ `role run admitted coder phase is missing: ${runId}`
5932
+ );
5933
+ }
5934
+ const taskPath = loaded.admittedFields.taskPath;
5935
+ if (taskPath === void 0) {
5936
+ throw new CliUsageError(
5937
+ `role run admitted coder task path is missing: ${runId}`
5938
+ );
5939
+ }
5940
+ if (loaded.admittedFields.instruction.trim() === "") {
5941
+ throw new CliUsageError(
5942
+ `role run admitted coder task is blank: ${runId}`
5943
+ );
5944
+ }
5945
+ const admitted = {
5946
+ role: "coder",
5947
+ phase,
5948
+ ...resumedBaseAdmitted(loaded),
5949
+ instructionEmpty: false,
5950
+ taskPath
5951
+ };
5952
+ return seatLoadedResult(loaded, admitted);
5953
+ }
5954
+ async function loadResumableFixerRun(home, runId, authority) {
5955
+ const loaded = await loadResumableRunRecord(home, runId, authority);
5956
+ if (loaded.run.role !== "fixer") {
5957
+ throw new CliUsageError(
5958
+ `role run ${runId} belongs to ${loaded.run.role}, not fixer`
5959
+ );
5960
+ }
5961
+ const phase = loaded.admittedFields.phase ?? loaded.run.phase;
5962
+ if (phase !== "plan" && phase !== "apply") {
5963
+ throw new CliUsageError(
5964
+ `role run admitted fixer phase is missing: ${runId}`
5965
+ );
5966
+ }
5967
+ const packetPath = loaded.admittedFields.packetPath;
5968
+ if (packetPath === void 0) {
5969
+ throw new CliUsageError(
5970
+ `role run admitted fixer packet path is missing: ${runId}`
5971
+ );
5972
+ }
5973
+ if (loaded.admittedFields.instruction.trim() === "") {
5974
+ throw new CliUsageError(
5975
+ `role run admitted fixer instruction is blank: ${runId}`
5976
+ );
5977
+ }
5978
+ const prerequisites = loaded.admittedFields.prerequisites ?? Object.freeze([]);
5979
+ const admitted = {
5980
+ role: "fixer",
5981
+ phase,
5982
+ ...resumedBaseAdmitted(loaded),
5983
+ instructionEmpty: false,
5984
+ packetPath,
5985
+ ...loaded.admittedFields.prerequisitesPath === void 0 ? {} : { prerequisitesPath: loaded.admittedFields.prerequisitesPath },
5986
+ prerequisites
5987
+ };
5988
+ return seatLoadedResult(loaded, admitted);
5989
+ }
5826
5990
  async function loadResumableReviewerRun(home, runId, authority) {
5827
5991
  const loaded = await loadResumableRunRecord(home, runId, authority);
5828
5992
  if (loaded.run.role !== "reviewer") {
@@ -5896,6 +6060,26 @@ async function loadResumableInstructionSeatRun(home, runId, authority) {
5896
6060
  };
5897
6061
  return seatLoadedResult(loaded, admitted);
5898
6062
  }
6063
+ async function loadResumableGleanerLeftRun(home, runId, authority) {
6064
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6065
+ if (loaded.run.role !== "gleaner-left") {
6066
+ throw new CliUsageError(
6067
+ `role run ${runId} belongs to ${loaded.run.role}, not gleaner-left`
6068
+ );
6069
+ }
6070
+ const baseRevision = loaded.admittedFields.baseRevision;
6071
+ if (baseRevision === void 0 || baseRevision.trim() === "") {
6072
+ throw new CliUsageError(
6073
+ `role run admitted gleaner-left base revision is missing: ${runId}`
6074
+ );
6075
+ }
6076
+ const admitted = {
6077
+ role: "gleaner-left",
6078
+ ...resumedBaseAdmitted(loaded),
6079
+ baseRevision
6080
+ };
6081
+ return seatLoadedResult(loaded, admitted);
6082
+ }
5899
6083
  async function loadResumableDiaristRun(home, runId, authority) {
5900
6084
  const loaded = await loadResumableRunRecord(home, runId, authority);
5901
6085
  if (loaded.run.role !== "diarist") {
@@ -5909,6 +6093,88 @@ async function loadResumableDiaristRun(home, runId, authority) {
5909
6093
  };
5910
6094
  return seatLoadedResult(loaded, admitted);
5911
6095
  }
6096
+ async function loadResumableSecretariatRun(home, runId, authority) {
6097
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6098
+ if (loaded.run.role !== "secretariat") {
6099
+ throw new CliUsageError(
6100
+ `role run ${runId} belongs to ${loaded.run.role}, not secretariat`
6101
+ );
6102
+ }
6103
+ const admitted = {
6104
+ role: "secretariat",
6105
+ ...resumedBaseAdmitted(loaded)
6106
+ };
6107
+ return seatLoadedResult(loaded, admitted);
6108
+ }
6109
+ async function loadResumableMergerRun(home, runId, authority) {
6110
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6111
+ if (loaded.run.role !== "merger") {
6112
+ throw new CliUsageError(
6113
+ `role run ${runId} belongs to ${loaded.run.role}, not merger`
6114
+ );
6115
+ }
6116
+ const mergerInputPath = loaded.admittedFields.mergerInputPath;
6117
+ if (mergerInputPath === void 0) {
6118
+ throw new CliUsageError(
6119
+ `role run admitted merger input path is missing: ${runId}`
6120
+ );
6121
+ }
6122
+ const derived = loaded.admittedFields.derived;
6123
+ if (derived === void 0) {
6124
+ throw new CliUsageError(
6125
+ `role run admitted merger envelope is missing: ${runId}`
6126
+ );
6127
+ }
6128
+ if (loaded.admittedFields.instruction.trim() === "") {
6129
+ throw new CliUsageError(
6130
+ `role run admitted merger task is blank: ${runId}`
6131
+ );
6132
+ }
6133
+ const admitted = {
6134
+ role: "merger",
6135
+ ...resumedBaseAdmitted(loaded),
6136
+ instructionEmpty: false,
6137
+ mergerInputPath,
6138
+ derived
6139
+ };
6140
+ return seatLoadedResult(loaded, admitted);
6141
+ }
6142
+ async function loadResumableCollectorRun(home, runId, authority) {
6143
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6144
+ if (loaded.run.role !== "collector") {
6145
+ throw new CliUsageError(
6146
+ `role run ${runId} belongs to ${loaded.run.role}, not collector`
6147
+ );
6148
+ }
6149
+ const { prNumber, repository, repositoryDisplay, manifestDigest } = loaded.admittedFields;
6150
+ if (repository === void 0 || repositoryDisplay === void 0 || manifestDigest === void 0) {
6151
+ throw new CliUsageError(
6152
+ `role run admitted collector repository identity is missing: ${runId}`
6153
+ );
6154
+ }
6155
+ let parsedRepository;
6156
+ try {
6157
+ parsedRepository = parseCollectorRepository(repositoryDisplay);
6158
+ } catch (error) {
6159
+ const detail = error instanceof Error ? error.message : String(error);
6160
+ throw new CliUsageError(detail, { cause: error });
6161
+ }
6162
+ if (parsedRepository.canonical !== repository) {
6163
+ throw new CliUsageError(
6164
+ `role run admitted collector repository does not match its canonical form: ${runId}`
6165
+ );
6166
+ }
6167
+ const admitted = {
6168
+ role: "collector",
6169
+ ...resumedBaseAdmitted(loaded),
6170
+ ...prNumber === void 0 ? {} : { prNumber },
6171
+ repository: parsedRepository,
6172
+ ...loaded.admittedFields.requestManifestPath === void 0 ? {} : { requestManifestPath: loaded.admittedFields.requestManifestPath },
6173
+ ...loaded.admittedFields.waitWindowMs === void 0 ? {} : { waitWindowMs: loaded.admittedFields.waitWindowMs },
6174
+ manifestDigest
6175
+ };
6176
+ return seatLoadedResult(loaded, admitted);
6177
+ }
5912
6178
  async function loadResumableDoctorRun(home, runId, authority) {
5913
6179
  const loaded = await loadResumableRunRecord(home, runId, authority);
5914
6180
  if (loaded.run.role !== "doctor") {
@@ -5966,6 +6232,12 @@ async function loadResumableInspectorRun(home, runId, authority) {
5966
6232
  };
5967
6233
  return seatLoadedResult(loaded, admitted);
5968
6234
  }
6235
+ async function peekRoleRunRole(home, runId) {
6236
+ const runDirectory = await findRunDirectoryById(home, runId);
6237
+ if (runDirectory === void 0) return void 0;
6238
+ const run = await readRoleRunIdentity(runDirectory);
6239
+ return run?.role;
6240
+ }
5969
6241
  var V1_RESUMABLE_PROVIDERS, AUTO_RESUME_LIMIT, RESUME_TRANSPORT_ENVELOPE, RUN_STATE_FILE, WRITER_LOCK_FILE, RunWriterLeaseHeldError, WRITER_LEASE_RECLAIM_ROUNDS, GATE_DOSSIER_POINTER_PREFIX;
5970
6242
  var init_run_lifecycle = __esm({
5971
6243
  "src/public-cli/run-lifecycle.ts"() {
@@ -5982,7 +6254,7 @@ var init_run_lifecycle = __esm({
5982
6254
  init_invocation();
5983
6255
  V1_RESUMABLE_PROVIDERS = ["openai-codex", "xai"];
5984
6256
  AUTO_RESUME_LIMIT = 2;
5985
- RESUME_TRANSPORT_ENVELOPE = "[ak-role:resume-continue]";
6257
+ RESUME_TRANSPORT_ENVELOPE = "\u7EE7\u7EED\u3002";
5986
6258
  RUN_STATE_FILE = "run-state.json";
5987
6259
  WRITER_LOCK_FILE = "writer.lock";
5988
6260
  RunWriterLeaseHeldError = class extends Error {
@@ -7037,7 +7309,7 @@ var init_option_definitions = __esm({
7037
7309
  },
7038
7310
  navigator: {
7039
7311
  command: "navigator",
7040
- summary: "Direct Navigator (\u6E38\u5955\u4F7F) route advice: ordered next-role candidates.",
7312
+ summary: "Direct Navigator (\u6E38\u5955\u4F7F) free-form prose route advice.",
7041
7313
  usage: ["ak-role navigator [options] [instruction]"],
7042
7314
  examples: [
7043
7315
  'ak-role navigator "\u521A\u5B8C\u6210 coder apply \u6536\u655B\uFF0C\u4E0B\u4E00\u6B65\uFF1F"'
@@ -11327,31 +11599,58 @@ async function restoreState(cwd, runId, scope) {
11327
11599
  }, 0)
11328
11600
  };
11329
11601
  }
11602
+ function sessionParentFromHostContext(context) {
11603
+ const runDirectory = runDirectoryFromHostContext(context);
11604
+ if (runDirectory !== void 0) return join22(runDirectory, "session", "session.jsonl");
11605
+ const sessionFile = context.sessionManager.getSessionFile?.();
11606
+ if (typeof sessionFile === "string" && sessionFile.length > 0) return sessionFile;
11607
+ const sessionDir = context.sessionManager.getSessionDir?.();
11608
+ if (typeof sessionDir === "string" && sessionDir.length > 0) {
11609
+ return join22(sessionDir, "session.jsonl");
11610
+ }
11611
+ return void 0;
11612
+ }
11613
+ function homeFromHostContext(context, home) {
11614
+ if (home !== void 0) return home;
11615
+ const sessionParent = sessionParentFromHostContext(context);
11616
+ return sessionParent !== void 0 ? tryHomeFromAkRolesPath(sessionParent) : void 0;
11617
+ }
11618
+ async function sealAcceptedSubmission(options) {
11619
+ const runId = runIdentity(options.context);
11620
+ const attemptId = attemptIdentity(options.context, runId);
11621
+ const sessionParent = sessionParentFromHostContext(options.context);
11622
+ const home = homeFromHostContext(options.context, options.home);
11623
+ const state = await restoreState(options.context.cwd, runId, {
11624
+ ...home === void 0 ? {} : { home },
11625
+ ...sessionParent === void 0 ? {} : { sessionParent }
11626
+ });
11627
+ const pointer = sitianReport({
11628
+ level: "event",
11629
+ kind: "sealed",
11630
+ subject: { runId, attemptId },
11631
+ ...state.prior === void 0 ? {} : { priorEventId: state.prior.identity },
11632
+ payload: {
11633
+ type: "sealed",
11634
+ attemptId,
11635
+ toolCallId: options.toolCallId,
11636
+ role: options.role,
11637
+ accepted: options.accepted
11638
+ },
11639
+ source: "role-runtime",
11640
+ cwd: options.context.cwd,
11641
+ ...home !== void 0 ? { home } : {},
11642
+ ...sessionParent === void 0 ? {} : { sessionParent }
11643
+ });
11644
+ state.prior = pointer;
11645
+ }
11330
11646
  function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (error) => {
11331
11647
  throw error;
11332
11648
  }, projectClosure = () => void 0, options) {
11333
11649
  const states = /* @__PURE__ */ new Map();
11334
- const sessionParentFromContext = (context) => {
11335
- const runDirectory = runDirectoryFromHostContext(context);
11336
- if (runDirectory !== void 0) {
11337
- return join22(runDirectory, "session", "session.jsonl");
11338
- }
11339
- const sessionFile = context.sessionManager.getSessionFile?.();
11340
- if (typeof sessionFile === "string" && sessionFile.length > 0) return sessionFile;
11341
- const sessionDir = context.sessionManager.getSessionDir?.();
11342
- if (typeof sessionDir === "string" && sessionDir.length > 0) {
11343
- return join22(sessionDir, "session.jsonl");
11344
- }
11345
- return void 0;
11346
- };
11347
- const resolveHomeFromContext = (context) => {
11348
- if (options?.home !== void 0) return options.home;
11349
- const sessionParent = sessionParentFromContext(context);
11350
- return sessionParent !== void 0 ? tryHomeFromAkRolesPath(sessionParent) : void 0;
11351
- };
11650
+ const resolveHomeFromContext = (context) => homeFromHostContext(context, options?.home);
11352
11651
  const stateFor = (context, runId) => states.get(runId) ?? (() => {
11353
11652
  const home = resolveHomeFromContext(context);
11354
- const sessionParent = sessionParentFromContext(context);
11653
+ const sessionParent = sessionParentFromHostContext(context);
11355
11654
  const pending = restoreState(context.cwd, runId, {
11356
11655
  ...home === void 0 ? {} : { home },
11357
11656
  ...sessionParent === void 0 ? {} : { sessionParent }
@@ -11361,7 +11660,7 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
11361
11660
  })();
11362
11661
  const appendFor = (state, context, runId, attemptId, event) => {
11363
11662
  const home = resolveHomeFromContext(context);
11364
- const sessionParent = sessionParentFromContext(context);
11663
+ const sessionParent = sessionParentFromHostContext(context);
11365
11664
  const pointer = sitianReport({
11366
11665
  level: "event",
11367
11666
  kind: event.type,
@@ -11712,12 +12011,12 @@ function createSystemCollectorClock() {
11712
12011
  return {
11713
12012
  wallNow: () => /* @__PURE__ */ new Date(),
11714
12013
  monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
11715
- sleep: (ms, signal) => new Promise((resolve22, reject) => {
12014
+ sleep: (ms, signal) => new Promise((resolve21, reject) => {
11716
12015
  if (signal?.aborted) {
11717
12016
  reject(signal.reason ?? new Error("aborted"));
11718
12017
  return;
11719
12018
  }
11720
- const timer = setTimeout(resolve22, ms);
12019
+ const timer = setTimeout(resolve21, ms);
11721
12020
  const onAbort = () => {
11722
12021
  clearTimeout(timer);
11723
12022
  reject(signal?.reason ?? new Error("aborted"));
@@ -13664,44 +13963,6 @@ var init_receipt_delivery_policy = __esm({
13664
13963
  }
13665
13964
  });
13666
13965
 
13667
- // src/public-command-renderer.ts
13668
- function isPublicCallableRole2(role) {
13669
- return PUBLIC_CALLABLE_ROLES3.has(role);
13670
- }
13671
- function renderPublicAkRoleCommand(target) {
13672
- if (!isPublicCallableRole2(target.role)) return void 0;
13673
- const role = target.role;
13674
- const metadata = packagedRoleMetadata(role);
13675
- if (metadata !== void 0 && "bareCommand" in metadata && metadata.bareCommand === false) {
13676
- return void 0;
13677
- }
13678
- if (target.phase === null || target.phase === void 0) {
13679
- return `ak-role ${role}`;
13680
- }
13681
- if (role === "coder" || role === "fixer") {
13682
- return `ak-role ${role} ${target.phase}`;
13683
- }
13684
- return `ak-role ${role}`;
13685
- }
13686
- var PUBLIC_CALLABLE_ROLES3;
13687
- var init_public_command_renderer = __esm({
13688
- "src/public-command-renderer.ts"() {
13689
- "use strict";
13690
- init_packaged_role_registry();
13691
- PUBLIC_CALLABLE_ROLES3 = new Set(
13692
- PACKAGED_ROLE_REGISTRY.map((entry) => entry.role)
13693
- );
13694
- }
13695
- });
13696
-
13697
- // src/public-cli/command-renderer.ts
13698
- var init_command_renderer = __esm({
13699
- "src/public-cli/command-renderer.ts"() {
13700
- "use strict";
13701
- init_public_command_renderer();
13702
- }
13703
- });
13704
-
13705
13966
  // src/public-cli/terminal.ts
13706
13967
  function encodeTerminalField(value) {
13707
13968
  return JSON.stringify(value);
@@ -13712,14 +13973,10 @@ function isLawfulTypedTerminalOutcome(outcome) {
13712
13973
  function exitCodeForTerminalOutcome(outcome) {
13713
13974
  return isLawfulTypedTerminalOutcome(outcome) ? 0 : 1;
13714
13975
  }
13715
- function recommendationNavigatorFact(input) {
13716
- const command = typeof input.modelCommand === "string" && input.modelCommand.trim() !== "" ? input.modelCommand : isPublicCallableRole2(input.next.role) ? renderPublicAkRoleCommand(input.next) : void 0;
13976
+ function adviceNavigatorFact(input) {
13717
13977
  return {
13718
- disposition: "recommendation",
13719
- next: input.next,
13720
- reason: input.reason,
13721
- ...command === void 0 ? {} : { command },
13722
- ...input.route === void 0 ? {} : { route: input.route },
13978
+ disposition: "advice",
13979
+ prose: input.prose,
13723
13980
  ...input.advisoryDiagnostic === void 0 ? {} : { advisoryDiagnostic: input.advisoryDiagnostic }
13724
13981
  };
13725
13982
  }
@@ -13747,14 +14004,8 @@ function formatTerminalResult(result) {
13747
14004
  if (result.navigator.advisoryDiagnostic !== void 0) {
13748
14005
  lines.push(`navigator-advisory ${encodeTerminalField(result.navigator.advisoryDiagnostic)}`);
13749
14006
  }
13750
- if (result.navigator.disposition === "recommendation") {
13751
- lines.push(
13752
- `next ${result.navigator.next.role} ${result.navigator.next.phase ?? "none"}`
13753
- );
13754
- lines.push(`reason ${encodeTerminalField(result.navigator.reason)}`);
13755
- if (result.navigator.command !== void 0) {
13756
- lines.push(`command ${encodeTerminalField(result.navigator.command)}`);
13757
- }
14007
+ if (result.navigator.disposition === "advice") {
14008
+ lines.push(`prose ${encodeTerminalField(result.navigator.prose)}`);
13758
14009
  } else if (result.navigator.disposition === "unavailable") {
13759
14010
  lines.push(
13760
14011
  `unavailable ${result.navigator.source} ${encodeTerminalField(result.navigator.reason)}`
@@ -13803,7 +14054,6 @@ function formatTerminalResult(result) {
13803
14054
  var init_terminal = __esm({
13804
14055
  "src/public-cli/terminal.ts"() {
13805
14056
  "use strict";
13806
- init_command_renderer();
13807
14057
  }
13808
14058
  });
13809
14059
 
@@ -14783,10 +15033,6 @@ async function appendRunAttemptHistory(source, outcome) {
14783
15033
  } catch {
14784
15034
  }
14785
15035
  }
14786
- function navigatorPhaseValue(value) {
14787
- if (value === "plan" || value === "apply") return value;
14788
- return null;
14789
- }
14790
15036
  function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
14791
15037
  if (attendanceIndex <= terminalIndex) return false;
14792
15038
  if (details.invocationId !== marker.invocationId) return false;
@@ -14795,29 +15041,33 @@ function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex,
14795
15041
  function parseNavigatorAttendanceDetails(details) {
14796
15042
  const disposition = details.disposition;
14797
15043
  const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
14798
- if (disposition === "recommendation") {
14799
- const next = details.next;
14800
- if (!isRecord11(next) || typeof next.role !== "string") {
15044
+ if (disposition === "advice" || disposition === "recommendation") {
15045
+ let prose;
15046
+ if (typeof details.prose === "string" && details.prose.trim() !== "") {
15047
+ prose = details.prose;
15048
+ } else {
15049
+ const next = isRecord11(details.next) && typeof details.next.role === "string" ? details.next.role : void 0;
15050
+ const reason = typeof details.reason === "string" && details.reason.trim() !== "" ? details.reason : void 0;
15051
+ const command = typeof details.command === "string" && details.command.trim() !== "" ? details.command : void 0;
15052
+ if (reason !== void 0 && next !== void 0) {
15053
+ prose = `${reason}\uFF08\u4E0B\u4E00\u6B65\uFF1A${next}\uFF09`;
15054
+ } else if (reason !== void 0) {
15055
+ prose = reason;
15056
+ } else if (next !== void 0) {
15057
+ prose = `\u4E0B\u4E00\u6B65\uFF1A${next}`;
15058
+ } else if (command !== void 0) {
15059
+ prose = command;
15060
+ }
15061
+ }
15062
+ if (prose === void 0 || prose.trim() === "") {
14801
15063
  return {
14802
- disposition: "unavailable",
14803
- source: "unknown",
14804
- reason: "navigator recommendation missing typed next role"
15064
+ disposition: "no-advice",
15065
+ ...advisoryDiagnostic
14805
15066
  };
14806
15067
  }
14807
- const reason = typeof details.reason === "string" ? details.reason : "";
14808
- const route = Array.isArray(details.route) ? details.route.filter(isRecord11).map((target) => ({
14809
- role: String(target.role),
14810
- phase: navigatorPhaseValue(target.phase)
14811
- })) : void 0;
14812
- return recommendationNavigatorFact({
14813
- ...advisoryDiagnostic,
14814
- next: {
14815
- role: next.role,
14816
- phase: navigatorPhaseValue(next.phase)
14817
- },
14818
- reason,
14819
- ...route === void 0 ? {} : { route },
14820
- ...typeof details.command === "string" ? { modelCommand: details.command } : {}
15068
+ return adviceNavigatorFact({
15069
+ prose,
15070
+ ...advisoryDiagnostic
14821
15071
  });
14822
15072
  }
14823
15073
  if (disposition === "unavailable") {
@@ -16243,10 +16493,10 @@ function presentFailureTerminal(terminal, io) {
16243
16493
  }
16244
16494
  function defaultNavigatorGraceSleep() {
16245
16495
  let timer;
16246
- const sleep = ((ms) => new Promise((resolve22) => {
16496
+ const sleep = ((ms) => new Promise((resolve21) => {
16247
16497
  timer = setTimeout(() => {
16248
16498
  timer = void 0;
16249
- resolve22();
16499
+ resolve21();
16250
16500
  }, ms);
16251
16501
  }));
16252
16502
  sleep.cancel = () => {
@@ -16258,7 +16508,7 @@ function defaultNavigatorGraceSleep() {
16258
16508
  return sleep;
16259
16509
  }
16260
16510
  function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep = defaultNavigatorGraceSleep()) {
16261
- return new Promise((resolve22, reject) => {
16511
+ return new Promise((resolve21, reject) => {
16262
16512
  let settled = false;
16263
16513
  const finish = (action) => {
16264
16514
  if (settled) return;
@@ -16267,11 +16517,11 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep
16267
16517
  action();
16268
16518
  };
16269
16519
  void work.then(
16270
- (value) => finish(() => resolve22({ status: "done", value })),
16520
+ (value) => finish(() => resolve21({ status: "done", value })),
16271
16521
  (error) => finish(() => reject(error))
16272
16522
  );
16273
16523
  void sleep(graceMs).then(() => {
16274
- finish(() => resolve22({ status: "timeout" }));
16524
+ finish(() => resolve21({ status: "timeout" }));
16275
16525
  });
16276
16526
  });
16277
16527
  }
@@ -17277,6 +17527,24 @@ var init_public_run_credentials = __esm({
17277
17527
  }
17278
17528
  });
17279
17529
 
17530
+ // src/public-cli/process-cancel.ts
17531
+ function processCancelSignalName(signal) {
17532
+ if (signal === void 0 || signal.aborted !== true) return void 0;
17533
+ const reason = signal.reason;
17534
+ if (reason === "SIGTERM" || reason === "SIGINT" || reason === "SIGHUP") {
17535
+ return reason;
17536
+ }
17537
+ return void 0;
17538
+ }
17539
+ function processCancelDiagnostic(signalName) {
17540
+ return `ak-role terminated by ${signalName}`;
17541
+ }
17542
+ var init_process_cancel = __esm({
17543
+ "src/public-cli/process-cancel.ts"() {
17544
+ "use strict";
17545
+ }
17546
+ });
17547
+
17280
17548
  // src/public-cli/auto-resume.ts
17281
17549
  import { constants as fsConstants2 } from "node:fs";
17282
17550
  import { randomUUID as randomUUID5 } from "node:crypto";
@@ -17579,6 +17847,10 @@ async function runWithAutoResumeLoop(options) {
17579
17847
  if (terminal !== void 0) presentTerminal(terminal, options.io);
17580
17848
  return result;
17581
17849
  }
17850
+ if (processCancelSignalName(options.signal) !== void 0) {
17851
+ if (terminal !== void 0) presentTerminal(terminal, options.io);
17852
+ return result;
17853
+ }
17582
17854
  }
17583
17855
  if (result !== void 0) {
17584
17856
  const terminal = result.terminal;
@@ -17612,6 +17884,28 @@ async function runWithAutoResumeLoop(options) {
17612
17884
  terminal
17613
17885
  };
17614
17886
  }
17887
+ const cancelName = processCancelSignalName(options.signal);
17888
+ if (cancelName !== void 0) {
17889
+ const terminal = await attachDispatchExceptionTerminal(
17890
+ options.admitted,
17891
+ dispatchExceptionFailureTerminal({
17892
+ role: options.admitted.role,
17893
+ runId: options.admitted.runId,
17894
+ causeError: lastThrownError,
17895
+ errorFiles: retainedErrorFiles,
17896
+ autoResumeAttempts,
17897
+ endReason: `ak-role terminated by ${cancelName}`,
17898
+ everyAttemptThrew
17899
+ }),
17900
+ options.io
17901
+ );
17902
+ await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
17903
+ presentTerminal(terminal, options.io);
17904
+ return {
17905
+ exitCode: 1,
17906
+ terminal
17907
+ };
17908
+ }
17615
17909
  if (!await isPrincipalAvailable(options.admitted.principal)) {
17616
17910
  const terminal = await attachDispatchExceptionTerminal(
17617
17911
  options.admitted,
@@ -17648,6 +17942,7 @@ var init_auto_resume = __esm({
17648
17942
  init_role_run_placement();
17649
17943
  init_run_lifecycle();
17650
17944
  init_config();
17945
+ init_process_cancel();
17651
17946
  init_terminal();
17652
17947
  init_settlement();
17653
17948
  dummyIo = { stdout: () => {
@@ -17680,6 +17975,36 @@ function describeCaughtError(error) {
17680
17975
  function isStationChildOfficerDialogue(role, env) {
17681
17976
  return env.stationChild === true && isOfficerReviewSeat(role);
17682
17977
  }
17978
+ function withProcessCancelSkipAutoResume(result, signal) {
17979
+ if (processCancelSignalName(signal) === void 0) {
17980
+ return result;
17981
+ }
17982
+ return { ...result, skipAutoResume: true };
17983
+ }
17984
+ async function settleProcessCancelAfterTurn(input) {
17985
+ const failed = await settleAfterTurnStarted(
17986
+ input.admitted,
17987
+ withEngineDetourInvocationScope(
17988
+ {
17989
+ timedOut: input.result.timedOut,
17990
+ code: input.result.code,
17991
+ stderr: input.result.stderr,
17992
+ knownDiagnostic: processCancelDiagnostic(input.cancelName)
17993
+ },
17994
+ input.invocationScopeId
17995
+ ),
17996
+ input.adapters,
17997
+ input.env.principalAuthority,
17998
+ input.io,
17999
+ input.persistRunState
18000
+ );
18001
+ return {
18002
+ ...failed,
18003
+ turnDispatched: true,
18004
+ skipAutoResume: true,
18005
+ ...input.deferredPersist
18006
+ };
18007
+ }
17683
18008
  function withOnceSuccessfulBeforeDispatch(adapters) {
17684
18009
  const hook = adapters.beforeDispatch;
17685
18010
  if (hook === void 0) return adapters;
@@ -17840,6 +18165,31 @@ async function dispatchPostAdmissionTurn(input) {
17840
18165
  const finishAfterTurn = async (result) => {
17841
18166
  if (afterDispatchApplied) return result;
17842
18167
  afterDispatchApplied = true;
18168
+ const cancelBeforeFinish = processCancelSignalName(env.signal);
18169
+ if (cancelBeforeFinish !== void 0 && result.terminal !== void 0 && isLawfulTypedTerminalOutcome(result.terminal.roleOutcome)) {
18170
+ result = {
18171
+ ...await settleAfterTurnStarted(
18172
+ admitted,
18173
+ withEngineDetourInvocationScope(
18174
+ {
18175
+ timedOut: false,
18176
+ code: null,
18177
+ stderr: "",
18178
+ knownDiagnostic: processCancelDiagnostic(cancelBeforeFinish),
18179
+ skipRunStateWrite: true
18180
+ },
18181
+ request.invocationScopeId
18182
+ ),
18183
+ adapters,
18184
+ env.principalAuthority,
18185
+ io,
18186
+ persistRunState
18187
+ ),
18188
+ turnDispatched: true,
18189
+ skipAutoResume: true,
18190
+ ...deferredPersist
18191
+ };
18192
+ }
17843
18193
  try {
17844
18194
  if (admitted.ticketNumber === void 0) {
17845
18195
  const rows = await readRecordedSubmissionRows(
@@ -17986,20 +18336,26 @@ async function dispatchPostAdmissionTurn(input) {
17986
18336
  try {
17987
18337
  result = await env.roleTurnHost.executeTurn(turnRequest);
17988
18338
  } catch (error) {
18339
+ const processCancelName = processCancelSignalName(env.signal);
17989
18340
  const settled2 = await settleAfterTurnStarted(
17990
18341
  admitted,
17991
18342
  withEngineDetourInvocationScope({
17992
18343
  timedOut: false,
17993
18344
  code: null,
17994
18345
  stderr: "",
17995
- thrown: error
18346
+ thrown: processCancelName === void 0 ? error : new Error(processCancelDiagnostic(processCancelName), { cause: error })
17996
18347
  }, request.invocationScopeId),
17997
18348
  adapters,
17998
18349
  env.principalAuthority,
17999
18350
  io,
18000
18351
  persistRunState
18001
18352
  );
18002
- return await finishAfterTurn({ ...settled2, turnDispatched: true, ...deferredPersist });
18353
+ return await finishAfterTurn(
18354
+ withProcessCancelSkipAutoResume(
18355
+ { ...settled2, turnDispatched: true, ...deferredPersist },
18356
+ env.signal
18357
+ )
18358
+ );
18003
18359
  }
18004
18360
  let stderrLogWriteFailure;
18005
18361
  try {
@@ -18039,7 +18395,8 @@ async function dispatchPostAdmissionTurn(input) {
18039
18395
  credential: credentialFailure,
18040
18396
  runDirectory: admitted.runDirectory
18041
18397
  });
18042
- const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || credentialFailure !== void 0;
18398
+ const processCancelName = processCancelSignalName(env.signal);
18399
+ const directHostFailureSignal = result.timedOut || result.knownFailure !== void 0 || runnerKnownFailure !== void 0 || credentialFailure !== void 0 || processCancelName !== void 0;
18043
18400
  hostSignalFailed = directHostFailureSignal || result.code !== null && result.code !== 0 || resolution.knownFailure !== void 0;
18044
18401
  settled = await adapters.trySettle(admitted, env.principalAuthority, courtScope);
18045
18402
  if (settled !== void 0) {
@@ -18047,7 +18404,8 @@ async function dispatchPostAdmissionTurn(input) {
18047
18404
  }
18048
18405
  const settledIsFreshThisAttempt = settled === void 0 || settled.roleOutcome.kind !== "accepted" && settled.roleOutcome.kind !== "audit_escalation" ? true : await attemptProducedFreshSubmission(admitted, courtScope);
18049
18406
  const staleAcceptanceOutranksRealFailure = !settledIsFreshThisAttempt && hostSignalFailed;
18050
- if (settled !== void 0 && shouldPresent(settled) && !directHostFailureSignal && !staleAcceptanceOutranksRealFailure && stderrLogWriteFailure === void 0) {
18407
+ const cancelAfterSettle = processCancelSignalName(env.signal);
18408
+ if (settled !== void 0 && shouldPresent(settled) && !directHostFailureSignal && !staleAcceptanceOutranksRealFailure && stderrLogWriteFailure === void 0 && cancelAfterSettle === void 0) {
18051
18409
  if (settled.roleOutcome.kind === "accepted" && request.courtAttemptId !== void 0 && request.courtAttemptId.length > 0) {
18052
18410
  try {
18053
18411
  await clearCurrentCourt(admitted.runDirectory, request.courtAttemptId);
@@ -18084,6 +18442,22 @@ async function dispatchPostAdmissionTurn(input) {
18084
18442
  return await finishAfterTurn({ ...settledFailure, turnDispatched: true, ...deferredPersist });
18085
18443
  }
18086
18444
  if (settledOutcome !== void 0) {
18445
+ const lateCancel = processCancelSignalName(env.signal);
18446
+ if (lateCancel !== void 0) {
18447
+ return await finishAfterTurn(
18448
+ await settleProcessCancelAfterTurn({
18449
+ admitted,
18450
+ cancelName: lateCancel,
18451
+ result,
18452
+ adapters,
18453
+ env,
18454
+ io,
18455
+ persistRunState,
18456
+ deferredPersist,
18457
+ invocationScopeId: request.invocationScopeId
18458
+ })
18459
+ );
18460
+ }
18087
18461
  if (persistRunState) {
18088
18462
  try {
18089
18463
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
@@ -18102,13 +18476,19 @@ async function dispatchPostAdmissionTurn(input) {
18102
18476
  io,
18103
18477
  persistRunState
18104
18478
  );
18105
- return await finishAfterTurn({ ...failed, turnDispatched: true, ...deferredPersist });
18479
+ return await finishAfterTurn(
18480
+ withProcessCancelSkipAutoResume(
18481
+ { ...failed, turnDispatched: true, ...deferredPersist },
18482
+ env.signal
18483
+ )
18484
+ );
18106
18485
  }
18107
18486
  }
18108
18487
  return await finishAfterTurn({ ...settledOutcome, ...deferredPersist });
18109
18488
  }
18110
18489
  if (hostSignalFailed) {
18111
18490
  const resolutionInput = controlledFailureInputFromResolution(resolution);
18491
+ const processCancelName = processCancelSignalName(env.signal);
18112
18492
  const stderrLogWriteDetails = stderrLogWriteFailure === void 0 ? void 0 : { stderrLogWriteFailure: describeCaughtError(stderrLogWriteFailure) };
18113
18493
  const failed = await settleAfterTurnStarted(
18114
18494
  admitted,
@@ -18117,6 +18497,7 @@ async function dispatchPostAdmissionTurn(input) {
18117
18497
  code: result.code,
18118
18498
  stderr: result.stderr,
18119
18499
  ...resolutionInput,
18500
+ ...processCancelName === void 0 ? {} : { knownDiagnostic: processCancelDiagnostic(processCancelName) },
18120
18501
  // Secondary fact only — never the cause. Rides on whichever channel
18121
18502
  // classification actually reads (knownFailure.details owns it when
18122
18503
  // a knownFailure exists; the top-level knownDetails otherwise).
@@ -18132,7 +18513,12 @@ async function dispatchPostAdmissionTurn(input) {
18132
18513
  io,
18133
18514
  persistRunState
18134
18515
  );
18135
- return await finishAfterTurn({ ...failed, turnDispatched: true, ...deferredPersist });
18516
+ return await finishAfterTurn(
18517
+ withProcessCancelSkipAutoResume(
18518
+ { ...failed, turnDispatched: true, ...deferredPersist },
18519
+ env.signal
18520
+ )
18521
+ );
18136
18522
  }
18137
18523
  if (stderrLogWriteFailure !== void 0) {
18138
18524
  const failed = await settleAfterTurnStarted(
@@ -18155,8 +18541,24 @@ async function dispatchPostAdmissionTurn(input) {
18155
18541
  await settleHostEndedNoReceipt(admitted, env.principalAuthority, courtScope),
18156
18542
  courtScope
18157
18543
  );
18158
- if (persistRunState) {
18159
- try {
18544
+ const noReceiptCancel = processCancelSignalName(env.signal);
18545
+ if (noReceiptCancel !== void 0) {
18546
+ return await finishAfterTurn(
18547
+ await settleProcessCancelAfterTurn({
18548
+ admitted,
18549
+ cancelName: noReceiptCancel,
18550
+ result,
18551
+ adapters,
18552
+ env,
18553
+ io,
18554
+ persistRunState,
18555
+ deferredPersist,
18556
+ invocationScopeId: request.invocationScopeId
18557
+ })
18558
+ );
18559
+ }
18560
+ if (persistRunState) {
18561
+ try {
18160
18562
  await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
18161
18563
  } catch (error) {
18162
18564
  const failed = await settleAfterTurnStarted(
@@ -18173,7 +18575,12 @@ async function dispatchPostAdmissionTurn(input) {
18173
18575
  io,
18174
18576
  persistRunState
18175
18577
  );
18176
- return await finishAfterTurn({ ...failed, turnDispatched: true, ...deferredPersist });
18578
+ return await finishAfterTurn(
18579
+ withProcessCancelSkipAutoResume(
18580
+ { ...failed, turnDispatched: true, ...deferredPersist },
18581
+ env.signal
18582
+ )
18583
+ );
18177
18584
  }
18178
18585
  }
18179
18586
  return await finishAfterTurn({
@@ -18369,6 +18776,7 @@ async function runPostAdmissionSeatResume(input) {
18369
18776
  io: input.io,
18370
18777
  sessionAppender: env.sessionAppender,
18371
18778
  autoResumeLimit: env.autoResumeLimit,
18779
+ ...env.signal === void 0 ? {} : { signal: env.signal },
18372
18780
  buildInitialPayload: () => ({ resumeTurn: false }),
18373
18781
  buildResumePayload: () => ({ resumeTurn: true }),
18374
18782
  // Same as public manual resume: prior-court sealed acceptance is not a
@@ -18444,7 +18852,7 @@ async function runPostAdmissionOneShot(input) {
18444
18852
  ...input.request,
18445
18853
  continuation: {
18446
18854
  kind: "resume",
18447
- prompt: buildResumeContinuationPrompt({
18855
+ prompt: buildAutoResumeContinuationPrompt({
18448
18856
  packageRoot: input.env.packageRoot,
18449
18857
  ...pickEngineAxis({
18450
18858
  engine: input.effectiveEngine ?? input.env.engine,
@@ -18472,6 +18880,7 @@ async function runPostAdmissionResumable(input) {
18472
18880
  io,
18473
18881
  sessionAppender: env.sessionAppender,
18474
18882
  autoResumeLimit: env.autoResumeLimit,
18883
+ ...env.signal === void 0 ? {} : { signal: env.signal },
18475
18884
  buildInitialPayload: buildScopedInitial,
18476
18885
  buildResumePayload: buildScopedResume,
18477
18886
  dispatch: async (request, lease, _isFirst, attemptIo) => {
@@ -18580,6 +18989,7 @@ var init_post_admission = __esm({
18580
18989
  init_host_transition_prior_native();
18581
18990
  init_public_run_credentials();
18582
18991
  init_run_lifecycle();
18992
+ init_process_cancel();
18583
18993
  init_activation_ledger_topology();
18584
18994
  init_settlement();
18585
18995
  init_terminal();
@@ -19316,7 +19726,7 @@ async function runPublicJudge(argv, env, io, parseJudgeArgv2) {
19316
19726
  ...admitted.correlationId === void 0 && env.correlationId === void 0 ? {} : { correlationId: admitted.correlationId ?? env.correlationId },
19317
19727
  continuation: {
19318
19728
  kind: "resume",
19319
- prompt: buildResumeContinuationPrompt({
19729
+ prompt: buildAutoResumeContinuationPrompt({
19320
19730
  packageRoot: env.packageRoot,
19321
19731
  ...pickEngineAxis(env)
19322
19732
  })
@@ -20699,14 +21109,32 @@ async function summonPublicRole(options) {
20699
21109
  case "navigator":
20700
21110
  case "gatekeeper": {
20701
21111
  const seat2 = options.role;
20702
- const [{ runPublicInstructionSeat: runPublicInstructionSeat2 }, invocation] = await Promise.all([
21112
+ const [{ runPublicInstructionSeat: runPublicInstructionSeat2, runPublicInstructionSeatResume: runPublicInstructionSeatResume2 }, invocation] = await Promise.all([
20703
21113
  Promise.resolve().then(() => (init_instruction_seat_run(), instruction_seat_run_exports)),
20704
21114
  Promise.resolve().then(() => (init_invocation(), invocation_exports))
20705
21115
  ]);
20706
21116
  const parse = seat2 === "auditor" ? invocation.parseAuditorArgv : seat2 === "navigator" ? invocation.parseNavigatorArgv : invocation.parseGatekeeperArgv;
20707
- const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat2(options.argv, env, io, seat2, once));
20708
- if ("fail" in stepped) return stepped.fail;
20709
- result = stepped.ok;
21117
+ const resumeRunId = typeof options.resumeRunId === "string" && options.resumeRunId.trim() !== "" ? options.resumeRunId.trim() : void 0;
21118
+ if (resumeRunId !== void 0) {
21119
+ const instruction = options.argv[0] ?? "";
21120
+ const stepped = await runPrepared(parse, (env) => runPublicInstructionSeatResume2(
21121
+ {
21122
+ runId: resumeRunId,
21123
+ summons: {
21124
+ instruction,
21125
+ instructionEmpty: instruction.trim() === ""
21126
+ }
21127
+ },
21128
+ env,
21129
+ io
21130
+ ));
21131
+ if ("fail" in stepped) return stepped.fail;
21132
+ result = stepped.ok;
21133
+ } else {
21134
+ const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat2(options.argv, env, io, seat2, once));
21135
+ if ("fail" in stepped) return stepped.fail;
21136
+ result = stepped.ok;
21137
+ }
20710
21138
  break;
20711
21139
  }
20712
21140
  case "judge": {
@@ -21653,7 +22081,7 @@ var init_archivist_record_entry = __esm({
21653
22081
  });
21654
22082
 
21655
22083
  // src/headless-host/production-host.ts
21656
- import { randomUUID as randomUUID10 } from "node:crypto";
22084
+ import { randomUUID as randomUUID11 } from "node:crypto";
21657
22085
 
21658
22086
  // src/role-runtime-dependencies.ts
21659
22087
  import { readFile as readFile22 } from "node:fs/promises";
@@ -21740,6 +22168,7 @@ import { Type as Type13 } from "typebox";
21740
22168
 
21741
22169
  // src/navigator-public-session.ts
21742
22170
  init_sitian_facade();
22171
+ import { basename as basename9 } from "node:path";
21743
22172
 
21744
22173
  // src/navigator-session-contracts.ts
21745
22174
  import { Type as Type12 } from "typebox";
@@ -21927,6 +22356,7 @@ async function resolveNavigatorSeatSelection(context) {
21927
22356
 
21928
22357
  // src/navigator-public-session.ts
21929
22358
  init_host_contracts();
22359
+ init_cli_errors();
21930
22360
  async function resolveNavigatorLedgerHome(context) {
21931
22361
  const { tryHomeFromAkRolesPath: tryHomeFromAkRolesPath2 } = await Promise.resolve().then(() => (init_activation_ledger_topology(), activation_ledger_topology_exports));
21932
22362
  const runDirectory = runDirectoryFromHostContext(context);
@@ -21941,7 +22371,42 @@ async function resolveNavigatorLedgerHome(context) {
21941
22371
  }
21942
22372
  return void 0;
21943
22373
  }
21944
- function createNativeNavigatorSessionFactory() {
22374
+ var NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
22375
+ function exactRecord2(value) {
22376
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22377
+ }
22378
+ function runIdFromNavigatorDirectory(runDirectory) {
22379
+ const entry = basename9(runDirectory);
22380
+ const suffix = "@navigator";
22381
+ if (!entry.endsWith(suffix)) return void 0;
22382
+ const runId = entry.slice(0, entry.length - suffix.length);
22383
+ return runId.length > 0 ? runId : void 0;
22384
+ }
22385
+ function readNavigatorHostRunPointer(entries) {
22386
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
22387
+ const entry = entries[index];
22388
+ if (!exactRecord2(entry)) continue;
22389
+ if (entry.type === "custom" && entry.customType === NAVIGATOR_HOST_RUN_POINTER_ENTRY) {
22390
+ const data = entry.data;
22391
+ if (exactRecord2(data) && typeof data.runId === "string" && data.runId.trim() !== "") {
22392
+ return data.runId.trim();
22393
+ }
22394
+ }
22395
+ }
22396
+ return void 0;
22397
+ }
22398
+ async function navigatorHostRunResumable(home, runId) {
22399
+ const { piDurablePrincipalAuthority: piDurablePrincipalAuthority2 } = await Promise.resolve().then(() => (init_durable_principal(), durable_principal_exports));
22400
+ const { loadResumableInstructionSeatRun: loadResumableInstructionSeatRun2 } = await Promise.resolve().then(() => (init_run_lifecycle(), run_lifecycle_exports));
22401
+ try {
22402
+ const loaded = await loadResumableInstructionSeatRun2(home, runId, piDurablePrincipalAuthority2);
22403
+ return loaded.admitted.role === "navigator";
22404
+ } catch (error) {
22405
+ if (error instanceof CliUsageError) return false;
22406
+ throw error;
22407
+ }
22408
+ }
22409
+ function createNativeNavigatorSessionFactory(deps) {
21945
22410
  return async ({ context, subject, tool }) => {
21946
22411
  let thinkingLevel;
21947
22412
  const { createRecordSession: createRecordSession2, NAVIGATOR_RECORD_KIND: NAVIGATOR_RECORD_KIND2 } = await Promise.resolve().then(() => (init_archivist_record_entry(), archivist_record_entry_exports));
@@ -21957,6 +22422,11 @@ function createNativeNavigatorSessionFactory() {
21957
22422
  let noReceipt;
21958
22423
  let disposed = false;
21959
22424
  let inFlightPrompt;
22425
+ let hostRunId = readNavigatorHostRunPointer(sessionManager.getEntries());
22426
+ const summon = deps?.summonPublicRole ?? (async (options) => {
22427
+ const { summonPublicRole: summonPublicRole2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
22428
+ return summonPublicRole2(options);
22429
+ });
21960
22430
  return {
21961
22431
  prompt: async (text) => {
21962
22432
  if (disposed) {
@@ -21966,14 +22436,24 @@ function createNativeNavigatorSessionFactory() {
21966
22436
  noReceipt = void 0;
21967
22437
  const run = (async () => {
21968
22438
  try {
21969
- const { summonPublicRole: summonPublicRole2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
21970
22439
  const summonHome = await resolveNavigatorLedgerHome(context);
21971
- const summoned = await summonPublicRole2({
22440
+ const resumeRunId = hostRunId;
22441
+ const baseSummon = {
21972
22442
  role: "navigator",
21973
22443
  argv: [text],
21974
22444
  cwd: context.cwd,
21975
22445
  ...summonHome === void 0 ? {} : { home: summonHome }
21976
- });
22446
+ };
22447
+ const resumable = deps?.hostRunResumable ?? navigatorHostRunResumable;
22448
+ let summoned;
22449
+ if (resumeRunId === void 0 || summonHome === void 0) {
22450
+ summoned = await summon(baseSummon);
22451
+ } else if (await resumable(summonHome, resumeRunId)) {
22452
+ summoned = await summon({ ...baseSummon, resumeRunId });
22453
+ } else {
22454
+ hostRunId = void 0;
22455
+ summoned = await summon(baseSummon);
22456
+ }
21977
22457
  const outcome = summoned.terminal?.roleOutcome;
21978
22458
  if (outcome === void 0) {
21979
22459
  const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
@@ -21996,21 +22476,31 @@ function createNativeNavigatorSessionFactory() {
21996
22476
  noReceipt = outcome;
21997
22477
  return;
21998
22478
  }
22479
+ const runDirectory = summoned.runDirectory ?? (typeof summoned.admitted?.runDirectory === "string" ? summoned.admitted.runDirectory : void 0);
22480
+ if (typeof runDirectory === "string" && runDirectory.trim() !== "") {
22481
+ const nextRunId = runIdFromNavigatorDirectory(runDirectory);
22482
+ if (nextRunId !== void 0) {
22483
+ hostRunId = nextRunId;
22484
+ sessionManager.appendCustomEntry(NAVIGATOR_HOST_RUN_POINTER_ENTRY, { runId: nextRunId });
22485
+ }
22486
+ }
21999
22487
  if (outcome.kind !== "accepted") {
22000
22488
  return;
22001
22489
  }
22490
+ const { navigatorProseFromUnknown: navigatorProseFromUnknown2 } = await Promise.resolve().then(() => (init_navigator_output(), navigator_output_exports));
22491
+ const proseParts = [];
22002
22492
  for (const payload of outcome.payloads ?? []) {
22003
- if (typeof payload !== "object" || payload === null || Array.isArray(payload)) continue;
22004
- const candidates = payload.candidates;
22005
- if (!Array.isArray(candidates)) continue;
22006
- await tool.execute(
22007
- "navigator-public-prepare",
22008
- { candidates },
22009
- void 0,
22010
- void 0,
22011
- context
22012
- );
22493
+ const prose = navigatorProseFromUnknown2(payload);
22494
+ if (prose !== void 0) proseParts.push(prose);
22013
22495
  }
22496
+ if (proseParts.length === 0) return;
22497
+ await tool.execute(
22498
+ "navigator-public-prepare",
22499
+ { prose: proseParts.join("\n\n") },
22500
+ void 0,
22501
+ void 0,
22502
+ context
22503
+ );
22014
22504
  } catch (error) {
22015
22505
  if (error instanceof NavigatorUnavailableError) throw error;
22016
22506
  const fact = navigatorProviderFailureFromError(error);
@@ -22064,9 +22554,9 @@ function createNativeNavigatorSessionFactory() {
22064
22554
 
22065
22555
  // src/navigator-attendance.ts
22066
22556
  init_sitian_facade();
22067
- init_public_command_renderer();
22068
22557
  init_work_subject_identity();
22069
22558
  init_receipt_delivery_policy();
22559
+ init_navigator_output();
22070
22560
  var NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
22071
22561
  var NAVIGATOR_PREPARE_ACCEPTED_TEXT = "\u6E38\u5955\u4F7F\u51C6\u5907\u5DF2\u63A5\u53D7";
22072
22562
  function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
@@ -22076,107 +22566,40 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
22076
22566
  }
22077
22567
  var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
22078
22568
  var prepareSchema = Type13.Object({
22079
- candidates: Type13.Optional(Type13.Unknown({
22080
- description: "\u65B9\u5411\u5019\u9009\uFF1Bcandidates[].next.role \u5FC5\u586B\uFF0Cphase \u53EF\u9009\uFF0Croute/matches/reason/command \u53EF\u9009\u4E0A\u4E0B\u6587\uFF0C\u975E\u53D7\u7406\u95F8"
22569
+ prose: Type13.Optional(Type13.Unknown({
22570
+ description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002\u975E\u53D7\u7406\u95F8"
22081
22571
  }))
22082
22572
  }, { additionalProperties: true });
22083
- var ROUTE_ENTRY = "ak-navigator-route";
22084
22573
  var CONTEXT_ENTRY = "ak-navigator-context";
22085
22574
  var INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
22086
22575
  var SETTLEMENT_ENTRY = "ak-navigator-settlement";
22087
- var targetRoles = new Set(NAVIGATOR_TARGETS.map(({ role }) => role));
22088
- function exactRecord2(value) {
22576
+ function exactRecord3(value) {
22089
22577
  return typeof value === "object" && value !== null && !Array.isArray(value);
22090
22578
  }
22091
22579
  function rejectedPrepareReason(entries, start) {
22092
22580
  const recent = entries.slice(start);
22093
22581
  const prepareCalls = /* @__PURE__ */ new Set();
22094
22582
  for (const entry of recent) {
22095
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
22583
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
22096
22584
  for (const part of entry.message.content) {
22097
- if (exactRecord2(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
22585
+ if (exactRecord3(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
22098
22586
  }
22099
22587
  }
22100
22588
  let reason;
22101
22589
  for (const entry of recent) {
22102
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
22590
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
22103
22591
  const callId = entry.message.toolCallId;
22104
22592
  if (entry.message.toolName !== NAVIGATOR_PREPARE_TOOL_NAME || typeof callId !== "string" || !prepareCalls.has(callId)) {
22105
22593
  return void 0;
22106
22594
  }
22107
22595
  const content = entry.message.content;
22108
- const text = Array.isArray(content) ? content.flatMap((part) => exactRecord2(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
22596
+ const text = Array.isArray(content) ? content.flatMap((part) => exactRecord3(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
22109
22597
  if (text.trim() !== "") reason = text.trim();
22110
22598
  }
22111
22599
  return reason;
22112
22600
  }
22113
- function targetIsValid(value) {
22114
- if (!exactRecord2(value) || !targetRoles.has(String(value.role))) return false;
22115
- const metadata = packagedRoleMetadata(String(value.role));
22116
- return metadata !== void 0 && metadata.phases.includes(value.phase);
22117
- }
22118
- function normalizeTarget(value) {
22119
- if (!exactRecord2(value)) return void 0;
22120
- const role = typeof value.role === "string" ? value.role.trim() : "";
22121
- if (role === "") return void 0;
22122
- if (value.phase === void 0 || value.phase === null) {
22123
- return { role, phase: null };
22124
- }
22125
- if (value.phase === "plan" || value.phase === "apply") {
22126
- return { role, phase: value.phase };
22127
- }
22128
- return { role, phase: null };
22129
- }
22130
- function normalizeMatches(value) {
22131
- if (!exactRecord2(value)) return void 0;
22132
- if (typeof value.role !== "string" || value.role.trim() === "") return void 0;
22133
- if (value.kind !== "accepted") return void 0;
22134
- let phase;
22135
- if (value.phase === void 0 || value.phase === null) phase = null;
22136
- else if (value.phase === "plan" || value.phase === "apply") phase = value.phase;
22137
- else return void 0;
22138
- if (value.statuses !== void 0) {
22139
- if (!Array.isArray(value.statuses) || value.statuses.some((status) => typeof status !== "string" || status.trim() === "")) {
22140
- return void 0;
22141
- }
22142
- return {
22143
- role: value.role,
22144
- phase,
22145
- kind: "accepted",
22146
- statuses: [...value.statuses]
22147
- };
22148
- }
22149
- return { role: value.role, phase, kind: "accepted" };
22150
- }
22151
- function normalizeCandidate(value) {
22152
- if (!exactRecord2(value)) return void 0;
22153
- const next = normalizeTarget(value.next);
22154
- const route = Array.isArray(value.route) ? value.route.map(normalizeTarget).filter((target) => target !== void 0) : void 0;
22155
- const matches = normalizeMatches(value.matches);
22156
- const id = typeof value.id === "string" && value.id.trim() !== "" ? value.id : void 0;
22157
- const reason = typeof value.reason === "string" && value.reason.trim() !== "" ? value.reason : void 0;
22158
- const command = typeof value.command === "string" ? value.command : void 0;
22159
- return {
22160
- ...id === void 0 ? {} : { id },
22161
- ...matches === void 0 ? {} : { matches },
22162
- ...route === void 0 || route.length === 0 ? {} : { route },
22163
- ...next === void 0 ? {} : { next },
22164
- ...reason === void 0 ? {} : { reason },
22165
- ...command === void 0 ? {} : { command }
22166
- };
22167
- }
22168
- function normalizePrepareOutput(value) {
22169
- if (!exactRecord2(value) || !Array.isArray(value.candidates)) return [];
22170
- return value.candidates.map(normalizeCandidate).filter((candidate) => candidate !== void 0);
22171
- }
22172
- function routeEqual(a, b) {
22173
- return a !== void 0 && a.length === b.length && a.every((target, index) => target.role === b[index].role && target.phase === b[index].phase);
22174
- }
22175
- function routeText(route) {
22176
- return route.map((target) => target.phase === null ? target.role : `${target.role} ${target.phase}`).join(" \u2192 ");
22177
- }
22178
- function targetText(target) {
22179
- return target.phase === null ? target.role : `${target.role} ${target.phase}`;
22601
+ function normalizePrepareProse(value) {
22602
+ return navigatorProseFromUnknown(value);
22180
22603
  }
22181
22604
  function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
22182
22605
  if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
@@ -22198,7 +22621,7 @@ function createNavigatorPrepareTool(onOutput) {
22198
22621
  return {
22199
22622
  name: NAVIGATOR_PREPARE_TOOL_NAME,
22200
22623
  label: "\u6E38\u5955\u4F7F\u51C6\u5907",
22201
- description: "\u63D0\u4EA4\u6E38\u5955\u4F7F\u65B9\u5411\u5EFA\u8BAE\u3002",
22624
+ description: "\u63D0\u4EA4\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\u3002",
22202
22625
  parameters: prepareSchema,
22203
22626
  async execute(_id, value) {
22204
22627
  onOutput(value);
@@ -22206,34 +22629,6 @@ function createNavigatorPrepareTool(onOutput) {
22206
22629
  }
22207
22630
  };
22208
22631
  }
22209
- function selectNavigatorCandidate(candidates, settlement) {
22210
- if (settlement.kind !== "accepted") return void 0;
22211
- const usable = candidates.filter((candidate) => candidate.next !== void 0);
22212
- if (usable.length === 0) return void 0;
22213
- const rolePhaseMatched = usable.filter(
22214
- (candidate) => candidate.matches !== void 0 && candidate.matches.role === settlement.role && candidate.matches.phase === settlement.phase
22215
- );
22216
- if (rolePhaseMatched.length > 0) {
22217
- if (settlement.status !== void 0) {
22218
- const statusSpecific = rolePhaseMatched.find(
22219
- (candidate) => candidate.matches?.statuses !== void 0 && candidate.matches.statuses.includes(settlement.status)
22220
- );
22221
- if (statusSpecific !== void 0) {
22222
- return { candidate: statusSpecific, matchedToSettlement: true };
22223
- }
22224
- }
22225
- const rolePhaseGeneric = rolePhaseMatched.find(
22226
- (candidate) => candidate.matches?.statuses === void 0
22227
- );
22228
- if (rolePhaseGeneric !== void 0) {
22229
- return { candidate: rolePhaseGeneric, matchedToSettlement: true };
22230
- }
22231
- return void 0;
22232
- }
22233
- const unbound = usable.find((candidate) => candidate.matches === void 0);
22234
- if (unbound === void 0) return void 0;
22235
- return { candidate: unbound, matchedToSettlement: false };
22236
- }
22237
22632
  function formatNavigatorReport(report) {
22238
22633
  const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [`\u8DEF\u4E66\u8BFB\u53D6\u5931\u8D25\uFF1A${report.routePlaybookReadFailure}`];
22239
22634
  if (report.disposition === "no-advice") return playbookFailure.join("\n");
@@ -22243,31 +22638,24 @@ function formatNavigatorReport(report) {
22243
22638
  if (report.disposition === "arrival") {
22244
22639
  return [...playbookFailure, ...report.arrivalMessage ? [report.arrivalMessage] : []].join("\n");
22245
22640
  }
22246
- return [
22247
- ...playbookFailure,
22248
- ...report.route === void 0 ? [] : [`\u8DEF\u7EBF\uFF1A${routeText(report.route)}`],
22249
- ...report.next === void 0 ? [] : [`\u4E0B\u4E00\u6B65\uFF1A${targetText(report.next)}`],
22250
- ...report.reason === void 0 || report.reason.trim() === "" ? [] : [`\u7406\u7531\uFF1A${report.reason}`],
22251
- ...report.command === void 0 || report.command.trim() === "" ? [] : [`\u547D\u4EE4\uFF1A${report.command}`]
22252
- ].join("\n");
22641
+ return [...playbookFailure, ...report.prose ? [report.prose] : []].join("\n");
22253
22642
  }
22254
22643
  function createNavigatorAttendance(options) {
22255
22644
  let preparation;
22645
+ let preparationInFlight = false;
22256
22646
  let sessionReady;
22257
22647
  let session;
22258
22648
  let subjectKey = options.subjectKey;
22259
22649
  let subject = options.subject;
22260
22650
  let authority = options.authority;
22261
22651
  let contextError = options.contextError;
22262
- let candidates;
22652
+ let preparedProse;
22263
22653
  const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
22264
22654
  let activeInvocationId = invocationPrincipal;
22265
- let previousRoute;
22266
22655
  let outputSink;
22267
22656
  let settlementTail = Promise.resolve();
22268
22657
  let settlementFailure;
22269
22658
  let preparationFailure;
22270
- let preparationNoReceipt = false;
22271
22659
  let routePlaybookReadFailure;
22272
22660
  let disposed = false;
22273
22661
  let warmedHelp;
@@ -22294,12 +22682,7 @@ function createNavigatorAttendance(options) {
22294
22682
  };
22295
22683
  let routePlaybookSettlement;
22296
22684
  let prepareBoundSettlement;
22297
- const prepare = async () => {
22298
- const boundSettlement = prepareBoundSettlement;
22299
- prepareBoundSettlement = void 0;
22300
- preparationNoReceipt = false;
22301
- const invocationId = invocationPrincipal;
22302
- activeInvocationId = invocationId;
22685
+ const loadMaterialsAndSession = async (invocationId) => {
22303
22686
  if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
22304
22687
  if (typeof authority !== "string" || authority.trim() === "") {
22305
22688
  throw navigatorUnavailableError(
@@ -22357,21 +22740,6 @@ function createNavigatorAttendance(options) {
22357
22740
  const helpContext = help.map(({ role, help: text }) => `<role_help role="${role}">
22358
22741
  ${text}
22359
22742
  </role_help>`).join("\n");
22360
- let output;
22361
- let prepareBatchRejected = false;
22362
- outputSink = (value) => {
22363
- if (output === void 0) {
22364
- output = value;
22365
- return;
22366
- }
22367
- const prior2 = output.candidates;
22368
- const next = value.candidates;
22369
- const merged = [
22370
- ...Array.isArray(prior2) ? prior2 : prior2 === void 0 ? [] : [prior2],
22371
- ...Array.isArray(next) ? next : next === void 0 ? [] : [next]
22372
- ];
22373
- output = { ...value, candidates: merged };
22374
- };
22375
22743
  const tool = createNavigatorPrepareTool((value) => {
22376
22744
  outputSink?.(value);
22377
22745
  });
@@ -22379,7 +22747,12 @@ ${text}
22379
22747
  sessionReady = (async () => {
22380
22748
  let created;
22381
22749
  try {
22382
- created = await options.createSession({ context: options.context, subject: subjectKey, ...options.modelSettingPath === void 0 ? {} : { modelSettingPath: options.modelSettingPath }, tool });
22750
+ created = await options.createSession({
22751
+ context: options.context,
22752
+ subject: subjectKey,
22753
+ ...options.modelSettingPath === void 0 ? {} : { modelSettingPath: options.modelSettingPath },
22754
+ tool
22755
+ });
22383
22756
  } catch (error) {
22384
22757
  throw navigatorUnavailableError("session", error);
22385
22758
  }
@@ -22410,26 +22783,63 @@ ${text}
22410
22783
  session.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
22411
22784
  }
22412
22785
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
22413
- const activeSession = session;
22414
- if (activeSession === void 0) throw new Error("Navigator session was not created");
22415
- const prior = activeSession.entries().filter((entry) => exactRecord2(entry) && entry.type === "custom" && entry.customType === ROUTE_ENTRY && exactRecord2(entry.data) && entry.data.subjectKey === subjectKey).at(-1)?.data;
22416
- if (exactRecord2(prior) && Array.isArray(prior.route) && prior.route.every((target) => targetIsValid(target))) {
22417
- previousRoute = prior.route.map((target) => ({ role: target.role, phase: target.phase }));
22418
- }
22419
- const publicSettlementHistory = activeSession.entries().filter((entry) => exactRecord2(entry) && entry.type === "custom" && entry.customType === SETTLEMENT_ENTRY && exactRecord2(entry.data)).map((entry) => entry.data);
22786
+ if (session === void 0) throw new Error("Navigator session was not created");
22787
+ return { soul, routePlaybook, helpContext, modelSetting, model, help, activeSession: session };
22788
+ };
22789
+ const prepare = async (materialsBundle) => {
22790
+ const boundSettlement = prepareBoundSettlement;
22791
+ prepareBoundSettlement = void 0;
22792
+ const invocationId = invocationPrincipal;
22793
+ activeInvocationId = invocationId;
22794
+ let output;
22795
+ let prepareBatchRejected = false;
22796
+ outputSink = (value) => {
22797
+ if (output === void 0) {
22798
+ output = value;
22799
+ return;
22800
+ }
22801
+ const prior = normalizePrepareProse(output) ?? "";
22802
+ const next = normalizePrepareProse(value) ?? "";
22803
+ const merged = [prior, next].filter((part) => part.trim() !== "").join("\n\n");
22804
+ output = { prose: merged };
22805
+ };
22806
+ const { soul, routePlaybook, helpContext, help, activeSession } = materialsBundle ?? await loadMaterialsAndSession(invocationId);
22807
+ const publicSettlementHistory = activeSession.entries().filter((entry) => exactRecord3(entry) && entry.type === "custom" && entry.customType === SETTLEMENT_ENTRY && exactRecord3(entry.data)).map((entry) => entry.data);
22420
22808
  const projection = {
22421
22809
  subjectKey,
22422
22810
  subject,
22423
22811
  authority,
22424
22812
  currentRole: { role: options.role, phase: options.phase },
22425
22813
  ...boundSettlement === void 0 ? {} : { currentSettlement: boundSettlement },
22426
- priorRoute: exactRecord2(prior) && Array.isArray(prior.route) && prior.route.every((target) => targetIsValid(target)) ? prior.route.map((target) => ({ role: target.role, phase: target.phase })) : null,
22427
22814
  publicSettlementHistory,
22428
22815
  liveRoleHelp: help
22429
22816
  };
22430
22817
  activeSession.appendEntry(CONTEXT_ENTRY, projection);
22431
- const request = [
22432
- "\u672C\u6B21\u5BFC\u822A\u6750\u6599\u5982\u4E0B\uFF1A",
22818
+ const request = boundSettlement === void 0 ? [
22819
+ "\u672C\u8F6E\u4E3A\u5F85\u547D\u8F6E\u3002",
22820
+ `<navigator_soul>
22821
+ ${soul}
22822
+ </navigator_soul>`,
22823
+ ...routePlaybookReadFailure === void 0 ? [`<route_playbook>
22824
+ ${routePlaybook}
22825
+ </route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
22826
+ `<work_subject>
22827
+ ${subject}
22828
+ </work_subject>`,
22829
+ `<controlling_authority>
22830
+ ${authority}
22831
+ </controlling_authority>`,
22832
+ `<current_role>
22833
+ ${JSON.stringify({ role: options.role, phase: options.phase })}
22834
+ </current_role>`,
22835
+ `<public_settlement_history>
22836
+ ${JSON.stringify(projection.publicSettlementHistory)}
22837
+ </public_settlement_history>`,
22838
+ `<live_role_help>
22839
+ ${helpContext}
22840
+ </live_role_help>`
22841
+ ].join("\n\n") : [
22842
+ "\u672C\u8F6E\u4E3A\u7ED3\u7B97\u6295\u5582\u8F6E\u3002",
22433
22843
  `<navigator_soul>
22434
22844
  ${soul}
22435
22845
  </navigator_soul>`,
@@ -22445,12 +22855,9 @@ ${authority}
22445
22855
  `<current_role>
22446
22856
  ${JSON.stringify({ role: options.role, phase: options.phase })}
22447
22857
  </current_role>`,
22448
- ...boundSettlement === void 0 ? [] : [`<current_settlement>
22858
+ `<current_settlement>
22449
22859
  ${JSON.stringify(boundSettlement)}
22450
- </current_settlement>`],
22451
- `<prior_route>
22452
- ${JSON.stringify(prior ?? null)}
22453
- </prior_route>`,
22860
+ </current_settlement>`,
22454
22861
  `<public_settlement_history>
22455
22862
  ${JSON.stringify(projection.publicSettlementHistory)}
22456
22863
  </public_settlement_history>`,
@@ -22491,33 +22898,47 @@ ${helpContext}
22491
22898
  if (deliveryRequest && output === void 0) delivery.recordDeliveryRequest();
22492
22899
  };
22493
22900
  await promptAllowingRejectedPrepare(request, false);
22494
- while (output === void 0 && delivery.nextAction() === "request-delivery") {
22495
- await promptAllowingRejectedPrepare(RECEIPT_DELIVERY_PROMPT, true);
22496
- }
22497
- if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
22498
- const facts = delivery.facts({ runPointer: activeSession.recordPointer(), attemptPointer: invocationId });
22499
- activeSession.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
22500
- preparationNoReceipt = true;
22501
- candidates = [];
22502
- return candidates;
22901
+ if (boundSettlement !== void 0) {
22902
+ while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
22903
+ await promptAllowingRejectedPrepare(RECEIPT_DELIVERY_PROMPT, true);
22904
+ }
22905
+ if (output === void 0 && delivery.nextAction() === "request-delivery") {
22906
+ while (delivery.nextAction() === "request-delivery") {
22907
+ delivery.recordDeliveryRequest();
22908
+ }
22909
+ }
22910
+ if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
22911
+ const facts = delivery.facts({ runPointer: activeSession.recordPointer(), attemptPointer: invocationId });
22912
+ activeSession.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
22913
+ preparedProse = void 0;
22914
+ return void 0;
22915
+ }
22503
22916
  }
22504
22917
  } catch (error) {
22505
22918
  throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("transport", error);
22506
22919
  }
22507
22920
  if (output === void 0) {
22921
+ if (boundSettlement === void 0) {
22922
+ preparedProse = void 0;
22923
+ return void 0;
22924
+ }
22508
22925
  const nativeFailure = [...activeSession.entries()].reverse().find((entry) => {
22509
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message)) return false;
22926
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message)) return false;
22510
22927
  return entry.message.role === "assistant" && typeof entry.message.errorMessage === "string" && entry.message.errorMessage.trim() !== "";
22511
22928
  });
22512
- const nativeMessage = exactRecord2(nativeFailure) && exactRecord2(nativeFailure.message) ? nativeFailure.message : void 0;
22929
+ const nativeMessage = exactRecord3(nativeFailure) && exactRecord3(nativeFailure.message) ? nativeFailure.message : void 0;
22513
22930
  const errorMessage = nativeMessage !== void 0 && typeof nativeMessage.errorMessage === "string" ? nativeMessage.errorMessage : "Navigator did not submit direction advice";
22514
22931
  const providerFailure = activeSession.providerFailure?.();
22515
22932
  const source = providerFailure?.source ?? "unknown";
22516
22933
  const cause = providerFailure?.cause ?? source;
22517
22934
  throw navigatorUnavailableError(source, errorMessage, cause);
22518
22935
  }
22519
- candidates = normalizePrepareOutput(output);
22520
- return candidates;
22936
+ if (boundSettlement === void 0) {
22937
+ preparedProse = void 0;
22938
+ return void 0;
22939
+ }
22940
+ preparedProse = normalizePrepareProse(output);
22941
+ return preparedProse;
22521
22942
  } finally {
22522
22943
  outputSink = void 0;
22523
22944
  }
@@ -22528,7 +22949,6 @@ ${helpContext}
22528
22949
  if (next.subjectKey !== subjectKey && session !== void 0) {
22529
22950
  const previous = session;
22530
22951
  session = void 0;
22531
- previousRoute = void 0;
22532
22952
  closing = previous.dispose();
22533
22953
  }
22534
22954
  subjectKey = next.subjectKey;
@@ -22550,13 +22970,16 @@ ${helpContext}
22550
22970
  prepare() {
22551
22971
  if (disposed || preparation !== void 0) return;
22552
22972
  preparationFailure = void 0;
22553
- preparation = prepare();
22973
+ preparationInFlight = true;
22974
+ preparation = prepare().finally(() => {
22975
+ preparationInFlight = false;
22976
+ });
22554
22977
  void preparation.catch((error) => {
22555
22978
  preparationFailure = error;
22556
22979
  });
22557
22980
  },
22558
22981
  isPreparing() {
22559
- return preparation !== void 0 || sessionReady !== void 0;
22982
+ return preparationInFlight;
22560
22983
  },
22561
22984
  knownRoutePlaybookReadFailure() {
22562
22985
  return routePlaybookReadFailure;
@@ -22580,81 +23003,70 @@ ${helpContext}
22580
23003
  if (disposed) return;
22581
23004
  const invocationId = activeInvocationId ?? invocationPrincipal;
22582
23005
  let report;
22583
- if (settlement.kind === "human_decision" || settlement.kind === "role_infrastructure_failure") {
22584
- if (sessionReady !== void 0) {
22585
- try {
22586
- await sessionReady;
22587
- } catch (error) {
22588
- preparationFailure ??= error;
22589
- }
23006
+ if (sessionReady !== void 0) {
23007
+ try {
23008
+ await sessionReady;
23009
+ } catch (error) {
23010
+ preparationFailure ??= error;
22590
23011
  }
22591
- if (preparation !== void 0) {
22592
- try {
22593
- await preparation;
22594
- } catch (error) {
22595
- preparationFailure ??= error;
22596
- }
23012
+ }
23013
+ if (preparation !== void 0) {
23014
+ try {
23015
+ await preparation;
23016
+ } catch (error) {
23017
+ preparationFailure ??= error;
22597
23018
  }
22598
- session?.appendEntry(SETTLEMENT_ENTRY, { invocationId, subjectKey, role: settlement.role, phase: settlement.phase, kind: settlement.kind, ...settlement.kind === "human_decision" ? { status: settlement.status } : {} });
23019
+ preparation = void 0;
23020
+ }
23021
+ const settlementFact = {
23022
+ invocationId,
23023
+ subjectKey,
23024
+ role: settlement.role,
23025
+ phase: settlement.phase,
23026
+ kind: settlement.kind,
23027
+ ..."status" in settlement && settlement.status !== void 0 ? { status: settlement.status } : {}
23028
+ };
23029
+ let drainedProse;
23030
+ if (settlement.kind === "arrival") {
23031
+ session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
22599
23032
  if (preparationFailure !== void 0) {
22600
23033
  report = unavailable(invocationId, preparationFailure);
22601
23034
  } else {
22602
- report = { disposition: "no-advice" };
23035
+ report = {
23036
+ disposition: "arrival",
23037
+ ...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message }
23038
+ };
22603
23039
  }
22604
- } else if (settlement.kind === "arrival") {
22605
- if (sessionReady !== void 0) {
23040
+ } else {
23041
+ if (session !== void 0) preparationFailure = void 0;
23042
+ let coldMaterials;
23043
+ if (session === void 0 && preparationFailure === void 0) {
22606
23044
  try {
22607
- await sessionReady;
23045
+ coldMaterials = await loadMaterialsAndSession(invocationId);
22608
23046
  } catch (error) {
22609
- preparationFailure ??= error;
23047
+ preparationFailure = error;
22610
23048
  }
22611
23049
  }
22612
- if (preparation !== void 0) {
23050
+ session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
23051
+ if (preparationFailure === void 0) {
23052
+ prepareBoundSettlement = settlement;
23053
+ preparation = prepare(coldMaterials);
23054
+ void preparation.catch((error) => {
23055
+ preparationFailure = error;
23056
+ });
22613
23057
  try {
22614
- await preparation;
23058
+ drainedProse = await preparation;
22615
23059
  } catch (error) {
22616
23060
  preparationFailure ??= error;
22617
23061
  }
23062
+ preparation = void 0;
22618
23063
  }
22619
- report = preparationFailure === void 0 ? { disposition: "arrival", ...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message } } : unavailable(invocationId, preparationFailure);
22620
- } else if (preparation === void 0) {
22621
- report = unavailable(invocationId, "Navigator preparation did not start");
22622
- } else {
22623
- try {
22624
- if (sessionReady !== void 0) await sessionReady;
22625
- let prepared = await preparation;
22626
- session?.appendEntry(SETTLEMENT_ENTRY, { invocationId, subjectKey, role: settlement.role, phase: settlement.phase, kind: settlement.kind, ...settlement.status === void 0 ? {} : { status: settlement.status } });
22627
- let selected = selectNavigatorCandidate(prepared, settlement);
22628
- if (selected?.candidate.next !== void 0 && !selected.matchedToSettlement) {
22629
- if (disposed) return;
22630
- prepareBoundSettlement = settlement;
22631
- prepared = await prepare();
22632
- if (disposed) return;
22633
- selected = selectNavigatorCandidate(prepared, settlement);
22634
- }
22635
- const selectedCandidate = selected?.candidate;
22636
- if (selectedCandidate?.next === void 0 && preparationNoReceipt) {
22637
- report = { disposition: "no-advice" };
22638
- } else if (selectedCandidate?.next === void 0) {
22639
- throw new Error("Navigator prepared no machine-usable next direction");
22640
- } else {
22641
- const selectedRoute = selectedCandidate.route;
22642
- const routeChanged = selectedRoute !== void 0 && !routeEqual(previousRoute, selectedRoute);
22643
- const command = typeof selectedCandidate.command === "string" && selectedCandidate.command.trim() !== "" ? selectedCandidate.command : renderPublicAkRoleCommand(selectedCandidate.next);
22644
- report = {
22645
- disposition: "recommendation",
22646
- ...routeChanged ? { route: selectedRoute } : {},
22647
- next: selectedCandidate.next,
22648
- ...selectedCandidate.reason === void 0 ? {} : { reason: selectedCandidate.reason },
22649
- ...command === void 0 ? {} : { command }
22650
- };
22651
- if (selectedRoute !== void 0) {
22652
- previousRoute = selectedRoute;
22653
- session?.appendEntry(ROUTE_ENTRY, { invocationId, subjectKey, route: selectedRoute });
22654
- }
22655
- }
22656
- } catch (error) {
22657
- report = unavailable(invocationId, error);
23064
+ if (preparationFailure !== void 0) {
23065
+ report = unavailable(invocationId, preparationFailure);
23066
+ } else if (typeof drainedProse === "string" && drainedProse.trim() !== "") {
23067
+ report = { disposition: "advice", prose: drainedProse };
23068
+ } else {
23069
+ report = { disposition: "no-advice" };
22658
23070
  }
22659
23071
  }
22660
23072
  await routePlaybookSettlement;
@@ -22668,10 +23080,7 @@ ${helpContext}
22668
23080
  role: options.role,
22669
23081
  phase: options.phase,
22670
23082
  subjectKey,
22671
- ...report.route === void 0 ? {} : { route: report.route },
22672
- ...report.next === void 0 ? {} : { next: report.next },
22673
- ...report.reason === void 0 ? {} : { reason: report.reason },
22674
- ...report.command === void 0 ? {} : { command: report.command },
23083
+ ...report.prose === void 0 ? {} : { prose: report.prose },
22675
23084
  ...report.unavailableReason === void 0 ? {} : { unavailableReason: report.unavailableReason },
22676
23085
  ...report.unavailableSource === void 0 ? {} : { unavailableSource: report.unavailableSource },
22677
23086
  ...report.unavailableCause === void 0 ? {} : { unavailableCause: report.unavailableCause },
@@ -22687,9 +23096,8 @@ ${helpContext}
22687
23096
  }
22688
23097
  preparation = void 0;
22689
23098
  sessionReady = void 0;
22690
- candidates = void 0;
23099
+ preparedProse = void 0;
22691
23100
  preparationFailure = void 0;
22692
- preparationNoReceipt = false;
22693
23101
  routePlaybookSettlement = void 0;
22694
23102
  routePlaybookReadFailure = void 0;
22695
23103
  }
@@ -22826,7 +23234,8 @@ init_host_contracts();
22826
23234
  init_sitian_facade();
22827
23235
  init_submission_ledger();
22828
23236
  init_collector_ledger();
22829
- import { readFileSync as readFileSync6, writeSync as writeSync4 } from "node:fs";
23237
+ import { randomUUID as randomUUID8 } from "node:crypto";
23238
+ import { readFileSync as readFileSync6, writeSync as writeSync3 } from "node:fs";
22830
23239
  import { join as join39 } from "node:path";
22831
23240
  import { Value as Value4 } from "typebox/value";
22832
23241
 
@@ -22868,16 +23277,7 @@ function namedActivationCause(error) {
22868
23277
  init_activation_ledger_topology();
22869
23278
 
22870
23279
  // src/activation-ledger.ts
22871
- init_activation_ledger_topology();
22872
23280
  init_activation_ledger_git();
22873
- import {
22874
- constants as constants2,
22875
- closeSync as closeSync2,
22876
- fstatSync,
22877
- openSync as openSync2,
22878
- writeSync
22879
- } from "node:fs";
22880
- import { dirname as dirname21, isAbsolute as isAbsolute10, resolve as resolve19 } from "node:path";
22881
23281
 
22882
23282
  // src/activation-ledger-session.ts
22883
23283
  init_activation_ledger_topology();
@@ -22981,129 +23381,11 @@ function durableSessionPointer(sessionManager) {
22981
23381
 
22982
23382
  // src/activation-ledger.ts
22983
23383
  init_activation_ledger_topology();
22984
- var ACTIVATION_LEDGER_APPEND_OPEN_FLAGS = constants2.O_APPEND | constants2.O_CREAT | constants2.O_WRONLY | constants2.O_NOFOLLOW;
22985
- var ACCEPTED_ACTIVATION_EVENT = "accepted-activation";
22986
- var ACCEPTED_ACTIVATION_FACT_KEYS = Object.freeze([
22987
- "event",
22988
- "role",
22989
- "observedAt",
22990
- "bookKey",
22991
- "session",
22992
- "correlation"
22993
- ]);
22994
- function correlationIdentityFromEnv(env = process.env) {
22995
- const raw = env.AK_CORRELATION_ID;
22996
- if (typeof raw === "string" && raw.trim().length > 0) {
22997
- return { kind: "caller", id: raw };
22998
- }
22999
- return { kind: "absent" };
23000
- }
23001
- function projectAcceptedActivationFact(input) {
23002
- const closed = {
23003
- event: ACCEPTED_ACTIVATION_EVENT,
23004
- role: input.role,
23005
- observedAt: input.observedAt,
23006
- bookKey: input.bookKey,
23007
- session: { kind: "session-file", path: input.session.path },
23008
- correlation: input.correlation.kind === "caller" ? { kind: "caller", id: input.correlation.id } : { kind: "absent" }
23009
- };
23010
- return Object.fromEntries(
23011
- ACCEPTED_ACTIVATION_FACT_KEYS.map((key) => [key, closed[key]])
23012
- );
23013
- }
23014
- function buildAcceptedActivationFact(input) {
23015
- return projectAcceptedActivationFact(input);
23016
- }
23017
- function serializeAcceptedActivationFact(fact) {
23018
- return `${JSON.stringify(projectAcceptedActivationFact(fact))}
23019
- `;
23020
- }
23021
- function appendActivationLedgerLine(ledgerPath, line2, options) {
23022
- if (!isAbsolute10(options.ledgerHome)) {
23023
- throw new ActivationLedgerError(
23024
- `activation ledger home must be absolute: ${options.ledgerHome}`
23025
- );
23026
- }
23027
- const resolvedLedger = resolve19(ledgerPath);
23028
- const resolvedHome = resolve19(options.ledgerHome);
23029
- const parent = dirname21(resolvedLedger);
23030
- ensureRealDirectoryTree(resolvedHome, parent);
23031
- assertLedgerFileInsideHome(resolvedLedger, resolvedHome);
23032
- if (typeof constants2.O_NOFOLLOW !== "number") {
23033
- throw new ActivationLedgerError(
23034
- "activation ledger append requires O_NOFOLLOW open-flag support (anti-symlink TOCTOU protection must not be silently dropped); refusing to append"
23035
- );
23036
- }
23037
- const bytes = Buffer.isBuffer(line2) ? line2 : Buffer.from(line2);
23038
- let ledgerFd;
23039
- let primaryFailure;
23040
- try {
23041
- try {
23042
- ledgerFd = openSync2(resolvedLedger, ACTIVATION_LEDGER_APPEND_OPEN_FLAGS, 420);
23043
- } catch (error) {
23044
- throw new ActivationLedgerError(
23045
- `activation ledger failed to open ledger file (${resolvedLedger}): ${errorText(error)}`,
23046
- { cause: error }
23047
- );
23048
- }
23049
- let opened;
23050
- try {
23051
- opened = fstatSync(ledgerFd);
23052
- } catch (error) {
23053
- throw new ActivationLedgerError(
23054
- `activation ledger failed to fstat ledger file (${resolvedLedger}): ${errorText(error)}`,
23055
- { cause: error }
23056
- );
23057
- }
23058
- if (!opened.isFile()) {
23059
- throw new ActivationLedgerError(
23060
- `activation ledger is not a regular file: ${resolvedLedger}`
23061
- );
23062
- }
23063
- const written = writeSync(ledgerFd, bytes, 0, bytes.length, null);
23064
- if (written !== bytes.length) {
23065
- throw new ActivationLedgerError(
23066
- `activation ledger short write: wrote ${written} of ${bytes.length} bytes to ${resolvedLedger}`
23067
- );
23068
- }
23069
- } catch (error) {
23070
- primaryFailure = error;
23071
- }
23072
- if (ledgerFd !== void 0) {
23073
- try {
23074
- closeSync2(ledgerFd);
23075
- } catch (closeFailure) {
23076
- if (primaryFailure !== void 0) {
23077
- throw new AggregateError(
23078
- [primaryFailure, closeFailure],
23079
- "activation ledger operation and close failed",
23080
- { cause: primaryFailure }
23081
- );
23082
- }
23083
- throw closeFailure;
23084
- }
23085
- }
23086
- if (primaryFailure !== void 0) throw primaryFailure;
23087
- }
23088
- function appendAcceptedActivationFact(ledgerPath, fact, options) {
23089
- appendActivationLedgerLine(
23090
- ledgerPath,
23091
- Buffer.from(serializeAcceptedActivationFact(fact), "utf8"),
23092
- { ledgerHome: options.ledgerHome }
23093
- );
23094
- }
23095
- function appendAcceptedActivationToBook(options) {
23096
- appendAcceptedActivationFact(
23097
- activationWaitingLedgerPath(options.ledgerHome, options.fact.bookKey),
23098
- options.fact,
23099
- { ledgerHome: options.ledgerHome }
23100
- );
23101
- }
23102
23384
 
23103
23385
  // src/stderr-jsonl.ts
23104
- import { writeSync as writeSync2 } from "node:fs";
23386
+ import { writeSync } from "node:fs";
23105
23387
  var STDERR_JSONL_WRITE_RETRY_LIMIT = 100;
23106
- function writeStderrJsonlRecord(record4, write = writeSync2) {
23388
+ function writeStderrJsonlRecord(record4, write = writeSync) {
23107
23389
  const bytes = Buffer.from(`${JSON.stringify(record4)}
23108
23390
  `);
23109
23391
  let offset = 0;
@@ -23123,7 +23405,7 @@ function writeStderrJsonlRecord(record4, write = writeSync2) {
23123
23405
  }
23124
23406
 
23125
23407
  // src/tool-execution-observation.ts
23126
- import { writeSync as writeSync3 } from "node:fs";
23408
+ import { writeSync as writeSync2 } from "node:fs";
23127
23409
  import { Type as Type15 } from "typebox";
23128
23410
  import { Value as Value3 } from "typebox/value";
23129
23411
  var TOOL_EXECUTION_UPDATE_THROTTLE_MS = 3e4;
@@ -23154,7 +23436,7 @@ function validateToolExecutionObservationRecord(record4) {
23154
23436
  }
23155
23437
  return record4;
23156
23438
  }
23157
- function writeToolExecutionObservationRecord(record4, write = writeSync3) {
23439
+ function writeToolExecutionObservationRecord(record4, write = writeSync2) {
23158
23440
  writeStderrJsonlRecord(validateToolExecutionObservationRecord(record4), write);
23159
23441
  }
23160
23442
  function isProducingToolUpdate(partialResult) {
@@ -23391,9 +23673,9 @@ import { join as join38, sep as sep6 } from "node:path";
23391
23673
  // src/atomic-write.ts
23392
23674
  import { randomUUID as randomUUID7 } from "node:crypto";
23393
23675
  import { rename as rename3, rm as rm5, writeFile as writeFile11 } from "node:fs/promises";
23394
- import { dirname as dirname22, join as join37 } from "node:path";
23676
+ import { dirname as dirname21, join as join37 } from "node:path";
23395
23677
  async function writeFileAtomically(destination, contents) {
23396
- const parent = dirname22(destination);
23678
+ const parent = dirname21(destination);
23397
23679
  const temporary = join37(parent, `.atomic-write-${randomUUID7()}.tmp`);
23398
23680
  try {
23399
23681
  await writeFile11(temporary, contents);
@@ -24672,7 +24954,7 @@ init_navigator_output();
24672
24954
  var NAVIGATOR_TOOL_SPEC = {
24673
24955
  name: NAVIGATOR_OUTPUT_TOOL_NAME,
24674
24956
  label: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
24675
- description: "\u6E38\u5955\u4F7F\u7EC8\u5C40\u56DE\u6267\uFF1A\u6392\u597D\u5E8F\u7684\u4E0B\u4E00\u6B65\u89D2\u8272\u8DEF\u7EBF\u5EFA\u8BAE\u3002",
24957
+ description: "\u6E38\u5955\u4F7F\u7EC8\u5C40\u56DE\u6267\uFF1A\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002",
24676
24958
  promptSnippet: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
24677
24959
  parameters: navigatorOutputSchema
24678
24960
  };
@@ -24899,7 +25181,7 @@ init_submission_errors();
24899
25181
  init_submission_errors();
24900
25182
  import { execFileSync as execFileSync4 } from "node:child_process";
24901
25183
  import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
24902
- import { resolve as resolve20 } from "node:path";
25184
+ import { resolve as resolve19 } from "node:path";
24903
25185
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
24904
25186
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
24905
25187
  var WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE = "commit-reminder-bounce";
@@ -24948,7 +25230,7 @@ function escapeGitConfigValueRegex(value) {
24948
25230
  function unsetOwnedHooksPath(file) {
24949
25231
  const owned = [];
24950
25232
  for (const value of tryGetAll(file, "core.hooksPath")) {
24951
- if (!ownedHook(resolve20(value, HOOK_FILE))) continue;
25233
+ if (!ownedHook(resolve19(value, HOOK_FILE))) continue;
24952
25234
  try {
24953
25235
  gitFile(file, [
24954
25236
  "--unset-all",
@@ -24963,15 +25245,15 @@ function unsetOwnedHooksPath(file) {
24963
25245
  return owned;
24964
25246
  }
24965
25247
  function rmOwnedDir(dir) {
24966
- const hookPath = resolve20(dir, HOOK_FILE);
25248
+ const hookPath = resolve19(dir, HOOK_FILE);
24967
25249
  if (!ownedHook(hookPath)) return;
24968
25250
  rmSync(hookPath, { force: true });
24969
25251
  if (existsSync12(dir) && readdirSync3(dir).length === 0) rmdirSync(dir);
24970
25252
  }
24971
25253
  function linkedGitDirs(commonDir) {
24972
- const root = resolve20(commonDir, "worktrees");
25254
+ const root = resolve19(commonDir, "worktrees");
24973
25255
  if (!existsSync12(root)) return [];
24974
- return readdirSync3(root).map((name) => resolve20(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
25256
+ return readdirSync3(root).map((name) => resolve19(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
24975
25257
  }
24976
25258
  function uninstallPackageWorkerHooks(cwd) {
24977
25259
  let inside;
@@ -24985,14 +25267,14 @@ function uninstallPackageWorkerHooks(cwd) {
24985
25267
  const clear = (configFile) => {
24986
25268
  for (const hooks of unsetOwnedHooksPath(configFile)) rmOwnedDir(hooks);
24987
25269
  };
24988
- clear(resolve20(commonDir, "config"));
24989
- clear(resolve20(commonDir, "config.worktree"));
24990
- rmOwnedDir(resolve20(commonDir, HOOKS_DIR));
24991
- const legacy = resolve20(commonDir, "hooks", HOOK_FILE);
25270
+ clear(resolve19(commonDir, "config"));
25271
+ clear(resolve19(commonDir, "config.worktree"));
25272
+ rmOwnedDir(resolve19(commonDir, HOOKS_DIR));
25273
+ const legacy = resolve19(commonDir, "hooks", HOOK_FILE);
24992
25274
  if (ownedHook(legacy)) rmSync(legacy, { force: true });
24993
25275
  for (const gitDir of linkedGitDirs(commonDir)) {
24994
- clear(resolve20(gitDir, "config.worktree"));
24995
- rmOwnedDir(resolve20(gitDir, HOOKS_DIR));
25276
+ clear(resolve19(gitDir, "config.worktree"));
25277
+ rmOwnedDir(resolve19(gitDir, HOOKS_DIR));
24996
25278
  }
24997
25279
  }
24998
25280
  function isRecord13(value) {
@@ -25745,7 +26027,7 @@ async function executeActivationStage(role, stage, infrastructure) {
25745
26027
  throw activationError;
25746
26028
  }
25747
26029
  }
25748
- function writeActivationTraceRecord(record4, write = writeSync4) {
26030
+ function writeActivationTraceRecord(record4, write = writeSync3) {
25749
26031
  writeStderrJsonlRecord(record4, write);
25750
26032
  }
25751
26033
  var ActivationBarrierError = class extends Error {
@@ -26171,6 +26453,21 @@ function createCountersignRoleRuntime(roleHost, dependencies, hostActions) {
26171
26453
  dependencies
26172
26454
  );
26173
26455
  }
26456
+ function lastAssistantProse(messages) {
26457
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
26458
+ const message = messages[index];
26459
+ if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
26460
+ const texts = [];
26461
+ for (const part of message.content) {
26462
+ if (part.type === "text" && typeof part.text === "string" && part.text.length > 0) {
26463
+ texts.push(part.text);
26464
+ }
26465
+ }
26466
+ if (texts.length === 0) continue;
26467
+ return texts.join("");
26468
+ }
26469
+ return void 0;
26470
+ }
26174
26471
  function createRoleRuntimeExtension(dependencies) {
26175
26472
  return (envelopeHost) => {
26176
26473
  let projectClosedSubmission = async () => {
@@ -26229,10 +26526,6 @@ function createRoleRuntimeExtension(dependencies) {
26229
26526
  if (settlement === void 0 || attendance === void 0) return;
26230
26527
  const workContext = navigatorWorkContext;
26231
26528
  const pending = (async () => {
26232
- if (settlement.kind !== "accepted") {
26233
- await attendance.settle(settlement);
26234
- return;
26235
- }
26236
26529
  const settlePromise = attendance.settle(settlement);
26237
26530
  void settlePromise.catch(() => void 0);
26238
26531
  const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
@@ -26433,10 +26726,8 @@ function createRoleRuntimeExtension(dependencies) {
26433
26726
  pendingSubmissionNonPassByToolCallId.delete(event.toolCallId);
26434
26727
  return { details: submissionNonPass, isError: true };
26435
26728
  }
26436
- if (event.isError) return;
26437
- return;
26438
26729
  });
26439
- roleHost.on("agent_end", (event, ctx) => {
26730
+ roleHost.on("agent_end", async (event, ctx) => {
26440
26731
  const lastMessage = event.messages.at(-1);
26441
26732
  if (lastMessage?.role === "assistant" && (lastMessage.stopReason === "error" || lastMessage.stopReason === "aborted")) {
26442
26733
  if (receiptDelivery.nextAction() !== "accepted") {
@@ -26444,6 +26735,47 @@ function createRoleRuntimeExtension(dependencies) {
26444
26735
  }
26445
26736
  return;
26446
26737
  }
26738
+ const role = selectedRole ?? roleHost.getFlag(ROLE_FLAG.name);
26739
+ if (role === "navigator" && receiptDelivery.nextAction() !== "accepted") {
26740
+ const prose = lastAssistantProse(event.messages);
26741
+ if (prose !== void 0 && prose.trim() !== "") {
26742
+ const accepted = { prose };
26743
+ await sealAcceptedSubmission({
26744
+ context: ctx,
26745
+ role: "navigator",
26746
+ accepted,
26747
+ toolCallId: `navigator-prose-exit:${randomUUID8()}`
26748
+ });
26749
+ await projectClosedSubmission(
26750
+ { role: "navigator", kind: "accepted", accepted },
26751
+ ctx
26752
+ );
26753
+ return;
26754
+ }
26755
+ if (!noReceiptRecorded) {
26756
+ const runPointer = runDirectoryFromHostContext(ctx);
26757
+ if (runPointer !== void 0) {
26758
+ noReceiptRecorded = true;
26759
+ while (receiptDelivery.nextAction() === "request-delivery") {
26760
+ receiptDelivery.recordDeliveryRequest();
26761
+ }
26762
+ const facts = receiptDelivery.facts({ runPointer, attemptPointer: `current:${runPointer}` });
26763
+ envelopeHost.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
26764
+ try {
26765
+ sitianReport({
26766
+ level: "event",
26767
+ kind: "no-receipt-lifecycle",
26768
+ cwd: ctx.cwd,
26769
+ sessionParent: ctx.sessionManager.getSessionFile(),
26770
+ payload: facts,
26771
+ source: "role-runtime"
26772
+ });
26773
+ } catch {
26774
+ }
26775
+ }
26776
+ }
26777
+ return;
26778
+ }
26447
26779
  if (receiptDelivery.nextAction() === "request-delivery") {
26448
26780
  receiptDelivery.recordDeliveryRequest();
26449
26781
  envelopeHost.appendEntry("ak-receipt-delivery-request");
@@ -26927,11 +27259,8 @@ function createRoleRuntimeExtension(dependencies) {
26927
27259
  }
26928
27260
  };
26929
27261
  try {
26930
- const bookKey = resolveBookKeyFromGit(ctx.cwd);
26931
- const correlation = correlationIdentityFromEnv();
26932
- const sessionFile = ctx.sessionManager.getSessionFile?.() || ctx.sessionManager.getSessionDir?.();
26933
- const ledgerHome = resolveActivationLedgerHomeForPath(sessionFile);
26934
- const session = durableSessionPointer(ctx.sessionManager);
27262
+ resolveBookKeyFromGit(ctx.cwd);
27263
+ durableSessionPointer(ctx.sessionManager);
26935
27264
  const isStationChild = roleHost.getFlag(STATION_CHILD_FLAG.name) === true;
26936
27265
  if (dependencies.createNavigatorAttendance !== void 0 && entry.role !== "navigator" && !isStationChild) {
26937
27266
  navigatorSessionParent = ctx.sessionManager.getSessionFile();
@@ -27018,16 +27347,6 @@ function createRoleRuntimeExtension(dependencies) {
27018
27347
  if (entry.role === "coder") coder.armSubmissionGate(ctx.cwd, ctx.sessionManager);
27019
27348
  else fixer.armSubmissionGate(ctx.cwd, ctx.sessionManager);
27020
27349
  }
27021
- appendAcceptedActivationToBook({
27022
- ledgerHome,
27023
- fact: buildAcceptedActivationFact({
27024
- role: entry.role,
27025
- observedAt: clock(),
27026
- bookKey,
27027
- session,
27028
- correlation
27029
- })
27030
- });
27031
27350
  admitted = true;
27032
27351
  } catch (error) {
27033
27352
  failInfrastructure(error, ctx);
@@ -27109,10 +27428,10 @@ function createRoleRuntimeDependencies(packageRoot) {
27109
27428
 
27110
27429
  // src/role-envelope.ts
27111
27430
  init_engine_detour();
27112
- import { randomUUID as randomUUID8 } from "node:crypto";
27113
- import { mkdir as mkdir7, writeFile as writeFile12 } from "node:fs/promises";
27431
+ import { randomUUID as randomUUID9 } from "node:crypto";
27432
+ import { appendFile as appendFile3, mkdir as mkdir7, writeFile as writeFile12 } from "node:fs/promises";
27114
27433
  import { createServer } from "node:net";
27115
- import { dirname as dirname24, join as join42 } from "node:path";
27434
+ import { dirname as dirname23, join as join42 } from "node:path";
27116
27435
  import { fileURLToPath as fileURLToPath2 } from "node:url";
27117
27436
 
27118
27437
  // src/gatekeeper-pass-envelope.ts
@@ -27199,14 +27518,14 @@ async function requireGatekeeperPass(options) {
27199
27518
 
27200
27519
  // src/host-native-method.ts
27201
27520
  import { lstat as lstat7, mkdir as mkdir6, readlink, realpath as realpath8, symlink } from "node:fs/promises";
27202
- import { basename as basename9, dirname as dirname23, join as join41 } from "node:path";
27521
+ import { basename as basename10, dirname as dirname22, join as join41 } from "node:path";
27203
27522
  var HOST_METHOD_PLUGIN_NAME = "ak-methods";
27204
27523
  var packagedMethodsDir = (root) => join41(root, "resources", "methods");
27205
27524
  var packagedMethodPluginDir = (root) => join41(root, "dist", "method-host-plugin");
27206
27525
  function hostMethodSkills(methods) {
27207
27526
  return Object.freeze(methods.flatMap((method) => {
27208
27527
  if (method.kind !== "skill") return [];
27209
- const name = basename9(dirname23(method.path));
27528
+ const name = basename10(dirname22(method.path));
27210
27529
  return name ? [Object.freeze({ name })] : [];
27211
27530
  }));
27212
27531
  }
@@ -27243,7 +27562,7 @@ async function installWorkspaceMethodSkills(cwd, packageRoot) {
27243
27562
  } catch (error) {
27244
27563
  if (error.code !== "ENOENT") throw error;
27245
27564
  }
27246
- await mkdir6(dirname23(link), { recursive: true });
27565
+ await mkdir6(dirname22(link), { recursive: true });
27247
27566
  try {
27248
27567
  await symlink(target, link);
27249
27568
  } catch (error) {
@@ -27260,11 +27579,11 @@ init_role_activation_flags();
27260
27579
  init_submission_correctable_error();
27261
27580
  init_navigator_invocation_identity();
27262
27581
  async function listen(server, path) {
27263
- await new Promise((resolve22, reject) => {
27582
+ await new Promise((resolve21, reject) => {
27264
27583
  server.once("error", reject);
27265
27584
  server.listen(path, () => {
27266
27585
  server.off("error", reject);
27267
- resolve22();
27586
+ resolve21();
27268
27587
  });
27269
27588
  });
27270
27589
  }
@@ -27297,10 +27616,10 @@ async function prepareRoleEnvelope(options) {
27297
27616
  let rejection;
27298
27617
  let infrastructureRoundFailure;
27299
27618
  const hostAbort = new AbortController();
27300
- const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID8();
27619
+ const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID9();
27301
27620
  await mkdir7(request.runDirectory, { recursive: true });
27302
27621
  let sessionFile = options.sessionFile ?? join42(request.runDirectory, "session", "session.jsonl");
27303
- await mkdir7(dirname24(sessionFile), { recursive: true });
27622
+ await mkdir7(dirname23(sessionFile), { recursive: true });
27304
27623
  if (request.continuation.kind !== "resume") {
27305
27624
  try {
27306
27625
  await writeFile12(
@@ -27319,6 +27638,25 @@ async function prepareRoleEnvelope(options) {
27319
27638
  if (error.code !== "EEXIST") throw error;
27320
27639
  }
27321
27640
  }
27641
+ let durableWriteChain = Promise.resolve();
27642
+ let armDurableWriteFailure;
27643
+ const persistPackageSessionEntry = (entry) => {
27644
+ const customType = typeof entry.customType === "string" ? entry.customType : "unknown";
27645
+ const line2 = `${JSON.stringify({
27646
+ ...entry,
27647
+ id: typeof entry.id === "string" ? entry.id : randomUUID9(),
27648
+ timestamp: typeof entry.timestamp === "string" ? entry.timestamp : (/* @__PURE__ */ new Date()).toISOString()
27649
+ })}
27650
+ `;
27651
+ durableWriteChain = durableWriteChain.then(async () => {
27652
+ try {
27653
+ await appendFile3(sessionFile, line2, "utf8");
27654
+ } catch (error) {
27655
+ const diagnostic = error instanceof Error ? error.message : String(error);
27656
+ armDurableWriteFailure?.(customType, diagnostic);
27657
+ }
27658
+ });
27659
+ };
27322
27660
  const context = {
27323
27661
  cwd: request.cwd,
27324
27662
  mode: "print",
@@ -27331,7 +27669,7 @@ async function prepareRoleEnvelope(options) {
27331
27669
  getLeafEntry: () => sessionEntries.at(-1),
27332
27670
  getLeafId: () => runId,
27333
27671
  getEntries: () => sessionEntries,
27334
- getSessionDir: () => dirname24(sessionFile),
27672
+ getSessionDir: () => dirname23(sessionFile),
27335
27673
  getSessionFile: () => sessionFile,
27336
27674
  getHeader: () => ({ type: "session", id: runId }),
27337
27675
  setSessionFile(path) {
@@ -27341,6 +27679,7 @@ async function prepareRoleEnvelope(options) {
27341
27679
  const entry = { type: "custom", customType, data };
27342
27680
  sessionEntries.push(entry);
27343
27681
  customEntries.push({ customType, data });
27682
+ persistPackageSessionEntry(entry);
27344
27683
  }
27345
27684
  },
27346
27685
  abort() {
@@ -27354,6 +27693,7 @@ async function prepareRoleEnvelope(options) {
27354
27693
  const entry = { type: "custom_message", customType, ...payload, message: payload };
27355
27694
  sessionEntries.push(entry);
27356
27695
  customEntries.push({ customType, data: message.details ?? message.content });
27696
+ persistPackageSessionEntry(entry);
27357
27697
  };
27358
27698
  const emit = async (event, value) => {
27359
27699
  const results = [];
@@ -27433,7 +27773,7 @@ async function prepareRoleEnvelope(options) {
27433
27773
  }
27434
27774
  };
27435
27775
  createRoleRuntimeExtension(options.dependencies)(envelope);
27436
- const token = randomUUID8();
27776
+ const token = randomUUID9();
27437
27777
  const server = createServer((socket) => serveSocket(socket));
27438
27778
  function rememberProjectedRejection(details, toolCallId, content) {
27439
27779
  if (typeof details !== "object" || details === null) return;
@@ -27469,6 +27809,17 @@ async function prepareRoleEnvelope(options) {
27469
27809
  };
27470
27810
  hostAbort.abort();
27471
27811
  }
27812
+ armDurableWriteFailure = (customType, diagnostic) => {
27813
+ rememberInfrastructureFailure(
27814
+ {
27815
+ cause: "infrastructure",
27816
+ kind: "role_infrastructure_failure",
27817
+ code: "durable-session-write-failed",
27818
+ customType
27819
+ },
27820
+ [{ type: "text", text: `ak-role: durable session entry flush failed (${customType}): ${diagnostic}` }]
27821
+ );
27822
+ };
27472
27823
  function declareRoundInfrastructureFailure(error) {
27473
27824
  const diagnostic = error instanceof Error ? error.message : String(error);
27474
27825
  const content = [{ type: "text", text: diagnostic }];
@@ -27514,7 +27865,7 @@ async function prepareRoleEnvelope(options) {
27514
27865
  async function invokeAkTool(name, args) {
27515
27866
  const tool = tools.get(name);
27516
27867
  if (tool === void 0) throw new Error(`Unknown AK tool: ${name}`);
27517
- const toolCallId = randomUUID8();
27868
+ const toolCallId = randomUUID9();
27518
27869
  calls.push({ toolCallId, toolName: name });
27519
27870
  sessionEntries.push({
27520
27871
  type: "message",
@@ -27630,6 +27981,15 @@ async function prepareRoleEnvelope(options) {
27630
27981
  const relay = fileURLToPath2(new URL("./mcp-relay.mjs", import.meta.url));
27631
27982
  await listen(server, options.socketPath);
27632
27983
  let disposed = false;
27984
+ let durableFailureHandedToCloseRound = false;
27985
+ const settleDurableWrites = async () => {
27986
+ await durableWriteChain;
27987
+ if (infrastructureRoundFailure !== void 0) {
27988
+ durableFailureHandedToCloseRound = true;
27989
+ return { accepted: false, failure: infrastructureRoundFailure };
27990
+ }
27991
+ return void 0;
27992
+ };
27633
27993
  const dispose = async () => {
27634
27994
  if (disposed) return;
27635
27995
  disposed = true;
@@ -27639,11 +27999,25 @@ async function prepareRoleEnvelope(options) {
27639
27999
  } catch (error) {
27640
28000
  cleanupFailures.push(error);
27641
28001
  }
28002
+ try {
28003
+ const alreadyHanded = durableFailureHandedToCloseRound;
28004
+ const durableFailure = await settleDurableWrites();
28005
+ if (durableFailure !== void 0 && !alreadyHanded) {
28006
+ cleanupFailures.push(
28007
+ Object.assign(
28008
+ new Error(durableFailure.failure.diagnostic ?? "durable session entry flush failed"),
28009
+ { code: durableFailure.failure.identity?.code ?? "durable-session-write-failed" }
28010
+ )
28011
+ );
28012
+ }
28013
+ } catch (error) {
28014
+ cleanupFailures.push(error);
28015
+ }
27642
28016
  try {
27643
28017
  const closeAll = server.closeAllConnections;
27644
28018
  if (typeof closeAll === "function") closeAll.call(server);
27645
- await new Promise((resolve22, reject) => {
27646
- server.close((error) => error ? reject(error) : resolve22());
28019
+ await new Promise((resolve21, reject) => {
28020
+ server.close((error) => error ? reject(error) : resolve21());
27647
28021
  });
27648
28022
  } catch (error) {
27649
28023
  cleanupFailures.push(error);
@@ -27660,6 +28034,7 @@ async function prepareRoleEnvelope(options) {
27660
28034
  if (calls.some((call) => call.toolName === terminatingToolName)) return;
27661
28035
  await invokeAkTool(terminatingToolName, params ?? {});
27662
28036
  }
28037
+ ;
27663
28038
  const closeRound = async () => {
27664
28039
  if (calls.length > 0) {
27665
28040
  const roundCalls = [...calls];
@@ -27667,6 +28042,7 @@ async function prepareRoleEnvelope(options) {
27667
28042
  await emit("turn_end", { turnIndex: 0, calls: roundCalls });
27668
28043
  }
27669
28044
  if (infrastructureRoundFailure !== void 0) {
28045
+ durableFailureHandedToCloseRound = true;
27670
28046
  return { accepted: false, failure: infrastructureRoundFailure };
27671
28047
  }
27672
28048
  let closure;
@@ -27678,6 +28054,8 @@ async function prepareRoleEnvelope(options) {
27678
28054
  }
27679
28055
  if (closure !== void 0) {
27680
28056
  await emit("agent_settled", {});
28057
+ const durableFailure2 = await settleDurableWrites();
28058
+ if (durableFailure2 !== void 0) return durableFailure2;
27681
28059
  return { accepted: true };
27682
28060
  }
27683
28061
  if (rejection !== void 0) {
@@ -27687,9 +28065,13 @@ async function prepareRoleEnvelope(options) {
27687
28065
  message: rejection.message
27688
28066
  };
27689
28067
  rejection = void 0;
28068
+ const durableFailure2 = await settleDurableWrites();
28069
+ if (durableFailure2 !== void 0) return durableFailure2;
27690
28070
  return { accepted: false, retry };
27691
28071
  }
27692
28072
  await emit("agent_settled", {});
28073
+ const durableFailure = await settleDurableWrites();
28074
+ if (durableFailure !== void 0) return durableFailure;
27693
28075
  return { accepted: true };
27694
28076
  };
27695
28077
  try {
@@ -27790,10 +28172,11 @@ function headlessTurnArgs(options) {
27790
28172
  description.promptFlag,
27791
28173
  ...description.fixedArgs,
27792
28174
  description.systemPromptFlag,
27793
- options.systemPromptPath,
27794
- description.jsonSchemaFlag,
27795
- JSON.stringify(options.jsonSchema)
28175
+ options.systemPromptPath
27796
28176
  ];
28177
+ if (options.jsonSchema !== void 0) {
28178
+ args.push(description.jsonSchemaFlag, JSON.stringify(options.jsonSchema));
28179
+ }
27797
28180
  if (options.pluginDir) args.push("--plugin-dir", options.pluginDir);
27798
28181
  if (options.mcpConfigPath !== void 0 && options.mcpConfigPath !== "") {
27799
28182
  args.push(description.mcpConfigFlag, options.mcpConfigPath);
@@ -28004,7 +28387,9 @@ function codexTurnArgs(options) {
28004
28387
  }
28005
28388
  }
28006
28389
  args.push("-c", `model_instructions_file=${codexTomlString(options.systemPromptPath)}`);
28007
- args.push("--output-schema", options.outputSchemaPath);
28390
+ if (options.outputSchemaPath !== void 0) {
28391
+ args.push("--output-schema", options.outputSchemaPath);
28392
+ }
28008
28393
  args.push(...codexMcpConfigArgs(options.mcpServers));
28009
28394
  if (options.model !== void 0 && options.model !== "") {
28010
28395
  args.push("-m", options.model);
@@ -28035,10 +28420,10 @@ function headlessMcpConfigDocument(mcpServers) {
28035
28420
 
28036
28421
  // src/headless-host/role-turn-host.ts
28037
28422
  import { spawn as spawn4, spawnSync } from "node:child_process";
28038
- import { randomUUID as randomUUID9 } from "node:crypto";
28423
+ import { randomUUID as randomUUID10 } from "node:crypto";
28039
28424
  import { existsSync as existsSync13 } from "node:fs";
28040
28425
  import { writeFile as writeFile13 } from "node:fs/promises";
28041
- import { dirname as dirname25, isAbsolute as isAbsolute11, join as join44, resolve as resolve21 } from "node:path";
28426
+ import { dirname as dirname24, isAbsolute as isAbsolute10, join as join44, resolve as resolve20 } from "node:path";
28042
28427
 
28043
28428
  // src/external-host-turn-loop.ts
28044
28429
  init_host_contracts();
@@ -28157,6 +28542,7 @@ function reportHostSessionEvent(input) {
28157
28542
  }
28158
28543
 
28159
28544
  // src/headless-host/role-turn-host.ts
28545
+ init_navigator_output();
28160
28546
  function failure(cause, name, code, details, diagnostic) {
28161
28547
  return {
28162
28548
  code: null,
@@ -28258,7 +28644,7 @@ function cwdIsGitWorkTree(cwd) {
28258
28644
  let dir = cwd;
28259
28645
  for (; ; ) {
28260
28646
  if (existsSync13(join44(dir, ".git"))) return true;
28261
- const parent = dirname25(dir);
28647
+ const parent = dirname24(dir);
28262
28648
  if (parent === dir) return false;
28263
28649
  dir = parent;
28264
28650
  }
@@ -28286,10 +28672,10 @@ function resolveGitCommonDir(cwd) {
28286
28672
  if (raw === "") {
28287
28673
  throw new Error("git rev-parse --git-common-dir returned empty stdout");
28288
28674
  }
28289
- return isAbsolute11(raw) ? raw : resolve21(cwd, raw);
28675
+ return isAbsolute10(raw) ? raw : resolve20(cwd, raw);
28290
28676
  }
28291
28677
  function spawnHeadlessTurn(options) {
28292
- return new Promise((resolve22, reject) => {
28678
+ return new Promise((resolve21, reject) => {
28293
28679
  if (options.signal?.aborted) {
28294
28680
  reject(hostAbortedError("headless host aborted"));
28295
28681
  return;
@@ -28364,7 +28750,7 @@ function spawnHeadlessTurn(options) {
28364
28750
  reject(stdinDeliveryError);
28365
28751
  return;
28366
28752
  }
28367
- resolve22({ code, stdout: resultStdout, stderr, timedOut });
28753
+ resolve21({ code, stdout: resultStdout, stderr, timedOut });
28368
28754
  };
28369
28755
  const onAbort = () => {
28370
28756
  child.kill("SIGTERM");
@@ -28425,10 +28811,9 @@ function buildTurnArgs(options) {
28425
28811
  if (options.sessionKind === "resume" && !options.sessionId) {
28426
28812
  throw new Error("codex resume requires a bound thread_id");
28427
28813
  }
28428
- if (options.outputSchemaPath === void 0) throw new Error("codex requires an output schema path");
28429
28814
  return codexTurnArgs({
28430
28815
  systemPromptPath: options.systemPromptPath,
28431
- outputSchemaPath: options.outputSchemaPath,
28816
+ ...options.outputSchemaPath === void 0 ? {} : { outputSchemaPath: options.outputSchemaPath },
28432
28817
  mcpServers: options.mcpServers,
28433
28818
  ...options.model === void 0 ? {} : { model: options.model },
28434
28819
  ...options.effort === void 0 ? {} : { effort: options.effort },
@@ -28443,7 +28828,8 @@ function buildTurnArgs(options) {
28443
28828
  return headlessTurnArgs({
28444
28829
  description: options.description,
28445
28830
  systemPromptPath: options.systemPromptPath,
28446
- jsonSchema: options.jsonSchema,
28831
+ // #959: navigator omits --json-schema so free-form prose is a lawful exit.
28832
+ ...options.jsonSchema === void 0 ? {} : { jsonSchema: options.jsonSchema },
28447
28833
  mcpConfigPath: options.mcpConfigPath,
28448
28834
  ...options.model === void 0 ? {} : { model: options.model },
28449
28835
  ...options.effort === void 0 ? {} : { effort: options.effort },
@@ -28461,7 +28847,7 @@ function createHeadlessRoleTurnHost(config) {
28461
28847
  let sessionId = await config.sessionIdentity.load(request.principal);
28462
28848
  let sessionKind = request.continuation.kind === "resume" && sessionId !== void 0 && sessionId !== "" ? "resume" : "new";
28463
28849
  if (sessionKind === "new" && !codex) {
28464
- sessionId = randomUUID9();
28850
+ sessionId = randomUUID10();
28465
28851
  await config.sessionIdentity.bind(request.principal, sessionId);
28466
28852
  }
28467
28853
  const env = { ...process.env, ...config.env ?? {} };
@@ -28472,13 +28858,15 @@ function createHeadlessRoleTurnHost(config) {
28472
28858
  let pluginDir;
28473
28859
  let applyMethodPrompt = codex ? (prompt) => applyCodexSkillInvocation(request.methods, prompt) : (prompt) => prompt;
28474
28860
  if (codex) {
28475
- outputSchemaPath = join44(request.runDirectory, "headless-output-schema.json");
28476
- await writeFile13(
28477
- outputSchemaPath,
28478
- `${JSON.stringify(closeJsonSchemaForCodex(prepared.jsonSchema), null, 2)}
28861
+ if (prepared.terminatingToolName !== NAVIGATOR_OUTPUT_TOOL_NAME) {
28862
+ outputSchemaPath = join44(request.runDirectory, "headless-output-schema.json");
28863
+ await writeFile13(
28864
+ outputSchemaPath,
28865
+ `${JSON.stringify(closeJsonSchemaForCodex(prepared.jsonSchema), null, 2)}
28479
28866
  `,
28480
- "utf8"
28481
- );
28867
+ "utf8"
28868
+ );
28869
+ }
28482
28870
  } else {
28483
28871
  mcpConfigPath = join44(request.runDirectory, "headless-mcp-config.json");
28484
28872
  await writeFile13(
@@ -28510,7 +28898,8 @@ function createHeadlessRoleTurnHost(config) {
28510
28898
  args = buildTurnArgs({
28511
28899
  description: config.description,
28512
28900
  systemPromptPath,
28513
- jsonSchema: prepared.jsonSchema,
28901
+ // #959: navigator prose exit — no closed JSON schema on claude either.
28902
+ ...prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME ? {} : { jsonSchema: prepared.jsonSchema },
28514
28903
  mcpServers: prepared.mcpServers,
28515
28904
  ...mcpConfigPath === void 0 ? {} : { mcpConfigPath },
28516
28905
  ...outputSchemaPath === void 0 ? {} : { outputSchemaPath },
@@ -28634,6 +29023,18 @@ function createHeadlessRoleTurnHost(config) {
28634
29023
  details: { sessionId, exitCode: spawned.code }
28635
29024
  });
28636
29025
  }
29026
+ if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME) {
29027
+ if (observation.finalMessage.trim() === "") {
29028
+ return terminalFromSpawned(spawned, {
29029
+ cause: "output",
29030
+ identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
29031
+ diagnostic: spawned.stderr.trim() || "codex exec produced empty agent_message",
29032
+ details: { sessionId, exitCode: spawned.code }
29033
+ });
29034
+ }
29035
+ await prepared.ingestStructuredOutput({ prose: observation.finalMessage });
29036
+ return { status: "delivered", stderr: spawned.stderr };
29037
+ }
28637
29038
  let receipt;
28638
29039
  try {
28639
29040
  receipt = JSON.parse(observation.finalMessage);
@@ -28678,6 +29079,8 @@ function createHeadlessRoleTurnHost(config) {
28678
29079
  }
28679
29080
  if (envelope.structured_output !== void 0) {
28680
29081
  await prepared.ingestStructuredOutput(envelope.structured_output);
29082
+ } else if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME && typeof envelope.result === "string" && envelope.result.trim() !== "") {
29083
+ await prepared.ingestStructuredOutput({ prose: envelope.result });
28681
29084
  }
28682
29085
  return { status: "delivered", stderr: spawned.stderr };
28683
29086
  }
@@ -28716,7 +29119,7 @@ function createProductionHeadlessRoleTurnHost(options) {
28716
29119
  sessionFile: sessionIdentity.resolveSessionFile(request.principal),
28717
29120
  // Same MCP relay as ACP so intermediate AK tools stay reachable;
28718
29121
  // headless adapter projects the row into --mcp-config.
28719
- socketPath: `/tmp/ak-headless-mcp-${randomUUID10()}.sock`,
29122
+ socketPath: `/tmp/ak-headless-mcp-${randomUUID11()}.sock`,
28720
29123
  // Schema channel owns the terminating receipt; hide it from MCP list.
28721
29124
  listTerminatingToolOnMcp: false
28722
29125
  })