@akagilnc/pi-workflow-roles 0.1.4528 → 0.1.4620

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 (55) hide show
  1. package/README.md +5 -4
  2. package/README.zh-CN.md +6 -5
  3. package/dist/acp-host/production-host.js +1834 -637
  4. package/dist/archivist-record-topology.js +27 -35
  5. package/dist/headless-host/description.js +7 -4
  6. package/dist/headless-host/production-host.js +1652 -519
  7. package/dist/migrate-book-topology.js +8 -11
  8. package/dist/navigator-attendance.js +146 -241
  9. package/dist/navigator-public-session.js +81 -15
  10. package/dist/package-contracts/navigator-output.js +30 -12
  11. package/dist/public-cli/invocation.js +10 -4
  12. package/dist/public-cli/judge-run.js +2 -2
  13. package/dist/public-cli/main.js +879 -410
  14. package/dist/public-cli/option-definitions.js +6 -6
  15. package/dist/public-cli/post-admission.js +25 -10
  16. package/dist/public-cli/reviewer-run.js +339 -0
  17. package/dist/public-cli/run-lifecycle.js +29 -7
  18. package/dist/public-cli/settlement.js +46 -32
  19. package/dist/public-cli/terminal.js +17 -27
  20. package/dist/public-cli/turn-request.js +1 -1
  21. package/dist/public-role-summons.js +370 -20
  22. package/dist/submission-ledger.js +56 -23
  23. package/package.json +1 -1
  24. package/resources/836-deleted-machine-instruction-inventory.md +2 -0
  25. package/resources/navigator-route-playbook.md +9 -0
  26. package/scripts/build-package.mjs +6 -1
  27. package/src/acp-host/role-turn-host.ts +129 -13
  28. package/src/headless-host/description.ts +17 -7
  29. package/src/headless-host/role-turn-host.ts +42 -11
  30. package/src/host-contracts.ts +0 -1
  31. package/src/navigator-attendance.ts +290 -425
  32. package/src/navigator-public-session.ts +126 -25
  33. package/src/navigator-role.ts +2 -2
  34. package/src/package-contracts/navigator-output.ts +41 -25
  35. package/src/public-cli/coder-run.ts +2 -2
  36. package/src/public-cli/fixer-run.ts +2 -2
  37. package/src/public-cli/invocation.ts +19 -9
  38. package/src/public-cli/judge-run.ts +2 -2
  39. package/src/public-cli/merger-run.ts +2 -2
  40. package/src/public-cli/option-definitions.ts +6 -6
  41. package/src/public-cli/post-admission.ts +41 -10
  42. package/src/public-cli/reviewer-run.ts +238 -53
  43. package/src/public-cli/run-lifecycle.ts +37 -7
  44. package/src/public-cli/settlement.ts +42 -34
  45. package/src/public-cli/terminal.ts +39 -37
  46. package/src/public-cli/turn-request.ts +7 -1
  47. package/src/public-role-summons.ts +544 -22
  48. package/src/reviewer-role.ts +1 -2
  49. package/src/role-envelope.ts +89 -4
  50. package/src/role-runtime.ts +76 -16
  51. package/src/submission-ledger.ts +63 -21
  52. package/dist/public-cli/command-renderer.js +0 -5
  53. package/dist/public-command-renderer.js +0 -29
  54. package/src/public-cli/command-renderer.ts +0 -9
  55. package/src/public-command-renderer.ts +0 -55
@@ -62,7 +62,7 @@ async function spawnEngineDetourOnce(input) {
62
62
  }
63
63
  const command = input.argv[0];
64
64
  const args = input.argv.slice(1);
65
- return await new Promise((resolve21, reject) => {
65
+ return await new Promise((resolve22, reject) => {
66
66
  let settled = false;
67
67
  const signal = input.signal;
68
68
  const child = spawn(command, args, {
@@ -92,7 +92,7 @@ async function spawnEngineDetourOnce(input) {
92
92
  if (signal !== void 0) {
93
93
  signal.removeEventListener("abort", onAbort);
94
94
  }
95
- resolve21(result);
95
+ resolve22(result);
96
96
  };
97
97
  const onAbort = () => {
98
98
  fail4(signal !== void 0 ? abortReasonError(signal) : new Error("aborted"));
@@ -1807,7 +1807,48 @@ var init_collector_output = __esm({
1807
1807
  });
1808
1808
 
1809
1809
  // src/package-contracts/navigator-output.ts
1810
+ var navigator_output_exports = {};
1811
+ __export(navigator_output_exports, {
1812
+ NAVIGATOR_ACCEPTED_TEXT: () => NAVIGATOR_ACCEPTED_TEXT,
1813
+ NAVIGATOR_OUTPUT_TOOL_NAME: () => NAVIGATOR_OUTPUT_TOOL_NAME,
1814
+ navigatorOutputSchema: () => navigatorOutputSchema,
1815
+ navigatorProseFromUnknown: () => navigatorProseFromUnknown,
1816
+ projectLawfulNavigatorOutput: () => projectLawfulNavigatorOutput,
1817
+ validateRecordedNavigatorOutput: () => validateRecordedNavigatorOutput
1818
+ });
1810
1819
  import { Type as Type5 } from "typebox";
1820
+ function projectLawfulNavigatorOutput(value) {
1821
+ if (value === void 0 || value === null) return void 0;
1822
+ if (typeof value === "string") return { prose: value };
1823
+ if (typeof value === "object" && !Array.isArray(value)) {
1824
+ const record4 = value;
1825
+ if (typeof record4.prose === "string") return { prose: record4.prose };
1826
+ if (record4.prose !== void 0 && record4.prose !== null) {
1827
+ return { prose: typeof record4.prose === "string" ? record4.prose : String(record4.prose) };
1828
+ }
1829
+ const keys = Object.keys(record4);
1830
+ if (keys.length === 0) return { prose: "" };
1831
+ try {
1832
+ return { prose: JSON.stringify(record4) };
1833
+ } catch {
1834
+ return { prose: String(record4) };
1835
+ }
1836
+ }
1837
+ return { prose: String(value) };
1838
+ }
1839
+ function validateRecordedNavigatorOutput(value) {
1840
+ const projected = projectLawfulNavigatorOutput(value);
1841
+ if (projected === void 0) {
1842
+ throw new Error("Navigator output is empty");
1843
+ }
1844
+ return projected;
1845
+ }
1846
+ function navigatorProseFromUnknown(value) {
1847
+ const projected = projectLawfulNavigatorOutput(value);
1848
+ if (projected === void 0) return void 0;
1849
+ const trimmed = projected.prose.trim();
1850
+ return trimmed === "" ? void 0 : projected.prose;
1851
+ }
1811
1852
  var NAVIGATOR_OUTPUT_TOOL_NAME, NAVIGATOR_ACCEPTED_TEXT, navigatorOutputSchema;
1812
1853
  var init_navigator_output = __esm({
1813
1854
  "src/package-contracts/navigator-output.ts"() {
@@ -1819,11 +1860,8 @@ var init_navigator_output = __esm({
1819
1860
  navigatorOutputSchema = withTerminatingOutputDeclarations(
1820
1861
  openToolObject(
1821
1862
  Type5.Object({
1822
- status: Type5.Unknown({
1823
- description: "advice \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
1824
- }),
1825
- candidates: Type5.Unknown({
1826
- 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"
1863
+ prose: Type5.Unknown({
1864
+ 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"
1827
1865
  })
1828
1866
  })
1829
1867
  )
@@ -4754,7 +4792,7 @@ function normalizeReviewComment(raw) {
4754
4792
  function createGhApiRunner(options = {}) {
4755
4793
  const spawnImpl = options.spawnImpl ?? spawn3;
4756
4794
  return async (args, runOptions = {}) => {
4757
- return await new Promise((resolve21, reject) => {
4795
+ return await new Promise((resolve22, reject) => {
4758
4796
  const signal = runOptions.signal;
4759
4797
  if (signal?.aborted) {
4760
4798
  reject(signal.reason ?? new Error("aborted"));
@@ -4827,11 +4865,11 @@ function createGhApiRunner(options = {}) {
4827
4865
  const value = line2.slice(idx + 1).trim();
4828
4866
  headers[name] = value;
4829
4867
  }
4830
- resolve21({ status, headers, bodyText });
4868
+ resolve22({ status, headers, bodyText });
4831
4869
  return;
4832
4870
  }
4833
4871
  if (code === 0) {
4834
- resolve21({ status: 200, headers: {}, bodyText: stdout });
4872
+ resolve22({ status: 200, headers: {}, bodyText: stdout });
4835
4873
  return;
4836
4874
  }
4837
4875
  const failure2 = new Error(
@@ -5420,6 +5458,56 @@ var init_typed_provider_http = __esm({
5420
5458
  });
5421
5459
 
5422
5460
  // src/public-cli/run-lifecycle.ts
5461
+ var run_lifecycle_exports = {};
5462
+ __export(run_lifecycle_exports, {
5463
+ AUTO_RESUME_LIMIT: () => AUTO_RESUME_LIMIT,
5464
+ GATE_DOSSIER_POINTER_PREFIX: () => GATE_DOSSIER_POINTER_PREFIX,
5465
+ RESUME_TRANSPORT_ENVELOPE: () => RESUME_TRANSPORT_ENVELOPE,
5466
+ RunWriterLeaseHeldError: () => RunWriterLeaseHeldError,
5467
+ V1_RESUMABLE_PROVIDERS: () => V1_RESUMABLE_PROVIDERS,
5468
+ acquireRunWriterLease: () => acquireRunWriterLease,
5469
+ autopsyWriterLock: () => autopsyWriterLock,
5470
+ buildAutoResumeContinuationPrompt: () => buildAutoResumeContinuationPrompt,
5471
+ buildResumeContinuationPrompt: () => buildResumeContinuationPrompt,
5472
+ clearCurrentCourt: () => clearCurrentCourt,
5473
+ clearTypedProviderHttpObservation: () => clearTypedProviderHttpObservation,
5474
+ describeErrorIdentity: () => describeErrorIdentity,
5475
+ findLatestRunIdForSeatTicket: () => findLatestRunIdForSeatTicket,
5476
+ findRunDirectoryById: () => findRunDirectoryById,
5477
+ isDurablePrincipalAvailable: () => isDurablePrincipalAvailable,
5478
+ isV1ResumableProvider: () => isV1ResumableProvider,
5479
+ loadResumableCoderRun: () => loadResumableCoderRun,
5480
+ loadResumableCollectorRun: () => loadResumableCollectorRun,
5481
+ loadResumableCountersignRun: () => loadResumableCountersignRun,
5482
+ loadResumableDiaristRun: () => loadResumableDiaristRun,
5483
+ loadResumableDoctorRun: () => loadResumableDoctorRun,
5484
+ loadResumableFixerRun: () => loadResumableFixerRun,
5485
+ loadResumableGleanerLeftRun: () => loadResumableGleanerLeftRun,
5486
+ loadResumableInspectorRun: () => loadResumableInspectorRun,
5487
+ loadResumableInstructionSeatRun: () => loadResumableInstructionSeatRun,
5488
+ loadResumableJudgeRun: () => loadResumableJudgeRun,
5489
+ loadResumableMergerRun: () => loadResumableMergerRun,
5490
+ loadResumableNotaryRun: () => loadResumableNotaryRun,
5491
+ loadResumableReviewerRun: () => loadResumableReviewerRun,
5492
+ loadResumableSecretariatRun: () => loadResumableSecretariatRun,
5493
+ markRunAdmitted: () => markRunAdmitted,
5494
+ markRunResumable: () => markRunResumable,
5495
+ markRunRunning: () => markRunRunning,
5496
+ markRunTerminal: () => markRunTerminal,
5497
+ parentRunPathFromGatePointerInstruction: () => parentRunPathFromGatePointerInstruction,
5498
+ peekRoleRunRole: () => peekRoleRunRole,
5499
+ readCurrentCourt: () => readCurrentCourt,
5500
+ readLatestTypedProviderHttpObservation: () => readLatestTypedProviderHttpObservation,
5501
+ readRoleRunIdentity: () => readRoleRunIdentity,
5502
+ readRoleRunState: () => readRoleRunState,
5503
+ readRunParentPath: () => readRunParentPath,
5504
+ readTypedHttp429Observation: () => readTypedHttp429Observation,
5505
+ recordCurrentCourt: () => recordCurrentCourt,
5506
+ recordTypedProviderHttpStatus: () => recordTypedProviderHttpStatus,
5507
+ renderResumeCommand: () => renderResumeCommand,
5508
+ selectResumeContinuationPrompt: () => selectResumeContinuationPrompt,
5509
+ writeRoleRunState: () => writeRoleRunState
5510
+ });
5423
5511
  import { chmod, lstat as lstat2, open, readdir as readdir4, readFile as readFile9, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
5424
5512
  import { basename as basename4, join as join15 } from "node:path";
5425
5513
  function selectResumeContinuationPrompt(message, engineMaterial) {
@@ -5435,6 +5523,15 @@ function buildResumeContinuationPrompt(options) {
5435
5523
  })
5436
5524
  );
5437
5525
  }
5526
+ function buildAutoResumeContinuationPrompt(options) {
5527
+ return selectResumeContinuationPrompt(
5528
+ RESUME_TRANSPORT_ENVELOPE,
5529
+ engineSessionMaterialFromOptions({
5530
+ packageRoot: options.packageRoot,
5531
+ ...pickEngineAxis(options)
5532
+ })
5533
+ );
5534
+ }
5438
5535
  function isV1ResumableProvider(provider) {
5439
5536
  return V1_RESUMABLE_PROVIDERS.includes(provider);
5440
5537
  }
@@ -5598,6 +5695,11 @@ function materializeRoleRunFromDisk(disk, authority) {
5598
5695
  return void 0;
5599
5696
  }
5600
5697
  }
5698
+ async function readRoleRunState(runDirectory, authority) {
5699
+ const disk = await readRoleRunStateDisk(runDirectory);
5700
+ if (disk === void 0) return void 0;
5701
+ return materializeRoleRunFromDisk(disk, authority)?.run;
5702
+ }
5601
5703
  async function readRoleRunIdentity(runDirectory) {
5602
5704
  const disk = await readRoleRunStateDisk(runDirectory);
5603
5705
  if (disk === void 0) return void 0;
@@ -6331,6 +6433,117 @@ async function loadResumableJudgeRun(home, runId, authority) {
6331
6433
  };
6332
6434
  return seatLoadedResult(loaded, admitted);
6333
6435
  }
6436
+ async function loadResumableCoderRun(home, runId, authority) {
6437
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6438
+ if (loaded.run.role !== "coder") {
6439
+ throw new CliUsageError(
6440
+ `role run ${runId} belongs to ${loaded.run.role}, not coder`
6441
+ );
6442
+ }
6443
+ const phase = loaded.admittedFields.phase ?? loaded.run.phase;
6444
+ if (phase !== "plan" && phase !== "apply") {
6445
+ throw new CliUsageError(
6446
+ `role run admitted coder phase is missing: ${runId}`
6447
+ );
6448
+ }
6449
+ const taskPath = loaded.admittedFields.taskPath;
6450
+ if (taskPath === void 0) {
6451
+ throw new CliUsageError(
6452
+ `role run admitted coder task path is missing: ${runId}`
6453
+ );
6454
+ }
6455
+ if (loaded.admittedFields.instruction.trim() === "") {
6456
+ throw new CliUsageError(
6457
+ `role run admitted coder task is blank: ${runId}`
6458
+ );
6459
+ }
6460
+ const admitted = {
6461
+ role: "coder",
6462
+ phase,
6463
+ ...resumedBaseAdmitted(loaded),
6464
+ instructionEmpty: false,
6465
+ taskPath
6466
+ };
6467
+ return seatLoadedResult(loaded, admitted);
6468
+ }
6469
+ async function loadResumableFixerRun(home, runId, authority) {
6470
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6471
+ if (loaded.run.role !== "fixer") {
6472
+ throw new CliUsageError(
6473
+ `role run ${runId} belongs to ${loaded.run.role}, not fixer`
6474
+ );
6475
+ }
6476
+ const phase = loaded.admittedFields.phase ?? loaded.run.phase;
6477
+ if (phase !== "plan" && phase !== "apply") {
6478
+ throw new CliUsageError(
6479
+ `role run admitted fixer phase is missing: ${runId}`
6480
+ );
6481
+ }
6482
+ const packetPath = loaded.admittedFields.packetPath;
6483
+ if (packetPath === void 0) {
6484
+ throw new CliUsageError(
6485
+ `role run admitted fixer packet path is missing: ${runId}`
6486
+ );
6487
+ }
6488
+ if (loaded.admittedFields.instruction.trim() === "") {
6489
+ throw new CliUsageError(
6490
+ `role run admitted fixer instruction is blank: ${runId}`
6491
+ );
6492
+ }
6493
+ const prerequisites = loaded.admittedFields.prerequisites ?? Object.freeze([]);
6494
+ const admitted = {
6495
+ role: "fixer",
6496
+ phase,
6497
+ ...resumedBaseAdmitted(loaded),
6498
+ instructionEmpty: false,
6499
+ packetPath,
6500
+ ...loaded.admittedFields.prerequisitesPath === void 0 ? {} : { prerequisitesPath: loaded.admittedFields.prerequisitesPath },
6501
+ prerequisites
6502
+ };
6503
+ return seatLoadedResult(loaded, admitted);
6504
+ }
6505
+ async function loadResumableReviewerRun(home, runId, authority) {
6506
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6507
+ if (loaded.run.role !== "reviewer") {
6508
+ throw new CliUsageError(
6509
+ `role run ${runId} belongs to ${loaded.run.role}, not reviewer`
6510
+ );
6511
+ }
6512
+ const rawBase = loaded.admittedFields.baseRevision;
6513
+ if (rawBase === void 0 || rawBase.trim() === "") {
6514
+ throw new CliUsageError(
6515
+ `role run admitted reviewer base revision is missing: ${runId}`
6516
+ );
6517
+ }
6518
+ if (/\s/.test(rawBase) || rawBase.startsWith("-")) {
6519
+ throw new CliUsageError(
6520
+ `role run admitted reviewer base revision is damaged: ${runId}`
6521
+ );
6522
+ }
6523
+ const baseRevision = rawBase;
6524
+ const lens = loaded.admittedFields.lens;
6525
+ if (!isReviewerLens(lens)) {
6526
+ throw new CliUsageError(
6527
+ `role run admitted reviewer lens is missing: ${runId}`
6528
+ );
6529
+ }
6530
+ const authorityRefs = Object.freeze([
6531
+ ...loaded.admittedFields.authorityRefs ?? []
6532
+ ]);
6533
+ if (authorityRefs.length === 0) {
6534
+ throw new CliUsageError(
6535
+ `role run admitted reviewer authority refs are missing: ${runId}`
6536
+ );
6537
+ }
6538
+ const admitted = {
6539
+ role: "reviewer",
6540
+ ...resumedBaseAdmitted(loaded),
6541
+ baseRevision,
6542
+ lens,
6543
+ authorityRefs
6544
+ };
6545
+ return seatLoadedResult(loaded, admitted);
6546
+ }
6334
6547
  async function loadResumableCountersignRun(home, runId, authority) {
6335
6548
  const loaded = await loadResumableRunRecord(home, runId, authority);
6336
6549
  if (loaded.run.role !== "countersign") {
@@ -6362,6 +6575,26 @@ async function loadResumableInstructionSeatRun(home, runId, authority) {
6362
6575
  };
6363
6576
  return seatLoadedResult(loaded, admitted);
6364
6577
  }
6578
+ async function loadResumableGleanerLeftRun(home, runId, authority) {
6579
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6580
+ if (loaded.run.role !== "gleaner-left") {
6581
+ throw new CliUsageError(
6582
+ `role run ${runId} belongs to ${loaded.run.role}, not gleaner-left`
6583
+ );
6584
+ }
6585
+ const baseRevision = loaded.admittedFields.baseRevision;
6586
+ if (baseRevision === void 0 || baseRevision.trim() === "") {
6587
+ throw new CliUsageError(
6588
+ `role run admitted gleaner-left base revision is missing: ${runId}`
6589
+ );
6590
+ }
6591
+ const admitted = {
6592
+ role: "gleaner-left",
6593
+ ...resumedBaseAdmitted(loaded),
6594
+ baseRevision
6595
+ };
6596
+ return seatLoadedResult(loaded, admitted);
6597
+ }
6365
6598
  async function loadResumableDiaristRun(home, runId, authority) {
6366
6599
  const loaded = await loadResumableRunRecord(home, runId, authority);
6367
6600
  if (loaded.run.role !== "diarist") {
@@ -6375,6 +6608,88 @@ async function loadResumableDiaristRun(home, runId, authority) {
6375
6608
  };
6376
6609
  return seatLoadedResult(loaded, admitted);
6377
6610
  }
6611
+ async function loadResumableSecretariatRun(home, runId, authority) {
6612
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6613
+ if (loaded.run.role !== "secretariat") {
6614
+ throw new CliUsageError(
6615
+ `role run ${runId} belongs to ${loaded.run.role}, not secretariat`
6616
+ );
6617
+ }
6618
+ const admitted = {
6619
+ role: "secretariat",
6620
+ ...resumedBaseAdmitted(loaded)
6621
+ };
6622
+ return seatLoadedResult(loaded, admitted);
6623
+ }
6624
+ async function loadResumableMergerRun(home, runId, authority) {
6625
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6626
+ if (loaded.run.role !== "merger") {
6627
+ throw new CliUsageError(
6628
+ `role run ${runId} belongs to ${loaded.run.role}, not merger`
6629
+ );
6630
+ }
6631
+ const mergerInputPath = loaded.admittedFields.mergerInputPath;
6632
+ if (mergerInputPath === void 0) {
6633
+ throw new CliUsageError(
6634
+ `role run admitted merger input path is missing: ${runId}`
6635
+ );
6636
+ }
6637
+ const derived = loaded.admittedFields.derived;
6638
+ if (derived === void 0) {
6639
+ throw new CliUsageError(
6640
+ `role run admitted merger envelope is missing: ${runId}`
6641
+ );
6642
+ }
6643
+ if (loaded.admittedFields.instruction.trim() === "") {
6644
+ throw new CliUsageError(
6645
+ `role run admitted merger task is blank: ${runId}`
6646
+ );
6647
+ }
6648
+ const admitted = {
6649
+ role: "merger",
6650
+ ...resumedBaseAdmitted(loaded),
6651
+ instructionEmpty: false,
6652
+ mergerInputPath,
6653
+ derived
6654
+ };
6655
+ return seatLoadedResult(loaded, admitted);
6656
+ }
6657
+ async function loadResumableCollectorRun(home, runId, authority) {
6658
+ const loaded = await loadResumableRunRecord(home, runId, authority);
6659
+ if (loaded.run.role !== "collector") {
6660
+ throw new CliUsageError(
6661
+ `role run ${runId} belongs to ${loaded.run.role}, not collector`
6662
+ );
6663
+ }
6664
+ const { prNumber, repository, repositoryDisplay, manifestDigest } = loaded.admittedFields;
6665
+ if (repository === void 0 || repositoryDisplay === void 0 || manifestDigest === void 0) {
6666
+ throw new CliUsageError(
6667
+ `role run admitted collector repository identity is missing: ${runId}`
6668
+ );
6669
+ }
6670
+ let parsedRepository;
6671
+ try {
6672
+ parsedRepository = parseCollectorRepository(repositoryDisplay);
6673
+ } catch (error) {
6674
+ const detail = error instanceof Error ? error.message : String(error);
6675
+ throw new CliUsageError(detail, { cause: error });
6676
+ }
6677
+ if (parsedRepository.canonical !== repository) {
6678
+ throw new CliUsageError(
6679
+ `role run admitted collector repository does not match its canonical form: ${runId}`
6680
+ );
6681
+ }
6682
+ const admitted = {
6683
+ role: "collector",
6684
+ ...resumedBaseAdmitted(loaded),
6685
+ ...prNumber === void 0 ? {} : { prNumber },
6686
+ repository: parsedRepository,
6687
+ ...loaded.admittedFields.requestManifestPath === void 0 ? {} : { requestManifestPath: loaded.admittedFields.requestManifestPath },
6688
+ ...loaded.admittedFields.waitWindowMs === void 0 ? {} : { waitWindowMs: loaded.admittedFields.waitWindowMs },
6689
+ manifestDigest
6690
+ };
6691
+ return seatLoadedResult(loaded, admitted);
6692
+ }
6378
6693
  async function loadResumableDoctorRun(home, runId, authority) {
6379
6694
  const loaded = await loadResumableRunRecord(home, runId, authority);
6380
6695
  if (loaded.run.role !== "doctor") {
@@ -6432,6 +6747,12 @@ async function loadResumableInspectorRun(home, runId, authority) {
6432
6747
  };
6433
6748
  return seatLoadedResult(loaded, admitted);
6434
6749
  }
6750
+ async function peekRoleRunRole(home, runId) {
6751
+ const runDirectory = await findRunDirectoryById(home, runId);
6752
+ if (runDirectory === void 0) return void 0;
6753
+ const run = await readRoleRunIdentity(runDirectory);
6754
+ return run?.role;
6755
+ }
6435
6756
  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;
6436
6757
  var init_run_lifecycle = __esm({
6437
6758
  "src/public-cli/run-lifecycle.ts"() {
@@ -6448,7 +6769,7 @@ var init_run_lifecycle = __esm({
6448
6769
  init_invocation();
6449
6770
  V1_RESUMABLE_PROVIDERS = ["openai-codex", "xai"];
6450
6771
  AUTO_RESUME_LIMIT = 2;
6451
- RESUME_TRANSPORT_ENVELOPE = "[ak-role:resume-continue]";
6772
+ RESUME_TRANSPORT_ENVELOPE = "\u7EE7\u7EED\u3002";
6452
6773
  RUN_STATE_FILE = "run-state.json";
6453
6774
  WRITER_LOCK_FILE = "writer.lock";
6454
6775
  RunWriterLeaseHeldError = class extends Error {
@@ -7088,12 +7409,12 @@ var init_option_definitions = __esm({
7088
7409
  canonical: "--lens",
7089
7410
  aliases: [],
7090
7411
  valueMetavar: "completeness|correctness",
7091
- required: true,
7412
+ required: false,
7092
7413
  repeatable: false,
7093
7414
  form: "option",
7094
7415
  description: {
7095
- en: "Required single review lens: completeness or correctness (no default).",
7096
- zh: "\u5FC5\u586B\u5355 lens\uFF1Acompleteness \u6216 correctness\uFF08\u65E0\u9ED8\u8BA4\u503C\uFF09\u3002"
7416
+ en: "Optional single-lens override: completeness or correctness; omitted runs both in parallel.",
7417
+ zh: "\u53EF\u9009\u5355 lens \u8986\u76D6\uFF1Acompleteness \u6216 correctness\uFF1B\u7701\u7565\u65F6\u5E76\u884C\u8FD0\u884C\u4E24\u8F74\u3002"
7097
7418
  }
7098
7419
  },
7099
7420
  {
@@ -7450,9 +7771,9 @@ var init_option_definitions = __esm({
7450
7771
  },
7451
7772
  reviewer: {
7452
7773
  command: "reviewer",
7453
- summary: "Fixed-target single-lens review (completeness or correctness).",
7774
+ summary: "Fixed-target parallel two-lens review, with an optional single-lens override.",
7454
7775
  usage: [
7455
- "ak-role reviewer --base <revision> --lens completeness|correctness --authority-ref <ref> [options] <instruction>"
7776
+ "ak-role reviewer --base <revision> [--lens completeness|correctness] --authority-ref <ref> [options] <instruction>"
7456
7777
  ],
7457
7778
  examples: [
7458
7779
  'ak-role reviewer --base main --lens completeness --authority-ref docs/adr/0001.md "Review the branch."',
@@ -7503,7 +7824,7 @@ var init_option_definitions = __esm({
7503
7824
  },
7504
7825
  navigator: {
7505
7826
  command: "navigator",
7506
- summary: "Direct Navigator (\u6E38\u5955\u4F7F) route advice: ordered next-role candidates.",
7827
+ summary: "Direct Navigator (\u6E38\u5955\u4F7F) free-form prose route advice.",
7507
7828
  usage: ["ak-role navigator [options] [instruction]"],
7508
7829
  examples: [
7509
7830
  'ak-role navigator "\u521A\u5B8C\u6210 coder apply \u6536\u655B\uFF0C\u4E0B\u4E00\u6B65\uFF1F"'
@@ -9585,7 +9906,7 @@ function parseReviewerArgv(args) {
9585
9906
  instruction: positional.join(" "),
9586
9907
  attachmentPaths,
9587
9908
  baseRevision,
9588
- lens,
9909
+ ...lens === void 0 ? {} : { lens },
9589
9910
  authorityRefs,
9590
9911
  ...project === void 0 ? {} : { project }
9591
9912
  };
@@ -9634,6 +9955,7 @@ async function admitReviewerInvocation(options) {
9634
9955
  baseRevision,
9635
9956
  lens,
9636
9957
  authorityRefs: [...authorityRefs],
9958
+ ...options.correlationId === void 0 ? {} : { correlationId: options.correlationId },
9637
9959
  attachments: attachments.map((a) => ({
9638
9960
  provenancePath: a.provenancePath,
9639
9961
  frozenPath: a.frozenPath,
@@ -9661,7 +9983,8 @@ async function admitReviewerInvocation(options) {
9661
9983
  admittedRequestPath,
9662
9984
  baseRevision,
9663
9985
  lens,
9664
- authorityRefs
9986
+ authorityRefs,
9987
+ ...options.correlationId === void 0 ? {} : { correlationId: options.correlationId }
9665
9988
  };
9666
9989
  }
9667
9990
  function buildReviewerSkillArgProjection(admitted) {
@@ -9878,11 +10201,11 @@ function parseAnalystCohortIssueToken(raw, flag) {
9878
10201
  `${flag} requires a comma-separated list of N or book:N`
9879
10202
  );
9880
10203
  }
9881
- const sep6 = trimmed.lastIndexOf(":");
9882
- if (sep6 > 0) {
9883
- const rhs = trimmed.slice(sep6 + 1);
10204
+ const sep7 = trimmed.lastIndexOf(":");
10205
+ if (sep7 > 0) {
10206
+ const rhs = trimmed.slice(sep7 + 1);
9884
10207
  if (ANALYST_TICKET_NUMBER_PATTERN.test(rhs)) {
9885
- const bookKey = trimmed.slice(0, sep6);
10208
+ const bookKey = trimmed.slice(0, sep7);
9886
10209
  if (bookKey.trim() === "") {
9887
10210
  throw new CliUsageError(
9888
10211
  `${flag} book:N requires a non-empty book key, got ${raw}`
@@ -11791,31 +12114,58 @@ async function restoreState(cwd, runId, scope) {
11791
12114
  }, 0)
11792
12115
  };
11793
12116
  }
12117
+ function sessionParentFromHostContext(context) {
12118
+ const runDirectory = runDirectoryFromHostContext(context);
12119
+ if (runDirectory !== void 0) return join24(runDirectory, "session", "session.jsonl");
12120
+ const sessionFile = context.sessionManager.getSessionFile?.();
12121
+ if (typeof sessionFile === "string" && sessionFile.length > 0) return sessionFile;
12122
+ const sessionDir = context.sessionManager.getSessionDir?.();
12123
+ if (typeof sessionDir === "string" && sessionDir.length > 0) {
12124
+ return join24(sessionDir, "session.jsonl");
12125
+ }
12126
+ return void 0;
12127
+ }
12128
+ function homeFromHostContext(context, home) {
12129
+ if (home !== void 0) return home;
12130
+ const sessionParent = sessionParentFromHostContext(context);
12131
+ return sessionParent !== void 0 ? tryHomeFromAkRolesPath(sessionParent) : void 0;
12132
+ }
12133
+ async function sealAcceptedSubmission(options) {
12134
+ const runId = runIdentity(options.context);
12135
+ const attemptId = attemptIdentity(options.context, runId);
12136
+ const sessionParent = sessionParentFromHostContext(options.context);
12137
+ const home = homeFromHostContext(options.context, options.home);
12138
+ const state = await restoreState(options.context.cwd, runId, {
12139
+ ...home === void 0 ? {} : { home },
12140
+ ...sessionParent === void 0 ? {} : { sessionParent }
12141
+ });
12142
+ const pointer = sitianReport({
12143
+ level: "event",
12144
+ kind: "sealed",
12145
+ subject: { runId, attemptId },
12146
+ ...state.prior === void 0 ? {} : { priorEventId: state.prior.identity },
12147
+ payload: {
12148
+ type: "sealed",
12149
+ attemptId,
12150
+ toolCallId: options.toolCallId,
12151
+ role: options.role,
12152
+ accepted: options.accepted
12153
+ },
12154
+ source: "role-runtime",
12155
+ cwd: options.context.cwd,
12156
+ ...home !== void 0 ? { home } : {},
12157
+ ...sessionParent === void 0 ? {} : { sessionParent }
12158
+ });
12159
+ state.prior = pointer;
12160
+ }
11794
12161
  function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (error) => {
11795
12162
  throw error;
11796
12163
  }, projectClosure = () => void 0, options) {
11797
12164
  const states = /* @__PURE__ */ new Map();
11798
- const sessionParentFromContext = (context) => {
11799
- const runDirectory = runDirectoryFromHostContext(context);
11800
- if (runDirectory !== void 0) {
11801
- return join24(runDirectory, "session", "session.jsonl");
11802
- }
11803
- const sessionFile = context.sessionManager.getSessionFile?.();
11804
- if (typeof sessionFile === "string" && sessionFile.length > 0) return sessionFile;
11805
- const sessionDir = context.sessionManager.getSessionDir?.();
11806
- if (typeof sessionDir === "string" && sessionDir.length > 0) {
11807
- return join24(sessionDir, "session.jsonl");
11808
- }
11809
- return void 0;
11810
- };
11811
- const resolveHomeFromContext = (context) => {
11812
- if (options?.home !== void 0) return options.home;
11813
- const sessionParent = sessionParentFromContext(context);
11814
- return sessionParent !== void 0 ? tryHomeFromAkRolesPath(sessionParent) : void 0;
11815
- };
12165
+ const resolveHomeFromContext = (context) => homeFromHostContext(context, options?.home);
11816
12166
  const stateFor = (context, runId) => states.get(runId) ?? (() => {
11817
12167
  const home = resolveHomeFromContext(context);
11818
- const sessionParent = sessionParentFromContext(context);
12168
+ const sessionParent = sessionParentFromHostContext(context);
11819
12169
  const pending = restoreState(context.cwd, runId, {
11820
12170
  ...home === void 0 ? {} : { home },
11821
12171
  ...sessionParent === void 0 ? {} : { sessionParent }
@@ -11825,7 +12175,7 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
11825
12175
  })();
11826
12176
  const appendFor = (state, context, runId, attemptId, event) => {
11827
12177
  const home = resolveHomeFromContext(context);
11828
- const sessionParent = sessionParentFromContext(context);
12178
+ const sessionParent = sessionParentFromHostContext(context);
11829
12179
  const pointer = sitianReport({
11830
12180
  level: "event",
11831
12181
  kind: event.type,
@@ -12268,12 +12618,12 @@ function createSystemCollectorClock() {
12268
12618
  return {
12269
12619
  wallNow: () => /* @__PURE__ */ new Date(),
12270
12620
  monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
12271
- sleep: (ms, signal) => new Promise((resolve21, reject) => {
12621
+ sleep: (ms, signal) => new Promise((resolve22, reject) => {
12272
12622
  if (signal?.aborted) {
12273
12623
  reject(signal.reason ?? new Error("aborted"));
12274
12624
  return;
12275
12625
  }
12276
- const timer = setTimeout(resolve21, ms);
12626
+ const timer = setTimeout(resolve22, ms);
12277
12627
  const onAbort = () => {
12278
12628
  clearTimeout(timer);
12279
12629
  reject(signal?.reason ?? new Error("aborted"));
@@ -14153,44 +14503,6 @@ var init_receipt_delivery_policy = __esm({
14153
14503
  }
14154
14504
  });
14155
14505
 
14156
- // src/public-command-renderer.ts
14157
- function isPublicCallableRole2(role) {
14158
- return PUBLIC_CALLABLE_ROLES3.has(role);
14159
- }
14160
- function renderPublicAkRoleCommand(target) {
14161
- if (!isPublicCallableRole2(target.role)) return void 0;
14162
- const role = target.role;
14163
- const metadata = packagedRoleMetadata(role);
14164
- if (metadata !== void 0 && "bareCommand" in metadata && metadata.bareCommand === false) {
14165
- return void 0;
14166
- }
14167
- if (target.phase === null || target.phase === void 0) {
14168
- return `ak-role ${role}`;
14169
- }
14170
- if (role === "coder" || role === "fixer") {
14171
- return `ak-role ${role} ${target.phase}`;
14172
- }
14173
- return `ak-role ${role}`;
14174
- }
14175
- var PUBLIC_CALLABLE_ROLES3;
14176
- var init_public_command_renderer = __esm({
14177
- "src/public-command-renderer.ts"() {
14178
- "use strict";
14179
- init_packaged_role_registry();
14180
- PUBLIC_CALLABLE_ROLES3 = new Set(
14181
- PACKAGED_ROLE_REGISTRY.map((entry) => entry.role)
14182
- );
14183
- }
14184
- });
14185
-
14186
- // src/public-cli/command-renderer.ts
14187
- var init_command_renderer = __esm({
14188
- "src/public-cli/command-renderer.ts"() {
14189
- "use strict";
14190
- init_public_command_renderer();
14191
- }
14192
- });
14193
-
14194
14506
  // src/public-cli/terminal.ts
14195
14507
  function encodeTerminalField(value) {
14196
14508
  return JSON.stringify(value);
@@ -14201,14 +14513,10 @@ function isLawfulTypedTerminalOutcome(outcome) {
14201
14513
  function exitCodeForTerminalOutcome(outcome) {
14202
14514
  return isLawfulTypedTerminalOutcome(outcome) ? 0 : 1;
14203
14515
  }
14204
- function recommendationNavigatorFact(input) {
14205
- const command = typeof input.modelCommand === "string" && input.modelCommand.trim() !== "" ? input.modelCommand : isPublicCallableRole2(input.next.role) ? renderPublicAkRoleCommand(input.next) : void 0;
14516
+ function adviceNavigatorFact(input) {
14206
14517
  return {
14207
- disposition: "recommendation",
14208
- next: input.next,
14209
- reason: input.reason,
14210
- ...command === void 0 ? {} : { command },
14211
- ...input.route === void 0 ? {} : { route: input.route },
14518
+ disposition: "advice",
14519
+ prose: input.prose,
14212
14520
  ...input.advisoryDiagnostic === void 0 ? {} : { advisoryDiagnostic: input.advisoryDiagnostic }
14213
14521
  };
14214
14522
  }
@@ -14236,14 +14544,8 @@ function formatTerminalResult(result) {
14236
14544
  if (result.navigator.advisoryDiagnostic !== void 0) {
14237
14545
  lines.push(`navigator-advisory ${encodeTerminalField(result.navigator.advisoryDiagnostic)}`);
14238
14546
  }
14239
- if (result.navigator.disposition === "recommendation") {
14240
- lines.push(
14241
- `next ${result.navigator.next.role} ${result.navigator.next.phase ?? "none"}`
14242
- );
14243
- lines.push(`reason ${encodeTerminalField(result.navigator.reason)}`);
14244
- if (result.navigator.command !== void 0) {
14245
- lines.push(`command ${encodeTerminalField(result.navigator.command)}`);
14246
- }
14547
+ if (result.navigator.disposition === "advice") {
14548
+ lines.push(`prose ${encodeTerminalField(result.navigator.prose)}`);
14247
14549
  } else if (result.navigator.disposition === "unavailable") {
14248
14550
  lines.push(
14249
14551
  `unavailable ${result.navigator.source} ${encodeTerminalField(result.navigator.reason)}`
@@ -14263,6 +14565,15 @@ function formatTerminalResult(result) {
14263
14565
  );
14264
14566
  }
14265
14567
  }
14568
+ if (result.reviewerChildOutcomes !== void 0) {
14569
+ for (const axis of ["completeness", "correctness"]) {
14570
+ const child = result.reviewerChildOutcomes[axis];
14571
+ lines.push(`reviewer-child ${axis} ${child.exitCode}`);
14572
+ if (child.stderr !== void 0 && child.stderr !== "") {
14573
+ lines.push(`reviewer-child-diagnostic ${axis} ${encodeTerminalField(child.stderr)}`);
14574
+ }
14575
+ }
14576
+ }
14266
14577
  if (result.resume !== void 0) {
14267
14578
  lines.push(`resume ${encodeTerminalField(result.resume.command)}`);
14268
14579
  } else if (result.runId !== void 0) {
@@ -14283,7 +14594,6 @@ function formatTerminalResult(result) {
14283
14594
  var init_terminal = __esm({
14284
14595
  "src/public-cli/terminal.ts"() {
14285
14596
  "use strict";
14286
- init_command_renderer();
14287
14597
  }
14288
14598
  });
14289
14599
 
@@ -15263,10 +15573,6 @@ async function appendRunAttemptHistory(source, outcome) {
15263
15573
  } catch {
15264
15574
  }
15265
15575
  }
15266
- function navigatorPhaseValue(value) {
15267
- if (value === "plan" || value === "apply") return value;
15268
- return null;
15269
- }
15270
15576
  function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
15271
15577
  if (attendanceIndex <= terminalIndex) return false;
15272
15578
  if (details.invocationId !== marker.invocationId) return false;
@@ -15275,29 +15581,33 @@ function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex,
15275
15581
  function parseNavigatorAttendanceDetails(details) {
15276
15582
  const disposition = details.disposition;
15277
15583
  const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
15278
- if (disposition === "recommendation") {
15279
- const next = details.next;
15280
- if (!isRecord11(next) || typeof next.role !== "string") {
15584
+ if (disposition === "advice" || disposition === "recommendation") {
15585
+ let prose;
15586
+ if (typeof details.prose === "string" && details.prose.trim() !== "") {
15587
+ prose = details.prose;
15588
+ } else {
15589
+ const next = isRecord11(details.next) && typeof details.next.role === "string" ? details.next.role : void 0;
15590
+ const reason = typeof details.reason === "string" && details.reason.trim() !== "" ? details.reason : void 0;
15591
+ const command = typeof details.command === "string" && details.command.trim() !== "" ? details.command : void 0;
15592
+ if (reason !== void 0 && next !== void 0) {
15593
+ prose = `${reason}\uFF08\u4E0B\u4E00\u6B65\uFF1A${next}\uFF09`;
15594
+ } else if (reason !== void 0) {
15595
+ prose = reason;
15596
+ } else if (next !== void 0) {
15597
+ prose = `\u4E0B\u4E00\u6B65\uFF1A${next}`;
15598
+ } else if (command !== void 0) {
15599
+ prose = command;
15600
+ }
15601
+ }
15602
+ if (prose === void 0 || prose.trim() === "") {
15281
15603
  return {
15282
- disposition: "unavailable",
15283
- source: "unknown",
15284
- reason: "navigator recommendation missing typed next role"
15604
+ disposition: "no-advice",
15605
+ ...advisoryDiagnostic
15285
15606
  };
15286
15607
  }
15287
- const reason = typeof details.reason === "string" ? details.reason : "";
15288
- const route = Array.isArray(details.route) ? details.route.filter(isRecord11).map((target) => ({
15289
- role: String(target.role),
15290
- phase: navigatorPhaseValue(target.phase)
15291
- })) : void 0;
15292
- return recommendationNavigatorFact({
15293
- ...advisoryDiagnostic,
15294
- next: {
15295
- role: next.role,
15296
- phase: navigatorPhaseValue(next.phase)
15297
- },
15298
- reason,
15299
- ...route === void 0 ? {} : { route },
15300
- ...typeof details.command === "string" ? { modelCommand: details.command } : {}
15608
+ return adviceNavigatorFact({
15609
+ prose,
15610
+ ...advisoryDiagnostic
15301
15611
  });
15302
15612
  }
15303
15613
  if (disposition === "unavailable") {
@@ -16723,10 +17033,10 @@ function presentFailureTerminal(terminal, io) {
16723
17033
  }
16724
17034
  function defaultNavigatorGraceSleep() {
16725
17035
  let timer;
16726
- const sleep = ((ms) => new Promise((resolve21) => {
17036
+ const sleep = ((ms) => new Promise((resolve22) => {
16727
17037
  timer = setTimeout(() => {
16728
17038
  timer = void 0;
16729
- resolve21();
17039
+ resolve22();
16730
17040
  }, ms);
16731
17041
  }));
16732
17042
  sleep.cancel = () => {
@@ -16738,7 +17048,7 @@ function defaultNavigatorGraceSleep() {
16738
17048
  return sleep;
16739
17049
  }
16740
17050
  function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep = defaultNavigatorGraceSleep()) {
16741
- return new Promise((resolve21, reject) => {
17051
+ return new Promise((resolve22, reject) => {
16742
17052
  let settled = false;
16743
17053
  const finish = (action) => {
16744
17054
  if (settled) return;
@@ -16747,11 +17057,11 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep
16747
17057
  action();
16748
17058
  };
16749
17059
  void work.then(
16750
- (value) => finish(() => resolve21({ status: "done", value })),
17060
+ (value) => finish(() => resolve22({ status: "done", value })),
16751
17061
  (error) => finish(() => reject(error))
16752
17062
  );
16753
17063
  void sleep(graceMs).then(() => {
16754
- finish(() => resolve21({ status: "timeout" }));
17064
+ finish(() => resolve22({ status: "timeout" }));
16755
17065
  });
16756
17066
  });
16757
17067
  }
@@ -18202,6 +18512,30 @@ async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic,
18202
18512
  }
18203
18513
  }
18204
18514
  }
18515
+ async function resolveResumeMethodMaterialAdapters(input) {
18516
+ if (input.shouldLoad === false) {
18517
+ return { kind: "continue", adapters: input.emptyAdapters };
18518
+ }
18519
+ try {
18520
+ const material = await input.loadMaterial();
18521
+ return { kind: "continue", adapters: input.adaptersWith(material) };
18522
+ } catch (error) {
18523
+ const terminal = await presentControlledFailure2(
18524
+ input.admitted,
18525
+ {
18526
+ timedOut: false,
18527
+ code: null,
18528
+ stderr: "",
18529
+ thrown: error,
18530
+ ...input.knownCause === void 0 ? {} : { knownCause: input.knownCause }
18531
+ },
18532
+ input.emptyAdapters,
18533
+ input.authority,
18534
+ input.io
18535
+ );
18536
+ return { kind: "terminal", ...terminal };
18537
+ }
18538
+ }
18205
18539
  async function presentControlledFailure2(admitted, failureInput, adapters, authority, io, persistRunState = true) {
18206
18540
  const hasThrown = Object.hasOwn(failureInput, "thrown");
18207
18541
  const resumeObservation = await resolveControlledFailureResumeObservation({
@@ -18752,6 +19086,8 @@ async function runPostAdmissionSeatResume(input) {
18752
19086
  }
18753
19087
  adapters = prepared.adapters;
18754
19088
  }
19089
+ let env = input.env;
19090
+ let preparedCleanup;
18755
19091
  const buildRequestAfterLease = async () => {
18756
19092
  let openCourtAttemptId;
18757
19093
  let admittedForBuild = loaded.admitted;
@@ -18802,7 +19138,12 @@ async function runPostAdmissionSeatResume(input) {
18802
19138
  return turnRequest;
18803
19139
  };
18804
19140
  try {
18805
- if (input.env.stationChild === true) {
19141
+ if (input.afterAdmittedPrepare !== void 0) {
19142
+ const prepared = await input.afterAdmittedPrepare(loaded.admitted);
19143
+ if (prepared.env !== void 0) env = prepared.env;
19144
+ preparedCleanup = prepared.cleanup;
19145
+ }
19146
+ if (env.stationChild === true) {
18806
19147
  let firstTurn;
18807
19148
  const stationAdapters = withOnceSuccessfulBeforeDispatch(adapters);
18808
19149
  const invocationScopeId = mintEngineDetourInvocationScope({
@@ -18810,14 +19151,14 @@ async function runPostAdmissionSeatResume(input) {
18810
19151
  });
18811
19152
  return await runWithAutoResumeLoop({
18812
19153
  admitted: loaded.admitted,
18813
- principalAuthority: input.env.principalAuthority,
19154
+ principalAuthority: env.principalAuthority,
18814
19155
  isPrincipalAvailable: resolveHostAwareSessionAvailability(
18815
- input.env.host,
18816
- input.env.principalAuthority
19156
+ env.host,
19157
+ env.principalAuthority
18817
19158
  ),
18818
19159
  io: input.io,
18819
- sessionAppender: input.env.sessionAppender,
18820
- autoResumeLimit: input.env.autoResumeLimit,
19160
+ sessionAppender: env.sessionAppender,
19161
+ autoResumeLimit: env.autoResumeLimit,
18821
19162
  buildInitialPayload: () => ({ resumeTurn: false }),
18822
19163
  buildResumePayload: () => ({ resumeTurn: true }),
18823
19164
  // Same as public manual resume: prior-court sealed acceptance is not a
@@ -18844,7 +19185,7 @@ async function runPostAdmissionSeatResume(input) {
18844
19185
  dispatch: async (turnRequest) => {
18845
19186
  const result = await dispatchPostAdmissionTurn({
18846
19187
  admitted: loaded.admitted,
18847
- env: input.env,
19188
+ env,
18848
19189
  io: attemptIo,
18849
19190
  request: turnRequest,
18850
19191
  lease,
@@ -18854,7 +19195,7 @@ async function runPostAdmissionSeatResume(input) {
18854
19195
  });
18855
19196
  return settleDeferredPersist(
18856
19197
  loaded.admitted,
18857
- input.env.principalAuthority,
19198
+ env.principalAuthority,
18858
19199
  stationAdapters,
18859
19200
  attemptIo,
18860
19201
  result
@@ -18865,7 +19206,7 @@ async function runPostAdmissionSeatResume(input) {
18865
19206
  }
18866
19207
  return await runPostAdmissionManualResume({
18867
19208
  admitted: loaded.admitted,
18868
- env: input.env,
19209
+ env,
18869
19210
  io: input.io,
18870
19211
  adapters,
18871
19212
  ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine },
@@ -18877,6 +19218,10 @@ async function runPostAdmissionSeatResume(input) {
18877
19218
  return { exitCode: 2 };
18878
19219
  }
18879
19220
  throw error;
19221
+ } finally {
19222
+ if (preparedCleanup !== void 0) {
19223
+ await preparedCleanup();
19224
+ }
18880
19225
  }
18881
19226
  }
18882
19227
  async function runPostAdmissionOneShot(input) {
@@ -18889,7 +19234,7 @@ async function runPostAdmissionOneShot(input) {
18889
19234
  ...input.request,
18890
19235
  continuation: {
18891
19236
  kind: "resume",
18892
- prompt: buildResumeContinuationPrompt({
19237
+ prompt: buildAutoResumeContinuationPrompt({
18893
19238
  packageRoot: input.env.packageRoot,
18894
19239
  ...pickEngineAxis({
18895
19240
  engine: input.effectiveEngine ?? input.env.engine,
@@ -19038,7 +19383,7 @@ var init_post_admission = __esm({
19038
19383
 
19039
19384
  // src/public-cli/turn-request.ts
19040
19385
  function projectRoleTurnRequest(admitted, roleDetails, options) {
19041
- const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
19386
+ const cwd = options.cwd ?? admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
19042
19387
  if (cwd === void 0) throw new Error("admitted invocation missing working directory");
19043
19388
  if (admitted.principal === void 0) throw new Error("admitted invocation missing principal");
19044
19389
  return {
@@ -19761,7 +20106,7 @@ async function runPublicJudge(argv, env, io, parseJudgeArgv2) {
19761
20106
  ...admitted.correlationId === void 0 && env.correlationId === void 0 ? {} : { correlationId: admitted.correlationId ?? env.correlationId },
19762
20107
  continuation: {
19763
20108
  kind: "resume",
19764
- prompt: buildResumeContinuationPrompt({
20109
+ prompt: buildAutoResumeContinuationPrompt({
19765
20110
  packageRoot: env.packageRoot,
19766
20111
  ...pickEngineAxis(env)
19767
20112
  })
@@ -20542,32 +20887,362 @@ var init_countersign_run = __esm({
20542
20887
  }
20543
20888
  });
20544
20889
 
20545
- // src/public-role-summons.ts
20546
- var public_role_summons_exports = {};
20547
- __export(public_role_summons_exports, {
20548
- AK_ROLE_PACKAGE_ROOT_ENV: () => AK_ROLE_PACKAGE_ROOT_ENV,
20549
- resolveSummonsPackageRoot: () => resolveSummonsPackageRoot,
20550
- summonGateOfficer: () => summonGateOfficer,
20551
- summonPublicRole: () => summonPublicRole
20890
+ // src/public-cli/reviewer-run.ts
20891
+ var reviewer_run_exports = {};
20892
+ __export(reviewer_run_exports, {
20893
+ buildReviewerTurnRequest: () => buildReviewerTurnRequest,
20894
+ runPublicReviewer: () => runPublicReviewer,
20895
+ runPublicReviewerResume: () => runPublicReviewerResume
20552
20896
  });
20553
- import { existsSync as existsSync11 } from "node:fs";
20554
- import { join as join35 } from "node:path";
20555
- function createCapturingIo() {
20556
- const chunks = [];
20557
- return {
20558
- io: {
20559
- stdout() {
20560
- },
20561
- stderr(text) {
20562
- chunks.push(text);
20563
- }
20564
- },
20565
- stderrText: () => chunks.join("")
20566
- };
20897
+ import { resolve as resolve14 } from "node:path";
20898
+ function reviewerMethods(packageRoot) {
20899
+ return [{ kind: "skill", path: resolvePackagedMethodSkillPath(packageRoot, "ak-cross-m-review") }];
20567
20900
  }
20568
- function parentDir(path) {
20569
- const end = path.endsWith("/") || path.endsWith("\\") ? path.slice(0, -1) : path;
20570
- const idx = Math.max(end.lastIndexOf("/"), end.lastIndexOf("\\"));
20901
+ async function runReviewerTurnInFreshCopy(env, projectRoot, io, body) {
20902
+ if (env.executionCwd !== void 0) {
20903
+ return body(env);
20904
+ }
20905
+ const { withEphemeralReviewerWorktree: withEphemeralReviewerWorktree2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
20906
+ return await withEphemeralReviewerWorktree2({
20907
+ projectRoot,
20908
+ onCleanupDiagnostic: (diagnostic) => {
20909
+ io.stderr(`${diagnostic}
20910
+ `);
20911
+ },
20912
+ run: (executionCwd) => body({ ...env, executionCwd })
20913
+ });
20914
+ }
20915
+ function buildReviewerTurnRequest(admitted, options) {
20916
+ return projectRoleTurnRequest(
20917
+ admitted,
20918
+ {
20919
+ activation: {
20920
+ role: "reviewer",
20921
+ baseRevision: admitted.baseRevision,
20922
+ lens: admitted.lens,
20923
+ authorityRefs: admitted.authorityRefs,
20924
+ ...admitted.ticketNumber === void 0 ? {} : { ticketNumber: admitted.ticketNumber }
20925
+ },
20926
+ methods: reviewerMethods(options.packageRoot)
20927
+ },
20928
+ options
20929
+ );
20930
+ }
20931
+ function reviewerAdapters(packageRoot, methodMaterial) {
20932
+ return {
20933
+ trySettle: (admitted, authority, scope) => methodMaterial === void 0 ? Promise.resolve(void 0) : trySettleReviewerTerminalResult(
20934
+ admitted,
20935
+ authority,
20936
+ {
20937
+ methodProvenance: methodMaterial.provenance,
20938
+ methodSkillPath: methodMaterial.skillPath,
20939
+ methodSkillConfiguredPath: resolvePackagedMethodSkillPath(
20940
+ packageRoot,
20941
+ "ak-cross-m-review"
20942
+ )
20943
+ },
20944
+ scope
20945
+ ),
20946
+ resolveRunnerKnownFailure: async ({ result, sessionFile }) => {
20947
+ const infrastructureFailure = await readEngineDetourInfrastructureFailure(sessionFile);
20948
+ return infrastructureFailure === void 0 ? result.knownFailure : {
20949
+ ...infrastructureFailure.cause === void 0 ? {} : { cause: infrastructureFailure.cause },
20950
+ diagnostic: infrastructureFailure.diagnostic,
20951
+ ...infrastructureFailure.identity === void 0 ? {} : { identity: infrastructureFailure.identity }
20952
+ };
20953
+ }
20954
+ };
20955
+ }
20956
+ async function loadReviewerMethodMaterial(packageRoot) {
20957
+ return await loadPackagedMethodSkillMaterial(packageRoot, "ak-cross-m-review");
20958
+ }
20959
+ function reviewerResumePrompt(env, message) {
20960
+ const lines = [RESUME_TRANSPORT_ENVELOPE];
20961
+ if (message !== void 0) lines.push("", message);
20962
+ return appendEngineSessionMaterial(
20963
+ lines,
20964
+ engineSessionMaterialFromOptions({
20965
+ ...pickEngineAxis(env),
20966
+ packageRoot: env.packageRoot
20967
+ })
20968
+ ).join("\n");
20969
+ }
20970
+ async function runPublicReviewer(argv, env, io, parseReviewerArgv2) {
20971
+ let parsed;
20972
+ try {
20973
+ parsed = parseReviewerArgv2(argv);
20974
+ } catch (error) {
20975
+ if (error instanceof CliUsageError) {
20976
+ presentStructuralRejection(error, io);
20977
+ return { exitCode: 2 };
20978
+ }
20979
+ throw error;
20980
+ }
20981
+ if (parsed.lens === void 0) {
20982
+ const { summonParallelReviewerLenses: summonParallelReviewerLenses2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
20983
+ const children = await summonParallelReviewerLenses2({
20984
+ argv,
20985
+ // Replay argv under the same cwd the single-axis entry would see (10a).
20986
+ // Do not substitute the resolved project path — relative --project must
20987
+ // not be re-resolved against a shifted cwd.
20988
+ cwd: env.cwd,
20989
+ projectRoot: resolve14(parsed.project ?? env.cwd),
20990
+ // Typed base from the public parse — precheck only; child argv stays verbatim.
20991
+ baseRevision: parsed.baseRevision,
20992
+ home: env.home,
20993
+ agentDir: env.agentDir,
20994
+ ...env.credentials === void 0 ? {} : { credentials: env.credentials },
20995
+ ...env.model === void 0 ? {} : { model: env.model },
20996
+ ...env.host === void 0 ? {} : { host: env.host },
20997
+ ...env.engine === void 0 ? {} : { engine: env.engine },
20998
+ ...env.engineModel === void 0 ? {} : { engineModel: env.engineModel },
20999
+ packageRoot: env.packageRoot,
21000
+ ...env.signal === void 0 ? {} : { signal: env.signal },
21001
+ ...env.correlationId === void 0 ? {} : { correlationId: env.correlationId },
21002
+ roleTurnHost: env.roleTurnHost,
21003
+ ...env.hostAdapters === void 0 ? {} : { hostAdapters: env.hostAdapters },
21004
+ principalAuthority: env.principalAuthority,
21005
+ ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs }
21006
+ });
21007
+ const childResults = [children.completeness, children.correctness];
21008
+ const terminals = childResults.map((child) => child.terminal).filter((terminal2) => terminal2 !== void 0);
21009
+ const failedChildren = childResults.filter((child) => child.terminal === void 0 || !isLawfulTypedTerminalOutcome(child.terminal.roleOutcome)).length;
21010
+ const overlayExit = childResults.some((child) => child.exitCode !== 0);
21011
+ const failed = failedChildren > 0 || overlayExit;
21012
+ const overlayDiagnostics = [...new Set(
21013
+ childResults.map((child) => child.stderr).filter((text) => typeof text === "string" && text !== "")
21014
+ )];
21015
+ const terminal = {
21016
+ batch: "reviewer",
21017
+ roleOutcome: failed ? {
21018
+ kind: "failure",
21019
+ role: "reviewer",
21020
+ diagnostic: failedChildren > 0 ? "Reviewer batch child failure" : overlayDiagnostics[0] ?? "Reviewer batch infrastructure failure",
21021
+ decisiveFacts: { failedChildren },
21022
+ payloads: terminals
21023
+ } : { kind: "accepted", role: "reviewer", payloads: terminals },
21024
+ reviewerChildren: {
21025
+ ...children.completeness.terminal === void 0 ? {} : { completeness: children.completeness.terminal },
21026
+ ...children.correctness.terminal === void 0 ? {} : { correctness: children.correctness.terminal }
21027
+ },
21028
+ reviewerChildOutcomes: {
21029
+ completeness: { exitCode: children.completeness.exitCode, ...children.completeness.stderr === void 0 ? {} : { stderr: children.completeness.stderr } },
21030
+ correctness: { exitCode: children.correctness.exitCode, ...children.correctness.stderr === void 0 ? {} : { stderr: children.correctness.stderr } }
21031
+ },
21032
+ // Batch has no parent run and no own attendance; no-advice is affirmative
21033
+ // only (navigator-attendance.ts). Children carry their own navigator facts.
21034
+ navigator: {
21035
+ disposition: "unavailable",
21036
+ source: "unknown",
21037
+ reason: "Reviewer batch has no parent-run Navigator attendance"
21038
+ },
21039
+ artifacts: terminals.flatMap((item) => item.artifacts)
21040
+ };
21041
+ io.stdout(formatTerminalResult(terminal));
21042
+ return { exitCode: failed ? 1 : 0, terminal };
21043
+ }
21044
+ let admitted;
21045
+ try {
21046
+ admitted = await admitReviewerInvocation({
21047
+ home: env.home,
21048
+ principalAuthority: env.principalAuthority,
21049
+ cwd: env.cwd,
21050
+ instruction: parsed.instruction,
21051
+ attachmentPaths: parsed.attachmentPaths,
21052
+ baseRevision: parsed.baseRevision,
21053
+ lens: parsed.lens,
21054
+ authorityRefs: parsed.authorityRefs,
21055
+ ...parsed.project === void 0 ? {} : { project: parsed.project },
21056
+ ...env.createRunId === void 0 ? {} : { createRunId: env.createRunId },
21057
+ ...env.correlationId === void 0 ? {} : { correlationId: env.correlationId },
21058
+ ...env.model === void 0 ? {} : { model: env.model }
21059
+ });
21060
+ } catch (error) {
21061
+ if (error instanceof CliUsageError) {
21062
+ presentStructuralRejection(error, io);
21063
+ return { exitCode: 2 };
21064
+ }
21065
+ throw error;
21066
+ }
21067
+ await markRunAdmitted(admitted, env.principalAuthority);
21068
+ let methodMaterial;
21069
+ try {
21070
+ methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
21071
+ } catch (error) {
21072
+ return await presentControlledFailure2(
21073
+ admitted,
21074
+ {
21075
+ timedOut: false,
21076
+ code: null,
21077
+ stderr: "",
21078
+ thrown: error
21079
+ },
21080
+ reviewerAdapters(env.packageRoot),
21081
+ env.principalAuthority,
21082
+ io
21083
+ );
21084
+ }
21085
+ try {
21086
+ return await runReviewerTurnInFreshCopy(env, admitted.projectRoot, io, async (sandboxedEnv) => await runPostAdmissionResumable({
21087
+ admitted,
21088
+ env: sandboxedEnv,
21089
+ io,
21090
+ buildInitialRequest: () => buildReviewerTurnRequest(admitted, {
21091
+ packageRoot: sandboxedEnv.packageRoot,
21092
+ home: sandboxedEnv.home,
21093
+ agentDir: sandboxedEnv.agentDir,
21094
+ ...sandboxedEnv.model === void 0 ? {} : { model: sandboxedEnv.model },
21095
+ ...pickEngineAxis(sandboxedEnv),
21096
+ ...sandboxedEnv.timeoutMs === void 0 ? {} : { timeoutMs: sandboxedEnv.timeoutMs },
21097
+ ...admitted.correlationId === void 0 && sandboxedEnv.correlationId === void 0 ? {} : { correlationId: admitted.correlationId ?? sandboxedEnv.correlationId },
21098
+ // Ephemeral worktree cwd; durable projectRoot stays on admitted caller project.
21099
+ ...sandboxedEnv.executionCwd === void 0 ? {} : { cwd: sandboxedEnv.executionCwd },
21100
+ continuation: {
21101
+ kind: "initial",
21102
+ prompt: buildReviewerTransportPrompt(
21103
+ admitted,
21104
+ engineSessionMaterialFromOptions({
21105
+ ...pickEngineAxis(sandboxedEnv),
21106
+ packageRoot: sandboxedEnv.packageRoot
21107
+ })
21108
+ )
21109
+ }
21110
+ }),
21111
+ buildResumeRequest: () => buildReviewerTurnRequest(admitted, {
21112
+ packageRoot: sandboxedEnv.packageRoot,
21113
+ home: sandboxedEnv.home,
21114
+ agentDir: sandboxedEnv.agentDir,
21115
+ ...sandboxedEnv.model === void 0 ? {} : { model: sandboxedEnv.model },
21116
+ ...pickEngineAxis(sandboxedEnv),
21117
+ ...sandboxedEnv.timeoutMs === void 0 ? {} : { timeoutMs: sandboxedEnv.timeoutMs },
21118
+ ...admitted.correlationId === void 0 && sandboxedEnv.correlationId === void 0 ? {} : { correlationId: admitted.correlationId ?? sandboxedEnv.correlationId },
21119
+ // In-batch auto-resume keeps the same call's sandbox (dual-lens or single).
21120
+ ...sandboxedEnv.executionCwd === void 0 ? {} : { cwd: sandboxedEnv.executionCwd },
21121
+ continuation: {
21122
+ kind: "resume",
21123
+ prompt: reviewerResumePrompt(sandboxedEnv)
21124
+ }
21125
+ }),
21126
+ adapters: reviewerAdapters(sandboxedEnv.packageRoot, methodMaterial),
21127
+ ...sandboxedEnv.engine === void 0 ? {} : { effectiveEngine: sandboxedEnv.engine }
21128
+ }));
21129
+ } catch (error) {
21130
+ return await presentControlledFailure2(
21131
+ admitted,
21132
+ {
21133
+ timedOut: false,
21134
+ code: null,
21135
+ stderr: "",
21136
+ thrown: error
21137
+ },
21138
+ reviewerAdapters(env.packageRoot, methodMaterial),
21139
+ env.principalAuthority,
21140
+ io
21141
+ );
21142
+ }
21143
+ }
21144
+ async function runPublicReviewerResume(request, env, io) {
21145
+ const sandbox = {
21146
+ ...env.executionCwd === void 0 ? {} : { executionCwd: env.executionCwd }
21147
+ };
21148
+ return await runPostAdmissionSeatResume({
21149
+ request,
21150
+ env,
21151
+ io,
21152
+ load: (effective) => loadResumableReviewerRun(env.home, effective.runId, env.principalAuthority),
21153
+ buildTurnRequest: (admitted, effective) => {
21154
+ const activeEnv = sandbox.executionCwd === void 0 ? env : { ...env, executionCwd: sandbox.executionCwd };
21155
+ const base = resumeTurnRequestProjectionOptions(admitted, effective, activeEnv);
21156
+ return buildReviewerTurnRequest(admitted, {
21157
+ ...base,
21158
+ // Fresh copy at resume time; durable projectRoot unchanged.
21159
+ ...sandbox.executionCwd === void 0 ? {} : { cwd: sandbox.executionCwd },
21160
+ continuation: {
21161
+ kind: "resume",
21162
+ prompt: reviewerResumePrompt(activeEnv, effective.message)
21163
+ }
21164
+ });
21165
+ },
21166
+ adapters: reviewerAdapters(env.packageRoot),
21167
+ afterAdmittedLoad: async (admitted) => {
21168
+ return resolveResumeMethodMaterialAdapters({
21169
+ admitted,
21170
+ authority: env.principalAuthority,
21171
+ io,
21172
+ loadMaterial: () => loadReviewerMethodMaterial(env.packageRoot),
21173
+ adaptersWith: (material) => reviewerAdapters(env.packageRoot, material),
21174
+ emptyAdapters: reviewerAdapters(env.packageRoot)
21175
+ });
21176
+ },
21177
+ afterAdmittedPrepare: async (admitted) => {
21178
+ if (sandbox.executionCwd !== void 0) {
21179
+ return { env: { ...env, executionCwd: sandbox.executionCwd } };
21180
+ }
21181
+ const { openEphemeralReviewerWorktree: openEphemeralReviewerWorktree2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
21182
+ const opened = await openEphemeralReviewerWorktree2({
21183
+ projectRoot: admitted.projectRoot,
21184
+ onCleanupDiagnostic: (diagnostic) => {
21185
+ io.stderr(`${diagnostic}
21186
+ `);
21187
+ }
21188
+ });
21189
+ sandbox.executionCwd = opened.executionCwd;
21190
+ return {
21191
+ env: { ...env, executionCwd: opened.executionCwd },
21192
+ cleanup: opened.close
21193
+ };
21194
+ },
21195
+ ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
21196
+ });
21197
+ }
21198
+ var init_reviewer_run = __esm({
21199
+ "src/public-cli/reviewer-run.ts"() {
21200
+ "use strict";
21201
+ init_engine_material();
21202
+ init_method_skill();
21203
+ init_cli_errors();
21204
+ init_invocation();
21205
+ init_run_lifecycle();
21206
+ init_settlement();
21207
+ init_terminal();
21208
+ init_turn_request();
21209
+ init_post_admission();
21210
+ }
21211
+ });
21212
+
21213
+ // src/public-role-summons.ts
21214
+ var public_role_summons_exports = {};
21215
+ __export(public_role_summons_exports, {
21216
+ AK_ROLE_PACKAGE_ROOT_ENV: () => AK_ROLE_PACKAGE_ROOT_ENV,
21217
+ openEphemeralReviewerWorktree: () => openEphemeralReviewerWorktree,
21218
+ resolveSummonsPackageRoot: () => resolveSummonsPackageRoot,
21219
+ summonGateOfficer: () => summonGateOfficer,
21220
+ summonParallelReviewerLenses: () => summonParallelReviewerLenses,
21221
+ summonPublicRole: () => summonPublicRole,
21222
+ withEphemeralReviewerWorktree: () => withEphemeralReviewerWorktree
21223
+ });
21224
+ import { execFile as execFile3 } from "node:child_process";
21225
+ import { existsSync as existsSync11 } from "node:fs";
21226
+ import { mkdir as mkdir5, mkdtemp as mkdtemp4, realpath as realpath6, rm as rm4 } from "node:fs/promises";
21227
+ import { tmpdir as tmpdir4 } from "node:os";
21228
+ import { join as join35, relative as relative3, sep as sep5 } from "node:path";
21229
+ import { promisify as promisify3 } from "node:util";
21230
+ function createCapturingIo() {
21231
+ const chunks = [];
21232
+ return {
21233
+ io: {
21234
+ stdout() {
21235
+ },
21236
+ stderr(text) {
21237
+ chunks.push(text);
21238
+ }
21239
+ },
21240
+ stderrText: () => chunks.join("")
21241
+ };
21242
+ }
21243
+ function parentDir(path) {
21244
+ const end = path.endsWith("/") || path.endsWith("\\") ? path.slice(0, -1) : path;
21245
+ const idx = Math.max(end.lastIndexOf("/"), end.lastIndexOf("\\"));
20571
21246
  if (idx <= 0) return end;
20572
21247
  return end.slice(0, idx);
20573
21248
  }
@@ -20639,13 +21314,14 @@ async function createSummonEnv(options, afterHost) {
20639
21314
  Promise.resolve().then(() => (init_role_turn_host_resolution(), role_turn_host_resolution_exports)),
20640
21315
  Promise.resolve().then(() => (init_config(), config_exports))
20641
21316
  ]);
20642
- const principalAuthority = piDurablePrincipalAuthority2;
21317
+ const principalAuthority = options.principalAuthority ?? piDurablePrincipalAuthority2;
20643
21318
  const roleTurnHost = resolveRoleTurnHost2(
20644
21319
  {
20645
21320
  packageRoot: options.packageRoot,
20646
21321
  ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
20647
21322
  ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
20648
- ...options.extraPiArgs === void 0 || options.extraPiArgs.length === 0 ? {} : { extraPiArgs: options.extraPiArgs }
21323
+ ...options.extraPiArgs === void 0 || options.extraPiArgs.length === 0 ? {} : { extraPiArgs: options.extraPiArgs },
21324
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
20649
21325
  },
20650
21326
  { role: options.role, seat: options.seat, principalAuthority }
20651
21327
  );
@@ -20658,13 +21334,16 @@ async function createSummonEnv(options, afterHost) {
20658
21334
  };
20659
21335
  }
20660
21336
  const hostName = seatWithModel.host ?? "pi";
20661
- const { loadHostProvidersTable: loadHostProvidersTable2, projectHostFacingProvider: projectHostFacingProvider2 } = await Promise.resolve().then(() => (init_host_providers(), host_providers_exports));
20662
- const hostFacingSelection = projectHostFacingProvider2(
20663
- seatWithModel.selection,
20664
- hostName,
20665
- loadHostProvidersTable2(options.home),
20666
- options.home
20667
- );
21337
+ let hostFacingSelection = options.hostFacingModel;
21338
+ if (hostFacingSelection === void 0) {
21339
+ const { loadHostProvidersTable: loadHostProvidersTable2, projectHostFacingProvider: projectHostFacingProvider2 } = await Promise.resolve().then(() => (init_host_providers(), host_providers_exports));
21340
+ hostFacingSelection = projectHostFacingProvider2(
21341
+ seatWithModel.selection,
21342
+ hostName,
21343
+ loadHostProvidersTable2(options.home),
21344
+ options.home
21345
+ );
21346
+ }
20668
21347
  return {
20669
21348
  ok: true,
20670
21349
  env: {
@@ -20678,7 +21357,8 @@ async function createSummonEnv(options, afterHost) {
20678
21357
  credentials: options.credentials,
20679
21358
  ...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
20680
21359
  ...projectSeatEngine(seatWithModel),
20681
- ...projectSeatHost(seatWithModel)
21360
+ ...projectSeatHost(seatWithModel),
21361
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
20682
21362
  }
20683
21363
  };
20684
21364
  }
@@ -20693,7 +21373,19 @@ async function summonPublicRole(options) {
20693
21373
  } = await Promise.resolve().then(() => (init_config(), config_exports));
20694
21374
  const credentials = options.credentials ?? await loadCredentialProviders2(agentDir);
20695
21375
  const config = await loadPublicCliConfig2(home);
20696
- const seat = resolveEffectiveSeat2(config, options.role, credentials);
21376
+ const resolvedSeat = resolveEffectiveSeat2(config, options.role, credentials);
21377
+ const inheritedSelection = options.model === void 0 ? void 0 : {
21378
+ provider: options.model.provider,
21379
+ model: options.model.model,
21380
+ ...options.model.thinking === void 0 ? {} : { thinking: options.model.thinking }
21381
+ };
21382
+ const seat = {
21383
+ ...resolvedSeat,
21384
+ ...inheritedSelection === void 0 ? {} : { selection: inheritedSelection, source: "invocation" },
21385
+ ...options.host === void 0 ? {} : { host: options.host, hostSource: "invocation" },
21386
+ ...options.engine === void 0 ? {} : { engine: options.engine, engineSource: "invocation" },
21387
+ ...options.engineModel === void 0 ? {} : { engineModel: options.engineModel }
21388
+ };
20697
21389
  const captured = options.io === void 0 ? createCapturingIo() : void 0;
20698
21390
  const io = options.io ?? captured.io;
20699
21391
  const summonEnvInput = {
@@ -20706,7 +21398,11 @@ async function summonPublicRole(options) {
20706
21398
  seat,
20707
21399
  ...options.extraPiArgs === void 0 ? {} : { extraPiArgs: options.extraPiArgs },
20708
21400
  ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
20709
- ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters }
21401
+ ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
21402
+ ...options.principalAuthority === void 0 ? {} : { principalAuthority: options.principalAuthority },
21403
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
21404
+ // Parent model is already host-facing; child must not project again.
21405
+ ...options.model === void 0 ? {} : { hostFacingModel: options.model }
20710
21406
  };
20711
21407
  async function prepareSummonEnv(afterHost) {
20712
21408
  try {
@@ -20718,7 +21414,9 @@ async function summonPublicRole(options) {
20718
21414
  ok: true,
20719
21415
  env: {
20720
21416
  ...built.env,
20721
- stationChild: true,
21417
+ // Nested court stations keep station-child semantics; dual-lens
21418
+ // ordinary Reviewer axes opt out (#946 / ADR 0082).
21419
+ ...options.stationChild === false ? {} : { stationChild: true },
20722
21420
  // Forward composition-root adapters so nested court stations (e.g.
20723
21421
  // countersign → diarist) select the same faux/production table (#924).
20724
21422
  ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
@@ -20728,7 +21426,8 @@ async function summonPublicRole(options) {
20728
21426
  ...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
20729
21427
  ...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
20730
21428
  ...options.correlationId === void 0 || options.correlationId.trim() === "" ? {} : { correlationId: options.correlationId },
20731
- ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
21429
+ ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId },
21430
+ ...options.executionCwd === void 0 ? {} : { executionCwd: options.executionCwd }
20732
21431
  }
20733
21432
  };
20734
21433
  } catch (error) {
@@ -20790,14 +21489,32 @@ async function summonPublicRole(options) {
20790
21489
  case "navigator":
20791
21490
  case "gatekeeper": {
20792
21491
  const seat2 = options.role;
20793
- const [{ runPublicInstructionSeat: runPublicInstructionSeat2 }, invocation] = await Promise.all([
21492
+ const [{ runPublicInstructionSeat: runPublicInstructionSeat2, runPublicInstructionSeatResume: runPublicInstructionSeatResume2 }, invocation] = await Promise.all([
20794
21493
  Promise.resolve().then(() => (init_instruction_seat_run(), instruction_seat_run_exports)),
20795
21494
  Promise.resolve().then(() => (init_invocation(), invocation_exports))
20796
21495
  ]);
20797
21496
  const parse = seat2 === "auditor" ? invocation.parseAuditorArgv : seat2 === "navigator" ? invocation.parseNavigatorArgv : invocation.parseGatekeeperArgv;
20798
- const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat2(options.argv, env, io, seat2, once));
20799
- if ("fail" in stepped) return stepped.fail;
20800
- result = stepped.ok;
21497
+ const resumeRunId = typeof options.resumeRunId === "string" && options.resumeRunId.trim() !== "" ? options.resumeRunId.trim() : void 0;
21498
+ if (resumeRunId !== void 0) {
21499
+ const instruction = options.argv[0] ?? "";
21500
+ const stepped = await runPrepared(parse, (env) => runPublicInstructionSeatResume2(
21501
+ {
21502
+ runId: resumeRunId,
21503
+ summons: {
21504
+ instruction,
21505
+ instructionEmpty: instruction.trim() === ""
21506
+ }
21507
+ },
21508
+ env,
21509
+ io
21510
+ ));
21511
+ if ("fail" in stepped) return stepped.fail;
21512
+ result = stepped.ok;
21513
+ } else {
21514
+ const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat2(options.argv, env, io, seat2, once));
21515
+ if ("fail" in stepped) return stepped.fail;
21516
+ result = stepped.ok;
21517
+ }
20801
21518
  break;
20802
21519
  }
20803
21520
  case "judge": {
@@ -20840,6 +21557,16 @@ async function summonPublicRole(options) {
20840
21557
  result = stepped.ok;
20841
21558
  break;
20842
21559
  }
21560
+ case "reviewer": {
21561
+ const [{ runPublicReviewer: runPublicReviewer2 }, { parseReviewerArgv: parseReviewerArgv2 }] = await Promise.all([
21562
+ Promise.resolve().then(() => (init_reviewer_run(), reviewer_run_exports)),
21563
+ Promise.resolve().then(() => (init_invocation(), invocation_exports))
21564
+ ]);
21565
+ const stepped = await runPrepared(parseReviewerArgv2, (env, once) => runPublicReviewer2(options.argv, env, io, once));
21566
+ if ("fail" in stepped) return stepped.fail;
21567
+ result = stepped.ok;
21568
+ break;
21569
+ }
20843
21570
  }
20844
21571
  const stderr = captured?.stderrText();
20845
21572
  const runDirectory = result.admitted?.runDirectory;
@@ -20851,6 +21578,296 @@ async function summonPublicRole(options) {
20851
21578
  ...stderr === void 0 || stderr === "" ? {} : { stderr }
20852
21579
  };
20853
21580
  }
21581
+ function withReviewerLens(argv, lens) {
21582
+ const separator = argv.indexOf("--");
21583
+ if (separator === -1) return [...argv, "--lens", lens];
21584
+ return [...argv.slice(0, separator), "--lens", lens, ...argv.slice(separator)];
21585
+ }
21586
+ async function resolveReviewerWorktreeRoots(projectRoot) {
21587
+ const callerProjectRoot = await realpath6(projectRoot);
21588
+ const sourceProjectRoot = await realpath6((await execFileAsync3(
21589
+ "git",
21590
+ ["rev-parse", "--show-toplevel"],
21591
+ { cwd: callerProjectRoot }
21592
+ )).stdout.trim());
21593
+ const callerRelative = relative3(sourceProjectRoot, callerProjectRoot);
21594
+ const projectRelative = callerRelative === "" || callerRelative === "." || callerRelative.startsWith(`..${sep5}`) || callerRelative === ".." ? "" : callerRelative;
21595
+ return { callerProjectRoot, sourceProjectRoot, projectRelative };
21596
+ }
21597
+ function reviewerSandboxPath(worktreeAxis, projectRelative) {
21598
+ return projectRelative === "" ? worktreeAxis : join35(worktreeAxis, projectRelative);
21599
+ }
21600
+ async function openEphemeralReviewerWorktree(options) {
21601
+ const { sourceProjectRoot, projectRelative } = await resolveReviewerWorktreeRoots(
21602
+ options.projectRoot
21603
+ );
21604
+ const { stdout: headStdout } = await execFileAsync3(
21605
+ "git",
21606
+ ["rev-parse", "--verify", "HEAD^{commit}"],
21607
+ { cwd: sourceProjectRoot }
21608
+ );
21609
+ const targetCommit = headStdout.trim();
21610
+ const root = await mkdtemp4(join35(tmpdir4(), "ak-reviewer-sandbox-"));
21611
+ const worktreeRoot = join35(root, "work");
21612
+ let registered = false;
21613
+ const rollback = async (cause) => {
21614
+ const cleanupErrors = [];
21615
+ if (registered) {
21616
+ try {
21617
+ await execFileAsync3("git", ["worktree", "remove", "--force", worktreeRoot], {
21618
+ cwd: sourceProjectRoot
21619
+ });
21620
+ } catch (error) {
21621
+ cleanupErrors.push(error);
21622
+ }
21623
+ }
21624
+ try {
21625
+ await rm4(root, { recursive: true, force: true });
21626
+ } catch (error) {
21627
+ cleanupErrors.push(error);
21628
+ }
21629
+ if (cleanupErrors.length > 0) {
21630
+ options.onCleanupDiagnostic?.([
21631
+ "reviewer worktree cleanup failed",
21632
+ ...cleanupErrors.map((error) => error instanceof Error ? error.message : String(error))
21633
+ ].join("\n"));
21634
+ }
21635
+ throw cause;
21636
+ };
21637
+ try {
21638
+ await execFileAsync3("git", ["worktree", "add", "--detach", worktreeRoot, targetCommit], {
21639
+ cwd: sourceProjectRoot
21640
+ });
21641
+ registered = true;
21642
+ if (projectRelative !== "") {
21643
+ await mkdir5(reviewerSandboxPath(worktreeRoot, projectRelative), { recursive: true });
21644
+ }
21645
+ } catch (error) {
21646
+ await rollback(error);
21647
+ }
21648
+ let closed = false;
21649
+ return {
21650
+ executionCwd: reviewerSandboxPath(worktreeRoot, projectRelative),
21651
+ close: async () => {
21652
+ if (closed) return;
21653
+ closed = true;
21654
+ const cleanupErrors = [];
21655
+ try {
21656
+ await execFileAsync3("git", ["worktree", "remove", worktreeRoot], {
21657
+ cwd: sourceProjectRoot
21658
+ });
21659
+ } catch (error) {
21660
+ cleanupErrors.push(error);
21661
+ }
21662
+ try {
21663
+ await rm4(root, { recursive: true, force: true });
21664
+ } catch (error) {
21665
+ cleanupErrors.push(error);
21666
+ }
21667
+ if (cleanupErrors.length > 0) {
21668
+ options.onCleanupDiagnostic?.([
21669
+ "reviewer worktree cleanup failed",
21670
+ ...cleanupErrors.map((error) => error instanceof Error ? error.message : String(error))
21671
+ ].join("\n"));
21672
+ }
21673
+ }
21674
+ };
21675
+ }
21676
+ async function withEphemeralReviewerWorktree(options) {
21677
+ const sandbox = await openEphemeralReviewerWorktree({
21678
+ projectRoot: options.projectRoot,
21679
+ ...options.onCleanupDiagnostic === void 0 ? {} : { onCleanupDiagnostic: options.onCleanupDiagnostic }
21680
+ });
21681
+ try {
21682
+ return await options.run(sandbox.executionCwd);
21683
+ } finally {
21684
+ await sandbox.close();
21685
+ }
21686
+ }
21687
+ async function summonParallelReviewerLenses(options) {
21688
+ const describeFailure = (error) => {
21689
+ if (error instanceof AggregateError) {
21690
+ return [error.message, ...error.errors.map(describeFailure)].join("\n");
21691
+ }
21692
+ return error instanceof Error ? error.message : String(error);
21693
+ };
21694
+ const failedResult = (error) => ({
21695
+ exitCode: 1,
21696
+ stderr: describeFailure(error)
21697
+ });
21698
+ const dualFailure = (error) => {
21699
+ const failure2 = failedResult(error);
21700
+ return { completeness: failure2, correctness: failure2 };
21701
+ };
21702
+ let sourceProjectRoot;
21703
+ let projectRelative;
21704
+ let targetCommit;
21705
+ const statusArgs = [
21706
+ "status",
21707
+ "--porcelain=v1",
21708
+ "--untracked-files=all",
21709
+ "--",
21710
+ ":/",
21711
+ ":(top,exclude).claude/worktrees/**"
21712
+ ];
21713
+ try {
21714
+ const roots = await resolveReviewerWorktreeRoots(options.projectRoot);
21715
+ sourceProjectRoot = roots.sourceProjectRoot;
21716
+ projectRelative = roots.projectRelative;
21717
+ const { stdout: statusStdout } = await execFileAsync3("git", statusArgs, {
21718
+ cwd: sourceProjectRoot
21719
+ });
21720
+ if (statusStdout !== "") {
21721
+ const diagnostic = [
21722
+ "Reviewer target status gate failed:",
21723
+ "git status --porcelain=v1 --untracked-files=all -- :/ ':(top,exclude).claude/worktrees/**'",
21724
+ statusStdout
21725
+ ].join("\n");
21726
+ return dualFailure(new Error(diagnostic));
21727
+ }
21728
+ const { stdout: targetStdout } = await execFileAsync3(
21729
+ "git",
21730
+ ["rev-parse", "--verify", "HEAD^{commit}"],
21731
+ { cwd: sourceProjectRoot }
21732
+ );
21733
+ targetCommit = targetStdout.trim();
21734
+ await execFileAsync3(
21735
+ "git",
21736
+ ["rev-parse", "--verify", `${options.baseRevision}^{commit}`],
21737
+ { cwd: sourceProjectRoot }
21738
+ );
21739
+ } catch (error) {
21740
+ return dualFailure(error);
21741
+ }
21742
+ const root = await mkdtemp4(join35(tmpdir4(), "ak-reviewer-lenses-"));
21743
+ const completenessRoot = join35(root, "completeness");
21744
+ const correctnessRoot = join35(root, "correctness");
21745
+ const worktrees = [completenessRoot, correctnessRoot];
21746
+ const created = /* @__PURE__ */ new Set();
21747
+ let results;
21748
+ const creation = await Promise.allSettled(
21749
+ worktrees.map(async (path) => {
21750
+ await execFileAsync3("git", ["worktree", "add", "--detach", path, targetCommit], {
21751
+ cwd: sourceProjectRoot
21752
+ });
21753
+ created.add(path);
21754
+ if (projectRelative !== "") {
21755
+ await mkdir5(reviewerSandboxPath(path, projectRelative), { recursive: true });
21756
+ }
21757
+ })
21758
+ );
21759
+ const creationFailures = creation.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
21760
+ if (creationFailures.length > 0) {
21761
+ const failure2 = failedResult(new AggregateError(
21762
+ creationFailures,
21763
+ "parallel reviewer worktree creation failed"
21764
+ ));
21765
+ results = { completeness: failure2, correctness: failure2 };
21766
+ } else {
21767
+ const summon = (lens, worktreeAxis) => {
21768
+ const sandbox = reviewerSandboxPath(worktreeAxis, projectRelative);
21769
+ return summonPublicRole({
21770
+ role: "reviewer",
21771
+ argv: withReviewerLens(options.argv, lens),
21772
+ cwd: options.cwd,
21773
+ executionCwd: sandbox,
21774
+ // Ordinary single-axis public semantics — not a nested court station.
21775
+ stationChild: false,
21776
+ home: options.home,
21777
+ ...options.agentDir === void 0 ? {} : { agentDir: options.agentDir },
21778
+ ...options.credentials === void 0 ? {} : { credentials: options.credentials },
21779
+ ...options.model === void 0 ? {} : { model: options.model },
21780
+ ...options.host === void 0 ? {} : { host: options.host },
21781
+ ...options.engine === void 0 ? {} : { engine: options.engine },
21782
+ ...options.engineModel === void 0 ? {} : { engineModel: options.engineModel },
21783
+ ...options.signal === void 0 ? {} : { signal: options.signal },
21784
+ ...options.correlationId === void 0 ? {} : { correlationId: options.correlationId },
21785
+ ...options.packageRoot === void 0 ? {} : { packageRoot: options.packageRoot },
21786
+ ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
21787
+ ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
21788
+ ...options.principalAuthority === void 0 ? {} : { principalAuthority: options.principalAuthority },
21789
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
21790
+ });
21791
+ };
21792
+ const settled = await Promise.allSettled([
21793
+ summon("completeness", completenessRoot),
21794
+ summon("correctness", correctnessRoot)
21795
+ ]);
21796
+ results = {
21797
+ completeness: settled[0].status === "fulfilled" ? settled[0].value : failedResult(settled[0].reason),
21798
+ correctness: settled[1].status === "fulfilled" ? settled[1].value : failedResult(settled[1].reason)
21799
+ };
21800
+ }
21801
+ let sealDiagnostic;
21802
+ try {
21803
+ const { stdout: headBeforeStdout } = await execFileAsync3(
21804
+ "git",
21805
+ ["rev-parse", "--verify", "HEAD^{commit}"],
21806
+ { cwd: sourceProjectRoot }
21807
+ );
21808
+ const { stdout: sealedStatusStdout } = await execFileAsync3("git", statusArgs, {
21809
+ cwd: sourceProjectRoot
21810
+ });
21811
+ const { stdout: headAfterStdout } = await execFileAsync3(
21812
+ "git",
21813
+ ["rev-parse", "--verify", "HEAD^{commit}"],
21814
+ { cwd: sourceProjectRoot }
21815
+ );
21816
+ const headBefore = headBeforeStdout.trim();
21817
+ const headAfter = headAfterStdout.trim();
21818
+ if (headBefore !== targetCommit || headAfter !== targetCommit || sealedStatusStdout !== "") {
21819
+ sealDiagnostic = [
21820
+ "Reviewer target final seal failed:",
21821
+ `HEAD before status => ${headBefore}`,
21822
+ `HEAD after status => ${headAfter}`,
21823
+ `expected PRE_HEAD ${targetCommit}`,
21824
+ "git status --porcelain=v1 --untracked-files=all -- :/ ':(top,exclude).claude/worktrees/**'",
21825
+ sealedStatusStdout
21826
+ ].join("\n");
21827
+ }
21828
+ } catch (error) {
21829
+ sealDiagnostic = `Reviewer target final seal failed:
21830
+ ${describeFailure(error)}`;
21831
+ }
21832
+ if (sealDiagnostic !== void 0) {
21833
+ const withSealFailure = (result) => ({
21834
+ ...result,
21835
+ exitCode: 1,
21836
+ stderr: [result.stderr, sealDiagnostic].filter(
21837
+ (text) => typeof text === "string" && text !== ""
21838
+ ).join("\n")
21839
+ });
21840
+ results = {
21841
+ completeness: withSealFailure(results.completeness),
21842
+ correctness: withSealFailure(results.correctness)
21843
+ };
21844
+ }
21845
+ const cleanup = await Promise.allSettled(
21846
+ [...created].map((path) => execFileAsync3("git", ["worktree", "remove", path], { cwd: sourceProjectRoot }))
21847
+ );
21848
+ const cleanupFailures = cleanup.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
21849
+ if (cleanupFailures.length === 0) {
21850
+ const rootCleanup = await Promise.allSettled([rm4(root, { recursive: true, force: true })]);
21851
+ cleanupFailures.push(...rootCleanup.flatMap((result) => result.status === "rejected" ? [result.reason] : []));
21852
+ }
21853
+ if (cleanupFailures.length > 0) {
21854
+ const diagnostic = [
21855
+ "parallel reviewer worktree cleanup failed",
21856
+ ...cleanupFailures.map((failure2) => failure2 instanceof Error ? failure2.message : String(failure2))
21857
+ ].join("\n");
21858
+ const withCleanupDiagnostic = (result) => ({
21859
+ ...result,
21860
+ stderr: [result.stderr, diagnostic].filter(
21861
+ (text) => typeof text === "string" && text !== ""
21862
+ ).join("\n")
21863
+ });
21864
+ results = {
21865
+ completeness: withCleanupDiagnostic(results.completeness),
21866
+ correctness: withCleanupDiagnostic(results.correctness)
21867
+ };
21868
+ }
21869
+ return results;
21870
+ }
20854
21871
  async function summonGateOfficer(options) {
20855
21872
  let home = options.home;
20856
21873
  if (home === void 0) {
@@ -20900,22 +21917,23 @@ async function summonGateOfficer(options) {
20900
21917
  ...common
20901
21918
  });
20902
21919
  }
20903
- var AK_ROLE_PACKAGE_ROOT_ENV;
21920
+ var AK_ROLE_PACKAGE_ROOT_ENV, execFileAsync3;
20904
21921
  var init_public_role_summons = __esm({
20905
21922
  "src/public-role-summons.ts"() {
20906
21923
  "use strict";
20907
21924
  init_engine_material();
20908
21925
  AK_ROLE_PACKAGE_ROOT_ENV = "AK_ROLE_PACKAGE_ROOT";
21926
+ execFileAsync3 = promisify3(execFile3);
20909
21927
  }
20910
21928
  });
20911
21929
 
20912
21930
  // src/acp-host/production-host.ts
20913
- import { randomUUID as randomUUID9 } from "node:crypto";
21931
+ import { randomUUID as randomUUID10 } from "node:crypto";
20914
21932
 
20915
21933
  // src/role-envelope.ts
20916
21934
  init_engine_detour();
20917
- import { randomUUID as randomUUID8 } from "node:crypto";
20918
- import { mkdir as mkdir6, writeFile as writeFile12 } from "node:fs/promises";
21935
+ import { randomUUID as randomUUID9 } from "node:crypto";
21936
+ import { appendFile as appendFile3, mkdir as mkdir7, writeFile as writeFile12 } from "node:fs/promises";
20919
21937
  import { createServer } from "node:net";
20920
21938
  import { dirname as dirname22, join as join41 } from "node:path";
20921
21939
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -21003,7 +22021,7 @@ async function requireGatekeeperPass(options) {
21003
22021
  }
21004
22022
 
21005
22023
  // src/host-native-method.ts
21006
- import { lstat as lstat7, mkdir as mkdir5, readlink, realpath as realpath6, symlink } from "node:fs/promises";
22024
+ import { lstat as lstat7, mkdir as mkdir6, readlink, realpath as realpath7, symlink } from "node:fs/promises";
21007
22025
  import { basename as basename9, dirname as dirname18, join as join36 } from "node:path";
21008
22026
  var packagedMethodsDir = (root) => join36(root, "resources", "methods");
21009
22027
  function hostMethodSkills(methods) {
@@ -21014,11 +22032,11 @@ function hostMethodSkills(methods) {
21014
22032
  }));
21015
22033
  }
21016
22034
  async function installWorkspaceMethodSkills(cwd, packageRoot) {
21017
- const target = await realpath6(packagedMethodsDir(packageRoot));
22035
+ const target = await realpath7(packagedMethodsDir(packageRoot));
21018
22036
  const link = join36(cwd, ".agents", "skills");
21019
22037
  try {
21020
22038
  const stat2 = await lstat7(link);
21021
- if (!stat2.isSymbolicLink() || await realpath6(link) !== target) {
22039
+ if (!stat2.isSymbolicLink() || await realpath7(link) !== target) {
21022
22040
  const detail = stat2.isSymbolicLink() ? `symlink to ${await readlink(link)}` : "non-symlink entry";
21023
22041
  throw new Error(`workspace method catalog conflict at ${link}: ${detail}`);
21024
22042
  }
@@ -21026,12 +22044,12 @@ async function installWorkspaceMethodSkills(cwd, packageRoot) {
21026
22044
  } catch (error) {
21027
22045
  if (error.code !== "ENOENT") throw error;
21028
22046
  }
21029
- await mkdir5(dirname18(link), { recursive: true });
22047
+ await mkdir6(dirname18(link), { recursive: true });
21030
22048
  try {
21031
22049
  await symlink(target, link);
21032
22050
  } catch (error) {
21033
22051
  if (error.code !== "EEXIST") throw error;
21034
- if (await realpath6(link).catch(() => "") !== target) {
22052
+ if (await realpath7(link).catch(() => "") !== target) {
21035
22053
  throw new Error(`workspace method catalog conflict at ${link}`);
21036
22054
  }
21037
22055
  }
@@ -21045,6 +22063,7 @@ init_host_contracts();
21045
22063
  init_sitian_facade();
21046
22064
  init_submission_ledger();
21047
22065
  init_collector_ledger();
22066
+ import { randomUUID as randomUUID8 } from "node:crypto";
21048
22067
  import { readFileSync as readFileSync6, writeSync as writeSync4 } from "node:fs";
21049
22068
  import { join as join40 } from "node:path";
21050
22069
  import { Value as Value4 } from "typebox/value";
@@ -21096,7 +22115,7 @@ import {
21096
22115
  openSync as openSync2,
21097
22116
  writeSync
21098
22117
  } from "node:fs";
21099
- import { dirname as dirname19, isAbsolute as isAbsolute10, resolve as resolve15 } from "node:path";
22118
+ import { dirname as dirname19, isAbsolute as isAbsolute10, resolve as resolve16 } from "node:path";
21100
22119
 
21101
22120
  // src/activation-ledger-session.ts
21102
22121
  init_activation_ledger_topology();
@@ -21106,7 +22125,7 @@ import {
21106
22125
  statSync as statSync4,
21107
22126
  writeFileSync as writeFileSync3
21108
22127
  } from "node:fs";
21109
- import { isAbsolute as isAbsolute9, resolve as resolve14 } from "node:path";
22128
+ import { isAbsolute as isAbsolute9, resolve as resolve15 } from "node:path";
21110
22129
  var ActivationSessionFileMissingError = class extends Error {
21111
22130
  code = "AK_ACTIVATION_SESSION_FILE_MISSING";
21112
22131
  path;
@@ -21151,7 +22170,7 @@ function durableSessionPointer(sessionManager) {
21151
22170
  `Workflow role activation requires an absolute durable session file path; got relative path: ${file}`
21152
22171
  );
21153
22172
  }
21154
- const resolvedFile = resolve14(file);
22173
+ const resolvedFile = resolve15(file);
21155
22174
  try {
21156
22175
  lstatSync2(resolvedFile);
21157
22176
  } catch (error) {
@@ -21243,8 +22262,8 @@ function appendActivationLedgerLine(ledgerPath, line2, options) {
21243
22262
  `activation ledger home must be absolute: ${options.ledgerHome}`
21244
22263
  );
21245
22264
  }
21246
- const resolvedLedger = resolve15(ledgerPath);
21247
- const resolvedHome = resolve15(options.ledgerHome);
22265
+ const resolvedLedger = resolve16(ledgerPath);
22266
+ const resolvedHome = resolve16(options.ledgerHome);
21248
22267
  const parent = dirname19(resolvedLedger);
21249
22268
  ensureRealDirectoryTree(resolvedHome, parent);
21250
22269
  assertLedgerFileInsideHome(resolvedLedger, resolvedHome);
@@ -21605,11 +22624,11 @@ init_collector_github();
21605
22624
 
21606
22625
  // src/collector-handbook.ts
21607
22626
  import { readFile as readFile19 } from "node:fs/promises";
21608
- import { join as join38, sep as sep5 } from "node:path";
22627
+ import { join as join38, sep as sep6 } from "node:path";
21609
22628
 
21610
22629
  // src/atomic-write.ts
21611
22630
  import { randomUUID as randomUUID7 } from "node:crypto";
21612
- import { rename as rename3, rm as rm4, writeFile as writeFile11 } from "node:fs/promises";
22631
+ import { rename as rename3, rm as rm5, writeFile as writeFile11 } from "node:fs/promises";
21613
22632
  import { dirname as dirname20, join as join37 } from "node:path";
21614
22633
  async function writeFileAtomically(destination, contents) {
21615
22634
  const parent = dirname20(destination);
@@ -21618,7 +22637,7 @@ async function writeFileAtomically(destination, contents) {
21618
22637
  await writeFile11(temporary, contents);
21619
22638
  await rename3(temporary, destination);
21620
22639
  } catch (error) {
21621
- await rm4(temporary, { force: true }).catch(() => void 0);
22640
+ await rm5(temporary, { force: true }).catch(() => void 0);
21622
22641
  throw error;
21623
22642
  }
21624
22643
  }
@@ -21719,7 +22738,7 @@ function resolveCollectorHandbookRoot(sessionPath) {
21719
22738
  if (typeof sessionPath !== "string" || sessionPath.trim().length === 0) {
21720
22739
  throw new Error("\u901A\u8FDB\u53F8\u624B\u518C\u8981\u6C42\u975E\u7A7A session \u8DEF\u5F84\uFF0C\u4E14\u4F4D\u4E8E books/<bookKey>/");
21721
22740
  }
21722
- const segments = sessionPath.split(sep5);
22741
+ const segments = sessionPath.split(sep6);
21723
22742
  let bookKey;
21724
22743
  for (let i = 0; i + 3 < segments.length; i += 1) {
21725
22744
  if (segments[i] === ".ak-roles" && segments[i + 1] === "books") {
@@ -22891,7 +23910,7 @@ init_navigator_output();
22891
23910
  var NAVIGATOR_TOOL_SPEC = {
22892
23911
  name: NAVIGATOR_OUTPUT_TOOL_NAME,
22893
23912
  label: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
22894
- description: "\u6E38\u5955\u4F7F\u7EC8\u5C40\u56DE\u6267\uFF1A\u6392\u597D\u5E8F\u7684\u4E0B\u4E00\u6B65\u89D2\u8272\u8DEF\u7EBF\u5EFA\u8BAE\u3002",
23913
+ description: "\u6E38\u5955\u4F7F\u7EC8\u5C40\u56DE\u6267\uFF1A\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002",
22895
23914
  promptSnippet: "\u6E38\u5955\u4F7F\u5EFA\u8BAE",
22896
23915
  parameters: navigatorOutputSchema
22897
23916
  };
@@ -22916,12 +23935,13 @@ import { createHash as createHash9 } from "node:crypto";
22916
23935
  init_navigator_invocation_identity();
22917
23936
  init_packaged_role_registry();
22918
23937
  init_activation_ledger_topology();
22919
- import { resolve as resolve16 } from "node:path";
23938
+ import { resolve as resolve17 } from "node:path";
22920
23939
  import "@earendil-works/pi-coding-agent";
22921
23940
  import { Type as Type22 } from "typebox";
22922
23941
 
22923
23942
  // src/navigator-public-session.ts
22924
23943
  init_sitian_facade();
23944
+ import { basename as basename10 } from "node:path";
22925
23945
 
22926
23946
  // src/navigator-session-contracts.ts
22927
23947
  import { Type as Type21 } from "typebox";
@@ -23109,6 +24129,7 @@ async function resolveNavigatorSeatSelection(context) {
23109
24129
 
23110
24130
  // src/navigator-public-session.ts
23111
24131
  init_host_contracts();
24132
+ init_cli_errors();
23112
24133
  async function resolveNavigatorLedgerHome(context) {
23113
24134
  const { tryHomeFromAkRolesPath: tryHomeFromAkRolesPath2 } = await Promise.resolve().then(() => (init_activation_ledger_topology(), activation_ledger_topology_exports));
23114
24135
  const runDirectory = runDirectoryFromHostContext(context);
@@ -23123,7 +24144,42 @@ async function resolveNavigatorLedgerHome(context) {
23123
24144
  }
23124
24145
  return void 0;
23125
24146
  }
23126
- function createNativeNavigatorSessionFactory() {
24147
+ var NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
24148
+ function exactRecord2(value) {
24149
+ return typeof value === "object" && value !== null && !Array.isArray(value);
24150
+ }
24151
+ function runIdFromNavigatorDirectory(runDirectory) {
24152
+ const entry = basename10(runDirectory);
24153
+ const suffix = "@navigator";
24154
+ if (!entry.endsWith(suffix)) return void 0;
24155
+ const runId = entry.slice(0, entry.length - suffix.length);
24156
+ return runId.length > 0 ? runId : void 0;
24157
+ }
24158
+ function readNavigatorHostRunPointer(entries) {
24159
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
24160
+ const entry = entries[index];
24161
+ if (!exactRecord2(entry)) continue;
24162
+ if (entry.type === "custom" && entry.customType === NAVIGATOR_HOST_RUN_POINTER_ENTRY) {
24163
+ const data = entry.data;
24164
+ if (exactRecord2(data) && typeof data.runId === "string" && data.runId.trim() !== "") {
24165
+ return data.runId.trim();
24166
+ }
24167
+ }
24168
+ }
24169
+ return void 0;
24170
+ }
24171
+ async function navigatorHostRunResumable(home, runId) {
24172
+ const { piDurablePrincipalAuthority: piDurablePrincipalAuthority2 } = await Promise.resolve().then(() => (init_durable_principal(), durable_principal_exports));
24173
+ const { loadResumableInstructionSeatRun: loadResumableInstructionSeatRun2 } = await Promise.resolve().then(() => (init_run_lifecycle(), run_lifecycle_exports));
24174
+ try {
24175
+ const loaded = await loadResumableInstructionSeatRun2(home, runId, piDurablePrincipalAuthority2);
24176
+ return loaded.admitted.role === "navigator";
24177
+ } catch (error) {
24178
+ if (error instanceof CliUsageError) return false;
24179
+ throw error;
24180
+ }
24181
+ }
24182
+ function createNativeNavigatorSessionFactory(deps) {
23127
24183
  return async ({ context, subject, tool }) => {
23128
24184
  let thinkingLevel;
23129
24185
  const { createRecordSession: createRecordSession2, NAVIGATOR_RECORD_KIND: NAVIGATOR_RECORD_KIND2 } = await Promise.resolve().then(() => (init_archivist_record_entry(), archivist_record_entry_exports));
@@ -23139,6 +24195,11 @@ function createNativeNavigatorSessionFactory() {
23139
24195
  let noReceipt;
23140
24196
  let disposed = false;
23141
24197
  let inFlightPrompt;
24198
+ let hostRunId = readNavigatorHostRunPointer(sessionManager.getEntries());
24199
+ const summon = deps?.summonPublicRole ?? (async (options) => {
24200
+ const { summonPublicRole: summonPublicRole2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
24201
+ return summonPublicRole2(options);
24202
+ });
23142
24203
  return {
23143
24204
  prompt: async (text) => {
23144
24205
  if (disposed) {
@@ -23148,14 +24209,24 @@ function createNativeNavigatorSessionFactory() {
23148
24209
  noReceipt = void 0;
23149
24210
  const run = (async () => {
23150
24211
  try {
23151
- const { summonPublicRole: summonPublicRole2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
23152
24212
  const summonHome = await resolveNavigatorLedgerHome(context);
23153
- const summoned = await summonPublicRole2({
24213
+ const resumeRunId = hostRunId;
24214
+ const baseSummon = {
23154
24215
  role: "navigator",
23155
24216
  argv: [text],
23156
24217
  cwd: context.cwd,
23157
24218
  ...summonHome === void 0 ? {} : { home: summonHome }
23158
- });
24219
+ };
24220
+ const resumable = deps?.hostRunResumable ?? navigatorHostRunResumable;
24221
+ let summoned;
24222
+ if (resumeRunId === void 0 || summonHome === void 0) {
24223
+ summoned = await summon(baseSummon);
24224
+ } else if (await resumable(summonHome, resumeRunId)) {
24225
+ summoned = await summon({ ...baseSummon, resumeRunId });
24226
+ } else {
24227
+ hostRunId = void 0;
24228
+ summoned = await summon(baseSummon);
24229
+ }
23159
24230
  const outcome = summoned.terminal?.roleOutcome;
23160
24231
  if (outcome === void 0) {
23161
24232
  const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
@@ -23178,21 +24249,31 @@ function createNativeNavigatorSessionFactory() {
23178
24249
  noReceipt = outcome;
23179
24250
  return;
23180
24251
  }
24252
+ const runDirectory = summoned.runDirectory ?? (typeof summoned.admitted?.runDirectory === "string" ? summoned.admitted.runDirectory : void 0);
24253
+ if (typeof runDirectory === "string" && runDirectory.trim() !== "") {
24254
+ const nextRunId = runIdFromNavigatorDirectory(runDirectory);
24255
+ if (nextRunId !== void 0) {
24256
+ hostRunId = nextRunId;
24257
+ sessionManager.appendCustomEntry(NAVIGATOR_HOST_RUN_POINTER_ENTRY, { runId: nextRunId });
24258
+ }
24259
+ }
23181
24260
  if (outcome.kind !== "accepted") {
23182
24261
  return;
23183
24262
  }
24263
+ const { navigatorProseFromUnknown: navigatorProseFromUnknown2 } = await Promise.resolve().then(() => (init_navigator_output(), navigator_output_exports));
24264
+ const proseParts = [];
23184
24265
  for (const payload of outcome.payloads ?? []) {
23185
- if (typeof payload !== "object" || payload === null || Array.isArray(payload)) continue;
23186
- const candidates = payload.candidates;
23187
- if (!Array.isArray(candidates)) continue;
23188
- await tool.execute(
23189
- "navigator-public-prepare",
23190
- { candidates },
23191
- void 0,
23192
- void 0,
23193
- context
23194
- );
24266
+ const prose = navigatorProseFromUnknown2(payload);
24267
+ if (prose !== void 0) proseParts.push(prose);
23195
24268
  }
24269
+ if (proseParts.length === 0) return;
24270
+ await tool.execute(
24271
+ "navigator-public-prepare",
24272
+ { prose: proseParts.join("\n\n") },
24273
+ void 0,
24274
+ void 0,
24275
+ context
24276
+ );
23196
24277
  } catch (error) {
23197
24278
  if (error instanceof NavigatorUnavailableError) throw error;
23198
24279
  const fact = navigatorProviderFailureFromError(error);
@@ -23246,9 +24327,9 @@ function createNativeNavigatorSessionFactory() {
23246
24327
 
23247
24328
  // src/navigator-attendance.ts
23248
24329
  init_sitian_facade();
23249
- init_public_command_renderer();
23250
24330
  init_work_subject_identity();
23251
24331
  init_receipt_delivery_policy();
24332
+ init_navigator_output();
23252
24333
  var NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
23253
24334
  var NAVIGATOR_PREPARE_ACCEPTED_TEXT = "\u6E38\u5955\u4F7F\u51C6\u5907\u5DF2\u63A5\u53D7";
23254
24335
  function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
@@ -23258,107 +24339,40 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
23258
24339
  }
23259
24340
  var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
23260
24341
  var prepareSchema = Type22.Object({
23261
- candidates: Type22.Optional(Type22.Unknown({
23262
- 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"
24342
+ prose: Type22.Optional(Type22.Unknown({
24343
+ 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"
23263
24344
  }))
23264
24345
  }, { additionalProperties: true });
23265
- var ROUTE_ENTRY = "ak-navigator-route";
23266
24346
  var CONTEXT_ENTRY = "ak-navigator-context";
23267
24347
  var INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
23268
24348
  var SETTLEMENT_ENTRY = "ak-navigator-settlement";
23269
- var targetRoles = new Set(NAVIGATOR_TARGETS.map(({ role }) => role));
23270
- function exactRecord2(value) {
24349
+ function exactRecord3(value) {
23271
24350
  return typeof value === "object" && value !== null && !Array.isArray(value);
23272
24351
  }
23273
24352
  function rejectedPrepareReason(entries, start) {
23274
24353
  const recent = entries.slice(start);
23275
24354
  const prepareCalls = /* @__PURE__ */ new Set();
23276
24355
  for (const entry of recent) {
23277
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
24356
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
23278
24357
  for (const part of entry.message.content) {
23279
- if (exactRecord2(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
23280
- }
23281
- }
23282
- let reason;
23283
- for (const entry of recent) {
23284
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
23285
- const callId = entry.message.toolCallId;
23286
- if (entry.message.toolName !== NAVIGATOR_PREPARE_TOOL_NAME || typeof callId !== "string" || !prepareCalls.has(callId)) {
23287
- return void 0;
24358
+ if (exactRecord3(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
23288
24359
  }
23289
- const content = entry.message.content;
23290
- const text = Array.isArray(content) ? content.flatMap((part) => exactRecord2(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
23291
- if (text.trim() !== "") reason = text.trim();
23292
- }
23293
- return reason;
23294
- }
23295
- function targetIsValid(value) {
23296
- if (!exactRecord2(value) || !targetRoles.has(String(value.role))) return false;
23297
- const metadata = packagedRoleMetadata(String(value.role));
23298
- return metadata !== void 0 && metadata.phases.includes(value.phase);
23299
- }
23300
- function normalizeTarget(value) {
23301
- if (!exactRecord2(value)) return void 0;
23302
- const role = typeof value.role === "string" ? value.role.trim() : "";
23303
- if (role === "") return void 0;
23304
- if (value.phase === void 0 || value.phase === null) {
23305
- return { role, phase: null };
23306
- }
23307
- if (value.phase === "plan" || value.phase === "apply") {
23308
- return { role, phase: value.phase };
23309
- }
23310
- return { role, phase: null };
23311
- }
23312
- function normalizeMatches(value) {
23313
- if (!exactRecord2(value)) return void 0;
23314
- if (typeof value.role !== "string" || value.role.trim() === "") return void 0;
23315
- if (value.kind !== "accepted") return void 0;
23316
- let phase;
23317
- if (value.phase === void 0 || value.phase === null) phase = null;
23318
- else if (value.phase === "plan" || value.phase === "apply") phase = value.phase;
23319
- else return void 0;
23320
- if (value.statuses !== void 0) {
23321
- if (!Array.isArray(value.statuses) || value.statuses.some((status) => typeof status !== "string" || status.trim() === "")) {
24360
+ }
24361
+ let reason;
24362
+ for (const entry of recent) {
24363
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
24364
+ const callId = entry.message.toolCallId;
24365
+ if (entry.message.toolName !== NAVIGATOR_PREPARE_TOOL_NAME || typeof callId !== "string" || !prepareCalls.has(callId)) {
23322
24366
  return void 0;
23323
24367
  }
23324
- return {
23325
- role: value.role,
23326
- phase,
23327
- kind: "accepted",
23328
- statuses: [...value.statuses]
23329
- };
24368
+ const content = entry.message.content;
24369
+ const text = Array.isArray(content) ? content.flatMap((part) => exactRecord3(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
24370
+ if (text.trim() !== "") reason = text.trim();
23330
24371
  }
23331
- return { role: value.role, phase, kind: "accepted" };
23332
- }
23333
- function normalizeCandidate(value) {
23334
- if (!exactRecord2(value)) return void 0;
23335
- const next = normalizeTarget(value.next);
23336
- const route = Array.isArray(value.route) ? value.route.map(normalizeTarget).filter((target) => target !== void 0) : void 0;
23337
- const matches = normalizeMatches(value.matches);
23338
- const id = typeof value.id === "string" && value.id.trim() !== "" ? value.id : void 0;
23339
- const reason = typeof value.reason === "string" && value.reason.trim() !== "" ? value.reason : void 0;
23340
- const command = typeof value.command === "string" ? value.command : void 0;
23341
- return {
23342
- ...id === void 0 ? {} : { id },
23343
- ...matches === void 0 ? {} : { matches },
23344
- ...route === void 0 || route.length === 0 ? {} : { route },
23345
- ...next === void 0 ? {} : { next },
23346
- ...reason === void 0 ? {} : { reason },
23347
- ...command === void 0 ? {} : { command }
23348
- };
23349
- }
23350
- function normalizePrepareOutput(value) {
23351
- if (!exactRecord2(value) || !Array.isArray(value.candidates)) return [];
23352
- return value.candidates.map(normalizeCandidate).filter((candidate) => candidate !== void 0);
23353
- }
23354
- function routeEqual(a, b) {
23355
- return a !== void 0 && a.length === b.length && a.every((target, index) => target.role === b[index].role && target.phase === b[index].phase);
23356
- }
23357
- function routeText(route) {
23358
- return route.map((target) => target.phase === null ? target.role : `${target.role} ${target.phase}`).join(" \u2192 ");
24372
+ return reason;
23359
24373
  }
23360
- function targetText(target) {
23361
- return target.phase === null ? target.role : `${target.role} ${target.phase}`;
24374
+ function normalizePrepareProse(value) {
24375
+ return navigatorProseFromUnknown(value);
23362
24376
  }
23363
24377
  function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
23364
24378
  if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
@@ -23369,7 +24383,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
23369
24383
  }
23370
24384
  function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
23371
24385
  if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
23372
- const resolvedReference = resolve16(cwd, reference);
24386
+ const resolvedReference = resolve17(cwd, reference);
23373
24387
  const marker = "/runs/";
23374
24388
  if (resolvedReference.includes(marker)) {
23375
24389
  return subjectRoot;
@@ -23380,7 +24394,7 @@ function createNavigatorPrepareTool(onOutput) {
23380
24394
  return {
23381
24395
  name: NAVIGATOR_PREPARE_TOOL_NAME,
23382
24396
  label: "\u6E38\u5955\u4F7F\u51C6\u5907",
23383
- description: "\u63D0\u4EA4\u6E38\u5955\u4F7F\u65B9\u5411\u5EFA\u8BAE\u3002",
24397
+ description: "\u63D0\u4EA4\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\u3002",
23384
24398
  parameters: prepareSchema,
23385
24399
  async execute(_id, value) {
23386
24400
  onOutput(value);
@@ -23388,34 +24402,6 @@ function createNavigatorPrepareTool(onOutput) {
23388
24402
  }
23389
24403
  };
23390
24404
  }
23391
- function selectNavigatorCandidate(candidates, settlement) {
23392
- if (settlement.kind !== "accepted") return void 0;
23393
- const usable = candidates.filter((candidate) => candidate.next !== void 0);
23394
- if (usable.length === 0) return void 0;
23395
- const rolePhaseMatched = usable.filter(
23396
- (candidate) => candidate.matches !== void 0 && candidate.matches.role === settlement.role && candidate.matches.phase === settlement.phase
23397
- );
23398
- if (rolePhaseMatched.length > 0) {
23399
- if (settlement.status !== void 0) {
23400
- const statusSpecific = rolePhaseMatched.find(
23401
- (candidate) => candidate.matches?.statuses !== void 0 && candidate.matches.statuses.includes(settlement.status)
23402
- );
23403
- if (statusSpecific !== void 0) {
23404
- return { candidate: statusSpecific, matchedToSettlement: true };
23405
- }
23406
- }
23407
- const rolePhaseGeneric = rolePhaseMatched.find(
23408
- (candidate) => candidate.matches?.statuses === void 0
23409
- );
23410
- if (rolePhaseGeneric !== void 0) {
23411
- return { candidate: rolePhaseGeneric, matchedToSettlement: true };
23412
- }
23413
- return void 0;
23414
- }
23415
- const unbound = usable.find((candidate) => candidate.matches === void 0);
23416
- if (unbound === void 0) return void 0;
23417
- return { candidate: unbound, matchedToSettlement: false };
23418
- }
23419
24405
  function formatNavigatorReport(report) {
23420
24406
  const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [`\u8DEF\u4E66\u8BFB\u53D6\u5931\u8D25\uFF1A${report.routePlaybookReadFailure}`];
23421
24407
  if (report.disposition === "no-advice") return playbookFailure.join("\n");
@@ -23425,31 +24411,24 @@ function formatNavigatorReport(report) {
23425
24411
  if (report.disposition === "arrival") {
23426
24412
  return [...playbookFailure, ...report.arrivalMessage ? [report.arrivalMessage] : []].join("\n");
23427
24413
  }
23428
- return [
23429
- ...playbookFailure,
23430
- ...report.route === void 0 ? [] : [`\u8DEF\u7EBF\uFF1A${routeText(report.route)}`],
23431
- ...report.next === void 0 ? [] : [`\u4E0B\u4E00\u6B65\uFF1A${targetText(report.next)}`],
23432
- ...report.reason === void 0 || report.reason.trim() === "" ? [] : [`\u7406\u7531\uFF1A${report.reason}`],
23433
- ...report.command === void 0 || report.command.trim() === "" ? [] : [`\u547D\u4EE4\uFF1A${report.command}`]
23434
- ].join("\n");
24414
+ return [...playbookFailure, ...report.prose ? [report.prose] : []].join("\n");
23435
24415
  }
23436
24416
  function createNavigatorAttendance(options) {
23437
24417
  let preparation;
24418
+ let preparationInFlight = false;
23438
24419
  let sessionReady;
23439
24420
  let session;
23440
24421
  let subjectKey = options.subjectKey;
23441
24422
  let subject = options.subject;
23442
24423
  let authority = options.authority;
23443
24424
  let contextError = options.contextError;
23444
- let candidates;
24425
+ let preparedProse;
23445
24426
  const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
23446
24427
  let activeInvocationId = invocationPrincipal;
23447
- let previousRoute;
23448
24428
  let outputSink;
23449
24429
  let settlementTail = Promise.resolve();
23450
24430
  let settlementFailure;
23451
24431
  let preparationFailure;
23452
- let preparationNoReceipt = false;
23453
24432
  let routePlaybookReadFailure;
23454
24433
  let disposed = false;
23455
24434
  let warmedHelp;
@@ -23476,12 +24455,7 @@ function createNavigatorAttendance(options) {
23476
24455
  };
23477
24456
  let routePlaybookSettlement;
23478
24457
  let prepareBoundSettlement;
23479
- const prepare = async () => {
23480
- const boundSettlement = prepareBoundSettlement;
23481
- prepareBoundSettlement = void 0;
23482
- preparationNoReceipt = false;
23483
- const invocationId = invocationPrincipal;
23484
- activeInvocationId = invocationId;
24458
+ const loadMaterialsAndSession = async (invocationId) => {
23485
24459
  if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
23486
24460
  if (typeof authority !== "string" || authority.trim() === "") {
23487
24461
  throw navigatorUnavailableError(
@@ -23539,21 +24513,6 @@ function createNavigatorAttendance(options) {
23539
24513
  const helpContext = help.map(({ role, help: text }) => `<role_help role="${role}">
23540
24514
  ${text}
23541
24515
  </role_help>`).join("\n");
23542
- let output;
23543
- let prepareBatchRejected = false;
23544
- outputSink = (value) => {
23545
- if (output === void 0) {
23546
- output = value;
23547
- return;
23548
- }
23549
- const prior2 = output.candidates;
23550
- const next = value.candidates;
23551
- const merged = [
23552
- ...Array.isArray(prior2) ? prior2 : prior2 === void 0 ? [] : [prior2],
23553
- ...Array.isArray(next) ? next : next === void 0 ? [] : [next]
23554
- ];
23555
- output = { ...value, candidates: merged };
23556
- };
23557
24516
  const tool = createNavigatorPrepareTool((value) => {
23558
24517
  outputSink?.(value);
23559
24518
  });
@@ -23561,7 +24520,12 @@ ${text}
23561
24520
  sessionReady = (async () => {
23562
24521
  let created;
23563
24522
  try {
23564
- created = await options.createSession({ context: options.context, subject: subjectKey, ...options.modelSettingPath === void 0 ? {} : { modelSettingPath: options.modelSettingPath }, tool });
24523
+ created = await options.createSession({
24524
+ context: options.context,
24525
+ subject: subjectKey,
24526
+ ...options.modelSettingPath === void 0 ? {} : { modelSettingPath: options.modelSettingPath },
24527
+ tool
24528
+ });
23565
24529
  } catch (error) {
23566
24530
  throw navigatorUnavailableError("session", error);
23567
24531
  }
@@ -23592,26 +24556,63 @@ ${text}
23592
24556
  session.appendEntry(INVOCATION_ENTRY, { invocationId, role: options.role, phase: options.phase, subjectKey });
23593
24557
  }
23594
24558
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
23595
- const activeSession = session;
23596
- if (activeSession === void 0) throw new Error("Navigator session was not created");
23597
- 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;
23598
- if (exactRecord2(prior) && Array.isArray(prior.route) && prior.route.every((target) => targetIsValid(target))) {
23599
- previousRoute = prior.route.map((target) => ({ role: target.role, phase: target.phase }));
23600
- }
23601
- const publicSettlementHistory = activeSession.entries().filter((entry) => exactRecord2(entry) && entry.type === "custom" && entry.customType === SETTLEMENT_ENTRY && exactRecord2(entry.data)).map((entry) => entry.data);
24559
+ if (session === void 0) throw new Error("Navigator session was not created");
24560
+ return { soul, routePlaybook, helpContext, modelSetting, model, help, activeSession: session };
24561
+ };
24562
+ const prepare = async (materialsBundle) => {
24563
+ const boundSettlement = prepareBoundSettlement;
24564
+ prepareBoundSettlement = void 0;
24565
+ const invocationId = invocationPrincipal;
24566
+ activeInvocationId = invocationId;
24567
+ let output;
24568
+ let prepareBatchRejected = false;
24569
+ outputSink = (value) => {
24570
+ if (output === void 0) {
24571
+ output = value;
24572
+ return;
24573
+ }
24574
+ const prior = normalizePrepareProse(output) ?? "";
24575
+ const next = normalizePrepareProse(value) ?? "";
24576
+ const merged = [prior, next].filter((part) => part.trim() !== "").join("\n\n");
24577
+ output = { prose: merged };
24578
+ };
24579
+ const { soul, routePlaybook, helpContext, help, activeSession } = materialsBundle ?? await loadMaterialsAndSession(invocationId);
24580
+ const publicSettlementHistory = activeSession.entries().filter((entry) => exactRecord3(entry) && entry.type === "custom" && entry.customType === SETTLEMENT_ENTRY && exactRecord3(entry.data)).map((entry) => entry.data);
23602
24581
  const projection = {
23603
24582
  subjectKey,
23604
24583
  subject,
23605
24584
  authority,
23606
24585
  currentRole: { role: options.role, phase: options.phase },
23607
24586
  ...boundSettlement === void 0 ? {} : { currentSettlement: boundSettlement },
23608
- priorRoute: exactRecord2(prior) && Array.isArray(prior.route) && prior.route.every((target) => targetIsValid(target)) ? prior.route.map((target) => ({ role: target.role, phase: target.phase })) : null,
23609
24587
  publicSettlementHistory,
23610
24588
  liveRoleHelp: help
23611
24589
  };
23612
24590
  activeSession.appendEntry(CONTEXT_ENTRY, projection);
23613
- const request = [
23614
- "\u672C\u6B21\u5BFC\u822A\u6750\u6599\u5982\u4E0B\uFF1A",
24591
+ const request = boundSettlement === void 0 ? [
24592
+ "\u672C\u8F6E\u4E3A\u5F85\u547D\u8F6E\u3002",
24593
+ `<navigator_soul>
24594
+ ${soul}
24595
+ </navigator_soul>`,
24596
+ ...routePlaybookReadFailure === void 0 ? [`<route_playbook>
24597
+ ${routePlaybook}
24598
+ </route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
24599
+ `<work_subject>
24600
+ ${subject}
24601
+ </work_subject>`,
24602
+ `<controlling_authority>
24603
+ ${authority}
24604
+ </controlling_authority>`,
24605
+ `<current_role>
24606
+ ${JSON.stringify({ role: options.role, phase: options.phase })}
24607
+ </current_role>`,
24608
+ `<public_settlement_history>
24609
+ ${JSON.stringify(projection.publicSettlementHistory)}
24610
+ </public_settlement_history>`,
24611
+ `<live_role_help>
24612
+ ${helpContext}
24613
+ </live_role_help>`
24614
+ ].join("\n\n") : [
24615
+ "\u672C\u8F6E\u4E3A\u7ED3\u7B97\u6295\u5582\u8F6E\u3002",
23615
24616
  `<navigator_soul>
23616
24617
  ${soul}
23617
24618
  </navigator_soul>`,
@@ -23627,12 +24628,9 @@ ${authority}
23627
24628
  `<current_role>
23628
24629
  ${JSON.stringify({ role: options.role, phase: options.phase })}
23629
24630
  </current_role>`,
23630
- ...boundSettlement === void 0 ? [] : [`<current_settlement>
24631
+ `<current_settlement>
23631
24632
  ${JSON.stringify(boundSettlement)}
23632
- </current_settlement>`],
23633
- `<prior_route>
23634
- ${JSON.stringify(prior ?? null)}
23635
- </prior_route>`,
24633
+ </current_settlement>`,
23636
24634
  `<public_settlement_history>
23637
24635
  ${JSON.stringify(projection.publicSettlementHistory)}
23638
24636
  </public_settlement_history>`,
@@ -23673,33 +24671,47 @@ ${helpContext}
23673
24671
  if (deliveryRequest && output === void 0) delivery.recordDeliveryRequest();
23674
24672
  };
23675
24673
  await promptAllowingRejectedPrepare(request, false);
23676
- while (output === void 0 && delivery.nextAction() === "request-delivery") {
23677
- await promptAllowingRejectedPrepare(RECEIPT_DELIVERY_PROMPT, true);
23678
- }
23679
- if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
23680
- const facts = delivery.facts({ runPointer: activeSession.recordPointer(), attemptPointer: invocationId });
23681
- activeSession.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
23682
- preparationNoReceipt = true;
23683
- candidates = [];
23684
- return candidates;
24674
+ if (boundSettlement !== void 0) {
24675
+ while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
24676
+ await promptAllowingRejectedPrepare(RECEIPT_DELIVERY_PROMPT, true);
24677
+ }
24678
+ if (output === void 0 && delivery.nextAction() === "request-delivery") {
24679
+ while (delivery.nextAction() === "request-delivery") {
24680
+ delivery.recordDeliveryRequest();
24681
+ }
24682
+ }
24683
+ if (output === void 0 && delivery.nextAction() === "no-receipt" && activeSession.providerFailure?.() === void 0) {
24684
+ const facts = delivery.facts({ runPointer: activeSession.recordPointer(), attemptPointer: invocationId });
24685
+ activeSession.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
24686
+ preparedProse = void 0;
24687
+ return void 0;
24688
+ }
23685
24689
  }
23686
24690
  } catch (error) {
23687
24691
  throw error instanceof NavigatorUnavailableError ? error : navigatorUnavailableError("transport", error);
23688
24692
  }
23689
24693
  if (output === void 0) {
24694
+ if (boundSettlement === void 0) {
24695
+ preparedProse = void 0;
24696
+ return void 0;
24697
+ }
23690
24698
  const nativeFailure = [...activeSession.entries()].reverse().find((entry) => {
23691
- if (!exactRecord2(entry) || entry.type !== "message" || !exactRecord2(entry.message)) return false;
24699
+ if (!exactRecord3(entry) || entry.type !== "message" || !exactRecord3(entry.message)) return false;
23692
24700
  return entry.message.role === "assistant" && typeof entry.message.errorMessage === "string" && entry.message.errorMessage.trim() !== "";
23693
24701
  });
23694
- const nativeMessage = exactRecord2(nativeFailure) && exactRecord2(nativeFailure.message) ? nativeFailure.message : void 0;
24702
+ const nativeMessage = exactRecord3(nativeFailure) && exactRecord3(nativeFailure.message) ? nativeFailure.message : void 0;
23695
24703
  const errorMessage = nativeMessage !== void 0 && typeof nativeMessage.errorMessage === "string" ? nativeMessage.errorMessage : "Navigator did not submit direction advice";
23696
24704
  const providerFailure = activeSession.providerFailure?.();
23697
24705
  const source = providerFailure?.source ?? "unknown";
23698
24706
  const cause = providerFailure?.cause ?? source;
23699
24707
  throw navigatorUnavailableError(source, errorMessage, cause);
23700
24708
  }
23701
- candidates = normalizePrepareOutput(output);
23702
- return candidates;
24709
+ if (boundSettlement === void 0) {
24710
+ preparedProse = void 0;
24711
+ return void 0;
24712
+ }
24713
+ preparedProse = normalizePrepareProse(output);
24714
+ return preparedProse;
23703
24715
  } finally {
23704
24716
  outputSink = void 0;
23705
24717
  }
@@ -23710,7 +24722,6 @@ ${helpContext}
23710
24722
  if (next.subjectKey !== subjectKey && session !== void 0) {
23711
24723
  const previous = session;
23712
24724
  session = void 0;
23713
- previousRoute = void 0;
23714
24725
  closing = previous.dispose();
23715
24726
  }
23716
24727
  subjectKey = next.subjectKey;
@@ -23732,13 +24743,16 @@ ${helpContext}
23732
24743
  prepare() {
23733
24744
  if (disposed || preparation !== void 0) return;
23734
24745
  preparationFailure = void 0;
23735
- preparation = prepare();
24746
+ preparationInFlight = true;
24747
+ preparation = prepare().finally(() => {
24748
+ preparationInFlight = false;
24749
+ });
23736
24750
  void preparation.catch((error) => {
23737
24751
  preparationFailure = error;
23738
24752
  });
23739
24753
  },
23740
24754
  isPreparing() {
23741
- return preparation !== void 0 || sessionReady !== void 0;
24755
+ return preparationInFlight;
23742
24756
  },
23743
24757
  knownRoutePlaybookReadFailure() {
23744
24758
  return routePlaybookReadFailure;
@@ -23762,81 +24776,70 @@ ${helpContext}
23762
24776
  if (disposed) return;
23763
24777
  const invocationId = activeInvocationId ?? invocationPrincipal;
23764
24778
  let report;
23765
- if (settlement.kind === "human_decision" || settlement.kind === "role_infrastructure_failure") {
23766
- if (sessionReady !== void 0) {
23767
- try {
23768
- await sessionReady;
23769
- } catch (error) {
23770
- preparationFailure ??= error;
23771
- }
24779
+ if (sessionReady !== void 0) {
24780
+ try {
24781
+ await sessionReady;
24782
+ } catch (error) {
24783
+ preparationFailure ??= error;
23772
24784
  }
23773
- if (preparation !== void 0) {
23774
- try {
23775
- await preparation;
23776
- } catch (error) {
23777
- preparationFailure ??= error;
23778
- }
24785
+ }
24786
+ if (preparation !== void 0) {
24787
+ try {
24788
+ await preparation;
24789
+ } catch (error) {
24790
+ preparationFailure ??= error;
23779
24791
  }
23780
- session?.appendEntry(SETTLEMENT_ENTRY, { invocationId, subjectKey, role: settlement.role, phase: settlement.phase, kind: settlement.kind, ...settlement.kind === "human_decision" ? { status: settlement.status } : {} });
24792
+ preparation = void 0;
24793
+ }
24794
+ const settlementFact = {
24795
+ invocationId,
24796
+ subjectKey,
24797
+ role: settlement.role,
24798
+ phase: settlement.phase,
24799
+ kind: settlement.kind,
24800
+ ..."status" in settlement && settlement.status !== void 0 ? { status: settlement.status } : {}
24801
+ };
24802
+ let drainedProse;
24803
+ if (settlement.kind === "arrival") {
24804
+ session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
23781
24805
  if (preparationFailure !== void 0) {
23782
24806
  report = unavailable(invocationId, preparationFailure);
23783
24807
  } else {
23784
- report = { disposition: "no-advice" };
24808
+ report = {
24809
+ disposition: "arrival",
24810
+ ...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message }
24811
+ };
23785
24812
  }
23786
- } else if (settlement.kind === "arrival") {
23787
- if (sessionReady !== void 0) {
24813
+ } else {
24814
+ if (session !== void 0) preparationFailure = void 0;
24815
+ let coldMaterials;
24816
+ if (session === void 0 && preparationFailure === void 0) {
23788
24817
  try {
23789
- await sessionReady;
24818
+ coldMaterials = await loadMaterialsAndSession(invocationId);
23790
24819
  } catch (error) {
23791
- preparationFailure ??= error;
24820
+ preparationFailure = error;
23792
24821
  }
23793
24822
  }
23794
- if (preparation !== void 0) {
24823
+ session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
24824
+ if (preparationFailure === void 0) {
24825
+ prepareBoundSettlement = settlement;
24826
+ preparation = prepare(coldMaterials);
24827
+ void preparation.catch((error) => {
24828
+ preparationFailure = error;
24829
+ });
23795
24830
  try {
23796
- await preparation;
24831
+ drainedProse = await preparation;
23797
24832
  } catch (error) {
23798
24833
  preparationFailure ??= error;
23799
24834
  }
24835
+ preparation = void 0;
23800
24836
  }
23801
- report = preparationFailure === void 0 ? { disposition: "arrival", ...settlement.message === void 0 ? {} : { arrivalMessage: settlement.message } } : unavailable(invocationId, preparationFailure);
23802
- } else if (preparation === void 0) {
23803
- report = unavailable(invocationId, "Navigator preparation did not start");
23804
- } else {
23805
- try {
23806
- if (sessionReady !== void 0) await sessionReady;
23807
- let prepared = await preparation;
23808
- session?.appendEntry(SETTLEMENT_ENTRY, { invocationId, subjectKey, role: settlement.role, phase: settlement.phase, kind: settlement.kind, ...settlement.status === void 0 ? {} : { status: settlement.status } });
23809
- let selected = selectNavigatorCandidate(prepared, settlement);
23810
- if (selected?.candidate.next !== void 0 && !selected.matchedToSettlement) {
23811
- if (disposed) return;
23812
- prepareBoundSettlement = settlement;
23813
- prepared = await prepare();
23814
- if (disposed) return;
23815
- selected = selectNavigatorCandidate(prepared, settlement);
23816
- }
23817
- const selectedCandidate = selected?.candidate;
23818
- if (selectedCandidate?.next === void 0 && preparationNoReceipt) {
23819
- report = { disposition: "no-advice" };
23820
- } else if (selectedCandidate?.next === void 0) {
23821
- throw new Error("Navigator prepared no machine-usable next direction");
23822
- } else {
23823
- const selectedRoute = selectedCandidate.route;
23824
- const routeChanged = selectedRoute !== void 0 && !routeEqual(previousRoute, selectedRoute);
23825
- const command = typeof selectedCandidate.command === "string" && selectedCandidate.command.trim() !== "" ? selectedCandidate.command : renderPublicAkRoleCommand(selectedCandidate.next);
23826
- report = {
23827
- disposition: "recommendation",
23828
- ...routeChanged ? { route: selectedRoute } : {},
23829
- next: selectedCandidate.next,
23830
- ...selectedCandidate.reason === void 0 ? {} : { reason: selectedCandidate.reason },
23831
- ...command === void 0 ? {} : { command }
23832
- };
23833
- if (selectedRoute !== void 0) {
23834
- previousRoute = selectedRoute;
23835
- session?.appendEntry(ROUTE_ENTRY, { invocationId, subjectKey, route: selectedRoute });
23836
- }
23837
- }
23838
- } catch (error) {
23839
- report = unavailable(invocationId, error);
24837
+ if (preparationFailure !== void 0) {
24838
+ report = unavailable(invocationId, preparationFailure);
24839
+ } else if (typeof drainedProse === "string" && drainedProse.trim() !== "") {
24840
+ report = { disposition: "advice", prose: drainedProse };
24841
+ } else {
24842
+ report = { disposition: "no-advice" };
23840
24843
  }
23841
24844
  }
23842
24845
  await routePlaybookSettlement;
@@ -23850,10 +24853,7 @@ ${helpContext}
23850
24853
  role: options.role,
23851
24854
  phase: options.phase,
23852
24855
  subjectKey,
23853
- ...report.route === void 0 ? {} : { route: report.route },
23854
- ...report.next === void 0 ? {} : { next: report.next },
23855
- ...report.reason === void 0 ? {} : { reason: report.reason },
23856
- ...report.command === void 0 ? {} : { command: report.command },
24856
+ ...report.prose === void 0 ? {} : { prose: report.prose },
23857
24857
  ...report.unavailableReason === void 0 ? {} : { unavailableReason: report.unavailableReason },
23858
24858
  ...report.unavailableSource === void 0 ? {} : { unavailableSource: report.unavailableSource },
23859
24859
  ...report.unavailableCause === void 0 ? {} : { unavailableCause: report.unavailableCause },
@@ -23869,9 +24869,8 @@ ${helpContext}
23869
24869
  }
23870
24870
  preparation = void 0;
23871
24871
  sessionReady = void 0;
23872
- candidates = void 0;
24872
+ preparedProse = void 0;
23873
24873
  preparationFailure = void 0;
23874
- preparationNoReceipt = false;
23875
24874
  routePlaybookSettlement = void 0;
23876
24875
  routePlaybookReadFailure = void 0;
23877
24876
  }
@@ -24010,7 +25009,7 @@ var reviewerAmendmentsSchema = Type24.Object({
24010
25009
  }))
24011
25010
  }, {
24012
25011
  additionalProperties: true,
24013
- description: "\u6240\u9009 lens \u7684 amendments \u627F\u8F7D candidates\u3001\u9010\u6761\u5904\u7F6E\u4E0E verdict \u7684\u5B8C\u6574\u62A5\u544A\uFF08\u975E\u4EC5 verdict \u884C\uFF09\uFF1B\u672A\u9009 lens \u53EF\u7701\u7565\u3002hard-stop\uFF0Fusage error \u4E3A refused \u65F6\uFF0C\u5DF2\u4EA7\u51FA\u62A5\u544A\u4ECD\u7167\u5F55\u8FDB\u6240\u9009 lens \u5B57\u6BB5\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\u3002"
25012
+ description: "\u5DF2\u8FD0\u884C lens \u7684 amendments \u627F\u8F7D candidates\u3001\u9010\u6761\u5904\u7F6E\u4E0E verdict \u7684\u5B8C\u6574\u62A5\u544A\uFF08\u975E\u4EC5 verdict \u884C\uFF09\uFF1B\u663E\u5F0F\u5355\u8F74\u65F6\u53E6\u4E00\u8F74\u53EF\u7701\u7565\u3002hard-stop\uFF0Fusage error \u4E3A refused \u65F6\uFF0C\u5DF2\u4EA7\u51FA\u62A5\u544A\u4ECD\u7167\u5F55\u5BF9\u5E94 lens \u5B57\u6BB5\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\u3002"
24014
25013
  });
24015
25014
  var REVIEWER_STATUS_DESCRIPTION = "completed | refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\u3002\u4E24\u79CD\u6B63\u5E38 lens verdict\uFF08completeness / correctness\uFF09\u5747 completed\uFF1Bhard-stop \u4E0E usage error \u4E3A refused\uFF08\u5DF2\u4EA7\u51FA\u62A5\u544A\u4ECD\u7167\u5F55\u8FDB\u6240\u9009 lens amendments\uFF09\u3002";
24016
25015
  var reviewerOutputVariants = Type24.Union([
@@ -24086,7 +25085,7 @@ init_submission_errors();
24086
25085
  init_submission_errors();
24087
25086
  import { execFileSync as execFileSync4 } from "node:child_process";
24088
25087
  import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
24089
- import { resolve as resolve17 } from "node:path";
25088
+ import { resolve as resolve18 } from "node:path";
24090
25089
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
24091
25090
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
24092
25091
  var WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE = "commit-reminder-bounce";
@@ -24135,7 +25134,7 @@ function escapeGitConfigValueRegex(value) {
24135
25134
  function unsetOwnedHooksPath(file) {
24136
25135
  const owned = [];
24137
25136
  for (const value of tryGetAll(file, "core.hooksPath")) {
24138
- if (!ownedHook(resolve17(value, HOOK_FILE))) continue;
25137
+ if (!ownedHook(resolve18(value, HOOK_FILE))) continue;
24139
25138
  try {
24140
25139
  gitFile(file, [
24141
25140
  "--unset-all",
@@ -24150,15 +25149,15 @@ function unsetOwnedHooksPath(file) {
24150
25149
  return owned;
24151
25150
  }
24152
25151
  function rmOwnedDir(dir) {
24153
- const hookPath = resolve17(dir, HOOK_FILE);
25152
+ const hookPath = resolve18(dir, HOOK_FILE);
24154
25153
  if (!ownedHook(hookPath)) return;
24155
25154
  rmSync(hookPath, { force: true });
24156
25155
  if (existsSync12(dir) && readdirSync3(dir).length === 0) rmdirSync(dir);
24157
25156
  }
24158
25157
  function linkedGitDirs(commonDir) {
24159
- const root = resolve17(commonDir, "worktrees");
25158
+ const root = resolve18(commonDir, "worktrees");
24160
25159
  if (!existsSync12(root)) return [];
24161
- return readdirSync3(root).map((name) => resolve17(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
25160
+ return readdirSync3(root).map((name) => resolve18(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
24162
25161
  }
24163
25162
  function uninstallPackageWorkerHooks(cwd) {
24164
25163
  let inside;
@@ -24172,14 +25171,14 @@ function uninstallPackageWorkerHooks(cwd) {
24172
25171
  const clear = (configFile) => {
24173
25172
  for (const hooks of unsetOwnedHooksPath(configFile)) rmOwnedDir(hooks);
24174
25173
  };
24175
- clear(resolve17(commonDir, "config"));
24176
- clear(resolve17(commonDir, "config.worktree"));
24177
- rmOwnedDir(resolve17(commonDir, HOOKS_DIR));
24178
- const legacy = resolve17(commonDir, "hooks", HOOK_FILE);
25174
+ clear(resolve18(commonDir, "config"));
25175
+ clear(resolve18(commonDir, "config.worktree"));
25176
+ rmOwnedDir(resolve18(commonDir, HOOKS_DIR));
25177
+ const legacy = resolve18(commonDir, "hooks", HOOK_FILE);
24179
25178
  if (ownedHook(legacy)) rmSync(legacy, { force: true });
24180
25179
  for (const gitDir of linkedGitDirs(commonDir)) {
24181
- clear(resolve17(gitDir, "config.worktree"));
24182
- rmOwnedDir(resolve17(gitDir, HOOKS_DIR));
25180
+ clear(resolve18(gitDir, "config.worktree"));
25181
+ rmOwnedDir(resolve18(gitDir, HOOKS_DIR));
24183
25182
  }
24184
25183
  }
24185
25184
  function isRecord13(value) {
@@ -24224,11 +25223,11 @@ function reliableWindow(cwd, baseline, head) {
24224
25223
  const raw = git2(cwd, ["log", "--format=%P%x1e%s", range]);
24225
25224
  if (raw.length === 0) return [];
24226
25225
  return raw.split("\n").flatMap((line2) => {
24227
- const sep6 = line2.indexOf("");
24228
- if (sep6 < 0) return [];
25226
+ const sep7 = line2.indexOf("");
25227
+ if (sep7 < 0) return [];
24229
25228
  return [{
24230
- subject: line2.slice(sep6 + 1),
24231
- merge: line2.slice(0, sep6).trim().includes(" ")
25229
+ subject: line2.slice(sep7 + 1),
25230
+ merge: line2.slice(0, sep7).trim().includes(" ")
24232
25231
  }];
24233
25232
  });
24234
25233
  }
@@ -24773,7 +25772,7 @@ var REVIEWER_TRANSPORT_FLAGS = Object.freeze([
24773
25772
  Object.freeze({
24774
25773
  name: "ak-review-lens",
24775
25774
  definition: Object.freeze({
24776
- description: "Caller-selected single review lens: completeness or correctness",
25775
+ description: "Single review lens: completeness or correctness",
24777
25776
  type: "string"
24778
25777
  })
24779
25778
  }),
@@ -25358,6 +26357,21 @@ function createCountersignRoleRuntime(roleHost, dependencies, hostActions) {
25358
26357
  dependencies
25359
26358
  );
25360
26359
  }
26360
+ function lastAssistantProse(messages) {
26361
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
26362
+ const message = messages[index];
26363
+ if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
26364
+ const texts = [];
26365
+ for (const part of message.content) {
26366
+ if (part.type === "text" && typeof part.text === "string" && part.text.length > 0) {
26367
+ texts.push(part.text);
26368
+ }
26369
+ }
26370
+ if (texts.length === 0) continue;
26371
+ return texts.join("");
26372
+ }
26373
+ return void 0;
26374
+ }
25361
26375
  function createRoleRuntimeExtension(dependencies) {
25362
26376
  return (envelopeHost) => {
25363
26377
  let projectClosedSubmission = async () => {
@@ -25416,10 +26430,6 @@ function createRoleRuntimeExtension(dependencies) {
25416
26430
  if (settlement === void 0 || attendance === void 0) return;
25417
26431
  const workContext = navigatorWorkContext;
25418
26432
  const pending = (async () => {
25419
- if (settlement.kind !== "accepted") {
25420
- await attendance.settle(settlement);
25421
- return;
25422
- }
25423
26433
  const settlePromise = attendance.settle(settlement);
25424
26434
  void settlePromise.catch(() => void 0);
25425
26435
  const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
@@ -25620,10 +26630,8 @@ function createRoleRuntimeExtension(dependencies) {
25620
26630
  pendingSubmissionNonPassByToolCallId.delete(event.toolCallId);
25621
26631
  return { details: submissionNonPass, isError: true };
25622
26632
  }
25623
- if (event.isError) return;
25624
- return;
25625
26633
  });
25626
- roleHost.on("agent_end", (event, ctx) => {
26634
+ roleHost.on("agent_end", async (event, ctx) => {
25627
26635
  const lastMessage = event.messages.at(-1);
25628
26636
  if (lastMessage?.role === "assistant" && (lastMessage.stopReason === "error" || lastMessage.stopReason === "aborted")) {
25629
26637
  if (receiptDelivery.nextAction() !== "accepted") {
@@ -25631,6 +26639,47 @@ function createRoleRuntimeExtension(dependencies) {
25631
26639
  }
25632
26640
  return;
25633
26641
  }
26642
+ const role = selectedRole ?? roleHost.getFlag(ROLE_FLAG.name);
26643
+ if (role === "navigator" && receiptDelivery.nextAction() !== "accepted") {
26644
+ const prose = lastAssistantProse(event.messages);
26645
+ if (prose !== void 0 && prose.trim() !== "") {
26646
+ const accepted = { prose };
26647
+ await sealAcceptedSubmission({
26648
+ context: ctx,
26649
+ role: "navigator",
26650
+ accepted,
26651
+ toolCallId: `navigator-prose-exit:${randomUUID8()}`
26652
+ });
26653
+ await projectClosedSubmission(
26654
+ { role: "navigator", kind: "accepted", accepted },
26655
+ ctx
26656
+ );
26657
+ return;
26658
+ }
26659
+ if (!noReceiptRecorded) {
26660
+ const runPointer = runDirectoryFromHostContext(ctx);
26661
+ if (runPointer !== void 0) {
26662
+ noReceiptRecorded = true;
26663
+ while (receiptDelivery.nextAction() === "request-delivery") {
26664
+ receiptDelivery.recordDeliveryRequest();
26665
+ }
26666
+ const facts = receiptDelivery.facts({ runPointer, attemptPointer: `current:${runPointer}` });
26667
+ envelopeHost.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
26668
+ try {
26669
+ sitianReport({
26670
+ level: "event",
26671
+ kind: "no-receipt-lifecycle",
26672
+ cwd: ctx.cwd,
26673
+ sessionParent: ctx.sessionManager.getSessionFile(),
26674
+ payload: facts,
26675
+ source: "role-runtime"
26676
+ });
26677
+ } catch {
26678
+ }
26679
+ }
26680
+ }
26681
+ return;
26682
+ }
25634
26683
  if (receiptDelivery.nextAction() === "request-delivery") {
25635
26684
  receiptDelivery.recordDeliveryRequest();
25636
26685
  envelopeHost.appendEntry("ak-receipt-delivery-request");
@@ -26228,11 +27277,11 @@ init_role_activation_flags();
26228
27277
  init_submission_correctable_error();
26229
27278
  init_navigator_invocation_identity();
26230
27279
  async function listen(server, path) {
26231
- await new Promise((resolve21, reject) => {
27280
+ await new Promise((resolve22, reject) => {
26232
27281
  server.once("error", reject);
26233
27282
  server.listen(path, () => {
26234
27283
  server.off("error", reject);
26235
- resolve21();
27284
+ resolve22();
26236
27285
  });
26237
27286
  });
26238
27287
  }
@@ -26265,10 +27314,10 @@ async function prepareRoleEnvelope(options) {
26265
27314
  let rejection;
26266
27315
  let infrastructureRoundFailure;
26267
27316
  const hostAbort = new AbortController();
26268
- const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID8();
26269
- await mkdir6(request.runDirectory, { recursive: true });
27317
+ const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID9();
27318
+ await mkdir7(request.runDirectory, { recursive: true });
26270
27319
  let sessionFile = options.sessionFile ?? join41(request.runDirectory, "session", "session.jsonl");
26271
- await mkdir6(dirname22(sessionFile), { recursive: true });
27320
+ await mkdir7(dirname22(sessionFile), { recursive: true });
26272
27321
  if (request.continuation.kind !== "resume") {
26273
27322
  try {
26274
27323
  await writeFile12(
@@ -26287,6 +27336,25 @@ async function prepareRoleEnvelope(options) {
26287
27336
  if (error.code !== "EEXIST") throw error;
26288
27337
  }
26289
27338
  }
27339
+ let durableWriteChain = Promise.resolve();
27340
+ let armDurableWriteFailure;
27341
+ const persistPackageSessionEntry = (entry) => {
27342
+ const customType = typeof entry.customType === "string" ? entry.customType : "unknown";
27343
+ const line2 = `${JSON.stringify({
27344
+ ...entry,
27345
+ id: typeof entry.id === "string" ? entry.id : randomUUID9(),
27346
+ timestamp: typeof entry.timestamp === "string" ? entry.timestamp : (/* @__PURE__ */ new Date()).toISOString()
27347
+ })}
27348
+ `;
27349
+ durableWriteChain = durableWriteChain.then(async () => {
27350
+ try {
27351
+ await appendFile3(sessionFile, line2, "utf8");
27352
+ } catch (error) {
27353
+ const diagnostic = error instanceof Error ? error.message : String(error);
27354
+ armDurableWriteFailure?.(customType, diagnostic);
27355
+ }
27356
+ });
27357
+ };
26290
27358
  const context = {
26291
27359
  cwd: request.cwd,
26292
27360
  mode: "print",
@@ -26309,6 +27377,7 @@ async function prepareRoleEnvelope(options) {
26309
27377
  const entry = { type: "custom", customType, data };
26310
27378
  sessionEntries.push(entry);
26311
27379
  customEntries.push({ customType, data });
27380
+ persistPackageSessionEntry(entry);
26312
27381
  }
26313
27382
  },
26314
27383
  abort() {
@@ -26322,6 +27391,7 @@ async function prepareRoleEnvelope(options) {
26322
27391
  const entry = { type: "custom_message", customType, ...payload, message: payload };
26323
27392
  sessionEntries.push(entry);
26324
27393
  customEntries.push({ customType, data: message.details ?? message.content });
27394
+ persistPackageSessionEntry(entry);
26325
27395
  };
26326
27396
  const emit = async (event, value) => {
26327
27397
  const results = [];
@@ -26401,7 +27471,7 @@ async function prepareRoleEnvelope(options) {
26401
27471
  }
26402
27472
  };
26403
27473
  createRoleRuntimeExtension(options.dependencies)(envelope);
26404
- const token = randomUUID8();
27474
+ const token = randomUUID9();
26405
27475
  const server = createServer((socket) => serveSocket(socket));
26406
27476
  function rememberProjectedRejection(details, toolCallId, content) {
26407
27477
  if (typeof details !== "object" || details === null) return;
@@ -26437,6 +27507,17 @@ async function prepareRoleEnvelope(options) {
26437
27507
  };
26438
27508
  hostAbort.abort();
26439
27509
  }
27510
+ armDurableWriteFailure = (customType, diagnostic) => {
27511
+ rememberInfrastructureFailure(
27512
+ {
27513
+ cause: "infrastructure",
27514
+ kind: "role_infrastructure_failure",
27515
+ code: "durable-session-write-failed",
27516
+ customType
27517
+ },
27518
+ [{ type: "text", text: `ak-role: durable session entry flush failed (${customType}): ${diagnostic}` }]
27519
+ );
27520
+ };
26440
27521
  function declareRoundInfrastructureFailure(error) {
26441
27522
  const diagnostic = error instanceof Error ? error.message : String(error);
26442
27523
  const content = [{ type: "text", text: diagnostic }];
@@ -26482,7 +27563,7 @@ async function prepareRoleEnvelope(options) {
26482
27563
  async function invokeAkTool(name, args) {
26483
27564
  const tool = tools.get(name);
26484
27565
  if (tool === void 0) throw new Error(`Unknown AK tool: ${name}`);
26485
- const toolCallId = randomUUID8();
27566
+ const toolCallId = randomUUID9();
26486
27567
  calls.push({ toolCallId, toolName: name });
26487
27568
  sessionEntries.push({
26488
27569
  type: "message",
@@ -26598,6 +27679,15 @@ async function prepareRoleEnvelope(options) {
26598
27679
  const relay = fileURLToPath2(new URL("./mcp-relay.mjs", import.meta.url));
26599
27680
  await listen(server, options.socketPath);
26600
27681
  let disposed = false;
27682
+ let durableFailureHandedToCloseRound = false;
27683
+ const settleDurableWrites = async () => {
27684
+ await durableWriteChain;
27685
+ if (infrastructureRoundFailure !== void 0) {
27686
+ durableFailureHandedToCloseRound = true;
27687
+ return { accepted: false, failure: infrastructureRoundFailure };
27688
+ }
27689
+ return void 0;
27690
+ };
26601
27691
  const dispose = async () => {
26602
27692
  if (disposed) return;
26603
27693
  disposed = true;
@@ -26607,11 +27697,25 @@ async function prepareRoleEnvelope(options) {
26607
27697
  } catch (error) {
26608
27698
  cleanupFailures.push(error);
26609
27699
  }
27700
+ try {
27701
+ const alreadyHanded = durableFailureHandedToCloseRound;
27702
+ const durableFailure = await settleDurableWrites();
27703
+ if (durableFailure !== void 0 && !alreadyHanded) {
27704
+ cleanupFailures.push(
27705
+ Object.assign(
27706
+ new Error(durableFailure.failure.diagnostic ?? "durable session entry flush failed"),
27707
+ { code: durableFailure.failure.identity?.code ?? "durable-session-write-failed" }
27708
+ )
27709
+ );
27710
+ }
27711
+ } catch (error) {
27712
+ cleanupFailures.push(error);
27713
+ }
26610
27714
  try {
26611
27715
  const closeAll = server.closeAllConnections;
26612
27716
  if (typeof closeAll === "function") closeAll.call(server);
26613
- await new Promise((resolve21, reject) => {
26614
- server.close((error) => error ? reject(error) : resolve21());
27717
+ await new Promise((resolve22, reject) => {
27718
+ server.close((error) => error ? reject(error) : resolve22());
26615
27719
  });
26616
27720
  } catch (error) {
26617
27721
  cleanupFailures.push(error);
@@ -26628,6 +27732,7 @@ async function prepareRoleEnvelope(options) {
26628
27732
  if (calls.some((call) => call.toolName === terminatingToolName)) return;
26629
27733
  await invokeAkTool(terminatingToolName, params ?? {});
26630
27734
  }
27735
+ ;
26631
27736
  const closeRound = async () => {
26632
27737
  if (calls.length > 0) {
26633
27738
  const roundCalls = [...calls];
@@ -26635,6 +27740,7 @@ async function prepareRoleEnvelope(options) {
26635
27740
  await emit("turn_end", { turnIndex: 0, calls: roundCalls });
26636
27741
  }
26637
27742
  if (infrastructureRoundFailure !== void 0) {
27743
+ durableFailureHandedToCloseRound = true;
26638
27744
  return { accepted: false, failure: infrastructureRoundFailure };
26639
27745
  }
26640
27746
  let closure;
@@ -26646,6 +27752,8 @@ async function prepareRoleEnvelope(options) {
26646
27752
  }
26647
27753
  if (closure !== void 0) {
26648
27754
  await emit("agent_settled", {});
27755
+ const durableFailure2 = await settleDurableWrites();
27756
+ if (durableFailure2 !== void 0) return durableFailure2;
26649
27757
  return { accepted: true };
26650
27758
  }
26651
27759
  if (rejection !== void 0) {
@@ -26655,9 +27763,13 @@ async function prepareRoleEnvelope(options) {
26655
27763
  message: rejection.message
26656
27764
  };
26657
27765
  rejection = void 0;
27766
+ const durableFailure2 = await settleDurableWrites();
27767
+ if (durableFailure2 !== void 0) return durableFailure2;
26658
27768
  return { accepted: false, retry };
26659
27769
  }
26660
27770
  await emit("agent_settled", {});
27771
+ const durableFailure = await settleDurableWrites();
27772
+ if (durableFailure !== void 0) return durableFailure;
26661
27773
  return { accepted: true };
26662
27774
  };
26663
27775
  try {
@@ -26743,9 +27855,9 @@ import { readFile as readFile22 } from "node:fs/promises";
26743
27855
  import { join as join42 } from "node:path";
26744
27856
 
26745
27857
  // src/canonical-skill-binding.ts
26746
- import { readFile as readFile20, realpath as realpath7 } from "node:fs/promises";
27858
+ import { readFile as readFile20, realpath as realpath8 } from "node:fs/promises";
26747
27859
  import { homedir } from "node:os";
26748
- import { dirname as dirname23, resolve as resolve18 } from "node:path";
27860
+ import { dirname as dirname23, resolve as resolve19 } from "node:path";
26749
27861
  import { stripFrontmatter } from "@earendil-works/pi-coding-agent";
26750
27862
  function captureCanonicalSkillExpansion(name, snapshot, configuredPath, evidence, originalRequest) {
26751
27863
  const matchedPath = evidence?.location === configuredPath ? configuredPath : evidence?.location === snapshot.path ? snapshot.path : void 0;
@@ -26768,14 +27880,14 @@ var CanonicalSkillUnavailableError = class extends Error {
26768
27880
  code = "canonical-skill-unavailable";
26769
27881
  };
26770
27882
  async function loadCanonicalSkillBinding(name) {
26771
- const configuredPath = resolve18(
27883
+ const configuredPath = resolve19(
26772
27884
  homedir(),
26773
27885
  `.agents/skills/${name}/SKILL.md`
26774
27886
  );
26775
27887
  let path;
26776
27888
  let raw;
26777
27889
  try {
26778
- path = await realpath7(configuredPath);
27890
+ path = await realpath8(configuredPath);
26779
27891
  raw = await readFile20(path, "utf8");
26780
27892
  } catch (error) {
26781
27893
  throw new CanonicalSkillUnavailableError(name, configuredPath, error);
@@ -26816,7 +27928,7 @@ init_doctor_evidence();
26816
27928
  init_doctor_evidence();
26817
27929
  init_host_contracts();
26818
27930
  import { readFile as readFile21 } from "node:fs/promises";
26819
- import { resolve as resolve19 } from "node:path";
27931
+ import { resolve as resolve20 } from "node:path";
26820
27932
  init_notary_source_run();
26821
27933
  init_packaged_role_registry();
26822
27934
  init_invocation();
@@ -26824,7 +27936,7 @@ function navigatorInputReference(getFlag, role) {
26824
27936
  if (getFlag === void 0) return void 0;
26825
27937
  const name = packagedRoleInputFlag(role);
26826
27938
  const value = name === void 0 ? void 0 : getFlag(name);
26827
- return typeof value === "string" && value !== "" ? resolve19(value) : void 0;
27939
+ return typeof value === "string" && value !== "" ? resolve20(value) : void 0;
26828
27940
  }
26829
27941
  async function loadNavigatorWorkContext(options) {
26830
27942
  const reference = navigatorInputReference(options.getFlag, options.role);
@@ -26845,7 +27957,7 @@ async function loadNavigatorWorkContext(options) {
26845
27957
  }
26846
27958
  const publicRunDir = runDirectoryFromHostContext(options.context);
26847
27959
  const currentSessionDir = options.context.sessionManager.getSessionDir();
26848
- const isBoundPublicRun = publicRunDir !== void 0 && resolve19(currentSessionDir) === resolve19(publicRunDir, "session");
27960
+ const isBoundPublicRun = publicRunDir !== void 0 && resolve20(currentSessionDir) === resolve20(publicRunDir, "session");
26849
27961
  if (options.role === "judge" && isBoundPublicRun) {
26850
27962
  let admitted;
26851
27963
  try {
@@ -26878,9 +27990,9 @@ async function loadNavigatorWorkContext(options) {
26878
27990
  }
26879
27991
  const workRoot = subjectRoot.includes("/.ak/work/") ? subjectRoot : void 0;
26880
27992
  const authorityFiles = workRoot === void 0 ? [] : [
26881
- resolve19(workRoot, "authority.md"),
26882
- resolve19(workRoot, "authority.txt"),
26883
- resolve19(workRoot, "design-v2/owner-direction.md")
27993
+ resolve20(workRoot, "authority.md"),
27994
+ resolve20(workRoot, "authority.txt"),
27995
+ resolve20(workRoot, "design-v2/owner-direction.md")
26884
27996
  ];
26885
27997
  let authorityMaterial;
26886
27998
  for (const path of authorityFiles) {
@@ -27064,7 +28176,7 @@ function hostAbortedError(message = "host aborted") {
27064
28176
  function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
27065
28177
  if (abortSignal?.aborted) return Promise.reject(hostAbortedError(message));
27066
28178
  if (abortSignal === void 0) return work;
27067
- return new Promise((resolve21, reject) => {
28179
+ return new Promise((resolve22, reject) => {
27068
28180
  let settled = false;
27069
28181
  const onAbort = () => {
27070
28182
  if (settled) return;
@@ -27079,7 +28191,7 @@ function raceAgainstHostAbort(work, abortSignal, message = "host aborted") {
27079
28191
  if (settled) return;
27080
28192
  settled = true;
27081
28193
  abortSignal.removeEventListener("abort", onAbort);
27082
- resolve21(value);
28194
+ resolve22(value);
27083
28195
  },
27084
28196
  (error) => {
27085
28197
  if (settled) return;
@@ -27171,6 +28283,9 @@ function reportHostSessionEvent(input) {
27171
28283
  });
27172
28284
  }
27173
28285
 
28286
+ // src/acp-host/role-turn-host.ts
28287
+ init_navigator_output();
28288
+
27174
28289
  // src/agent-start-materials.ts
27175
28290
  function renderAgentStartMaterials(body, materials) {
27176
28291
  if (materials.length === 0) return body;
@@ -27183,7 +28298,42 @@ function renderSystemPromptOverride(authority) {
27183
28298
  }
27184
28299
 
27185
28300
  // src/acp-host/role-turn-host.ts
27186
- function failure(cause, name, code, details) {
28301
+ function acpAgentTextChunk(params) {
28302
+ let kind;
28303
+ let content;
28304
+ let textFallback;
28305
+ const nested = params.update;
28306
+ if (typeof nested === "object" && nested !== null && !Array.isArray(nested)) {
28307
+ const record4 = nested;
28308
+ kind = record4.sessionUpdate;
28309
+ content = record4.content;
28310
+ textFallback = record4.text;
28311
+ } else {
28312
+ kind = params.sessionUpdate ?? nested;
28313
+ content = params.content;
28314
+ textFallback = params.text;
28315
+ }
28316
+ if (kind !== "agent_message_chunk" && kind !== "agent_message") return void 0;
28317
+ if (typeof content === "string" && content.length > 0) return content;
28318
+ if (typeof content === "object" && content !== null && !Array.isArray(content)) {
28319
+ const record4 = content;
28320
+ if (typeof record4.text === "string" && record4.text.length > 0) return record4.text;
28321
+ }
28322
+ if (Array.isArray(content)) {
28323
+ const parts = [];
28324
+ for (const part of content) {
28325
+ if (typeof part === "string" && part.length > 0) parts.push(part);
28326
+ else if (typeof part === "object" && part !== null) {
28327
+ const record4 = part;
28328
+ if (typeof record4.text === "string" && record4.text.length > 0) parts.push(record4.text);
28329
+ }
28330
+ }
28331
+ if (parts.length > 0) return parts.join("");
28332
+ }
28333
+ if (typeof textFallback === "string" && textFallback.length > 0) return textFallback;
28334
+ return void 0;
28335
+ }
28336
+ function failure(cause, name, code, details, diagnostic) {
27187
28337
  return {
27188
28338
  code: null,
27189
28339
  stderr: "",
@@ -27191,10 +28341,24 @@ function failure(cause, name, code, details) {
27191
28341
  knownFailure: {
27192
28342
  cause,
27193
28343
  identity: { name, code },
28344
+ ...diagnostic === void 0 ? {} : { diagnostic },
27194
28345
  ...details === void 0 ? {} : { details }
27195
28346
  }
27196
28347
  };
27197
28348
  }
28349
+ function withCleanupFailure(outcome, cleanupError) {
28350
+ const message = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
28351
+ if (outcome.knownFailure === void 0) {
28352
+ return failure("session", "AcpDisposeFailure", "dispose-failed", { cleanupError: message }, message);
28353
+ }
28354
+ return {
28355
+ ...outcome,
28356
+ knownFailure: {
28357
+ ...outcome.knownFailure,
28358
+ details: { ...outcome.knownFailure.details ?? {}, cleanupError: message }
28359
+ }
28360
+ };
28361
+ }
27198
28362
  function acpError(code, message, cause) {
27199
28363
  return Object.assign(new Error(message, cause === void 0 ? void 0 : { cause }), { code });
27200
28364
  }
@@ -27267,8 +28431,8 @@ function connectAcpStdio(options) {
27267
28431
  request(method, params) {
27268
28432
  if (closed) return Promise.reject(terminalError ?? acpError("acp-connection-closed", "ACP connection is closed"));
27269
28433
  const id = ++nextId;
27270
- return new Promise((resolve21, reject) => {
27271
- pending.set(id, { resolve: resolve21, reject });
28434
+ return new Promise((resolve22, reject) => {
28435
+ pending.set(id, { resolve: resolve22, reject });
27272
28436
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
27273
28437
  `, (error) => {
27274
28438
  if (error === null || error === void 0) return;
@@ -27295,7 +28459,7 @@ function connectAcpStdio(options) {
27295
28459
  settleClosed(acpError("acp-connection-closed", "ACP connection is closed"));
27296
28460
  child.stdin.end();
27297
28461
  child.kill("SIGTERM");
27298
- await new Promise((resolve21) => child.once("close", () => resolve21()));
28462
+ await new Promise((resolve22) => child.once("close", () => resolve22()));
27299
28463
  }
27300
28464
  });
27301
28465
  }
@@ -27306,137 +28470,168 @@ function createAcpRoleTurnHost(config) {
27306
28470
  let connection;
27307
28471
  let sessionId;
27308
28472
  let accepted = false;
28473
+ let outcome = failure("session", "AcpNoOutcome", "no-outcome");
27309
28474
  try {
27310
28475
  if (prepared.mcpServers.length === 0) {
27311
- return failure("activation", "UncontrolledAcpSession", "ak-config-missing");
27312
- }
27313
- connection = await config.connect(request);
27314
- const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
27315
- const recordAbort = new AbortController();
27316
- let hostSessionRecordFailure;
27317
- const hostSessionRecordResult = () => ({
27318
- code: null,
27319
- stderr: "",
27320
- timedOut: false,
27321
- knownFailure: hostSessionRecordFailure
27322
- });
27323
- const noteHostSessionRecordFailure = (error) => {
27324
- if (hostSessionRecordFailure !== void 0) return;
27325
- hostSessionRecordFailure = {
27326
- cause: "session",
27327
- identity: { name: "HostSessionRecordFailure", code: "host-session-record-failed" },
27328
- diagnostic: error instanceof Error ? error.message : String(error)
27329
- };
27330
- try {
27331
- recordAbort.abort();
27332
- } catch {
27333
- }
27334
- };
27335
- const rpc = (method, params) => raceAgainstHostAbort(connection.request(method, params), recordAbort.signal, "host-session-record-failed");
27336
- connection.onNotification?.((method, params) => {
27337
- if (method !== "session/update" || hostSessionRecordFailure !== void 0) return;
27338
- try {
27339
- reportHostSessionEvent({
27340
- host: config.hostName,
27341
- cwd: request.cwd,
27342
- sessionParent,
27343
- source: "acp-host",
27344
- event: { method, params }
27345
- });
27346
- } catch (error) {
27347
- noteHostSessionRecordFailure(error);
27348
- }
27349
- });
27350
- try {
27351
- const initialized = await rpc("initialize", {
27352
- protocolVersion: 1,
27353
- clientCapabilities: {}
28476
+ outcome = failure("activation", "UncontrolledAcpSession", "ak-config-missing");
28477
+ } else {
28478
+ connection = await config.connect(request);
28479
+ const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
28480
+ const recordAbort = new AbortController();
28481
+ let hostSessionRecordFailure;
28482
+ const hostSessionRecordResult = () => ({
28483
+ code: null,
28484
+ stderr: "",
28485
+ timedOut: false,
28486
+ knownFailure: hostSessionRecordFailure
27354
28487
  });
27355
- const initializeMeta = initialized._meta;
27356
- const availableModels = Array.isArray(initializeMeta?.modelState?.availableModels) ? initializeMeta.modelState.availableModels : void 0;
27357
- if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === acpModelId(config.modelPassing, request.model))) {
27358
- return failure("activation", "AcpHostModelMismatch", "host-model-mismatch", {
27359
- provider: request.model.provider,
27360
- model: request.model.model
27361
- });
27362
- }
27363
- const sessionBindParams = {
27364
- cwd: request.cwd,
27365
- mcpServers: prepared.mcpServers,
27366
- _meta: { systemPromptOverride, yoloMode: false }
27367
- };
27368
- const loadSession = async (bindSessionId) => {
27369
- const loaded = await rpc("session/load", {
27370
- sessionId: bindSessionId,
27371
- ...sessionBindParams
27372
- });
27373
- return typeof loaded.sessionId === "string" && loaded.sessionId !== "" ? loaded.sessionId : bindSessionId;
28488
+ const noteHostSessionRecordFailure = (error) => {
28489
+ if (hostSessionRecordFailure !== void 0) return;
28490
+ hostSessionRecordFailure = {
28491
+ cause: "session",
28492
+ identity: { name: "HostSessionRecordFailure", code: "host-session-record-failed" },
28493
+ diagnostic: error instanceof Error ? error.message : String(error)
28494
+ };
28495
+ try {
28496
+ recordAbort.abort();
28497
+ } catch {
28498
+ }
27374
28499
  };
27375
- if (request.continuation.kind === "resume" && config.boundResume === "session/load") {
27376
- const boundSessionId = await config.sessionIdentity.load(request.principal);
27377
- if (boundSessionId !== void 0 && boundSessionId !== "") {
27378
- sessionId = await loadSession(boundSessionId);
28500
+ const rpc = (method, params) => raceAgainstHostAbort(connection.request(method, params), recordAbort.signal, "host-session-record-failed");
28501
+ const agentProseChunks = [];
28502
+ let collectAgentProse = false;
28503
+ connection.onNotification?.((method, params) => {
28504
+ if (method !== "session/update" || hostSessionRecordFailure !== void 0) return;
28505
+ if (collectAgentProse) {
28506
+ const chunk = acpAgentTextChunk(params);
28507
+ if (chunk !== void 0) agentProseChunks.push(chunk);
27379
28508
  }
27380
- }
27381
- if (sessionId === void 0) {
27382
- const session = await rpc("session/new", sessionBindParams);
27383
- sessionId = typeof session.sessionId === "string" ? session.sessionId : void 0;
27384
- if (sessionId === void 0 || sessionId === "") {
27385
- return failure("session", "AcpSessionFailure", "session-id-missing");
28509
+ try {
28510
+ reportHostSessionEvent({
28511
+ host: config.hostName,
28512
+ cwd: request.cwd,
28513
+ sessionParent,
28514
+ source: "acp-host",
28515
+ event: { method, params }
28516
+ });
28517
+ } catch (error) {
28518
+ noteHostSessionRecordFailure(error);
27386
28519
  }
27387
- await config.sessionIdentity.bind(request.principal, sessionId);
27388
- }
27389
- if (config.modelPassing === "set_model" && request.model !== void 0 && sessionId !== void 0) {
27390
- await rpc("session/set_model", {
27391
- sessionId,
27392
- modelId: acpModelId(config.modelPassing, request.model)
28520
+ });
28521
+ try {
28522
+ const initialized = await rpc("initialize", {
28523
+ protocolVersion: 1,
28524
+ clientCapabilities: {}
27393
28525
  });
27394
- sessionId = await loadSession(sessionId);
27395
- }
27396
- const activeConnection = connection;
27397
- const activeSessionId = sessionId;
27398
- const turnResult = await driveExternalRoleTurnRounds(prepared, request, {
27399
- roundLimitName: "AcpRoundLimit",
27400
- currentSessionId: () => sessionId,
27401
- async runRound({ prompt, abortSignal }) {
27402
- if (hostSessionRecordFailure !== void 0) return { status: "terminal", result: hostSessionRecordResult() };
27403
- const abortParts = [recordAbort.signal];
27404
- if (abortSignal !== void 0) abortParts.push(abortSignal);
27405
- const combinedAbort = AbortSignal.any(abortParts);
27406
- let result;
27407
- try {
27408
- result = await raceAgainstHostAbort(
27409
- activeConnection.request("session/prompt", {
27410
- sessionId: activeSessionId,
27411
- prompt: [{ type: "text", text: prompt }]
27412
- }),
27413
- combinedAbort,
27414
- "ACP host aborted"
27415
- );
27416
- } catch (error) {
27417
- if (hostSessionRecordFailure !== void 0) {
27418
- return { status: "terminal", result: hostSessionRecordResult() };
28526
+ const initializeMeta = initialized._meta;
28527
+ const availableModels = Array.isArray(initializeMeta?.modelState?.availableModels) ? initializeMeta.modelState.availableModels : void 0;
28528
+ if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === acpModelId(config.modelPassing, request.model))) {
28529
+ outcome = failure("activation", "AcpHostModelMismatch", "host-model-mismatch", {
28530
+ provider: request.model.provider,
28531
+ model: request.model.model
28532
+ });
28533
+ } else {
28534
+ const sessionBindParams = {
28535
+ cwd: request.cwd,
28536
+ mcpServers: prepared.mcpServers,
28537
+ _meta: { systemPromptOverride, yoloMode: false }
28538
+ };
28539
+ const loadSession = async (bindSessionId) => {
28540
+ const loaded = await rpc("session/load", {
28541
+ sessionId: bindSessionId,
28542
+ ...sessionBindParams
28543
+ });
28544
+ return typeof loaded.sessionId === "string" && loaded.sessionId !== "" ? loaded.sessionId : bindSessionId;
28545
+ };
28546
+ if (request.continuation.kind === "resume" && config.boundResume === "session/load") {
28547
+ const boundSessionId = await config.sessionIdentity.load(request.principal);
28548
+ if (boundSessionId !== void 0 && boundSessionId !== "") {
28549
+ sessionId = await loadSession(boundSessionId);
27419
28550
  }
27420
- throw error;
27421
28551
  }
27422
- if (result.stopReason === "refusal") {
27423
- return {
27424
- status: "terminal",
27425
- result: failure("output", "AcpRefusal", "refusal", { sessionId })
27426
- };
28552
+ let sessionReady = true;
28553
+ if (sessionId === void 0) {
28554
+ const session = await rpc("session/new", sessionBindParams);
28555
+ sessionId = typeof session.sessionId === "string" ? session.sessionId : void 0;
28556
+ if (sessionId === void 0 || sessionId === "") {
28557
+ outcome = failure("session", "AcpSessionFailure", "session-id-missing");
28558
+ sessionReady = false;
28559
+ } else {
28560
+ await config.sessionIdentity.bind(request.principal, sessionId);
28561
+ }
28562
+ }
28563
+ if (sessionReady) {
28564
+ if (config.modelPassing === "set_model" && request.model !== void 0 && sessionId !== void 0) {
28565
+ await rpc("session/set_model", {
28566
+ sessionId,
28567
+ modelId: acpModelId(config.modelPassing, request.model)
28568
+ });
28569
+ sessionId = await loadSession(sessionId);
28570
+ }
28571
+ const activeConnection = connection;
28572
+ const activeSessionId = sessionId;
28573
+ const turnResult = await driveExternalRoleTurnRounds(prepared, request, {
28574
+ roundLimitName: "AcpRoundLimit",
28575
+ currentSessionId: () => sessionId,
28576
+ async runRound({ prompt, abortSignal }) {
28577
+ if (hostSessionRecordFailure !== void 0) return { status: "terminal", result: hostSessionRecordResult() };
28578
+ const abortParts = [recordAbort.signal];
28579
+ if (abortSignal !== void 0) abortParts.push(abortSignal);
28580
+ const combinedAbort = AbortSignal.any(abortParts);
28581
+ let result;
28582
+ agentProseChunks.length = 0;
28583
+ collectAgentProse = prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME;
28584
+ try {
28585
+ result = await raceAgainstHostAbort(
28586
+ activeConnection.request("session/prompt", {
28587
+ sessionId: activeSessionId,
28588
+ prompt: [{ type: "text", text: prompt }]
28589
+ }),
28590
+ combinedAbort,
28591
+ "ACP host aborted"
28592
+ );
28593
+ } catch (error) {
28594
+ collectAgentProse = false;
28595
+ agentProseChunks.length = 0;
28596
+ if (hostSessionRecordFailure !== void 0) {
28597
+ return { status: "terminal", result: hostSessionRecordResult() };
28598
+ }
28599
+ throw error;
28600
+ }
28601
+ collectAgentProse = false;
28602
+ if (result.stopReason === "refusal") {
28603
+ agentProseChunks.length = 0;
28604
+ return {
28605
+ status: "terminal",
28606
+ result: failure("output", "AcpRefusal", "refusal", { sessionId })
28607
+ };
28608
+ }
28609
+ if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME) {
28610
+ const prose = agentProseChunks.join("");
28611
+ agentProseChunks.length = 0;
28612
+ if (navigatorProseFromUnknown(prose) !== void 0) {
28613
+ await prepared.ingestStructuredOutput({ prose });
28614
+ }
28615
+ } else {
28616
+ agentProseChunks.length = 0;
28617
+ }
28618
+ return { status: "delivered", stderr: activeConnection.stderr?.() ?? "" };
28619
+ },
28620
+ async afterAccepted() {
28621
+ await rpc("session/close", { sessionId: activeSessionId });
28622
+ accepted = true;
28623
+ }
28624
+ });
28625
+ outcome = hostSessionRecordFailure !== void 0 ? hostSessionRecordResult() : turnResult;
27427
28626
  }
27428
- return { status: "delivered", stderr: activeConnection.stderr?.() ?? "" };
27429
- },
27430
- async afterAccepted() {
27431
- await rpc("session/close", { sessionId: activeSessionId });
27432
- accepted = true;
27433
28627
  }
27434
- });
27435
- if (hostSessionRecordFailure !== void 0) return hostSessionRecordResult();
27436
- return turnResult;
27437
- } catch (error) {
27438
- if (hostSessionRecordFailure !== void 0) return hostSessionRecordResult();
27439
- throw error;
28628
+ } catch (error) {
28629
+ if (hostSessionRecordFailure !== void 0) {
28630
+ outcome = hostSessionRecordResult();
28631
+ } else {
28632
+ throw error;
28633
+ }
28634
+ }
27440
28635
  }
27441
28636
  } finally {
27442
28637
  if (connection !== void 0) {
@@ -27453,16 +28648,18 @@ function createAcpRoleTurnHost(config) {
27453
28648
  }
27454
28649
  try {
27455
28650
  await prepared.dispose?.();
27456
- } catch {
28651
+ } catch (cleanupError) {
28652
+ outcome = withCleanupFailure(outcome, cleanupError);
27457
28653
  }
27458
28654
  }
28655
+ return outcome;
27459
28656
  });
27460
28657
  }
27461
28658
 
27462
28659
  // src/acp-host/seat-profile-soul.ts
27463
28660
  import { constants as constants3 } from "node:fs";
27464
- import { access as access4, copyFile, lstat as lstat8, mkdir as mkdir7, readlink as readlink2, symlink as symlink2, unlink as unlink3 } from "node:fs/promises";
27465
- import { dirname as dirname25, join as join44, relative as relative3, resolve as resolve20 } from "node:path";
28661
+ import { access as access4, copyFile, lstat as lstat8, mkdir as mkdir8, readlink as readlink2, symlink as symlink2, unlink as unlink3 } from "node:fs/promises";
28662
+ import { dirname as dirname25, join as join44, relative as relative4, resolve as resolve21 } from "node:path";
27466
28663
  function seatProfileName(spec, role) {
27467
28664
  return `${spec.namePrefix}${role}`;
27468
28665
  }
@@ -27480,7 +28677,7 @@ async function pathExists2(path) {
27480
28677
  async function ensureSeatProfileSoul(options) {
27481
28678
  const { spec, operatorHome, packageRoot, role } = options;
27482
28679
  const profileName = seatProfileName(spec, role);
27483
- const soulTarget = resolve20(packageRoleSoulPath(packageRoot, role));
28680
+ const soulTarget = resolve21(packageRoleSoulPath(packageRoot, role));
27484
28681
  if (!await pathExists2(soulTarget)) {
27485
28682
  throw new Error(`packaged role soul missing: ${soulTarget}`);
27486
28683
  }
@@ -27489,16 +28686,16 @@ async function ensureSeatProfileSoul(options) {
27489
28686
  const hostRoot = dirname25(profilesRoot);
27490
28687
  const soulPath = join44(profileDir, spec.soulFileName);
27491
28688
  if (!await pathExists2(profileDir)) {
27492
- await mkdir7(profileDir, { recursive: true });
28689
+ await mkdir8(profileDir, { recursive: true });
27493
28690
  for (const name of ["auth.json", ".env", "config.yaml"]) {
27494
28691
  const source = join44(hostRoot, name);
27495
28692
  if (!await pathExists2(source)) continue;
27496
28693
  await copyFile(source, join44(profileDir, name));
27497
28694
  }
27498
28695
  } else {
27499
- await mkdir7(profileDir, { recursive: true });
28696
+ await mkdir8(profileDir, { recursive: true });
27500
28697
  }
27501
- const desiredLink = relative3(profileDir, soulTarget);
28698
+ const desiredLink = relative4(profileDir, soulTarget);
27502
28699
  let current;
27503
28700
  try {
27504
28701
  const st = await lstat8(soulPath);
@@ -27526,7 +28723,7 @@ function createComposedAcpRoleTurnHost(config) {
27526
28723
  request,
27527
28724
  dependencies: config.roleRuntimeDependencies,
27528
28725
  sessionFile: config.sessionIdentity.resolveSessionFile(request.principal),
27529
- socketPath: config.socketPath?.(request) ?? `/tmp/ak-acp-mcp-${randomUUID9()}.sock`
28726
+ socketPath: config.socketPath?.(request) ?? `/tmp/ak-acp-mcp-${randomUUID10()}.sock`
27530
28727
  })
27531
28728
  });
27532
28729
  }