@akagilnc/pi-workflow-roles 0.1.5478 → 0.1.5504

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 (79) hide show
  1. package/dist/acp-host/production-host.js +4945 -4980
  2. package/dist/analyst-gate-cycles-read.js +11 -29
  3. package/dist/analyst-ledger.js +10 -12
  4. package/dist/archivist-record-entry.js +4 -3
  5. package/dist/archivist-record-pointer.js +59 -32
  6. package/dist/atomic-write.js +2 -2
  7. package/dist/auditor-dossier-tool.js +8 -4
  8. package/dist/auditor-soul.js +2 -1
  9. package/dist/collector-config.js +6 -5
  10. package/dist/doctor-evidence.js +5 -1
  11. package/dist/engine-detour-usage.js +4 -10
  12. package/dist/headless-host/description.js +251 -0
  13. package/dist/headless-host/production-host.js +2787 -2658
  14. package/dist/ledger-session-read.js +5 -0
  15. package/dist/migrate-book-topology.js +129 -100
  16. package/dist/navigator-public-session.js +13 -17
  17. package/dist/notary-source-run.js +7 -15
  18. package/dist/packaged-role-registry.js +0 -12
  19. package/dist/pi/durable-principal.js +2 -3
  20. package/dist/pi/role-turn-host.js +27 -13
  21. package/dist/public-cli/instruction-seat-run.js +4 -4
  22. package/dist/public-cli/invocation.js +17 -45
  23. package/dist/public-cli/main.js +1074 -1085
  24. package/dist/public-cli/run-lifecycle.js +17 -47
  25. package/dist/public-cli/settlement.js +28 -128
  26. package/dist/public-cli/terminal.js +0 -12
  27. package/dist/role-run-placement.js +52 -5
  28. package/dist/role-run-relocation.js +39 -2
  29. package/dist/run-terminal-artifacts.js +2 -6
  30. package/dist/run-ticket-number.js +33 -4
  31. package/dist/session-assistant-usage.js +9 -18
  32. package/dist/session-identity.js +3 -4
  33. package/dist/sitian-appender.js +20 -6
  34. package/dist/submission-ledger.js +4 -4
  35. package/dist/ticket-provenance-contracts.js +2 -8
  36. package/dist/ticket-provenance.js +5 -4
  37. package/package.json +1 -1
  38. package/src/acp-host/role-turn-host.ts +2 -2
  39. package/src/analyst-gate-cycles-read.ts +11 -34
  40. package/src/analyst-ledger.ts +14 -14
  41. package/src/archivist-record-entry.ts +4 -3
  42. package/src/archivist-record-pointer.ts +70 -34
  43. package/src/atomic-write.ts +3 -1
  44. package/src/auditor-dossier-tool.ts +8 -4
  45. package/src/auditor-soul.ts +2 -1
  46. package/src/collector-config.ts +5 -3
  47. package/src/doctor-evidence.ts +5 -1
  48. package/src/engine-detour-usage.ts +10 -13
  49. package/src/factory-board.ts +16 -81
  50. package/src/headless-host/description.ts +248 -1
  51. package/src/headless-host/production-host.ts +1 -2
  52. package/src/headless-host/role-turn-host.ts +10 -9
  53. package/src/ledger-session-read.ts +6 -0
  54. package/src/navigator-public-session.ts +13 -18
  55. package/src/navigator-work-context.ts +3 -1
  56. package/src/notary-role.ts +2 -1
  57. package/src/notary-source-run.ts +7 -17
  58. package/src/packaged-role-registry.ts +0 -15
  59. package/src/pi/durable-principal.ts +2 -4
  60. package/src/pi/role-turn-host.ts +35 -12
  61. package/src/public-cli/instruction-seat-run.ts +4 -4
  62. package/src/public-cli/invocation.ts +29 -57
  63. package/src/public-cli/run-lifecycle.ts +20 -43
  64. package/src/public-cli/settlement.ts +30 -173
  65. package/src/public-cli/terminal.ts +0 -60
  66. package/src/role-envelope.ts +4 -2
  67. package/src/role-run-placement.ts +63 -4
  68. package/src/role-run-relocation.ts +39 -2
  69. package/src/role-runtime.ts +40 -59
  70. package/src/run-terminal-artifacts.ts +3 -5
  71. package/src/run-ticket-number.ts +41 -3
  72. package/src/session-assistant-usage.ts +8 -20
  73. package/src/session-identity.ts +3 -4
  74. package/src/sitian-appender.ts +20 -12
  75. package/src/submission-ledger.ts +4 -4
  76. package/src/ticket-provenance-contracts.ts +3 -6
  77. package/src/ticket-provenance.ts +5 -6
  78. package/src/ticket-snapshot.ts +3 -2
  79. package/src/ticket-trajectory.ts +85 -99
@@ -831,17 +831,47 @@ var init_activation_ledger_topology = __esm({
831
831
  var run_ticket_number_exports = {};
832
832
  __export(run_ticket_number_exports, {
833
833
  MIGRATION_TICKET_DERIVATION_PAGE: () => MIGRATION_TICKET_DERIVATION_PAGE,
834
+ isPositiveTicketNumber: () => isPositiveTicketNumber,
834
835
  isSafePositiveTicketNumber: () => isSafePositiveTicketNumber,
836
+ isTicketNumberString: () => isTicketNumberString,
837
+ parseTicketNumber: () => parseTicketNumber,
835
838
  readBoardTicketNumber: () => readBoardTicketNumber,
836
839
  readDeclaredTicketNumber: () => readDeclaredTicketNumber,
837
840
  readMigrationDerivedTicketNumber: () => readMigrationDerivedTicketNumber,
838
841
  readRunTicketNumber: () => readRunTicketNumber,
839
- requireSafePositiveTicketNumber: () => requireSafePositiveTicketNumber
842
+ requireSafePositiveTicketNumber: () => requireSafePositiveTicketNumber,
843
+ sitianSubjectTicketNumber: () => sitianSubjectTicketNumber,
844
+ ticketNumberFromSitianSubject: () => ticketNumberFromSitianSubject
840
845
  });
841
846
  import { readFile } from "node:fs/promises";
842
847
  import { join as join3 } from "node:path";
848
+ function isPositiveTicketNumber(value) {
849
+ return typeof value === "number" && Number.isInteger(value) && value >= 1;
850
+ }
843
851
  function isSafePositiveTicketNumber(value) {
844
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
852
+ return isPositiveTicketNumber(value) && Number.isSafeInteger(value);
853
+ }
854
+ function isTicketNumberString(value) {
855
+ return typeof value === "string" && /^[1-9][0-9]*$/.test(value);
856
+ }
857
+ function parseTicketNumber(value) {
858
+ if (isSafePositiveTicketNumber(value)) return value;
859
+ if (!isTicketNumberString(value)) return void 0;
860
+ const parsed = Number(value);
861
+ return isSafePositiveTicketNumber(parsed) ? parsed : void 0;
862
+ }
863
+ function sitianSubjectTicketNumber(subject) {
864
+ if (typeof subject === "string" || typeof subject === "number") {
865
+ return parseTicketNumber(subject);
866
+ }
867
+ if (subject !== null && typeof subject === "object" && !Array.isArray(subject)) {
868
+ return parseTicketNumber(subject.ticketNumber);
869
+ }
870
+ return void 0;
871
+ }
872
+ function ticketNumberFromSitianSubject(subject) {
873
+ const parsed = sitianSubjectTicketNumber(subject);
874
+ return parsed === void 0 ? void 0 : String(parsed);
845
875
  }
846
876
  function readDeclaredTicketNumber(value) {
847
877
  if (isSafePositiveTicketNumber(value)) return value;
@@ -849,8 +879,7 @@ function readDeclaredTicketNumber(value) {
849
879
  const trimmed = value.trim();
850
880
  const match = /^#?([1-9]\d*)(?!\.\d)(?:\b|$)/.exec(trimmed);
851
881
  if (match === null) return void 0;
852
- const ticketNumber = Number(match[1]);
853
- return isSafePositiveTicketNumber(ticketNumber) ? ticketNumber : void 0;
882
+ return parseTicketNumber(match[1]);
854
883
  }
855
884
  function requireSafePositiveTicketNumber(ticketNumber, context = "ticketNumber") {
856
885
  if (!isSafePositiveTicketNumber(ticketNumber)) {
@@ -905,7 +934,30 @@ var init_run_ticket_number = __esm({
905
934
 
906
935
  // src/role-run-placement.ts
907
936
  import { readdir } from "node:fs/promises";
908
- import { join as join4 } from "node:path";
937
+ import { basename as basename3, dirname as dirname4, join as join4 } from "node:path";
938
+ function formatRunLeaf(runId, role) {
939
+ return `${runId}@${role}`;
940
+ }
941
+ function parseRunLeaf(name) {
942
+ const at = name.lastIndexOf("@");
943
+ if (at <= 0 || at === name.length - 1) return void 0;
944
+ return { runId: name.slice(0, at), role: name.slice(at + 1) };
945
+ }
946
+ function sessionDirectoryOf(runDirectory) {
947
+ return join4(runDirectory, "session");
948
+ }
949
+ function sessionFileIn(sessionDirectory) {
950
+ return join4(sessionDirectory, ROLE_RUN_SESSION_FILENAME);
951
+ }
952
+ function sessionFileOf(runDirectory) {
953
+ return sessionFileIn(sessionDirectoryOf(runDirectory));
954
+ }
955
+ function runDirectoryOfSessionFile(sessionFile) {
956
+ return dirname4(dirname4(sessionFile));
957
+ }
958
+ function runDirectoryFromSessionDirectory(sessionDirectory) {
959
+ return dirname4(sessionDirectory);
960
+ }
909
961
  async function listBookRunDirectories(bookDir) {
910
962
  const out = [];
911
963
  const seen = /* @__PURE__ */ new Set();
@@ -939,6 +991,20 @@ async function listBookRunDirectories(bookDir) {
939
991
  }
940
992
  return out.sort();
941
993
  }
994
+ async function findRoleRunDirectory(bookDirectories, runId, onlyRole) {
995
+ const matches = [];
996
+ for (const bookDirectory of bookDirectories) {
997
+ for (const runDirectory of await listBookRunDirectories(bookDirectory)) {
998
+ const parsed = parseRunLeaf(basename3(runDirectory));
999
+ if (parsed === void 0 || parsed.runId !== runId) continue;
1000
+ if (onlyRole !== void 0 && parsed.role !== onlyRole) continue;
1001
+ matches.push(runDirectory);
1002
+ }
1003
+ }
1004
+ if (matches.length === 0) return void 0;
1005
+ if (matches.length === 1) return matches[0];
1006
+ throw new Error(`ambiguous role run id ${runId}: ${matches.join(", ")}`);
1007
+ }
942
1008
  function roleRunPlacement(ledgerHome, input) {
943
1009
  const subjectDirectory = "ticketNumber" in input.subject ? String(requireSafePositiveTicketNumber(
944
1010
  input.subject.ticketNumber,
@@ -948,13 +1014,13 @@ function roleRunPlacement(ledgerHome, input) {
948
1014
  activationBookDirectory(ledgerHome, input.bookKey),
949
1015
  subjectDirectory,
950
1016
  "runs",
951
- `${input.runId}@${input.role}`
1017
+ formatRunLeaf(input.runId, input.role)
952
1018
  );
953
- const sessionDirectory = join4(runDirectory, "session");
1019
+ const sessionDirectory = sessionDirectoryOf(runDirectory);
954
1020
  return {
955
1021
  runDirectory,
956
1022
  sessionDirectory,
957
- sessionFile: join4(sessionDirectory, "session.jsonl"),
1023
+ sessionFile: sessionFileIn(sessionDirectory),
958
1024
  artifactsDirectory: roleRunArtifactsDirectory(runDirectory),
959
1025
  attachmentsDirectory: join4(runDirectory, "attachments")
960
1026
  };
@@ -976,12 +1042,14 @@ function ensureRoleRunPlacement(ledgerHome, placement) {
976
1042
  ensureRoleRunDirectory(ledgerHome, directory);
977
1043
  }
978
1044
  }
1045
+ var ROLE_RUN_SESSION_FILENAME;
979
1046
  var init_role_run_placement = __esm({
980
1047
  "src/role-run-placement.ts"() {
981
1048
  "use strict";
982
1049
  init_activation_ledger_topology();
983
1050
  init_run_ticket_number();
984
1051
  init_unknown_value();
1052
+ ROLE_RUN_SESSION_FILENAME = "session.jsonl";
985
1053
  }
986
1054
  });
987
1055
 
@@ -991,7 +1059,6 @@ __export(durable_principal_exports, {
991
1059
  issuePiDurablePrincipalCoordinates: () => issuePiDurablePrincipalCoordinates,
992
1060
  piDurablePrincipalAuthority: () => piDurablePrincipalAuthority
993
1061
  });
994
- import { join as join5 } from "node:path";
995
1062
  function encode(coordinates) {
996
1063
  return coordinates;
997
1064
  }
@@ -1041,7 +1108,7 @@ var init_durable_principal = __esm({
1041
1108
  }
1042
1109
  return {
1043
1110
  sessionDirectory: record.sessionDirectory,
1044
- sessionFile: typeof record.sessionFile === "string" && record.sessionFile.trim() !== "" ? record.sessionFile : join5(record.sessionDirectory, "session.jsonl")
1111
+ sessionFile: typeof record.sessionFile === "string" && record.sessionFile.trim() !== "" ? record.sessionFile : sessionFileIn(record.sessionDirectory)
1045
1112
  };
1046
1113
  }
1047
1114
  };
@@ -1050,7 +1117,7 @@ var init_durable_principal = __esm({
1050
1117
 
1051
1118
  // src/package-resources/engine-material.ts
1052
1119
  import { existsSync as existsSync2, readdirSync } from "node:fs";
1053
- import { join as join6 } from "node:path";
1120
+ import { join as join5 } from "node:path";
1054
1121
  function pickEngineAxis(source) {
1055
1122
  return {
1056
1123
  ...source.engine === void 0 ? {} : { engine: source.engine },
@@ -1071,11 +1138,11 @@ function isEngineNameSyntax(name) {
1071
1138
  return true;
1072
1139
  }
1073
1140
  function resolveEngineMaterialDirectory(packageRoot2) {
1074
- return join6(packageRoot2, ENGINE_MATERIAL_RELATIVE_ROOT);
1141
+ return join5(packageRoot2, ENGINE_MATERIAL_RELATIVE_ROOT);
1075
1142
  }
1076
1143
  function resolveEngineMaterialPath(packageRoot2, name) {
1077
1144
  const legal = assertLegalEngineName(name);
1078
- return join6(resolveEngineMaterialDirectory(packageRoot2), `${legal}.md`);
1145
+ return join5(resolveEngineMaterialDirectory(packageRoot2), `${legal}.md`);
1079
1146
  }
1080
1147
  function assertLegalEngineName(name) {
1081
1148
  if (!isEngineNameSyntax(name)) {
@@ -14892,6 +14959,7 @@ var TICKET_PROVENANCE_KIND;
14892
14959
  var init_ticket_provenance_contracts = __esm({
14893
14960
  "src/ticket-provenance-contracts.ts"() {
14894
14961
  "use strict";
14962
+ init_run_ticket_number();
14895
14963
  init_unknown_value();
14896
14964
  TICKET_PROVENANCE_KIND = "ticket-provenance";
14897
14965
  }
@@ -15014,7 +15082,6 @@ __export(packaged_role_registry_exports, {
15014
15082
  packagedRoleOutputTool: () => packagedRoleOutputTool,
15015
15083
  packagedRolePhaseFlag: () => packagedRolePhaseFlag,
15016
15084
  packagedRoleSessionMaterials: () => packagedRoleSessionMaterials,
15017
- packagedSkipsGateOnInfrastructureStage: () => packagedSkipsGateOnInfrastructureStage,
15018
15085
  packagedStoresSourceRunRaw: () => packagedStoresSourceRunRaw,
15019
15086
  packagedSubjectChoices: () => packagedSubjectChoices
15020
15087
  });
@@ -15116,11 +15183,6 @@ function packagedAuditToolName(role) {
15116
15183
  if (record === void 0 || !("auditTool" in record)) return void 0;
15117
15184
  return record.auditTool;
15118
15185
  }
15119
- function packagedSkipsGateOnInfrastructureStage(stage) {
15120
- return typeof stage === "string" && PUBLIC_ROLE_RECORDS.some(
15121
- (record) => "skipGateOnInfrastructureStage" in record && record.skipGateOnInfrastructureStage === true && record.role === stage
15122
- );
15123
- }
15124
15186
  function packagedDurableOfficerEntry(officer) {
15125
15187
  return typeof officer === "string" && PUBLIC_ROLE_RECORDS.some(
15126
15188
  (record) => "durableOfficerEntry" in record && record.durableOfficerEntry === true && record.role === officer
@@ -15473,8 +15535,6 @@ var init_packaged_role_registry = __esm({
15473
15535
  sourceRunStored: "raw",
15474
15536
  argvResult: "source-run",
15475
15537
  sameParent: "source-locator",
15476
- /** Infrastructure failure at this stage has no accepted gate cycle to project. */
15477
- skipGateOnInfrastructureStage: true,
15478
15538
  /** 符宝郎 is a review officer and inherits the gatekeeper model. */
15479
15539
  reviewOfficer: true,
15480
15540
  provinceConfig: true,
@@ -15582,8 +15642,6 @@ var init_packaged_role_registry = __esm({
15582
15642
  sameParent: "gate-pointer",
15583
15643
  /** Resume restores an optional source-run path onto the admitted face. */
15584
15644
  resumeSourcePath: true,
15585
- /** Infrastructure failure at this stage has no accepted gate cycle to project. */
15586
- skipGateOnInfrastructureStage: true,
15587
15645
  /** 台院 is a review officer and inherits the gatekeeper model. */
15588
15646
  reviewOfficer: true,
15589
15647
  provinceConfig: true,
@@ -15615,8 +15673,6 @@ var init_packaged_role_registry = __esm({
15615
15673
  presentSettled: "always",
15616
15674
  summonResume: true,
15617
15675
  admission: "instruction",
15618
- /** Infrastructure failure at this stage has no accepted gate cycle to project. */
15619
- skipGateOnInfrastructureStage: true,
15620
15676
  sameParent: "none",
15621
15677
  /** Province model root. Officers name this seat via modelInheritsFrom. */
15622
15678
  provinceConfig: true,
@@ -15775,9 +15831,9 @@ var init_institutional_resolution = __esm({
15775
15831
  });
15776
15832
 
15777
15833
  // src/host-descriptions.ts
15778
- import { join as join7 } from "node:path";
15834
+ import { join as join6 } from "node:path";
15779
15835
  function resolveHostBinary(description, operatorHome) {
15780
- return join7(operatorHome, ...description.binaryFromHome);
15836
+ return join6(operatorHome, ...description.binaryFromHome);
15781
15837
  }
15782
15838
  function lookupHostDescription(host) {
15783
15839
  return Object.hasOwn(HOST_DESCRIPTIONS, host) ? HOST_DESCRIPTIONS[host] : void 0;
@@ -15913,7 +15969,7 @@ __export(config_exports, {
15913
15969
  validatePublicCliConfigAxes: () => validatePublicCliConfigAxes
15914
15970
  });
15915
15971
  import { mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
15916
- import { dirname as dirname4, join as join8 } from "node:path";
15972
+ import { dirname as dirname5, join as join7 } from "node:path";
15917
15973
  function isGateOfficerSeat(value) {
15918
15974
  return packagedProvinceConfig(value);
15919
15975
  }
@@ -15921,7 +15977,7 @@ function publicCliConfigPath(home) {
15921
15977
  if (typeof home !== "string" || home.trim() === "") {
15922
15978
  throw new Error("home must be explicitly provided");
15923
15979
  }
15924
- return join8(home, ".ak-roles", "public-cli.json");
15980
+ return join7(home, ".ak-roles", "public-cli.json");
15925
15981
  }
15926
15982
  async function loadPublicCliConfig(home) {
15927
15983
  const path = publicCliConfigPath(home);
@@ -15935,7 +15991,7 @@ async function loadPublicCliConfig(home) {
15935
15991
  }
15936
15992
  async function savePublicCliConfig(config, home) {
15937
15993
  const path = publicCliConfigPath(home);
15938
- await mkdir(dirname4(path), { recursive: true });
15994
+ await mkdir(dirname5(path), { recursive: true });
15939
15995
  const normalized = parsePublicCliConfig(config);
15940
15996
  await writeFile(
15941
15997
  path,
@@ -16381,11 +16437,11 @@ function credentialProvidersFromAuthData(data) {
16381
16437
  };
16382
16438
  }
16383
16439
  function resolvePublicAgentDir(explicit, home) {
16384
- return explicit ?? process.env.PI_CODING_AGENT_DIR ?? join8(home, ".pi", "agent");
16440
+ return explicit ?? process.env.PI_CODING_AGENT_DIR ?? join7(home, ".pi", "agent");
16385
16441
  }
16386
16442
  async function loadCredentialProviders(agentDir) {
16387
16443
  try {
16388
- const raw = await readFile2(join8(agentDir, "auth.json"), "utf8");
16444
+ const raw = await readFile2(join7(agentDir, "auth.json"), "utf8");
16389
16445
  return credentialProvidersFromAuthData(JSON.parse(raw));
16390
16446
  } catch (error) {
16391
16447
  if (isEnoent(error)) return { "openai-codex": false, xai: false };
@@ -16410,15 +16466,15 @@ var init_config2 = __esm({
16410
16466
 
16411
16467
  // src/public-cli/host-providers.ts
16412
16468
  import { readFileSync } from "node:fs";
16413
- import { join as join9 } from "node:path";
16469
+ import { join as join8 } from "node:path";
16414
16470
  function hostProvidersPath(home) {
16415
16471
  if (typeof home !== "string" || home.trim() === "") {
16416
16472
  throw new Error("home must be explicitly provided");
16417
16473
  }
16418
- return join9(home, ".ak-roles", "host-providers.json");
16474
+ return join8(home, ".ak-roles", "host-providers.json");
16419
16475
  }
16420
16476
  function hermesProviderModelsCachePath(home) {
16421
- return join9(home, ".hermes", "provider_models_cache.json");
16477
+ return join8(home, ".hermes", "provider_models_cache.json");
16422
16478
  }
16423
16479
  function parseHostProvidersTable(value) {
16424
16480
  if (!isRecord(value)) {
@@ -16592,16 +16648,16 @@ var init_cli_errors = __esm({
16592
16648
  // src/public-cli/machine-method-skills.ts
16593
16649
  import { accessSync, constants, statSync as statSync2 } from "node:fs";
16594
16650
  import { lstat, mkdir as mkdir2, symlink } from "node:fs/promises";
16595
- import { join as join10 } from "node:path";
16651
+ import { join as join9 } from "node:path";
16596
16652
  import { spawnSync } from "node:child_process";
16597
16653
  function skillRoot(home) {
16598
- return join10(home, ".agents/skills");
16654
+ return join9(home, ".agents/skills");
16599
16655
  }
16600
16656
  function installedMethodSkillPath(home, name) {
16601
16657
  return installedSkillPath(skillRoot(home), name);
16602
16658
  }
16603
16659
  function installedSkillPath(root, name) {
16604
- const path = join10(root, name, "SKILL.md");
16660
+ const path = join9(root, name, "SKILL.md");
16605
16661
  try {
16606
16662
  if (!statSync2(path).isFile()) return void 0;
16607
16663
  accessSync(path, constants.R_OK);
@@ -16614,9 +16670,9 @@ function installedSkillPath(root, name) {
16614
16670
  }
16615
16671
  function linkedSkillRoot(home, host) {
16616
16672
  if (host === "claude" || host === "claude-code") {
16617
- return join10(process.env.CLAUDE_CONFIG_DIR?.trim() || join10(home, ".claude"), "skills");
16673
+ return join9(process.env.CLAUDE_CONFIG_DIR?.trim() || join9(home, ".claude"), "skills");
16618
16674
  }
16619
- if (host === "hermes") return join10(home, ".hermes/skills");
16675
+ if (host === "hermes") return join9(home, ".hermes/skills");
16620
16676
  return void 0;
16621
16677
  }
16622
16678
  async function occupied(path) {
@@ -16673,7 +16729,7 @@ async function runMachineSkillSetup(home, stdout) {
16673
16729
  const missingBySource = /* @__PURE__ */ new Map();
16674
16730
  let unsourced = false;
16675
16731
  for (const name of packagedMethodSkillNames()) {
16676
- const path = join10(canonical, name);
16732
+ const path = join9(canonical, name);
16677
16733
  if (await occupied(path)) {
16678
16734
  warnOccupied(path, stdout);
16679
16735
  continue;
@@ -16703,9 +16759,9 @@ async function runMachineSkillSetup(home, stdout) {
16703
16759
  throw error;
16704
16760
  }
16705
16761
  for (const name of packagedMethodSkillNames()) {
16706
- const target = join10(canonical, name);
16762
+ const target = join9(canonical, name);
16707
16763
  if (installedMethodSkillPath(home, name) === void 0) continue;
16708
- const link = join10(root, name);
16764
+ const link = join9(root, name);
16709
16765
  if (await occupied(link)) {
16710
16766
  warnOccupied(link, stdout);
16711
16767
  continue;
@@ -16768,10 +16824,9 @@ function parseCollectorRepository(raw) {
16768
16824
  return { display: raw, canonical: `${owner}/${repo}`, owner, repo };
16769
16825
  }
16770
16826
  function parseCollectorPrNumber(raw) {
16771
- if (typeof raw === "string" && !/^[1-9][0-9]*$/.test(raw)) fail3("Collector pull request number must be a positive safe integer string");
16772
16827
  if (typeof raw !== "string" && typeof raw !== "number") fail3("Collector pull request number is required");
16773
- const value = Number(raw);
16774
- if (!Number.isSafeInteger(value) || value < 1) fail3("Collector pull request number must be a positive safe integer");
16828
+ const value = parseTicketNumber(raw);
16829
+ if (value === void 0) fail3(typeof raw === "string" && !isTicketNumberString(raw) ? "Collector pull request number must be a positive safe integer string" : "Collector pull request number must be a positive safe integer");
16775
16830
  return value;
16776
16831
  }
16777
16832
  function canonicalManifest(requests) {
@@ -16815,17 +16870,18 @@ var init_collector_config = __esm({
16815
16870
  "use strict";
16816
16871
  init_sha256();
16817
16872
  init_unknown_value();
16873
+ init_run_ticket_number();
16818
16874
  COLLECTOR_OWNER_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;
16819
16875
  COLLECTOR_REPO_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,98}[A-Za-z0-9])?$/;
16820
16876
  }
16821
16877
  });
16822
16878
 
16823
16879
  // src/auditor-dossier-tool.ts
16824
- import { dirname as dirname5, join as join11, resolve as resolve3 } from "node:path";
16880
+ import { join as join10, resolve as resolve3 } from "node:path";
16825
16881
  function auditorRunDirectory(context) {
16826
16882
  const sessionFile = context.sessionManager?.getSessionFile?.();
16827
16883
  if (sessionFile === void 0) return void 0;
16828
- return resolve3(dirname5(dirname5(sessionFile)));
16884
+ return resolve3(runDirectoryOfSessionFile(sessionFile));
16829
16885
  }
16830
16886
  var init_auditor_dossier_tool = __esm({
16831
16887
  "src/auditor-dossier-tool.ts"() {
@@ -17128,17 +17184,6 @@ function formatTerminalResult(result) {
17128
17184
  for (const artifact of result.artifacts) {
17129
17185
  lines.push(`artifact ${artifact.kind} ${encodeTerminalField(artifact.path)}`);
17130
17186
  }
17131
- if (result.gate !== void 0) {
17132
- lines.push(
17133
- `gate ${encodeTerminalField(result.gate.actualSeats.join(","))} ${result.gate.rounds.length}`
17134
- );
17135
- for (const round of result.gate.rounds) {
17136
- const reason = round.dispatch.kind === "historical_dispatch" && round.dispatch.reason !== void 0 ? encodeTerminalField(round.dispatch.reason) : "";
17137
- lines.push(
17138
- `gate-round ${round.roundIndex} ${round.dispatch.kind} ${round.dispatch.officer} ${reason} ${round.officer.seat} ${encodeTerminalField(round.officer.status)} ${encodeTerminalField(JSON.stringify(round.officer.findings))}`
17139
- );
17140
- }
17141
- }
17142
17187
  if (result.reviewerChildOutcomes !== void 0) {
17143
17188
  for (const axis of ["completeness", "correctness"]) {
17144
17189
  const child = result.reviewerChildOutcomes[axis];
@@ -17192,7 +17237,7 @@ __export(run_terminal_artifacts_exports, {
17192
17237
  });
17193
17238
  import { randomUUID } from "node:crypto";
17194
17239
  import { readdir as readdir2, readFile as readFile4 } from "node:fs/promises";
17195
- import { basename as basename3, dirname as dirname6, join as join12 } from "node:path";
17240
+ import { basename as basename4, dirname as dirname6, join as join11 } from "node:path";
17196
17241
  function uniqueErrorFallbackName() {
17197
17242
  return `${UNIQUE_ERROR_FALLBACK_STEM}.${randomUUID()}.json`;
17198
17243
  }
@@ -17261,16 +17306,13 @@ async function listUniqueErrorFallbackPaths(directories) {
17261
17306
  }
17262
17307
  for (const name of names.sort((a, b) => a.localeCompare(b))) {
17263
17308
  if (!UNIQUE_ERROR_FALLBACK_NAME.test(name)) continue;
17264
- found.push(join12(dir, name));
17309
+ found.push(join11(dir, name));
17265
17310
  }
17266
17311
  }
17267
17312
  return found;
17268
17313
  }
17269
17314
  function runIdFromRunDirectory(runDirectory) {
17270
- const name = basename3(runDirectory);
17271
- const at = name.lastIndexOf("@");
17272
- if (at <= 0 || at === name.length - 1) return void 0;
17273
- return name.slice(0, at);
17315
+ return parseRunLeaf(basename4(runDirectory))?.runId;
17274
17316
  }
17275
17317
  function presentUniqueFallbackBoundToRun(body, expectedRunId) {
17276
17318
  if (expectedRunId === void 0) return false;
@@ -17307,11 +17349,11 @@ async function readRunTerminalArtifact(runDirectory) {
17307
17349
  unreadable.push(read);
17308
17350
  };
17309
17351
  for (const file of RUN_TERMINAL_ARTIFACT_FILES) {
17310
- consider(await readTerminalArtifactAtPath(join12(artifactsDir, file), file));
17352
+ consider(await readTerminalArtifactAtPath(join11(artifactsDir, file), file));
17311
17353
  }
17312
17354
  for (const relative3 of RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS) {
17313
17355
  consider(
17314
- await readTerminalArtifactAtPath(join12(runDirectory, relative3), "error.json")
17356
+ await readTerminalArtifactAtPath(join11(runDirectory, relative3), "error.json")
17315
17357
  );
17316
17358
  }
17317
17359
  for (const path of await listSeamOwnedUniqueErrorFacePaths(runDirectory)) {
@@ -17750,6 +17792,204 @@ var init_receipt_delivery_policy = __esm({
17750
17792
  }
17751
17793
  });
17752
17794
 
17795
+ // src/ledger-session-read.ts
17796
+ import { readFile as readFile5 } from "node:fs/promises";
17797
+ async function readStrictPiSessionJsonl(path) {
17798
+ const text = await readFile5(path, "utf8");
17799
+ return text.trim().split("\n").filter(Boolean).map((line2) => JSON.parse(line2));
17800
+ }
17801
+ async function readLedgerSessionJsonlLines(path) {
17802
+ const text = await readFile5(path, "utf8");
17803
+ const lines = text.split("\n");
17804
+ const out = [];
17805
+ for (let index = 0; index < lines.length; index += 1) {
17806
+ const raw = lines[index];
17807
+ if (!raw.trim()) continue;
17808
+ const lineNumber = index + 1;
17809
+ let row;
17810
+ try {
17811
+ row = JSON.parse(raw);
17812
+ } catch (error) {
17813
+ if (!(error instanceof SyntaxError)) throw error;
17814
+ const completedByTerminator = index < lines.length - 1;
17815
+ if (!completedByTerminator) break;
17816
+ out.push({
17817
+ line: lineNumber,
17818
+ raw,
17819
+ error: `malformed JSONL record in ${path} at line ${lineNumber}: ${error.message}`
17820
+ });
17821
+ continue;
17822
+ }
17823
+ if (!isRecord(row)) {
17824
+ const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
17825
+ out.push({
17826
+ line: lineNumber,
17827
+ raw,
17828
+ error: `complete non-object JSONL record in ${path} at line ${lineNumber}: expected object, got ${kind}`
17829
+ });
17830
+ continue;
17831
+ }
17832
+ out.push({ line: lineNumber, raw, row });
17833
+ }
17834
+ return out;
17835
+ }
17836
+ async function readLedgerSessionJsonl(path) {
17837
+ const rows = [];
17838
+ for (const line2 of await readLedgerSessionJsonlLines(path)) {
17839
+ if (line2.row === void 0) {
17840
+ throw new LedgerSessionJsonlError(line2.error ?? `unreadable JSONL record in ${path} at line ${line2.line}`, {
17841
+ path,
17842
+ line: line2.line,
17843
+ prefixRows: rows
17844
+ });
17845
+ }
17846
+ rows.push(line2.row);
17847
+ }
17848
+ return rows;
17849
+ }
17850
+ function extractSessionTimestampSpan(rows) {
17851
+ let startedAt;
17852
+ let endedAt;
17853
+ for (const row of rows) {
17854
+ if (typeof row.timestamp !== "string" || !row.timestamp) continue;
17855
+ if (startedAt === void 0) startedAt = row.timestamp;
17856
+ endedAt = row.timestamp;
17857
+ }
17858
+ return {
17859
+ ...startedAt !== void 0 ? { startedAt } : {},
17860
+ ...endedAt !== void 0 ? { endedAt } : {}
17861
+ };
17862
+ }
17863
+ function extractSessionModelSequence(rows) {
17864
+ const seen = /* @__PURE__ */ new Set();
17865
+ const ordered = [];
17866
+ const push = (raw) => {
17867
+ const model = raw.trim();
17868
+ if (model === "" || seen.has(model)) return;
17869
+ seen.add(model);
17870
+ ordered.push(model);
17871
+ };
17872
+ for (const row of rows) {
17873
+ if (row.type === "model_change" && typeof row.modelId === "string") {
17874
+ push(row.modelId);
17875
+ }
17876
+ const message = isRecord(row.message) ? row.message : void 0;
17877
+ if (message?.role === "assistant" && typeof message.model === "string") {
17878
+ push(message.model);
17879
+ }
17880
+ }
17881
+ return ordered;
17882
+ }
17883
+ function bashCommandFirstLine(command) {
17884
+ const match = /^[^\r\n]*/.exec(command);
17885
+ return match?.[0] ?? "";
17886
+ }
17887
+ function extractSessionToolIntervals(rows) {
17888
+ const order = [];
17889
+ const openById = /* @__PURE__ */ new Map();
17890
+ for (const row of rows) {
17891
+ const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
17892
+ const message = isRecord(row.message) ? row.message : void 0;
17893
+ if (message?.role === "assistant" && Array.isArray(message.content)) {
17894
+ const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
17895
+ for (const part of message.content) {
17896
+ if (!isRecord(part) || part.type !== "toolCall") continue;
17897
+ if (typeof part.id !== "string" || part.id.length === 0) {
17898
+ throw new Error("toolCall frame missing string id");
17899
+ }
17900
+ if (typeof part.name !== "string" || part.name.length === 0) {
17901
+ throw new Error(`toolCall ${part.id} missing string name`);
17902
+ }
17903
+ if (callTimestamp === void 0 || callTimestamp.length === 0) {
17904
+ throw new Error(`toolCall ${part.id} missing timestamp`);
17905
+ }
17906
+ if (openById.has(part.id)) {
17907
+ throw new Error(`duplicate toolCall id ${part.id}`);
17908
+ }
17909
+ const args = isRecord(part.arguments) ? part.arguments : void 0;
17910
+ const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
17911
+ const interval = {
17912
+ toolCallId: part.id,
17913
+ toolName: part.name,
17914
+ startedAt: callTimestamp,
17915
+ ...command !== void 0 ? { command } : {}
17916
+ };
17917
+ order.push(interval);
17918
+ openById.set(part.id, interval);
17919
+ }
17920
+ }
17921
+ if (message?.role === "toolResult") {
17922
+ if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) {
17923
+ throw new Error("toolResult frame missing string toolCallId");
17924
+ }
17925
+ const resultTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
17926
+ if (resultTimestamp === void 0 || resultTimestamp.length === 0) {
17927
+ throw new Error(`toolResult ${message.toolCallId} missing timestamp`);
17928
+ }
17929
+ const open4 = openById.get(message.toolCallId);
17930
+ if (open4 === void 0) {
17931
+ const toolName = typeof message.toolName === "string" && message.toolName.length > 0 ? message.toolName : "unknown";
17932
+ order.push({
17933
+ toolCallId: message.toolCallId,
17934
+ toolName,
17935
+ startedAt: resultTimestamp,
17936
+ endedAt: resultTimestamp
17937
+ });
17938
+ continue;
17939
+ }
17940
+ if (open4.endedAt !== void 0) {
17941
+ throw new Error(`duplicate toolResult for toolCallId ${message.toolCallId}`);
17942
+ }
17943
+ open4.endedAt = resultTimestamp;
17944
+ }
17945
+ }
17946
+ return order.map((interval) => {
17947
+ const base = {
17948
+ toolCallId: interval.toolCallId,
17949
+ toolName: interval.toolName,
17950
+ startedAt: interval.startedAt,
17951
+ ...interval.command !== void 0 ? { command: interval.command } : {}
17952
+ };
17953
+ return interval.endedAt === void 0 ? base : { ...base, endedAt: interval.endedAt };
17954
+ });
17955
+ }
17956
+ function intervalRowsAroundAnchor(rows, anchorIndex, isBindingRow) {
17957
+ let start = 0;
17958
+ for (let i = anchorIndex; i >= 0; i -= 1) {
17959
+ if (isBindingRow(rows[i])) {
17960
+ start = i;
17961
+ break;
17962
+ }
17963
+ }
17964
+ let end = rows.length;
17965
+ for (let i = Math.max(anchorIndex, start) + 1; i < rows.length; i += 1) {
17966
+ if (isBindingRow(rows[i])) {
17967
+ end = i;
17968
+ break;
17969
+ }
17970
+ }
17971
+ return { rows: rows.slice(start, end), closed: end < rows.length };
17972
+ }
17973
+ var LedgerSessionJsonlError;
17974
+ var init_ledger_session_read = __esm({
17975
+ "src/ledger-session-read.ts"() {
17976
+ "use strict";
17977
+ init_unknown_value();
17978
+ LedgerSessionJsonlError = class extends Error {
17979
+ path;
17980
+ line;
17981
+ prefixRows;
17982
+ constructor(message, init) {
17983
+ super(message);
17984
+ this.name = "LedgerSessionJsonlError";
17985
+ this.path = init.path;
17986
+ this.line = init.line;
17987
+ this.prefixRows = init.prefixRows;
17988
+ }
17989
+ };
17990
+ }
17991
+ });
17992
+
17753
17993
  // src/session-assistant-usage.ts
17754
17994
  var session_assistant_usage_exports = {};
17755
17995
  __export(session_assistant_usage_exports, {
@@ -17757,20 +17997,13 @@ __export(session_assistant_usage_exports, {
17757
17997
  sessionFileFromPublicSummon: () => sessionFileFromPublicSummon,
17758
17998
  usageFromPublicSummon: () => usageFromPublicSummon
17759
17999
  });
17760
- import { join as join13 } from "node:path";
17761
18000
  async function readAssistantUsageFromSessionFile(sessionFile) {
17762
- const { readFile: readFile22 } = await import("node:fs/promises");
17763
- let text;
17764
- try {
17765
- text = await readFile22(sessionFile, "utf8");
17766
- } catch (error) {
17767
- if (error?.code === "ENOENT") return void 0;
17768
- throw error;
17769
- }
17770
18001
  let rows;
17771
18002
  try {
17772
- rows = text.trim().split("\n").filter(Boolean).map((line2) => JSON.parse(line2));
18003
+ rows = await readStrictPiSessionJsonl(sessionFile);
17773
18004
  } catch (error) {
18005
+ if (error?.code === "ENOENT") return void 0;
18006
+ if (!(error instanceof SyntaxError)) throw error;
17774
18007
  throw new Error(
17775
18008
  `session usage parse failed (${sessionFile}): ${errorText(error)}`,
17776
18009
  { cause: error }
@@ -17827,16 +18060,16 @@ async function readAssistantUsageFromSessionFile(sessionFile) {
17827
18060
  }
17828
18061
  function sessionFileFromPublicSummon(summoned) {
17829
18062
  if (typeof summoned.runDirectory === "string" && summoned.runDirectory.trim() !== "") {
17830
- return join13(summoned.runDirectory, "session", "session.jsonl");
18063
+ return sessionFileOf(summoned.runDirectory);
17831
18064
  }
17832
- const fromArtifacts = summoned.terminal?.artifacts?.map((a) => a.path).find((p) => typeof p === "string" && p.endsWith("session.jsonl"));
18065
+ const fromArtifacts = summoned.terminal?.artifacts?.map((a) => a.path).find((p) => typeof p === "string" && p.endsWith(ROLE_RUN_SESSION_FILENAME));
17833
18066
  if (fromArtifacts !== void 0) return fromArtifacts;
17834
18067
  const outcome = summoned.terminal?.roleOutcome;
17835
18068
  if (outcome === void 0) return void 0;
17836
18069
  const facts = outcome.decisiveFacts;
17837
18070
  const pointer = facts?.runPointer;
17838
18071
  if (typeof pointer === "string" && pointer.trim() !== "") {
17839
- return join13(pointer, "session", "session.jsonl");
18072
+ return sessionFileOf(pointer);
17840
18073
  }
17841
18074
  return void 0;
17842
18075
  }
@@ -17848,6 +18081,8 @@ async function usageFromPublicSummon(summoned) {
17848
18081
  var init_session_assistant_usage = __esm({
17849
18082
  "src/session-assistant-usage.ts"() {
17850
18083
  "use strict";
18084
+ init_role_run_placement();
18085
+ init_ledger_session_read();
17851
18086
  init_unknown_value();
17852
18087
  }
17853
18088
  });
@@ -18014,7 +18249,7 @@ var init_process_cancel = __esm({
18014
18249
  import { constants as fsConstants } from "node:fs";
18015
18250
  import { randomUUID as randomUUID2 } from "node:crypto";
18016
18251
  import { open } from "node:fs/promises";
18017
- import { join as join14 } from "node:path";
18252
+ import { join as join12 } from "node:path";
18018
18253
  async function persistReturnedRunState(admitted) {
18019
18254
  await markRunTerminal(admitted.runDirectory);
18020
18255
  }
@@ -18058,7 +18293,7 @@ function jsonSafeReplacer() {
18058
18293
  };
18059
18294
  }
18060
18295
  async function writeHardenedArtifactFile(artifactsDir, namePrefix, payload) {
18061
- const filePath = join14(artifactsDir, `${namePrefix}-${randomUUID2()}.json`);
18296
+ const filePath = join12(artifactsDir, `${namePrefix}-${randomUUID2()}.json`);
18062
18297
  const body = `${JSON.stringify(payload, jsonSafeReplacer(), 2)}
18063
18298
  `;
18064
18299
  const noFollowFlag = typeof fsConstants.O_NOFOLLOW === "number" ? fsConstants.O_NOFOLLOW : 0;
@@ -18306,489 +18541,6 @@ var init_auto_resume = __esm({
18306
18541
  }
18307
18542
  });
18308
18543
 
18309
- // src/ledger-session-read.ts
18310
- import { readFile as readFile5 } from "node:fs/promises";
18311
- async function readLedgerSessionJsonlLines(path) {
18312
- const text = await readFile5(path, "utf8");
18313
- const lines = text.split("\n");
18314
- const out = [];
18315
- for (let index = 0; index < lines.length; index += 1) {
18316
- const raw = lines[index];
18317
- if (!raw.trim()) continue;
18318
- const lineNumber = index + 1;
18319
- let row;
18320
- try {
18321
- row = JSON.parse(raw);
18322
- } catch (error) {
18323
- if (!(error instanceof SyntaxError)) throw error;
18324
- const completedByTerminator = index < lines.length - 1;
18325
- if (!completedByTerminator) break;
18326
- out.push({
18327
- line: lineNumber,
18328
- raw,
18329
- error: `malformed JSONL record in ${path} at line ${lineNumber}: ${error.message}`
18330
- });
18331
- continue;
18332
- }
18333
- if (!isRecord(row)) {
18334
- const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
18335
- out.push({
18336
- line: lineNumber,
18337
- raw,
18338
- error: `complete non-object JSONL record in ${path} at line ${lineNumber}: expected object, got ${kind}`
18339
- });
18340
- continue;
18341
- }
18342
- out.push({ line: lineNumber, raw, row });
18343
- }
18344
- return out;
18345
- }
18346
- async function readLedgerSessionJsonl(path) {
18347
- const rows = [];
18348
- for (const line2 of await readLedgerSessionJsonlLines(path)) {
18349
- if (line2.row === void 0) {
18350
- throw new LedgerSessionJsonlError(line2.error ?? `unreadable JSONL record in ${path} at line ${line2.line}`, {
18351
- path,
18352
- line: line2.line,
18353
- prefixRows: rows
18354
- });
18355
- }
18356
- rows.push(line2.row);
18357
- }
18358
- return rows;
18359
- }
18360
- function extractSessionTimestampSpan(rows) {
18361
- let startedAt;
18362
- let endedAt;
18363
- for (const row of rows) {
18364
- if (typeof row.timestamp !== "string" || !row.timestamp) continue;
18365
- if (startedAt === void 0) startedAt = row.timestamp;
18366
- endedAt = row.timestamp;
18367
- }
18368
- return {
18369
- ...startedAt !== void 0 ? { startedAt } : {},
18370
- ...endedAt !== void 0 ? { endedAt } : {}
18371
- };
18372
- }
18373
- function extractSessionModelSequence(rows) {
18374
- const seen = /* @__PURE__ */ new Set();
18375
- const ordered = [];
18376
- const push = (raw) => {
18377
- const model = raw.trim();
18378
- if (model === "" || seen.has(model)) return;
18379
- seen.add(model);
18380
- ordered.push(model);
18381
- };
18382
- for (const row of rows) {
18383
- if (row.type === "model_change" && typeof row.modelId === "string") {
18384
- push(row.modelId);
18385
- }
18386
- const message = isRecord(row.message) ? row.message : void 0;
18387
- if (message?.role === "assistant" && typeof message.model === "string") {
18388
- push(message.model);
18389
- }
18390
- }
18391
- return ordered;
18392
- }
18393
- function bashCommandFirstLine(command) {
18394
- const match = /^[^\r\n]*/.exec(command);
18395
- return match?.[0] ?? "";
18396
- }
18397
- function extractSessionToolIntervals(rows) {
18398
- const order = [];
18399
- const openById = /* @__PURE__ */ new Map();
18400
- for (const row of rows) {
18401
- const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
18402
- const message = isRecord(row.message) ? row.message : void 0;
18403
- if (message?.role === "assistant" && Array.isArray(message.content)) {
18404
- const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
18405
- for (const part of message.content) {
18406
- if (!isRecord(part) || part.type !== "toolCall") continue;
18407
- if (typeof part.id !== "string" || part.id.length === 0) {
18408
- throw new Error("toolCall frame missing string id");
18409
- }
18410
- if (typeof part.name !== "string" || part.name.length === 0) {
18411
- throw new Error(`toolCall ${part.id} missing string name`);
18412
- }
18413
- if (callTimestamp === void 0 || callTimestamp.length === 0) {
18414
- throw new Error(`toolCall ${part.id} missing timestamp`);
18415
- }
18416
- if (openById.has(part.id)) {
18417
- throw new Error(`duplicate toolCall id ${part.id}`);
18418
- }
18419
- const args = isRecord(part.arguments) ? part.arguments : void 0;
18420
- const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
18421
- const interval = {
18422
- toolCallId: part.id,
18423
- toolName: part.name,
18424
- startedAt: callTimestamp,
18425
- ...command !== void 0 ? { command } : {}
18426
- };
18427
- order.push(interval);
18428
- openById.set(part.id, interval);
18429
- }
18430
- }
18431
- if (message?.role === "toolResult") {
18432
- if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) {
18433
- throw new Error("toolResult frame missing string toolCallId");
18434
- }
18435
- const resultTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
18436
- if (resultTimestamp === void 0 || resultTimestamp.length === 0) {
18437
- throw new Error(`toolResult ${message.toolCallId} missing timestamp`);
18438
- }
18439
- const open4 = openById.get(message.toolCallId);
18440
- if (open4 === void 0) {
18441
- const toolName = typeof message.toolName === "string" && message.toolName.length > 0 ? message.toolName : "unknown";
18442
- order.push({
18443
- toolCallId: message.toolCallId,
18444
- toolName,
18445
- startedAt: resultTimestamp,
18446
- endedAt: resultTimestamp
18447
- });
18448
- continue;
18449
- }
18450
- if (open4.endedAt !== void 0) {
18451
- throw new Error(`duplicate toolResult for toolCallId ${message.toolCallId}`);
18452
- }
18453
- open4.endedAt = resultTimestamp;
18454
- }
18455
- }
18456
- return order.map((interval) => {
18457
- const base = {
18458
- toolCallId: interval.toolCallId,
18459
- toolName: interval.toolName,
18460
- startedAt: interval.startedAt,
18461
- ...interval.command !== void 0 ? { command: interval.command } : {}
18462
- };
18463
- return interval.endedAt === void 0 ? base : { ...base, endedAt: interval.endedAt };
18464
- });
18465
- }
18466
- function intervalRowsAroundAnchor(rows, anchorIndex, isBindingRow) {
18467
- let start = 0;
18468
- for (let i = anchorIndex; i >= 0; i -= 1) {
18469
- if (isBindingRow(rows[i])) {
18470
- start = i;
18471
- break;
18472
- }
18473
- }
18474
- let end = rows.length;
18475
- for (let i = Math.max(anchorIndex, start) + 1; i < rows.length; i += 1) {
18476
- if (isBindingRow(rows[i])) {
18477
- end = i;
18478
- break;
18479
- }
18480
- }
18481
- return { rows: rows.slice(start, end), closed: end < rows.length };
18482
- }
18483
- var LedgerSessionJsonlError;
18484
- var init_ledger_session_read = __esm({
18485
- "src/ledger-session-read.ts"() {
18486
- "use strict";
18487
- init_unknown_value();
18488
- LedgerSessionJsonlError = class extends Error {
18489
- path;
18490
- line;
18491
- prefixRows;
18492
- constructor(message, init) {
18493
- super(message);
18494
- this.name = "LedgerSessionJsonlError";
18495
- this.path = init.path;
18496
- this.line = init.line;
18497
- this.prefixRows = init.prefixRows;
18498
- }
18499
- };
18500
- }
18501
- });
18502
-
18503
- // src/analyst-gate-cycles-read.ts
18504
- import { readdir as readdir3 } from "node:fs/promises";
18505
- import { join as join15 } from "node:path";
18506
- function isParentAttemptBindingRow(row) {
18507
- return row.type === "custom" && row.customType === AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE;
18508
- }
18509
- function intervalRowsForGateCall(rows, callRowIndex) {
18510
- return intervalRowsAroundAnchor(rows, callRowIndex, isParentAttemptBindingRow).rows;
18511
- }
18512
- function normalizeOfficerArg(raw) {
18513
- if (typeof raw !== "string") return void 0;
18514
- return OFFICER_ARG_ALIASES[raw.trim()];
18515
- }
18516
- function asFindings(value) {
18517
- return Array.isArray(value) ? value : [];
18518
- }
18519
- function optionalDispatchReason(raw) {
18520
- if (typeof raw !== "string") return void 0;
18521
- if (raw.trim() === "") return void 0;
18522
- return raw;
18523
- }
18524
- function isGateTerminatingToolName(toolName) {
18525
- return toolName === "ak_submission_output" || DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== void 0;
18526
- }
18527
- function acceptedGateReceiptIds(rows) {
18528
- const accepted = /* @__PURE__ */ new Set();
18529
- for (const row of rows) {
18530
- const message = isRecord(row.message) ? row.message : void 0;
18531
- if (message?.role !== "toolResult") continue;
18532
- if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) continue;
18533
- if (message.isError === false) accepted.add(message.toolCallId);
18534
- }
18535
- return accepted;
18536
- }
18537
- function readAcceptedGateStatus(args) {
18538
- if (args === void 0) return "";
18539
- return typeof args.status === "string" ? args.status : args.status === void 0 ? "" : String(args.status);
18540
- }
18541
- function requireAcceptedGateSpan(rows, filePath) {
18542
- const span = extractSessionTimestampSpan(rows);
18543
- if (span.startedAt === void 0 || span.endedAt === void 0) {
18544
- throw new Error(
18545
- `accepted gate volume missing session timestamp span in ${filePath}`
18546
- );
18547
- }
18548
- const startedMs = Date.parse(span.startedAt);
18549
- const endedMs = Date.parse(span.endedAt);
18550
- if (!Number.isFinite(startedMs) || !Number.isFinite(endedMs) || endedMs < startedMs) {
18551
- throw new Error(
18552
- `accepted gate volume has unusable timestamp span in ${filePath}`
18553
- );
18554
- }
18555
- return {
18556
- startedAt: span.startedAt,
18557
- endedAt: span.endedAt,
18558
- wallMs: endedMs - startedMs
18559
- };
18560
- }
18561
- function nearestAttemptBindingBefore(rows, beforeIndex) {
18562
- for (let i = beforeIndex - 1; i >= 0; i -= 1) {
18563
- const row = rows[i];
18564
- if (!isParentAttemptBindingRow(row)) continue;
18565
- if (!isRecord(row.data) || !isRecord(row.data.parent)) continue;
18566
- const id = row.data.parent.attemptEntryId;
18567
- const sessionFile = row.data.parent.sessionFile;
18568
- return {
18569
- ...typeof id === "string" && id.length > 0 ? { attemptEntryId: id } : {},
18570
- ...typeof sessionFile === "string" && sessionFile.length > 0 ? { parentSessionFile: sessionFile } : {}
18571
- };
18572
- }
18573
- return {};
18574
- }
18575
- function extractAllAcceptedGateToolCalls(rows) {
18576
- const acceptedIds = acceptedGateReceiptIds(rows);
18577
- const out = [];
18578
- for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
18579
- const row = rows[rowIndex];
18580
- const message = isRecord(row.message) ? row.message : void 0;
18581
- if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
18582
- for (const part of message.content) {
18583
- if (!isRecord(part) || part.type !== "toolCall") continue;
18584
- if (typeof part.id !== "string" || part.id.length === 0) continue;
18585
- if (typeof part.name !== "string" || part.name.length === 0) continue;
18586
- if (!isGateTerminatingToolName(part.name)) continue;
18587
- if (!acceptedIds.has(part.id)) continue;
18588
- const binding = nearestAttemptBindingBefore(rows, rowIndex);
18589
- out.push({
18590
- toolName: part.name,
18591
- args: isRecord(part.arguments) ? part.arguments : void 0,
18592
- accepted: true,
18593
- rowIndex,
18594
- ...binding
18595
- });
18596
- }
18597
- }
18598
- return out;
18599
- }
18600
- function projectAcceptedGateCall(filePath, rows, call, pointerOfficer) {
18601
- const span = requireAcceptedGateSpan(intervalRowsForGateCall(rows, call.rowIndex), filePath);
18602
- const status = readAcceptedGateStatus(call.args);
18603
- const findings = asFindings(call.args?.findings);
18604
- const findingsCount = findings.length;
18605
- const bindingFields = {
18606
- ...call.attemptEntryId === void 0 ? {} : { attemptEntryId: call.attemptEntryId },
18607
- ...call.parentSessionFile === void 0 ? {} : { parentSessionFile: call.parentSessionFile }
18608
- };
18609
- if (DISPATCH_TOOLS.has(call.toolName)) {
18610
- if (status !== "dispatch") {
18611
- return void 0;
18612
- }
18613
- const officer2 = normalizeOfficerArg(call.args?.officer);
18614
- if (officer2 === void 0) {
18615
- return void 0;
18616
- }
18617
- const reason = optionalDispatchReason(call.args?.reason);
18618
- return {
18619
- kind: "dispatch",
18620
- startedAt: span.startedAt,
18621
- officer: officer2,
18622
- status,
18623
- ...reason === void 0 ? {} : { reason },
18624
- ...bindingFields
18625
- };
18626
- }
18627
- const officer = call.toolName === "ak_submission_output" ? pointerOfficer : OFFICER_TOOL_TO_FACE[call.toolName];
18628
- if (officer === void 0) {
18629
- throw new Error(
18630
- `accepted gate receipt has unknown officer tool ${call.toolName} in ${filePath}`
18631
- );
18632
- }
18633
- return {
18634
- kind: "officer",
18635
- startedAt: span.startedAt,
18636
- endedAt: span.endedAt,
18637
- officer,
18638
- status,
18639
- findings,
18640
- findingsCount,
18641
- officerWallMs: span.wallMs,
18642
- ...bindingFields
18643
- };
18644
- }
18645
- async function classifyAuditorVolume(filePath, pointerOfficer) {
18646
- const rows = await readLedgerSessionJsonl(filePath);
18647
- const accepted = extractAllAcceptedGateToolCalls(rows);
18648
- if (accepted.length === 0) return [];
18649
- const volumes = [];
18650
- for (const call of accepted) {
18651
- const projected = call.toolName === "ak_submission_output" && pointerOfficer === void 0 ? void 0 : projectAcceptedGateCall(filePath, rows, call, pointerOfficer);
18652
- if (projected !== void 0) volumes.push(projected);
18653
- }
18654
- return volumes;
18655
- }
18656
- function pairGateRounds(volumes) {
18657
- const ordered = [...volumes].sort((a, b) => {
18658
- if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
18659
- if (a.kind !== b.kind) return a.kind === "dispatch" ? -1 : 1;
18660
- return 0;
18661
- });
18662
- const usedOfficerIdx = /* @__PURE__ */ new Set();
18663
- const rounds = [];
18664
- for (let i = 0; i < ordered.length; i += 1) {
18665
- const vol = ordered[i];
18666
- if (vol.kind !== "dispatch") continue;
18667
- let match;
18668
- for (let j = i + 1; j < ordered.length; j += 1) {
18669
- if (usedOfficerIdx.has(j)) continue;
18670
- const candidate = ordered[j];
18671
- if (candidate.kind !== "officer") continue;
18672
- if (candidate.officer !== vol.officer) continue;
18673
- if (vol.attemptEntryId === void 0 || candidate.attemptEntryId === void 0 || candidate.attemptEntryId !== vol.attemptEntryId) {
18674
- continue;
18675
- }
18676
- match = { index: j, officer: candidate };
18677
- break;
18678
- }
18679
- if (match === void 0) continue;
18680
- usedOfficerIdx.add(match.index);
18681
- rounds.push({
18682
- roundIndex: rounds.length + 1,
18683
- officer: match.officer.officer,
18684
- status: match.officer.status,
18685
- officerWallMs: match.officer.officerWallMs,
18686
- officerStartedAt: match.officer.startedAt,
18687
- officerEndedAt: match.officer.endedAt,
18688
- findings: match.officer.findings,
18689
- findingsCount: match.officer.findingsCount,
18690
- origin: {
18691
- kind: "historical_dispatch",
18692
- ...vol.reason === void 0 ? {} : { reason: vol.reason }
18693
- }
18694
- });
18695
- }
18696
- for (let i = 0; i < ordered.length; i += 1) {
18697
- const vol = ordered[i];
18698
- if (vol.kind !== "officer" || usedOfficerIdx.has(i)) continue;
18699
- rounds.push({
18700
- roundIndex: 0,
18701
- officer: vol.officer,
18702
- status: vol.status,
18703
- officerWallMs: vol.officerWallMs,
18704
- officerStartedAt: vol.startedAt,
18705
- officerEndedAt: vol.endedAt,
18706
- findings: vol.findings,
18707
- findingsCount: vol.findingsCount,
18708
- origin: { kind: "direct" }
18709
- });
18710
- }
18711
- return rounds.sort((a, b) => a.officerStartedAt.localeCompare(b.officerStartedAt)).map((round, index) => ({ ...round, roundIndex: index + 1 }));
18712
- }
18713
- async function resolveOfficerSessionFromPointerFile(pointerPath) {
18714
- const { readFile: readFile22 } = await import("node:fs/promises");
18715
- let raw;
18716
- try {
18717
- raw = JSON.parse(await readFile22(pointerPath, "utf8"));
18718
- } catch (error) {
18719
- throw new Error(
18720
- `direct officer run pointer unreadable in ${pointerPath}: ${errorText(error)}`,
18721
- { cause: error }
18722
- );
18723
- }
18724
- if (!isRecord(raw) || raw.kind !== "direct-officer-run-pointer" || raw.version !== 1) {
18725
- throw new Error(`direct officer run pointer has unknown shape in ${pointerPath}`);
18726
- }
18727
- const sessionFile = raw.sessionFile;
18728
- if (typeof sessionFile !== "string" || sessionFile.trim() === "") {
18729
- throw new Error(`direct officer run pointer missing sessionFile in ${pointerPath}`);
18730
- }
18731
- const officer = raw.officer === "inspector" || raw.officer === "notary" ? raw.officer : void 0;
18732
- return { sessionFile, ...officer === void 0 ? {} : { officer } };
18733
- }
18734
- async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, options = {}) {
18735
- const directories = typeof auditorRolesDirectory === "string" ? [auditorRolesDirectory] : auditorRolesDirectory;
18736
- const volumes = [];
18737
- const classifiedOfficerSessions = /* @__PURE__ */ new Set();
18738
- for (const directory of directories) {
18739
- let names;
18740
- try {
18741
- const entries = await readdir3(directory, { withFileTypes: true });
18742
- names = entries.filter(
18743
- (e) => e.isFile() && (e.name.endsWith(".jsonl") || e.name.endsWith(".pointer.json"))
18744
- ).map((e) => e.name).sort();
18745
- } catch (error) {
18746
- if (isEnoent(error)) continue;
18747
- throw error;
18748
- }
18749
- for (const name of names) {
18750
- const path = join15(directory, name);
18751
- const fromPointer = name.endsWith(".pointer.json");
18752
- const pointer = fromPointer ? await resolveOfficerSessionFromPointerFile(path) : void 0;
18753
- const sessionPath = pointer?.sessionFile ?? path;
18754
- if (fromPointer) {
18755
- if (classifiedOfficerSessions.has(sessionPath)) continue;
18756
- classifiedOfficerSessions.add(sessionPath);
18757
- }
18758
- const classified = await classifyAuditorVolume(sessionPath, pointer?.officer);
18759
- for (const volume of classified) {
18760
- if (options.parentSessionFile !== void 0 && volume.parentSessionFile !== void 0 && volume.parentSessionFile !== options.parentSessionFile) {
18761
- continue;
18762
- }
18763
- volumes.push(volume);
18764
- }
18765
- }
18766
- }
18767
- return pairGateRounds(volumes);
18768
- }
18769
- var DISPATCH_TOOLS, OFFICER_TOOL_TO_FACE, OFFICER_ARG_ALIASES;
18770
- var init_analyst_gate_cycles_read = __esm({
18771
- "src/analyst-gate-cycles-read.ts"() {
18772
- "use strict";
18773
- init_compliance_transport();
18774
- init_ledger_session_read();
18775
- init_unknown_value();
18776
- DISPATCH_TOOLS = /* @__PURE__ */ new Set(["ak_menxia_output", "ak_gatekeeper_output"]);
18777
- OFFICER_TOOL_TO_FACE = {
18778
- ak_jishizhong_output: "inspector",
18779
- ak_inspector_output: "inspector",
18780
- ak_fubaolang_output: "notary",
18781
- ak_notary_output: "notary"
18782
- };
18783
- OFFICER_ARG_ALIASES = {
18784
- jishizhong: "inspector",
18785
- inspector: "inspector",
18786
- fubaolang: "notary",
18787
- notary: "notary"
18788
- };
18789
- }
18790
- });
18791
-
18792
18544
  // src/sitian-contracts.ts
18793
18545
  function attachDirectErrnoCode(error, cause) {
18794
18546
  if (cause === null || typeof cause !== "object" || !("code" in cause)) return;
@@ -18813,7 +18565,7 @@ var init_sitian_contracts = __esm({
18813
18565
  // src/sitian-appender.ts
18814
18566
  import { randomUUID as randomUUID3 } from "node:crypto";
18815
18567
  import { appendFileSync } from "node:fs";
18816
- import { dirname as dirname7, join as join16 } from "node:path";
18568
+ import { dirname as dirname7, join as join13 } from "node:path";
18817
18569
  function appendSitianRecordBlock(input, block) {
18818
18570
  if (block === "") return;
18819
18571
  try {
@@ -18834,13 +18586,22 @@ function resolveSitianVolumeCategory(kind) {
18834
18586
  }
18835
18587
  return kind;
18836
18588
  }
18589
+ function sitianVolumeDirectory(sessionDirectory, category) {
18590
+ return join13(sessionDirectory, category);
18591
+ }
18592
+ function sitianRunVolumeDirectory(runDirectory, category) {
18593
+ return sitianVolumeDirectory(sessionDirectoryOf(runDirectory), category);
18594
+ }
18595
+ function sitianVolumeRecordsFile(volumeDirectory) {
18596
+ return join13(volumeDirectory, SITIAN_RECORDS_LEAF);
18597
+ }
18837
18598
  function ticketProvenanceUnderBookPaths(ledgerHome, bookKey, ticketId) {
18838
- const sessionDir = join16(activationBookDirectory(ledgerHome, bookKey), ticketId);
18839
- return { sessionDir, recordFile: join16(sessionDir, SITIAN_RECORDS_LEAF) };
18599
+ const sessionDir = join13(activationBookDirectory(ledgerHome, bookKey), ticketId);
18600
+ return { sessionDir, recordFile: sitianVolumeRecordsFile(sessionDir) };
18840
18601
  }
18841
18602
  function resolveSitianRecordPathInLedger(input, ledgerHome) {
18842
18603
  const category = resolveSitianVolumeCategory(input.kind);
18843
- const ticketNumber = category === "ticket-provenance" ? typeof input.subject === "string" && /^[1-9][0-9]*$/.test(input.subject) ? input.subject : typeof input.subject === "object" && typeof input.subject.ticketNumber === "number" && Number.isSafeInteger(input.subject.ticketNumber) && input.subject.ticketNumber > 0 ? String(input.subject.ticketNumber) : void 0 : void 0;
18604
+ const ticketNumber = category === "ticket-provenance" ? ticketNumberFromSitianSubject(input.subject) : void 0;
18844
18605
  let sessionDir;
18845
18606
  let recordFile;
18846
18607
  if (ticketNumber !== void 0) {
@@ -18853,13 +18614,13 @@ function resolveSitianRecordPathInLedger(input, ledgerHome) {
18853
18614
  recordFile = paths.recordFile;
18854
18615
  } else if (category === "ticket-provenance" && input.runDirectory !== void 0) {
18855
18616
  sessionDir = input.runDirectory;
18856
- recordFile = join16(sessionDir, SITIAN_RECORDS_LEAF);
18617
+ recordFile = sitianVolumeRecordsFile(sessionDir);
18857
18618
  } else {
18858
18619
  if (input.sessionParent === void 0 || input.sessionParent.length === 0 || !physicallyContainedIn(ledgerHome, input.sessionParent)) {
18859
18620
  throw new Error("Sitian record ownership requires a parent session inside the ledger home");
18860
18621
  }
18861
- sessionDir = join16(dirname7(input.sessionParent), category);
18862
- recordFile = join16(sessionDir, SITIAN_RECORDS_LEAF);
18622
+ sessionDir = sitianVolumeDirectory(dirname7(input.sessionParent), category);
18623
+ recordFile = sitianVolumeRecordsFile(sessionDir);
18863
18624
  }
18864
18625
  if (!physicallyContainedIn(ledgerHome, sessionDir)) {
18865
18626
  throw new Error("Sitian record ownership requires a directory inside the ledger home");
@@ -18911,6 +18672,8 @@ var S4_SUBMISSION_LEDGER_KINDS, SITIAN_RECORDS_LEAF;
18911
18672
  var init_sitian_appender = __esm({
18912
18673
  "src/sitian-appender.ts"() {
18913
18674
  "use strict";
18675
+ init_role_run_placement();
18676
+ init_run_ticket_number();
18914
18677
  init_activation_ledger_git();
18915
18678
  init_activation_ledger_topology();
18916
18679
  init_sitian_contracts();
@@ -18999,14 +18762,13 @@ var init_submission_correctable_error = __esm({
18999
18762
  });
19000
18763
 
19001
18764
  // src/submission-ledger.ts
19002
- import { join as join17 } from "node:path";
19003
18765
  async function submissionRecordFile(cwd, runId, scope) {
19004
18766
  const ledgerHome = resolveActivationLedgerHome(scope.home);
19005
18767
  let sessionParent = scope.sessionParent;
19006
18768
  if (sessionParent === void 0) {
19007
18769
  const discoveredRun = await findRunDirectoryById(scope.home, runId);
19008
18770
  if (discoveredRun === void 0) return void 0;
19009
- sessionParent = join17(discoveredRun, "session", "session.jsonl");
18771
+ sessionParent = sessionFileOf(discoveredRun);
19010
18772
  }
19011
18773
  return resolveSitianRecordPathInLedger({
19012
18774
  level: "event",
@@ -19156,6 +18918,7 @@ async function readRecordedSubmissions(cwd, runId, homeOrScope) {
19156
18918
  var init_submission_ledger = __esm({
19157
18919
  "src/submission-ledger.ts"() {
19158
18920
  "use strict";
18921
+ init_role_run_placement();
19159
18922
  init_activation_ledger_topology();
19160
18923
  init_host_contracts();
19161
18924
  init_run_terminal_artifacts();
@@ -19171,7 +18934,7 @@ var init_submission_ledger = __esm({
19171
18934
  // src/engine-detour-usage.ts
19172
18935
  import { randomUUID as randomUUID4 } from "node:crypto";
19173
18936
  import { readFileSync as readFileSync2 } from "node:fs";
19174
- import { dirname as dirname8, join as join18 } from "node:path";
18937
+ import { join as join14 } from "node:path";
19175
18938
  function callFactFromSitianPayload(payload, pointer) {
19176
18939
  if (!isRecord(payload)) return void 0;
19177
18940
  if (payload.tool !== ENGINE_DETOUR_TOOL_NAME) return void 0;
@@ -19235,7 +18998,7 @@ async function readEngineDetourToolUsage(input) {
19235
18998
  function readInvocationRecord(runDirectory) {
19236
18999
  try {
19237
19000
  const raw = JSON.parse(
19238
- readFileSync2(join18(runDirectory, "invocation.json"), "utf8")
19001
+ readFileSync2(join14(runDirectory, "invocation.json"), "utf8")
19239
19002
  );
19240
19003
  return isRecord(raw) ? raw : void 0;
19241
19004
  } catch (error) {
@@ -19259,12 +19022,6 @@ function withEngineDetourToolUsageFact(outcome, usage) {
19259
19022
  }
19260
19023
  };
19261
19024
  }
19262
- function runDirectoryFromSessionDirectory(sessionDirectory) {
19263
- return dirname8(sessionDirectory);
19264
- }
19265
- function sessionFileFromSessionDirectory(sessionDirectory) {
19266
- return join18(sessionDirectory, "session.jsonl");
19267
- }
19268
19025
  function mintEngineDetourInvocationScope(_input) {
19269
19026
  return randomUUID4();
19270
19027
  }
@@ -19281,12 +19038,16 @@ var ENGINE_DETOUR_CALL_KIND, ENGINE_DETOUR_TOOL_USAGE_FACT_KEY, ENGINE_DETOUR_CA
19281
19038
  var init_engine_detour_usage = __esm({
19282
19039
  "src/engine-detour-usage.ts"() {
19283
19040
  "use strict";
19041
+ init_role_run_placement();
19284
19042
  init_engine_detour();
19043
+ init_sitian_appender();
19285
19044
  init_sitian_facade();
19286
19045
  init_unknown_value();
19287
19046
  ENGINE_DETOUR_CALL_KIND = "engine-detour-call";
19288
19047
  ENGINE_DETOUR_TOOL_USAGE_FACT_KEY = "engineDetourToolUsage";
19289
- ENGINE_DETOUR_CALL_RECORD_FILE_RELATIVE = `session/${ENGINE_DETOUR_CALL_KIND}/records.jsonl`;
19048
+ ENGINE_DETOUR_CALL_RECORD_FILE_RELATIVE = sitianVolumeRecordsFile(
19049
+ sitianRunVolumeDirectory("", ENGINE_DETOUR_CALL_KIND)
19050
+ );
19290
19051
  }
19291
19052
  });
19292
19053
 
@@ -19416,12 +19177,12 @@ var init_terminating_tools = __esm({
19416
19177
  });
19417
19178
 
19418
19179
  // src/doctor-evidence.ts
19419
- import { readdir as readdir4, readFile as readFile7, realpath, stat } from "node:fs/promises";
19420
- import { dirname as dirname9, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
19180
+ import { readdir as readdir3, readFile as readFile7, realpath, stat } from "node:fs/promises";
19181
+ import { dirname as dirname8, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
19421
19182
  async function discoverCaseFiles(root) {
19422
19183
  const found = [];
19423
19184
  async function walk(dir, depth) {
19424
- for (const item of await readdir4(dir, { withFileTypes: true })) {
19185
+ for (const item of await readdir3(dir, { withFileTypes: true })) {
19425
19186
  const path = resolve5(dir, item.name);
19426
19187
  if (item.isDirectory()) {
19427
19188
  await walk(path, depth + 1);
@@ -19450,7 +19211,7 @@ async function stableRunsIdentity(root) {
19450
19211
  } catch (error) {
19451
19212
  if (!isMissingPathError(error)) throw error;
19452
19213
  }
19453
- const parent = dirname9(cursor);
19214
+ const parent = dirname8(cursor);
19454
19215
  if (parent === cursor) return root;
19455
19216
  cursor = parent;
19456
19217
  }
@@ -19518,8 +19279,11 @@ function deriveSession(content, id) {
19518
19279
  const session = complete ? { source: id, startedAt, endedAt, wallMilliseconds: wall, completion: "accepted" } : { source: id, ...startedAt ? { startedAt } : {}, ...endedAt ? { endedAt } : {}, ...wall !== void 0 && wall >= 0 ? { wallMilliseconds: wall } : {}, completion: "incomplete", ...degradationReason ? { degradationReason } : {} };
19519
19280
  return { session, turns, calls, tokens, statuses, commits };
19520
19281
  }
19521
- async function loadDoctorCase(runsPath) {
19282
+ async function loadDoctorCase(runsPath, projectRoot) {
19522
19283
  const root = await realpath(runsPath);
19284
+ if (projectRoot !== void 0 && !physicallyContainedIn(projectRoot, root)) {
19285
+ throw new Error("doctor --runs escapes the project root");
19286
+ }
19523
19287
  const match = root.split(sep2).join("/").match(/\/\.ak-roles\/books\/[^/]+\/(?:issues\/)?([1-9]\d*)\/runs$/);
19524
19288
  if (!match) throw new Error("Doctor case must be an .ak-roles/books/<book>/<n>/runs directory");
19525
19289
  const evidence = [], sessions = [], statuses = [], commits = [];
@@ -19539,7 +19303,7 @@ async function loadDoctorCase(runsPath) {
19539
19303
  accumulate(calls, result.calls, id);
19540
19304
  accumulate(tokens, result.tokens, id);
19541
19305
  }
19542
- const runDirs = (await readdir4(root, { withFileTypes: true })).filter((item) => item.isDirectory()).map((item) => item.name).sort();
19306
+ const runDirs = (await readdir3(root, { withFileTypes: true })).filter((item) => item.isDirectory()).map((item) => item.name).sort();
19543
19307
  const legs = evidence.filter((entry) => entry.kind === "session").map((entry) => entry.id);
19544
19308
  const retryDirs = runDirs.filter((name) => /(?:^|[-_])retry(?:[-_]|$)/i.test(name));
19545
19309
  const rawBytes = evidence.filter((entry) => entry.kind === "session").reduce((sum, entry) => sum + entry.byteLength, 0);
@@ -19550,6 +19314,7 @@ var init_doctor_evidence = __esm({
19550
19314
  "src/doctor-evidence.ts"() {
19551
19315
  "use strict";
19552
19316
  init_sha256();
19317
+ init_activation_ledger_topology();
19553
19318
  init_terminating_tools();
19554
19319
  init_unknown_value();
19555
19320
  }
@@ -19709,7 +19474,6 @@ var init_session_dialogue = __esm({
19709
19474
 
19710
19475
  // src/ticket-provenance.ts
19711
19476
  import { readFile as readFile9, unlink } from "node:fs/promises";
19712
- import { basename as basename4, dirname as dirname10, join as join19, resolve as resolve7 } from "node:path";
19713
19477
  function ticketProvenanceSubject(ticketNumber) {
19714
19478
  if (!isSafePositiveTicketNumber(ticketNumber)) {
19715
19479
  throw new Error(
@@ -19729,7 +19493,7 @@ function ticketProvenanceRecordInput(ticketNumber, cwd, home, runDirectory) {
19729
19493
  };
19730
19494
  }
19731
19495
  async function rehomeUnboundTicketProvenance(runDirectory, ticketNumber, cwd, home) {
19732
- const source = join19(runDirectory, "records.jsonl");
19496
+ const source = sitianVolumeRecordsFile(runDirectory);
19733
19497
  let content;
19734
19498
  try {
19735
19499
  content = await readFile9(source, "utf8");
@@ -19746,6 +19510,8 @@ var init_ticket_provenance = __esm({
19746
19510
  init_activation_ledger_topology();
19747
19511
  init_ledger_session_read();
19748
19512
  init_run_ticket_number();
19513
+ init_role_run_placement();
19514
+ init_sitian_appender();
19749
19515
  init_session_dialogue();
19750
19516
  init_sitian_facade();
19751
19517
  init_ticket_provenance_contracts();
@@ -19779,7 +19545,7 @@ var init_uuidv7 = __esm({
19779
19545
  });
19780
19546
 
19781
19547
  // src/notary-source-run.ts
19782
- import { dirname as dirname11, isAbsolute as isAbsolute4, join as join20, resolve as resolve8, basename as basename5 } from "node:path";
19548
+ import { dirname as dirname9, isAbsolute as isAbsolute4, join as join15, resolve as resolve7, basename as basename5 } from "node:path";
19783
19549
  import { lstat as lstat2, realpath as realpath2 } from "node:fs/promises";
19784
19550
  async function readRetainedIdentity(runDirectory) {
19785
19551
  try {
@@ -19791,11 +19557,6 @@ async function readRetainedIdentity(runDirectory) {
19791
19557
  });
19792
19558
  }
19793
19559
  }
19794
- function parseRunDirectoryName(name) {
19795
- const match = RUN_DIR_NAME.exec(name);
19796
- if (match === null) return void 0;
19797
- return { runId: match[1], role: match[2] };
19798
- }
19799
19560
  async function requireRunDirectory(candidate, display) {
19800
19561
  let real;
19801
19562
  try {
@@ -19820,7 +19581,7 @@ async function requireRunDirectory(candidate, display) {
19820
19581
  `notary --source-run must be a run directory: ${display}`
19821
19582
  );
19822
19583
  }
19823
- const identity = parseRunDirectoryName(basename5(real));
19584
+ const identity = parseRunLeaf(basename5(real));
19824
19585
  if (identity === void 0) {
19825
19586
  throw new NotarySourceRunError(
19826
19587
  `notary --source-run must be named <runId>@<role>: ${basename5(real)}`
@@ -19836,16 +19597,16 @@ async function resolveNotarySourceRunLocator(options) {
19836
19597
  const ledgerHome = resolveActivationLedgerHome(options.home);
19837
19598
  const bookKey = resolveBookKeyFromGit(options.projectRoot);
19838
19599
  const bookDirectory = activationBookDirectory(ledgerHome, bookKey);
19839
- const bookRunsRoot = join20(bookDirectory, "runs");
19600
+ const bookRunsRoot = join15(bookDirectory, "runs");
19840
19601
  let candidate;
19841
- const bare = parseRunDirectoryName(raw);
19602
+ const bare = parseRunLeaf(raw);
19842
19603
  if (bare !== void 0 && !raw.includes("/") && !raw.includes("\\")) {
19843
- candidate = await findRunDirectoryById(options.home, bare.runId, bookKey, bare.role) ?? join20(bookRunsRoot, `${bare.runId}@${bare.role}`);
19604
+ candidate = await findRunDirectoryById(options.home, bare.runId, bookKey, bare.role) ?? join15(bookRunsRoot, formatRunLeaf(bare.runId, bare.role));
19844
19605
  } else {
19845
- candidate = isAbsolute4(raw) ? raw : resolve8(options.projectRoot, raw);
19846
- const identity2 = parseRunDirectoryName(basename5(candidate));
19847
- const subjectDirectory = dirname11(dirname11(candidate));
19848
- const isLegacyUnboundLocator = identity2 !== void 0 && basename5(dirname11(candidate)) === "runs" && basename5(subjectDirectory) === "unbound" && resolve8(dirname11(subjectDirectory)) === resolve8(bookDirectory);
19606
+ candidate = isAbsolute4(raw) ? raw : resolve7(options.projectRoot, raw);
19607
+ const identity2 = parseRunLeaf(basename5(candidate));
19608
+ const subjectDirectory = dirname9(dirname9(candidate));
19609
+ const isLegacyUnboundLocator = identity2 !== void 0 && basename5(dirname9(candidate)) === "runs" && basename5(subjectDirectory) === "unbound" && resolve7(dirname9(subjectDirectory)) === resolve7(bookDirectory);
19849
19610
  if (isLegacyUnboundLocator) {
19850
19611
  candidate = await findRunDirectoryById(
19851
19612
  options.home,
@@ -19856,11 +19617,11 @@ async function resolveNotarySourceRunLocator(options) {
19856
19617
  }
19857
19618
  }
19858
19619
  const real = await requireRunDirectory(candidate, raw);
19859
- const identity = parseRunDirectoryName(basename5(real));
19620
+ const identity = parseRunLeaf(basename5(real));
19860
19621
  const bookIdentity = physicalPathIdentity(bookDirectory);
19861
- const parentIdentity = physicalPathIdentity(dirname11(real));
19862
- const subjectBookIdentity = physicalPathIdentity(dirname11(dirname11(dirname11(real))));
19863
- if (parentIdentity !== physicalPathIdentity(bookRunsRoot) && !(basename5(dirname11(real)) === "runs" && subjectBookIdentity === bookIdentity)) {
19622
+ const parentIdentity = physicalPathIdentity(dirname9(real));
19623
+ const subjectBookIdentity = physicalPathIdentity(dirname9(dirname9(dirname9(real))));
19624
+ if (parentIdentity !== physicalPathIdentity(bookRunsRoot) && !(basename5(dirname9(real)) === "runs" && subjectBookIdentity === bookIdentity)) {
19864
19625
  throw new NotarySourceRunError(
19865
19626
  "notary --source-run must resolve to a retained run under the project machine-ledger book"
19866
19627
  );
@@ -19892,14 +19653,14 @@ async function resolveNotarySourceRunLocator(options) {
19892
19653
  role: identity.role
19893
19654
  };
19894
19655
  }
19895
- var RUN_DIR_NAME, NotarySourceRunError;
19656
+ var NotarySourceRunError;
19896
19657
  var init_notary_source_run = __esm({
19897
19658
  "src/notary-source-run.ts"() {
19898
19659
  "use strict";
19899
19660
  init_activation_ledger_git();
19900
19661
  init_activation_ledger_topology();
19901
19662
  init_run_lifecycle();
19902
- RUN_DIR_NAME = /^([A-Za-z0-9][A-Za-z0-9._-]*)@([A-Za-z][A-Za-z0-9_-]*)$/;
19663
+ init_role_run_placement();
19903
19664
  NotarySourceRunError = class extends Error {
19904
19665
  constructor(message, options) {
19905
19666
  super(message, options);
@@ -20956,7 +20717,7 @@ import {
20956
20717
  writeFile as writeFile2
20957
20718
  } from "node:fs/promises";
20958
20719
  import { tmpdir } from "node:os";
20959
- import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute5, join as join21, resolve as resolve9, sep as sep3 } from "node:path";
20720
+ import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute5, join as join16, resolve as resolve8 } from "node:path";
20960
20721
  function issueAdmissionPlacement(authority, request) {
20961
20722
  const ledgerHome = resolveActivationLedgerHome(request.home);
20962
20723
  const bookKey = resolveBookKeyFromGit(request.cwd);
@@ -21010,14 +20771,14 @@ async function writeRoleInvocationLedger(source, role, effectiveModel) {
21010
20771
  ...effectiveModelLedgerFields(effectiveModel)
21011
20772
  };
21012
20773
  await writeFile2(
21013
- join21(source.runDirectory, "invocation.json"),
20774
+ join16(source.runDirectory, "invocation.json"),
21014
20775
  `${JSON.stringify(identity, null, 2)}
21015
20776
  `,
21016
20777
  "utf8"
21017
20778
  );
21018
20779
  }
21019
20780
  async function recordEffectiveInvocationModel(runDirectory, model, engine, host, engineModel) {
21020
- await updateDurableJsonPage(join21(runDirectory, "invocation.json"), (current) => {
20781
+ await updateDurableJsonPage(join16(runDirectory, "invocation.json"), (current) => {
21021
20782
  const next = { ...current };
21022
20783
  if (model !== void 0) {
21023
20784
  next.provider = model.provider;
@@ -21052,7 +20813,7 @@ async function updateDurableJsonPage(path, update) {
21052
20813
  `, "utf8");
21053
20814
  }
21054
20815
  async function mergeInvocationIdentityPage(runDirectory, fields) {
21055
- await updateDurableJsonPage(join21(runDirectory, "invocation.json"), (current) => ({
20816
+ await updateDurableJsonPage(join16(runDirectory, "invocation.json"), (current) => ({
21056
20817
  ...current,
21057
20818
  ...fields
21058
20819
  }));
@@ -21111,14 +20872,14 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
21111
20872
  runId: admitted.runId,
21112
20873
  role: admitted.role
21113
20874
  });
21114
- ensureRoleRunDirectory(ledgerHome, dirname12(target.runDirectory));
20875
+ ensureRoleRunDirectory(ledgerHome, dirname10(target.runDirectory));
21115
20876
  const principal = authority.seal(target);
21116
20877
  if (admitted.role !== "diarist") {
21117
20878
  const parentPage = JSON.parse(await readFile10(admitted.admittedRequestPath, "utf8"));
21118
20879
  const childRunIds = parentPage.childDiaristRunIds;
21119
20880
  for (const childRunId of Array.isArray(childRunIds) ? childRunIds : []) {
21120
20881
  if (typeof childRunId !== "string") continue;
21121
- const childDirectory = join21(dirname12(oldRunDirectory), `${childRunId}@diarist`);
20882
+ const childDirectory = join16(dirname10(oldRunDirectory), formatRunLeaf(childRunId, "diarist"));
21122
20883
  if (!existsSync5(childDirectory)) continue;
21123
20884
  const childTarget = roleRunPlacement(ledgerHome, {
21124
20885
  bookKey: admitted.bookKey,
@@ -21129,7 +20890,7 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
21129
20890
  authority.seal(childTarget);
21130
20891
  await bindTicketNumberOnRunDirectory(childDirectory, admitted.ticketNumber);
21131
20892
  await rehomeUnboundTicketProvenance(childDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
21132
- ensureRoleRunDirectory(ledgerHome, dirname12(childTarget.runDirectory));
20893
+ ensureRoleRunDirectory(ledgerHome, dirname10(childTarget.runDirectory));
21133
20894
  await rename(childDirectory, childTarget.runDirectory);
21134
20895
  }
21135
20896
  }
@@ -21175,7 +20936,7 @@ async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
21175
20936
  ticketNumber,
21176
20937
  "bindTicketNumberOnRunDirectory"
21177
20938
  );
21178
- const admittedPath = join21(runDirectory, "admitted-request.json");
20939
+ const admittedPath = join16(runDirectory, "admitted-request.json");
21179
20940
  let unchanged = false;
21180
20941
  await updateDurableJsonPage(admittedPath, (admitted) => {
21181
20942
  if (admitted.ticketNumber === ticketNumber) {
@@ -21196,7 +20957,7 @@ async function recordLaunchedPiIdentity(runDirectory, identity) {
21196
20957
  async function observeLaunchedRolePackageIdentity(packageRoot2, selectedRoleEntry) {
21197
20958
  const rolePackageRoot = packageRoot2;
21198
20959
  const raw = JSON.parse(
21199
- await readFile10(join21(rolePackageRoot, "package.json"), "utf8")
20960
+ await readFile10(join16(rolePackageRoot, "package.json"), "utf8")
21200
20961
  );
21201
20962
  if (typeof raw.version !== "string" || raw.version.trim() === "") {
21202
20963
  throw new Error(
@@ -21218,6 +20979,11 @@ async function recordLaunchedRolePackageIdentity(runDirectory, identity) {
21218
20979
  entryMode: identity.entryMode
21219
20980
  });
21220
20981
  }
20982
+ function rejectUnlessTicketNumber(raw, message) {
20983
+ const parsed = parseTicketNumber(raw.trim());
20984
+ if (parsed === void 0) throw new CliUsageError(message);
20985
+ return parsed;
20986
+ }
21221
20987
  function scanPublicArgv(args, options, handlers) {
21222
20988
  const tokens = [...args];
21223
20989
  while (tokens.length > 0) {
@@ -21459,7 +21225,7 @@ function requireAuthorityRef(value) {
21459
21225
  });
21460
21226
  }
21461
21227
  async function readRegularFileAttachment(sourcePath) {
21462
- const absolute = isAbsolute5(sourcePath) ? sourcePath : resolve9(sourcePath);
21228
+ const absolute = isAbsolute5(sourcePath) ? sourcePath : resolve8(sourcePath);
21463
21229
  let st;
21464
21230
  try {
21465
21231
  st = await lstat3(absolute);
@@ -21488,13 +21254,13 @@ async function removePreparedAttachmentDirectory(stagingDirectory) {
21488
21254
  }
21489
21255
  async function withPreparedAttachments(attachmentPaths, use) {
21490
21256
  if (attachmentPaths.length === 0) return await use([]);
21491
- const stagingDirectory = await mkdtemp(join21(tmpdir(), "ak-role-attachments-"));
21257
+ const stagingDirectory = await mkdtemp(join16(tmpdir(), "ak-role-attachments-"));
21492
21258
  const prepared = [];
21493
21259
  let result;
21494
21260
  try {
21495
21261
  for (let index = 0; index < attachmentPaths.length; index += 1) {
21496
21262
  const { absolute, bytes } = await readRegularFileAttachment(attachmentPaths[index]);
21497
- const snapshotPath = join21(stagingDirectory, String(index).padStart(6, "0"));
21263
+ const snapshotPath = join16(stagingDirectory, String(index).padStart(6, "0"));
21498
21264
  await writeFile2(snapshotPath, bytes);
21499
21265
  prepared.push({ absolute, snapshotPath });
21500
21266
  }
@@ -21515,7 +21281,7 @@ async function withPreparedAttachments(attachmentPaths, use) {
21515
21281
  return result;
21516
21282
  }
21517
21283
  async function freezeAttachmentBytes(provenancePath, bytes, destinationDir, index) {
21518
- const frozenPath = join21(
21284
+ const frozenPath = join16(
21519
21285
  destinationDir,
21520
21286
  `${String(index).padStart(2, "0")}-${basename6(provenancePath)}`
21521
21287
  );
@@ -21558,14 +21324,14 @@ async function freezeAttachments(attachmentPaths, attachmentsDirectory) {
21558
21324
  async function freezeAttachmentsIntoRun(attachmentPaths, runDirectory, summonsKey = `s-${Date.now().toString(36)}`) {
21559
21325
  if (attachmentPaths.length === 0) return [];
21560
21326
  const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(runDirectory));
21561
- const attachmentsDirectory = join21(runDirectory, "attachments", summonsKey);
21327
+ const attachmentsDirectory = join16(runDirectory, "attachments", summonsKey);
21562
21328
  ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
21563
21329
  return freezeAttachments(attachmentPaths, attachmentsDirectory);
21564
21330
  }
21565
21331
  async function freezePreparedAttachmentsIntoRun(prepared, runDirectory, summonsKey) {
21566
21332
  if (prepared.length === 0) return [];
21567
21333
  const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(runDirectory));
21568
- const attachmentsDirectory = summonsKey === void 0 ? join21(runDirectory, "attachments") : join21(runDirectory, "attachments", summonsKey);
21334
+ const attachmentsDirectory = summonsKey === void 0 ? join16(runDirectory, "attachments") : join16(runDirectory, "attachments", summonsKey);
21569
21335
  ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
21570
21336
  const attachments = [];
21571
21337
  for (let index = 0; index < prepared.length; index += 1) {
@@ -21642,7 +21408,7 @@ async function admitPublicRole(role, parsed, env, override) {
21642
21408
  attachmentPaths,
21643
21409
  ...project,
21644
21410
  placedFields: async (placed) => {
21645
- const taskPath = join21(placed.runDirectory, "task.md");
21411
+ const taskPath = join16(placed.runDirectory, "task.md");
21646
21412
  await writeFile2(taskPath, instruction, "utf8");
21647
21413
  return { phase, taskPath };
21648
21414
  }
@@ -21659,7 +21425,7 @@ async function admitPublicRole(role, parsed, env, override) {
21659
21425
  let prerequisites = Object.freeze([]);
21660
21426
  let prerequisitesSource;
21661
21427
  if (parsed.prerequisitesPath !== void 0) {
21662
- const absolutePrereq = isAbsolute5(parsed.prerequisitesPath) ? parsed.prerequisitesPath : resolve9(parsed.prerequisitesPath);
21428
+ const absolutePrereq = isAbsolute5(parsed.prerequisitesPath) ? parsed.prerequisitesPath : resolve8(parsed.prerequisitesPath);
21663
21429
  try {
21664
21430
  prerequisitesSource = await readFile10(absolutePrereq, "utf8");
21665
21431
  } catch (error) {
@@ -21685,7 +21451,7 @@ async function admitPublicRole(role, parsed, env, override) {
21685
21451
  placedFields: async (placed) => {
21686
21452
  let prerequisitesPath;
21687
21453
  if (prerequisitesSource !== void 0) {
21688
- prerequisitesPath = join21(placed.runDirectory, "prerequisites.json");
21454
+ prerequisitesPath = join16(placed.runDirectory, "prerequisites.json");
21689
21455
  await writeFile2(
21690
21456
  prerequisitesPath,
21691
21457
  `${JSON.stringify(prerequisites, null, 2)}
@@ -21693,7 +21459,7 @@ async function admitPublicRole(role, parsed, env, override) {
21693
21459
  "utf8"
21694
21460
  );
21695
21461
  }
21696
- const packetPath = join21(placed.runDirectory, "fix-packet.md");
21462
+ const packetPath = join16(placed.runDirectory, "fix-packet.md");
21697
21463
  await writeFile2(packetPath, instruction, "utf8");
21698
21464
  return {
21699
21465
  phase,
@@ -21706,7 +21472,7 @@ async function admitPublicRole(role, parsed, env, override) {
21706
21472
  }
21707
21473
  case "collect-target": {
21708
21474
  const explicitPrNumber = parsed.prNumber;
21709
- const projectRoot = resolve9(parsed.project ?? shared.cwd);
21475
+ const projectRoot = resolve8(parsed.project ?? shared.cwd);
21710
21476
  let repository;
21711
21477
  if (parsed.repo !== void 0) {
21712
21478
  try {
@@ -21740,7 +21506,7 @@ async function admitPublicRole(role, parsed, env, override) {
21740
21506
  placedFields: async (placed) => {
21741
21507
  let requestManifestPath;
21742
21508
  if (manifestCanonicalJson !== void 0) {
21743
- requestManifestPath = join21(placed.runDirectory, "request-manifest.json");
21509
+ requestManifestPath = join16(placed.runDirectory, "request-manifest.json");
21744
21510
  await writeFile2(requestManifestPath, manifestCanonicalJson, "utf8");
21745
21511
  }
21746
21512
  return {
@@ -21788,7 +21554,10 @@ async function admitPublicRole(role, parsed, env, override) {
21788
21554
  }
21789
21555
  let caseIdentity;
21790
21556
  try {
21791
- const patient = await loadDoctorCase(caseRunsPath);
21557
+ const patient = await loadDoctorCase(
21558
+ caseRunsPath,
21559
+ parsed.runs === void 0 ? void 0 : placed.projectRoot
21560
+ );
21792
21561
  if (patient.identity.issueNumber !== issueNumber) {
21793
21562
  throw new CliUsageError(
21794
21563
  `doctor case issue ${patient.identity.issueNumber} does not match --issue ${issueNumber}`
@@ -21816,7 +21585,7 @@ async function admitPublicRole(role, parsed, env, override) {
21816
21585
  return { ...admittedDoctor, attachments: frozenAttachments };
21817
21586
  }
21818
21587
  case "source-locator": {
21819
- const projectRoot = resolve9(parsed.project ?? shared.cwd);
21588
+ const projectRoot = resolve8(parsed.project ?? shared.cwd);
21820
21589
  let sourceRun = override?.resolvedSourceRun;
21821
21590
  if (sourceRun === void 0) {
21822
21591
  try {
@@ -21892,7 +21661,7 @@ async function admitPublicRole(role, parsed, env, override) {
21892
21661
  if (instruction.trim() === "") {
21893
21662
  throw new CliUsageError("merger requires a nonblank task instruction");
21894
21663
  }
21895
- const projectRoot = resolve9(parsed.project ?? shared.cwd);
21664
+ const projectRoot = resolve8(parsed.project ?? shared.cwd);
21896
21665
  const derived = await deriveMergerEnvelopeFromActiveMerge(
21897
21666
  projectRoot,
21898
21667
  createProductionMergerGitState(projectRoot)
@@ -21923,7 +21692,7 @@ async function admitPublicRole(role, parsed, env, override) {
21923
21692
  resolutionScope: [...derived.resolutionScope],
21924
21693
  authorizedChecks: []
21925
21694
  });
21926
- const mergerInputPath = join21(placed.runDirectory, "merger-input.json");
21695
+ const mergerInputPath = join16(placed.runDirectory, "merger-input.json");
21927
21696
  await writeFile2(
21928
21697
  mergerInputPath,
21929
21698
  `${JSON.stringify(mergerInput, null, 2)}
@@ -21950,7 +21719,7 @@ function admissionSubject(ticketNumber) {
21950
21719
  return { ticketNumber: fields.ticketNumber };
21951
21720
  }
21952
21721
  async function placeRoleAdmission(options) {
21953
- const projectRoot = resolve9(options.project ?? options.cwd);
21722
+ const projectRoot = resolve8(options.project ?? options.cwd);
21954
21723
  const runId = options.runId ?? (options.createRunId ?? uuidv7)();
21955
21724
  const ticketFields = ticketAdmissionFields(options.assertedTicketNumber);
21956
21725
  const {
@@ -21994,7 +21763,7 @@ function persistedAttachmentRefs(attachments) {
21994
21763
  }));
21995
21764
  }
21996
21765
  async function persistPlacedAdmission(admitted, placed, model) {
21997
- const admittedRequestPath = join21(placed.runDirectory, "admitted-request.json");
21766
+ const admittedRequestPath = join16(placed.runDirectory, "admitted-request.json");
21998
21767
  await writeAdmittedRequestPersistence(admittedRequestPath, admitted, {
21999
21768
  sessionDirectory: placed.sessionDirectory,
22000
21769
  sessionFile: placed.sessionFile
@@ -22047,7 +21816,7 @@ async function admitStandardMaterialInvocation(role, options) {
22047
21816
  attachments: persistedAttachmentRefs(placed.attachments),
22048
21817
  ...placed.ticketFields
22049
21818
  };
22050
- const admittedRequestPath = defer ? join21(placed.runDirectory, "admitted-request.json") : await persistPlacedAdmission(admitted, placed, options.model);
21819
+ const admittedRequestPath = defer ? join16(placed.runDirectory, "admitted-request.json") : await persistPlacedAdmission(admitted, placed, options.model);
22051
21820
  return {
22052
21821
  role,
22053
21822
  runId: placed.runId,
@@ -22125,7 +21894,7 @@ async function materializeCountersignInvocation(admitted, options) {
22125
21894
  });
22126
21895
  const placement = placed;
22127
21896
  admitted.runDirectory = placement.runDirectory;
22128
- admitted.admittedRequestPath = join21(
21897
+ admitted.admittedRequestPath = join16(
22129
21898
  placement.runDirectory,
22130
21899
  "admitted-request.json"
22131
21900
  );
@@ -22211,17 +21980,14 @@ function isGitRemoteMissing(error) {
22211
21980
  return status === 2;
22212
21981
  }
22213
21982
  function parseDoctorIssueNumber(raw) {
22214
- const trimmed = raw.trim();
22215
- if (!DOCTOR_ISSUE_NUMBER_PATTERN.test(trimmed)) {
22216
- throw new CliUsageError(
22217
- `doctor --issue must be a positive integer, got ${raw}`
22218
- );
22219
- }
22220
- return Number(trimmed);
21983
+ return rejectUnlessTicketNumber(
21984
+ raw,
21985
+ `doctor --issue must be a positive integer, got ${raw}`
21986
+ );
22221
21987
  }
22222
21988
  async function resolveDoctorCaseRunsPath(options) {
22223
21989
  const ledgerHome = resolveActivationLedgerHome(options.home);
22224
- const defaultRuns = join21(
21990
+ const defaultRuns = join16(
22225
21991
  activationBookDirectory(ledgerHome, options.bookKey),
22226
21992
  String(options.issueNumber),
22227
21993
  "runs"
@@ -22238,7 +22004,7 @@ async function resolveDoctorCaseRunsPath(options) {
22238
22004
  "doctor --runs must be a project-relative path"
22239
22005
  );
22240
22006
  }
22241
- const resolved = resolve9(options.projectRoot, raw);
22007
+ const resolved = resolve8(options.projectRoot, raw);
22242
22008
  if (resolved !== options.projectRoot && !pathContainedIn(options.projectRoot, resolved)) {
22243
22009
  throw new CliUsageError(
22244
22010
  "doctor --runs escapes the project root"
@@ -22254,18 +22020,6 @@ async function resolveDoctorCaseRunsPath(options) {
22254
22020
  { cause: error }
22255
22021
  );
22256
22022
  }
22257
- const normalized = real.split(sep3).join("/");
22258
- const match = normalized.match(DOCTOR_CASE_RUNS_PATH_PATTERN);
22259
- if (!match) {
22260
- throw new CliUsageError(
22261
- "doctor --runs must be an .ak-roles/books/<book>/<n>/runs directory"
22262
- );
22263
- }
22264
- if (Number(match[1]) !== options.issueNumber) {
22265
- throw new CliUsageError(
22266
- `doctor --runs issue ${match[1]} does not match --issue ${options.issueNumber}`
22267
- );
22268
- }
22269
22023
  return real;
22270
22024
  }
22271
22025
  function buildReviewerSkillArgProjection(admitted) {
@@ -22294,19 +22048,10 @@ async function deriveMergerEnvelopeFromActiveMerge(projectRoot, gitState = creat
22294
22048
  });
22295
22049
  }
22296
22050
  function parseAnalystTicketNumber(raw, flag = "--ticket") {
22297
- const trimmed = raw.trim();
22298
- if (!ANALYST_TICKET_NUMBER_PATTERN.test(trimmed)) {
22299
- throw new CliUsageError(
22300
- `analyst ${flag} must be a positive integer, got ${raw}`
22301
- );
22302
- }
22303
- const value = Number(trimmed);
22304
- if (!Number.isSafeInteger(value) || value < 1) {
22305
- throw new CliUsageError(
22306
- `analyst ${flag} must be a positive integer, got ${raw}`
22307
- );
22308
- }
22309
- return value;
22051
+ return rejectUnlessTicketNumber(
22052
+ raw,
22053
+ `analyst ${flag} must be a positive integer, got ${raw}`
22054
+ );
22310
22055
  }
22311
22056
  function parseAnalystCohortIssueToken(raw, flag) {
22312
22057
  const trimmed = raw.trim();
@@ -22318,7 +22063,7 @@ function parseAnalystCohortIssueToken(raw, flag) {
22318
22063
  const sep5 = trimmed.lastIndexOf(":");
22319
22064
  if (sep5 > 0) {
22320
22065
  const rhs = trimmed.slice(sep5 + 1);
22321
- if (ANALYST_TICKET_NUMBER_PATTERN.test(rhs)) {
22066
+ if (parseTicketNumber(rhs) !== void 0) {
22322
22067
  const bookKey = trimmed.slice(0, sep5);
22323
22068
  if (bookKey.trim() === "") {
22324
22069
  throw new CliUsageError(
@@ -22510,7 +22255,6 @@ function parseAnalystArgv(args) {
22510
22255
  ...ticketRaw === void 0 ? {} : { ticket: parseAnalystTicketNumber(ticketRaw) }
22511
22256
  };
22512
22257
  }
22513
- var DOCTOR_ISSUE_NUMBER_PATTERN, DOCTOR_CASE_RUNS_PATH_PATTERN, ANALYST_TICKET_NUMBER_PATTERN;
22514
22258
  var init_invocation = __esm({
22515
22259
  "src/public-cli/invocation.ts"() {
22516
22260
  "use strict";
@@ -22535,9 +22279,6 @@ var init_invocation = __esm({
22535
22279
  init_cli_errors();
22536
22280
  init_option_definitions();
22537
22281
  init_unknown_value();
22538
- DOCTOR_ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/;
22539
- DOCTOR_CASE_RUNS_PATH_PATTERN = /\/\.ak-roles\/books\/[^/]+\/(?:issues\/)?([1-9]\d*)\/runs$/;
22540
- ANALYST_TICKET_NUMBER_PATTERN = /^[1-9]\d*$/;
22541
22282
  }
22542
22283
  });
22543
22284
 
@@ -22661,14 +22402,13 @@ __export(settlement_exports, {
22661
22402
  LifecycleReadFailure: () => LifecycleReadFailure,
22662
22403
  NAVIGATOR_POST_ROLE_GRACE_MS: () => NAVIGATOR_POST_ROLE_GRACE_MS,
22663
22404
  appendRunAttemptHistory: () => appendRunAttemptHistory,
22664
- attachPostAuditProjection: () => attachPostAuditProjection,
22405
+ attachPostAuditCountersignFact: () => attachPostAuditCountersignFact,
22665
22406
  attachRecordedSubmissions: () => attachRecordedSubmissions,
22666
22407
  classifyPostAdmissionFailure: () => classifyPostAdmissionFailure,
22667
22408
  conciseChildDiagnostic: () => conciseChildDiagnostic,
22668
22409
  ensureRealArtifactsDirectory: () => ensureRealArtifactsDirectory,
22669
22410
  exitCodeForTerminalOutcome: () => exitCodeForTerminalOutcome,
22670
22411
  explicitInternalKnownFailureClassificationInput: () => explicitInternalKnownFailureClassificationInput,
22671
- extractGateFactFromSessionDirectory: () => extractGateFactFromSessionDirectory,
22672
22412
  extractNavigatorFact: () => extractNavigatorFact,
22673
22413
  formatCliDiagnostic: () => formatCliDiagnostic,
22674
22414
  formatErrorCauseDetail: () => formatErrorCauseDetail,
@@ -22680,7 +22420,6 @@ __export(settlement_exports, {
22680
22420
  presentControlledFailure: () => presentControlledFailure,
22681
22421
  presentFailureTerminal: () => presentFailureTerminal,
22682
22422
  presentStructuralRejection: () => presentStructuralRejection,
22683
- projectTerminalGateFact: () => projectTerminalGateFact,
22684
22423
  projectThrownFailureLeaf: () => projectThrownFailureLeaf,
22685
22424
  publishFailureArtifacts: () => publishFailureArtifacts,
22686
22425
  raceNavigatorGrace: () => raceNavigatorGrace,
@@ -22693,8 +22432,8 @@ __export(settlement_exports, {
22693
22432
  withSubmissions: () => withSubmissions
22694
22433
  });
22695
22434
  import { randomUUID as randomUUID5 } from "node:crypto";
22696
- import { dirname as dirname13, join as join22 } from "node:path";
22697
- import { lstat as lstat4, mkdir as mkdir3, readFile as readFile11, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
22435
+ import { dirname as dirname11, join as join17 } from "node:path";
22436
+ import { lstat as lstat4, mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
22698
22437
  function sealedLedgerHome(admitted) {
22699
22438
  return homeFromRunDirectory(admitted.runDirectory);
22700
22439
  }
@@ -22771,7 +22510,7 @@ async function noteSettlementFault(runDirectory, scope, diagnostic) {
22771
22510
  function ledgerReadScope(admitted, scope) {
22772
22511
  return {
22773
22512
  home: sealedLedgerHome(admitted),
22774
- sessionParent: join22(admitted.runDirectory, "session", "session.jsonl"),
22513
+ sessionParent: sessionFileOf(admitted.runDirectory),
22775
22514
  ...scope?.courtAttemptId === void 0 || scope.courtAttemptId.length === 0 ? {} : { attemptId: scope.courtAttemptId }
22776
22515
  };
22777
22516
  }
@@ -22925,7 +22664,7 @@ async function settleNoReceiptTerminal(admitted, authority, scope, facts) {
22925
22664
  );
22926
22665
  }
22927
22666
  if (scope?.previewOnly !== true) await clearOppositeTerminalArtifactFace(admitted.runDirectory);
22928
- return withOptionalGateProjection({
22667
+ return attachEngineDetourToolUsage({
22929
22668
  roleOutcome,
22930
22669
  navigator: await extractNavigatorFactFromAdmittedSession(
22931
22670
  coordinates.sessionFile,
@@ -22934,7 +22673,7 @@ async function settleNoReceiptTerminal(admitted, authority, scope, facts) {
22934
22673
  ),
22935
22674
  artifacts: [],
22936
22675
  runId: admitted.runId
22937
- }, coordinates.sessionDirectory, detourGateContext(admitted, scope));
22676
+ }, coordinates.sessionDirectory, detourUsageContext(admitted, scope));
22938
22677
  }
22939
22678
  function coordinatesFromAdmitted(authority, admitted) {
22940
22679
  return authority.decode(admitted.principal);
@@ -23165,12 +22904,7 @@ function explicitInternalKnownFailureClassificationInput(failure) {
23165
22904
  };
23166
22905
  }
23167
22906
  async function readBoundSessionEntries(sessionFile) {
23168
- const text = await readFile11(sessionFile, "utf8");
23169
- const entries = [];
23170
- for (const line2 of text.trim().split("\n").filter(Boolean)) {
23171
- entries.push(JSON.parse(line2));
23172
- }
23173
- return entries;
22907
+ return await readStrictPiSessionJsonl(sessionFile);
23174
22908
  }
23175
22909
  async function appendRunAttemptHistory(source, outcome) {
23176
22910
  sitianReport({
@@ -23234,57 +22968,22 @@ function parseNavigatorAttendanceDetails(details) {
23234
22968
  reason: "Navigator attendance disposition is unparseable"
23235
22969
  };
23236
22970
  }
23237
- function projectTerminalGateFact(rounds) {
23238
- if (rounds.length === 0) return void 0;
23239
- const seen = /* @__PURE__ */ new Set();
23240
- for (const round of rounds) {
23241
- if (round.origin.kind === "historical_dispatch") seen.add("gatekeeper");
23242
- seen.add(round.officer);
23243
- }
23244
- const actualSeats = ["gatekeeper", "inspector", "notary"].filter(
23245
- (seat) => seen.has(seat)
23246
- );
23247
- return {
23248
- actualSeats,
23249
- rounds: rounds.map((round) => ({
23250
- roundIndex: round.roundIndex,
23251
- dispatch: round.origin.kind === "direct" ? { kind: "direct", officer: round.officer } : {
23252
- kind: "historical_dispatch",
23253
- officer: round.officer,
23254
- ...round.origin.reason === void 0 ? {} : { reason: round.origin.reason }
23255
- },
23256
- officer: {
23257
- seat: round.officer,
23258
- status: round.status,
23259
- findings: round.findings
23260
- }
23261
- }))
23262
- };
23263
- }
23264
- async function extractGateFactFromSessionDirectory(sessionDirectory, options = {}) {
23265
- const directories = [join22(sessionDirectory, "auditor-roles")];
23266
- const parentSessionFile = options.parentSessionFile ?? join22(sessionDirectory, "session.jsonl");
23267
- const rounds = await readAnalystGateCyclesFromAuditorRoles(directories, {
23268
- parentSessionFile
23269
- });
23270
- return projectTerminalGateFact(rounds);
23271
- }
23272
- async function attachEngineDetourToolUsage(base, sessionDirectory, gateContext = {}) {
23273
- const runDirectory = typeof gateContext.runDirectory === "string" && gateContext.runDirectory.length > 0 ? gateContext.runDirectory : runDirectoryFromSessionDirectory(sessionDirectory);
22971
+ async function attachEngineDetourToolUsage(base, sessionDirectory, detourContext = {}) {
22972
+ const runDirectory = typeof detourContext.runDirectory === "string" && detourContext.runDirectory.length > 0 ? detourContext.runDirectory : runDirectoryFromSessionDirectory(sessionDirectory);
23274
22973
  let engineMounted = false;
23275
22974
  try {
23276
22975
  engineMounted = await readInvocationEngineMounted(runDirectory);
23277
22976
  } catch (error) {
23278
22977
  await noteSettlementFault(
23279
22978
  runDirectory,
23280
- gateContext.notePackageFault === void 0 ? void 0 : { notePackageFault: gateContext.notePackageFault },
22979
+ detourContext.notePackageFault === void 0 ? void 0 : { notePackageFault: detourContext.notePackageFault },
23281
22980
  `engine mount read failed beside host terminal: ${describeErrorIdentity(error)}`
23282
22981
  );
23283
22982
  return base;
23284
22983
  }
23285
22984
  if (!engineMounted) return base;
23286
- const invocationScopeId = typeof gateContext.invocationScopeId === "string" && gateContext.invocationScopeId.length > 0 ? gateContext.invocationScopeId : void 0;
23287
- const sessionFile = sessionFileFromSessionDirectory(sessionDirectory);
22985
+ const invocationScopeId = typeof detourContext.invocationScopeId === "string" && detourContext.invocationScopeId.length > 0 ? detourContext.invocationScopeId : void 0;
22986
+ const sessionFile = sessionFileIn(sessionDirectory);
23288
22987
  let usage;
23289
22988
  try {
23290
22989
  usage = await readEngineDetourToolUsage({
@@ -23296,7 +22995,7 @@ async function attachEngineDetourToolUsage(base, sessionDirectory, gateContext =
23296
22995
  } catch (error) {
23297
22996
  await noteSettlementFault(
23298
22997
  runDirectory,
23299
- gateContext.notePackageFault === void 0 ? void 0 : { notePackageFault: gateContext.notePackageFault },
22998
+ detourContext.notePackageFault === void 0 ? void 0 : { notePackageFault: detourContext.notePackageFault },
23300
22999
  `engine detour read failed beside host terminal: ${describeErrorIdentity(error)}`
23301
23000
  );
23302
23001
  return base;
@@ -23306,33 +23005,13 @@ async function attachEngineDetourToolUsage(base, sessionDirectory, gateContext =
23306
23005
  roleOutcome: withEngineDetourToolUsageFact(base.roleOutcome, usage)
23307
23006
  };
23308
23007
  }
23309
- function detourGateContext(admitted, scope) {
23008
+ function detourUsageContext(admitted, scope) {
23310
23009
  return {
23311
23010
  runDirectory: admitted.runDirectory,
23312
- ...scope?.courtAttemptId === void 0 || scope.courtAttemptId.length === 0 ? {} : { courtAttemptId: scope.courtAttemptId },
23313
23011
  ...scope?.invocationScopeId === void 0 || scope.invocationScopeId.length === 0 ? {} : { invocationScopeId: scope.invocationScopeId },
23314
23012
  ...scope?.notePackageFault === void 0 ? {} : { notePackageFault: scope.notePackageFault }
23315
23013
  };
23316
23014
  }
23317
- async function withOptionalGateProjection(base, sessionDirectory, gateContext = {}) {
23318
- const secondaryEvidence = base.roleOutcome.kind === "failure" ? base.roleOutcome.decisiveFacts.secondaryEvidence : void 0;
23319
- const skipGate = isRecord(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && packagedSkipsGateOnInfrastructureStage(secondaryEvidence.stage);
23320
- let next = base;
23321
- if (!skipGate) {
23322
- try {
23323
- const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
23324
- if (gate !== void 0) next = { ...base, gate };
23325
- } catch (error) {
23326
- const runDirectory = gateContext.runDirectory ?? runDirectoryFromSessionDirectory(sessionDirectory);
23327
- await noteSettlementFault(
23328
- runDirectory,
23329
- gateContext.notePackageFault === void 0 ? void 0 : { notePackageFault: gateContext.notePackageFault },
23330
- `gate read failed beside host terminal: ${describeErrorIdentity(error)}`
23331
- );
23332
- }
23333
- }
23334
- return attachEngineDetourToolUsage(next, sessionDirectory, gateContext);
23335
- }
23336
23015
  function routePlaybookFailureMessage(entries) {
23337
23016
  for (let i = entries.length - 1; i >= 0; i -= 1) {
23338
23017
  const entry = entries[i];
@@ -23406,10 +23085,10 @@ async function removeFaceIfPresent(path) {
23406
23085
  async function clearOppositeTerminalArtifactFace(runDirectory) {
23407
23086
  const artifactsDir = roleRunArtifactsDirectory(runDirectory);
23408
23087
  for (const file of RUN_TERMINAL_ARTIFACT_FILES) {
23409
- await removeFaceIfPresent(join22(artifactsDir, file));
23088
+ await removeFaceIfPresent(join17(artifactsDir, file));
23410
23089
  }
23411
23090
  for (const relative3 of RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS) {
23412
- await removeFaceIfPresent(join22(runDirectory, relative3));
23091
+ await removeFaceIfPresent(join17(runDirectory, relative3));
23413
23092
  }
23414
23093
  for (const path of await listSeamOwnedUniqueErrorFacePaths(runDirectory)) {
23415
23094
  await removeFaceIfPresent(path);
@@ -23436,8 +23115,8 @@ async function publishAcceptedTerminalArtifacts(admitted, roleOutcome, coordinat
23436
23115
  );
23437
23116
  }
23438
23117
  const artifactsDir = await ensureTerminalArtifactFace(admitted.runDirectory);
23439
- const reportPath = join22(artifactsDir, RUN_TERMINAL_REPORT_FILE);
23440
- const evidencePath = join22(artifactsDir, RUN_TERMINAL_EVIDENCE_FILE);
23118
+ const reportPath = join17(artifactsDir, RUN_TERMINAL_REPORT_FILE);
23119
+ const evidencePath = join17(artifactsDir, RUN_TERMINAL_EVIDENCE_FILE);
23441
23120
  await writeFile3(
23442
23121
  reportPath,
23443
23122
  `${JSON.stringify(bodies.report, null, 2)}
@@ -23484,12 +23163,12 @@ async function settleSealedSeat(admitted, authority, scope, options) {
23484
23163
  }
23485
23164
  async function finishLawfulSeat(admitted, coordinates, entries, roleOutcome, scope) {
23486
23165
  const artifacts = scope?.previewOnly === true ? [] : await publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries, scope?.recordAttemptHistory === true);
23487
- const terminal = await withOptionalGateProjection({
23166
+ const terminal = await attachEngineDetourToolUsage({
23488
23167
  roleOutcome,
23489
23168
  navigator: extractNavigatorFact(entries),
23490
23169
  artifacts,
23491
23170
  runId: admitted.runId
23492
- }, coordinates.sessionDirectory, detourGateContext(admitted, scope));
23171
+ }, coordinates.sessionDirectory, detourUsageContext(admitted, scope));
23493
23172
  return attachRecordedSubmissions(admitted, terminal, scope);
23494
23173
  }
23495
23174
  async function settleSeat(admitted, authority, scope) {
@@ -23679,24 +23358,9 @@ async function applySecretariatCountersignTerminal(admitted, authority, settled,
23679
23358
  }
23680
23359
  return settled;
23681
23360
  }
23682
- async function attachPostAuditProjection(admitted, authority, terminal, scope) {
23683
- const { sessionDirectory, sessionFile } = coordinatesFromAdmitted(authority, admitted);
23684
- let gate;
23685
- try {
23686
- gate = await extractGateFactFromSessionDirectory(sessionDirectory, {
23687
- runDirectory: admitted.runDirectory,
23688
- parentSessionFile: sessionFile
23689
- });
23690
- } catch (error) {
23691
- await noteSettlementFault(
23692
- admitted.runDirectory,
23693
- scope,
23694
- `gate read failed beside host terminal: ${describeErrorIdentity(error)}`
23695
- );
23696
- }
23697
- const withGate = gate === void 0 ? terminal : { ...terminal, gate };
23698
- if (admitted.role !== "secretariat") return withGate;
23699
- return applySecretariatCountersignTerminal(admitted, authority, withGate, scope);
23361
+ async function attachPostAuditCountersignFact(admitted, authority, terminal, scope) {
23362
+ if (admitted.role !== "secretariat") return terminal;
23363
+ return applySecretariatCountersignTerminal(admitted, authority, terminal, scope);
23700
23364
  }
23701
23365
  function publicationAttemptFromError(path, error) {
23702
23366
  if (error instanceof Error) {
@@ -23710,7 +23374,7 @@ function publicationAttemptFromError(path, error) {
23710
23374
  }
23711
23375
  function uniqueFailureFallbackDirs(runDirectory, baseDir) {
23712
23376
  const dirs = [];
23713
- for (const dir of [baseDir, runDirectory, dirname13(runDirectory)]) {
23377
+ for (const dir of [baseDir, runDirectory, dirname11(runDirectory)]) {
23714
23378
  if (!dirs.includes(dir)) dirs.push(dir);
23715
23379
  }
23716
23380
  return dirs;
@@ -23732,7 +23396,7 @@ async function writeFailureJsonRetainingCause(preferredCandidates, uniqueFallbac
23732
23396
  const candidates = [
23733
23397
  ...preferredCandidates,
23734
23398
  // One unique name per fallback dir — collisions on fixed names cannot exhaust this.
23735
- ...uniqueFallbackDirs.map((dir) => join22(dir, stem === UNIQUE_ERROR_FALLBACK_STEM ? uniqueErrorFallbackName() : `${stem}.${randomUUID5()}.json`))
23399
+ ...uniqueFallbackDirs.map((dir) => join17(dir, stem === UNIQUE_ERROR_FALLBACK_STEM ? uniqueErrorFallbackName() : `${stem}.${randomUUID5()}.json`))
23736
23400
  ];
23737
23401
  for (let i = 0; i < candidates.length; i += 1) {
23738
23402
  const path = candidates[i];
@@ -23793,20 +23457,20 @@ async function publishFailureArtifacts(admitted, failure, authority, onErrorPubl
23793
23457
  baseDir
23794
23458
  );
23795
23459
  const errorCandidates = underArtifacts ? [
23796
- join22(baseDir, RUN_TERMINAL_ERROR_FILE),
23797
- join22(baseDir, RUN_TERMINAL_ERROR_SETTLEMENT_FILE),
23798
- join22(admitted.runDirectory, RUN_TERMINAL_ERROR_SETTLEMENT_FILE)
23460
+ join17(baseDir, RUN_TERMINAL_ERROR_FILE),
23461
+ join17(baseDir, RUN_TERMINAL_ERROR_SETTLEMENT_FILE),
23462
+ join17(admitted.runDirectory, RUN_TERMINAL_ERROR_SETTLEMENT_FILE)
23799
23463
  ] : [
23800
- join22(baseDir, RUN_TERMINAL_ERROR_SETTLEMENT_FILE),
23801
- join22(baseDir, RUN_TERMINAL_ERROR_FILE)
23464
+ join17(baseDir, RUN_TERMINAL_ERROR_SETTLEMENT_FILE),
23465
+ join17(baseDir, RUN_TERMINAL_ERROR_FILE)
23802
23466
  ];
23803
23467
  const evidenceCandidates = underArtifacts ? [
23804
- join22(baseDir, RUN_TERMINAL_EVIDENCE_FILE),
23805
- join22(baseDir, "evidence.settlement.json"),
23806
- join22(admitted.runDirectory, "evidence.settlement.json")
23468
+ join17(baseDir, RUN_TERMINAL_EVIDENCE_FILE),
23469
+ join17(baseDir, "evidence.settlement.json"),
23470
+ join17(admitted.runDirectory, "evidence.settlement.json")
23807
23471
  ] : [
23808
- join22(baseDir, "evidence.settlement.json"),
23809
- join22(baseDir, RUN_TERMINAL_EVIDENCE_FILE)
23472
+ join17(baseDir, "evidence.settlement.json"),
23473
+ join17(baseDir, RUN_TERMINAL_EVIDENCE_FILE)
23810
23474
  ];
23811
23475
  const errorPayloadBase = {
23812
23476
  kind: "error",
@@ -23901,10 +23565,10 @@ async function settleFailureTerminalResult(admitted, failure, authority, options
23901
23565
  diagnostic: failure.diagnostic,
23902
23566
  decisiveFacts
23903
23567
  };
23904
- return withOptionalGateProjection(
23568
+ return attachEngineDetourToolUsage(
23905
23569
  { roleOutcome, navigator, artifacts, runId: admitted.runId },
23906
23570
  sessionDirectory,
23907
- detourGateContext(admitted, options)
23571
+ detourUsageContext(admitted, options)
23908
23572
  );
23909
23573
  }
23910
23574
  function presentFailureTerminal(terminal, io) {
@@ -23932,10 +23596,10 @@ function presentFailureTerminal(terminal, io) {
23932
23596
  }
23933
23597
  function defaultNavigatorGraceSleep() {
23934
23598
  let timer;
23935
- const sleep2 = ((ms) => new Promise((resolve14) => {
23599
+ const sleep2 = ((ms) => new Promise((resolve13) => {
23936
23600
  timer = setTimeout(() => {
23937
23601
  timer = void 0;
23938
- resolve14();
23602
+ resolve13();
23939
23603
  }, ms);
23940
23604
  }));
23941
23605
  sleep2.cancel = () => {
@@ -23947,7 +23611,7 @@ function defaultNavigatorGraceSleep() {
23947
23611
  return sleep2;
23948
23612
  }
23949
23613
  function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep2 = defaultNavigatorGraceSleep()) {
23950
- return new Promise((resolve14, reject) => {
23614
+ return new Promise((resolve13, reject) => {
23951
23615
  let settled = false;
23952
23616
  const finish = (action) => {
23953
23617
  if (settled) return;
@@ -23956,11 +23620,11 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep2
23956
23620
  action();
23957
23621
  };
23958
23622
  void work.then(
23959
- (value) => finish(() => resolve14({ status: "done", value })),
23623
+ (value) => finish(() => resolve13({ status: "done", value })),
23960
23624
  (error) => finish(() => reject(error))
23961
23625
  );
23962
23626
  void sleep2(graceMs).then(() => {
23963
- finish(() => resolve14({ status: "timeout" }));
23627
+ finish(() => resolve13({ status: "timeout" }));
23964
23628
  });
23965
23629
  });
23966
23630
  }
@@ -23968,12 +23632,13 @@ var LifecycleReadFailure, NAVIGATOR_POST_ROLE_GRACE_MS, ATTEMPT_HISTORY_ENTRY_TY
23968
23632
  var init_settlement = __esm({
23969
23633
  "src/public-cli/settlement.ts"() {
23970
23634
  "use strict";
23635
+ init_role_run_placement();
23971
23636
  init_auto_resume();
23972
- init_analyst_gate_cycles_read();
23973
23637
  init_sitian_facade();
23974
23638
  init_submission_ledger();
23975
23639
  init_host_contracts();
23976
23640
  init_process_cancel();
23641
+ init_ledger_session_read();
23977
23642
  init_serialize_thrown_value();
23978
23643
  init_run_lifecycle();
23979
23644
  init_engine_detour_usage();
@@ -24011,17 +23676,19 @@ __export(role_turn_host_exports, {
24011
23676
  buildPiTurnExtraArgs: () => buildPiTurnExtraArgs,
24012
23677
  createDefaultPiSpawnRunner: () => createDefaultPiSpawnRunner,
24013
23678
  createPiRoleTurnHost: () => createPiRoleTurnHost,
23679
+ formatPiSessionCustomEntry: () => formatPiSessionCustomEntry,
23680
+ piSessionCustomParentId: () => piSessionCustomParentId,
24014
23681
  resolveInternalRoleEntrypoint: () => resolveInternalRoleEntrypoint
24015
23682
  });
24016
23683
  import { execFile as execFile2, spawn } from "node:child_process";
24017
23684
  import { constants as constants2 } from "node:fs";
24018
- import { access as access2, appendFile, readFile as readFile12, realpath as realpath4 } from "node:fs/promises";
24019
- import { delimiter as delimiter2, dirname as dirname14, isAbsolute as isAbsolute6, join as join23, resolve as resolve10 } from "node:path";
23685
+ import { access as access2, appendFile, realpath as realpath4 } from "node:fs/promises";
23686
+ import { delimiter as delimiter2, dirname as dirname12, isAbsolute as isAbsolute6, join as join18, resolve as resolve9 } from "node:path";
24020
23687
  import { platform } from "node:process";
24021
23688
  import { promisify as promisify2 } from "node:util";
24022
23689
  import { randomUUID as randomUUID6 } from "node:crypto";
24023
23690
  function resolveInternalRoleEntrypoint(packageRoot2) {
24024
- return join23(packageRoot2, INTERNAL_ROLE_ENTRYPOINT_RELATIVE2);
23691
+ return join18(packageRoot2, INTERNAL_ROLE_ENTRYPOINT_RELATIVE2);
24025
23692
  }
24026
23693
  function buildExplicitInternalActivationArgs(selectedRoleEntry, extraArgs = []) {
24027
23694
  return ["--no-extensions", "-e", selectedRoleEntry, ...extraArgs];
@@ -24049,7 +23716,7 @@ function buildMethodArgs(methods) {
24049
23716
  const skillArgs = [];
24050
23717
  for (const method of methods) {
24051
23718
  if (method.kind === "skill") {
24052
- skillArgs.push("--skill", dirname14(method.path));
23719
+ skillArgs.push("--skill", dirname12(method.path));
24053
23720
  }
24054
23721
  }
24055
23722
  return skillArgs;
@@ -24089,7 +23756,7 @@ function piUserDialogueBody(request) {
24089
23756
  }
24090
23757
  async function resolveSelectedPi(command, cwd, env) {
24091
23758
  const searchPath = env.PATH ?? (platform === "win32" ? process.env.PATH ?? "" : "/usr/bin:/bin");
24092
- const candidates = isAbsolute6(command) || command.includes("/") ? [resolve10(cwd, command)] : searchPath.split(delimiter2).map((dir) => resolve10(cwd, dir, command));
23759
+ const candidates = isAbsolute6(command) || command.includes("/") ? [resolve9(cwd, command)] : searchPath.split(delimiter2).map((dir) => resolve9(cwd, dir, command));
24093
23760
  for (const candidate of candidates) {
24094
23761
  try {
24095
23762
  await access2(candidate, constants2.X_OK);
@@ -24279,24 +23946,34 @@ function createPiRoleTurnHost(config) {
24279
23946
  }
24280
23947
  };
24281
23948
  }
24282
- async function appendPiSessionCustomEntry(authority, principal, customType, data) {
24283
- const { sessionFile } = authority.decode(principal);
24284
- const text = await readFile12(sessionFile, "utf8");
23949
+ function piSessionCustomParentId(entries) {
24285
23950
  let parentId = null;
24286
- for (const line2 of text.trim().split("\n").filter(Boolean)) {
24287
- const entry = JSON.parse(line2);
23951
+ for (const entry of entries) {
24288
23952
  if (typeof entry.id === "string" && entry.type !== "session") parentId = entry.id;
24289
23953
  }
24290
- const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
24291
- const pointerLine = `${JSON.stringify({
23954
+ return parentId;
23955
+ }
23956
+ function formatPiSessionCustomEntry(input) {
23957
+ return `${JSON.stringify({
24292
23958
  type: "custom",
24293
- customType,
24294
- data,
23959
+ customType: input.customType,
23960
+ data: input.data,
24295
23961
  id: randomUUID6(),
24296
- parentId,
24297
- timestamp: timestamp2
23962
+ parentId: input.parentId,
23963
+ timestamp: input.timestamp
24298
23964
  })}
24299
23965
  `;
23966
+ }
23967
+ async function appendPiSessionCustomEntry(authority, principal, customType, data) {
23968
+ const { sessionFile } = authority.decode(principal);
23969
+ const entries = await readStrictPiSessionJsonl(sessionFile);
23970
+ const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
23971
+ const pointerLine = formatPiSessionCustomEntry({
23972
+ customType,
23973
+ data,
23974
+ parentId: piSessionCustomParentId(entries),
23975
+ timestamp: timestamp2
23976
+ });
24300
23977
  await appendFile(sessionFile, pointerLine, "utf8");
24301
23978
  sitianReport({
24302
23979
  level: "event",
@@ -24314,6 +23991,7 @@ var init_role_turn_host = __esm({
24314
23991
  init_engine_detour();
24315
23992
  init_role_activation_flags();
24316
23993
  init_user_dialogue_stdin();
23994
+ init_ledger_session_read();
24317
23995
  init_settlement();
24318
23996
  init_run_lifecycle();
24319
23997
  init_receipt_delivery_policy();
@@ -24333,15 +24011,15 @@ var init_role_turn_host = __esm({
24333
24011
 
24334
24012
  // src/public-cli/load-production-acp-host.ts
24335
24013
  import { existsSync as existsSync6 } from "node:fs";
24336
- import { join as join24 } from "node:path";
24014
+ import { join as join19 } from "node:path";
24337
24015
  import { pathToFileURL } from "node:url";
24338
24016
  async function loadProductionAcpHostFactory(packageRoot2, host) {
24339
24017
  const description = lookupHostDescription(host);
24340
24018
  if (description === void 0) {
24341
24019
  throw new Error(`unregistered host: ${host}`);
24342
24020
  }
24343
- const built = join24(packageRoot2, "dist/acp-host/production-host.js");
24344
- const source = join24(packageRoot2, "src/acp-host/production-host.ts");
24021
+ const built = join19(packageRoot2, "dist/acp-host/production-host.js");
24022
+ const source = join19(packageRoot2, "src/acp-host/production-host.ts");
24345
24023
  const target = existsSync6(built) ? built : source;
24346
24024
  const href = pathToFileURL(target).href;
24347
24025
  const mod = await import(href);
@@ -24357,15 +24035,15 @@ var init_load_production_acp_host = __esm({
24357
24035
 
24358
24036
  // src/public-cli/load-production-headless-host.ts
24359
24037
  import { existsSync as existsSync7 } from "node:fs";
24360
- import { join as join25 } from "node:path";
24038
+ import { join as join20 } from "node:path";
24361
24039
  import { pathToFileURL as pathToFileURL2 } from "node:url";
24362
24040
  async function loadProductionHeadlessHostFactory(packageRoot2, host) {
24363
24041
  const description = lookupHeadlessHostDescription(host);
24364
24042
  if (description === void 0) {
24365
24043
  throw new Error(`unregistered headless host: ${host}`);
24366
24044
  }
24367
- const built = join25(packageRoot2, "dist/headless-host/production-host.js");
24368
- const source = join25(packageRoot2, "src/headless-host/production-host.ts");
24045
+ const built = join20(packageRoot2, "dist/headless-host/production-host.js");
24046
+ const source = join20(packageRoot2, "src/headless-host/production-host.ts");
24369
24047
  const target = existsSync7(built) ? built : source;
24370
24048
  const href = pathToFileURL2(target).href;
24371
24049
  const mod = await import(href);
@@ -24534,11 +24212,14 @@ var init_role_seat_runtime = __esm({
24534
24212
 
24535
24213
  // src/archivist-record-pointer.ts
24536
24214
  import { mkdirSync as mkdirSync3, writeFileSync } from "node:fs";
24537
- import { readFile as readFile13 } from "node:fs/promises";
24538
- import { dirname as dirname15, join as join26 } from "node:path";
24215
+ import { readFile as readFile12 } from "node:fs/promises";
24216
+ import { basename as basename7, dirname as dirname13, join as join21 } from "node:path";
24217
+ function directOfficerRunPointerFile(parentSessionFile, officer) {
24218
+ return join21(sitianVolumeDirectory(dirname13(parentSessionFile), "auditor-roles"), `${officer}.pointer.json`);
24219
+ }
24539
24220
  function bookDirectOfficerRunPointer(options) {
24540
- const nest = join26(dirname15(options.parentSessionFile), "auditor-roles");
24541
- mkdirSync3(nest, { recursive: true });
24221
+ const pointerFile = directOfficerRunPointerFile(options.parentSessionFile, options.officer);
24222
+ mkdirSync3(dirname13(pointerFile), { recursive: true });
24542
24223
  const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
24543
24224
  const pointer = {
24544
24225
  version: 1,
@@ -24549,34 +24230,58 @@ function bookDirectOfficerRunPointer(options) {
24549
24230
  ...submissionToolCallId === "" ? {} : { submissionToolCallId }
24550
24231
  };
24551
24232
  writeFileSync(
24552
- join26(nest, `${options.officer}.pointer.json`),
24233
+ pointerFile,
24553
24234
  `${JSON.stringify(pointer)}
24554
24235
  `,
24555
24236
  "utf8"
24556
24237
  );
24557
24238
  return pointer;
24558
24239
  }
24559
- async function readDirectOfficerRunPointer(parentSessionFile, officer) {
24240
+ async function resolveOfficerSessionFromPointerFile(pointerPath) {
24241
+ let raw;
24560
24242
  try {
24561
- const raw = JSON.parse(await readFile13(
24562
- join26(dirname15(parentSessionFile), "auditor-roles", `${officer}.pointer.json`),
24563
- "utf8"
24564
- ));
24565
- if (!isRecord(raw) || raw.kind !== DIRECT_OFFICER_RUN_POINTER_KIND || raw.version !== 1) {
24566
- return void 0;
24243
+ raw = JSON.parse(await readFile12(pointerPath, "utf8"));
24244
+ } catch (error) {
24245
+ throw new Error(`direct officer run pointer unreadable in ${pointerPath}: ${errorText(error)}`, { cause: error });
24246
+ }
24247
+ if (!isRecord(raw) || raw.kind !== DIRECT_OFFICER_RUN_POINTER_KIND || raw.version !== 1) {
24248
+ throw new Error(`direct officer run pointer has unknown shape in ${pointerPath}`);
24249
+ }
24250
+ if (typeof raw.sessionFile !== "string" || raw.sessionFile.trim() === "") {
24251
+ throw new Error(`direct officer run pointer missing sessionFile in ${pointerPath}`);
24252
+ }
24253
+ const officer = raw.officer === "inspector" || raw.officer === "notary" || raw.officer === "auditor" || raw.officer === "countersign" ? raw.officer : void 0;
24254
+ let runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== "" ? raw.runDirectory : void 0;
24255
+ let sessionFile = raw.sessionFile;
24256
+ const recordedRunDirectory = runDirectory ?? runDirectoryOfSessionFile(sessionFile);
24257
+ const leaf = parseRunLeaf(basename7(recordedRunDirectory));
24258
+ const parentRunDirectory = runDirectoryFromSessionDirectory(dirname13(dirname13(pointerPath)));
24259
+ const parentIdentity = await readRoleRunIdentity(parentRunDirectory);
24260
+ if (leaf !== void 0 && parentIdentity !== void 0) {
24261
+ const currentRunDirectory = await findRunDirectoryById(
24262
+ homeFromRunDirectory(parentRunDirectory),
24263
+ leaf.runId,
24264
+ parentIdentity.bookKey,
24265
+ leaf.role
24266
+ );
24267
+ if (currentRunDirectory !== void 0) {
24268
+ sessionFile = rewriteRunDirectoryPathValue(sessionFile, recordedRunDirectory, currentRunDirectory);
24269
+ if (runDirectory !== void 0) runDirectory = currentRunDirectory;
24567
24270
  }
24568
- if (raw.officer !== officer) return void 0;
24569
- if (typeof raw.sessionFile !== "string" || raw.sessionFile.trim() === "") return void 0;
24570
- const runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== "" ? raw.runDirectory : void 0;
24571
- const submissionToolCallId = typeof raw.submissionToolCallId === "string" && raw.submissionToolCallId.trim() !== "" ? raw.submissionToolCallId : void 0;
24572
- return {
24573
- version: 1,
24574
- kind: DIRECT_OFFICER_RUN_POINTER_KIND,
24575
- officer,
24576
- sessionFile: raw.sessionFile,
24577
- ...runDirectory === void 0 ? {} : { runDirectory },
24578
- ...submissionToolCallId === void 0 ? {} : { submissionToolCallId }
24579
- };
24271
+ }
24272
+ const submissionToolCallId = typeof raw.submissionToolCallId === "string" && raw.submissionToolCallId.trim() !== "" ? raw.submissionToolCallId : void 0;
24273
+ return {
24274
+ sessionFile,
24275
+ ...officer === void 0 ? {} : { officer },
24276
+ ...runDirectory === void 0 ? {} : { runDirectory },
24277
+ ...submissionToolCallId === void 0 ? {} : { submissionToolCallId }
24278
+ };
24279
+ }
24280
+ async function readDirectOfficerRunPointer(parentSessionFile, officer) {
24281
+ try {
24282
+ const pointer = await resolveOfficerSessionFromPointerFile(directOfficerRunPointerFile(parentSessionFile, officer));
24283
+ if (pointer.officer !== officer) return void 0;
24284
+ return { ...pointer, officer, version: 1, kind: DIRECT_OFFICER_RUN_POINTER_KIND };
24580
24285
  } catch {
24581
24286
  return void 0;
24582
24287
  }
@@ -24586,6 +24291,11 @@ var init_archivist_record_pointer = __esm({
24586
24291
  "src/archivist-record-pointer.ts"() {
24587
24292
  "use strict";
24588
24293
  init_unknown_value();
24294
+ init_activation_ledger_topology();
24295
+ init_run_lifecycle();
24296
+ init_role_run_relocation();
24297
+ init_role_run_placement();
24298
+ init_sitian_appender();
24589
24299
  DIRECT_OFFICER_RUN_POINTER_KIND = "direct-officer-run-pointer";
24590
24300
  }
24591
24301
  });
@@ -24840,23 +24550,23 @@ var init_submission_gate = __esm({
24840
24550
 
24841
24551
  // src/session-opening-materials.ts
24842
24552
  import { existsSync as existsSync8 } from "node:fs";
24843
- import { readFile as readFile14 } from "node:fs/promises";
24844
- import { dirname as dirname16, join as join27 } from "node:path";
24553
+ import { readFile as readFile13 } from "node:fs/promises";
24554
+ import { dirname as dirname14, join as join22 } from "node:path";
24845
24555
  import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
24846
24556
  function resolvePackageRootDir(moduleUrl = import.meta.url) {
24847
- let dir = dirname16(fileURLToPath(moduleUrl));
24557
+ let dir = dirname14(fileURLToPath(moduleUrl));
24848
24558
  for (let i = 0; i < 8; i += 1) {
24849
- if (existsSync8(join27(dir, "package.json")) && existsSync8(join27(dir, "souls"))) {
24559
+ if (existsSync8(join22(dir, "package.json")) && existsSync8(join22(dir, "souls"))) {
24850
24560
  return dir;
24851
24561
  }
24852
- const parent = dirname16(dir);
24562
+ const parent = dirname14(dir);
24853
24563
  if (parent === dir) break;
24854
24564
  dir = parent;
24855
24565
  }
24856
24566
  return fileURLToPath(new URL("..", moduleUrl));
24857
24567
  }
24858
24568
  async function readPackageMaterial(relativePath) {
24859
- return readFile14(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
24569
+ return readFile13(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
24860
24570
  }
24861
24571
  async function joinPackageMaterials(relativePaths) {
24862
24572
  const chunks = [];
@@ -24898,8 +24608,8 @@ __export(auditor_soul_exports, {
24898
24608
  readAuditorResumeBinding: () => readAuditorResumeBinding,
24899
24609
  resolveAuditorSubject: () => resolveAuditorSubject
24900
24610
  });
24901
- import { readFile as readFile15 } from "node:fs/promises";
24902
- import { basename as basename7, join as join28 } from "node:path";
24611
+ import { readFile as readFile14 } from "node:fs/promises";
24612
+ import { basename as basename8, join as join23 } from "node:path";
24903
24613
  function auditorSoulRelativePath(role) {
24904
24614
  return `souls/${role}-auditor.md`;
24905
24615
  }
@@ -24935,13 +24645,13 @@ function loadAuditorReferenceMaterialsFromSubjectInput(raw) {
24935
24645
  return loadAuditorReferenceMaterials(resolveAuditorSubject(raw));
24936
24646
  }
24937
24647
  function subjectFromSourceDirectory(sourceRunDirectory) {
24938
- const role = basename7(sourceRunDirectory).split("@")[1];
24648
+ const role = parseRunLeaf(basename8(sourceRunDirectory))?.role;
24939
24649
  return isAuditorSoulRole(role) ? role : void 0;
24940
24650
  }
24941
24651
  async function readAuditorResumeBinding(runDirectory) {
24942
24652
  let raw;
24943
24653
  try {
24944
- raw = JSON.parse(await readFile15(join28(runDirectory, "admitted-request.json"), "utf8"));
24654
+ raw = JSON.parse(await readFile14(join23(runDirectory, "admitted-request.json"), "utf8"));
24945
24655
  } catch (error) {
24946
24656
  if (error.code === "ENOENT") return void 0;
24947
24657
  throw error;
@@ -24957,6 +24667,7 @@ var AUDITOR_SOUL_ROLES, AK_ROLE_AUDITOR_SUBJECT_ENV, AK_ROLE_AUDITOR_SOURCE_RUN_
24957
24667
  var init_auditor_soul = __esm({
24958
24668
  "src/auditor-soul.ts"() {
24959
24669
  "use strict";
24670
+ init_role_run_placement();
24960
24671
  init_unknown_value();
24961
24672
  init_session_opening_materials();
24962
24673
  AUDITOR_SOUL_ROLES = [
@@ -25208,7 +24919,7 @@ __export(instruction_seat_run_exports, {
25208
24919
  runPublicInstructionSeat: () => runPublicInstructionSeat,
25209
24920
  runPublicInstructionSeatResume: () => runPublicInstructionSeatResume
25210
24921
  });
25211
- import { dirname as dirname17, resolve as resolve11 } from "node:path";
24922
+ import { dirname as dirname15, resolve as resolve10 } from "node:path";
25212
24923
  function unreadablePostSubmissionStatus(admitted, terminal) {
25213
24924
  if (terminal?.roleOutcome.kind !== "accepted") return void 0;
25214
24925
  const route = POST_SUBMISSION_ROUTING[admitted.role];
@@ -25444,7 +25155,7 @@ async function runOmittedLensBatch(argv2, parsed, env, io) {
25444
25155
  const children = await summonParallelReviewerLenses2({
25445
25156
  argv: argv2,
25446
25157
  cwd: env.cwd,
25447
- projectRoot: resolve11(parsed.project ?? env.cwd),
25158
+ projectRoot: resolve10(parsed.project ?? env.cwd),
25448
25159
  baseRevision: parsed.baseRevision ?? "",
25449
25160
  home: env.home,
25450
25161
  agentDir: env.agentDir,
@@ -25526,7 +25237,7 @@ async function runCountersignBody(parsed, env, io) {
25526
25237
  const resumed = await resumeSameParentInstructionSeat({
25527
25238
  env,
25528
25239
  io,
25529
- projectRoot: resolve11(parsed.project ?? env.cwd),
25240
+ projectRoot: resolve10(parsed.project ?? env.cwd),
25530
25241
  role: "countersign",
25531
25242
  parentRunPath: gateParentRunPath,
25532
25243
  ...isSafePositiveTicketNumber(env.boundTicketNumber) ? { ticketNumber: env.boundTicketNumber } : {},
@@ -26055,7 +25766,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
26055
25766
  runDirectory: admitted.runDirectory,
26056
25767
  sessionManager: {
26057
25768
  getSessionFile: () => sessionFile,
26058
- getSessionDir: () => dirname17(sessionFile),
25769
+ getSessionDir: () => dirname15(sessionFile),
26059
25770
  getEntries: () => entries,
26060
25771
  getLeafEntry: () => void 0,
26061
25772
  getLeafId: () => admitted.runId,
@@ -26232,7 +25943,7 @@ async function auditSubmittedRole(turn, env, io, resumedOfficer, passedReceipt)
26232
25943
  }
26233
25944
  }
26234
25945
  if (turn.terminal === void 0) throw new Error(`audited ${admitted.role} submission did not settle`);
26235
- const terminal = await attachPostAuditProjection(
25946
+ const terminal = await attachPostAuditCountersignFact(
26236
25947
  admitted,
26237
25948
  env.principalAuthority,
26238
25949
  turn.terminal,
@@ -26333,7 +26044,7 @@ __export(public_role_summons_exports, {
26333
26044
  import { execFile as execFile3 } from "node:child_process";
26334
26045
  import { existsSync as existsSync9 } from "node:fs";
26335
26046
  import { realpath as realpath5 } from "node:fs/promises";
26336
- import { join as join29 } from "node:path";
26047
+ import { join as join24 } from "node:path";
26337
26048
  import { promisify as promisify3 } from "node:util";
26338
26049
  function createCapturingIo() {
26339
26050
  const chunks = [];
@@ -26357,7 +26068,7 @@ function parentDir(path) {
26357
26068
  function walkPackageRoot(start) {
26358
26069
  let dir = start;
26359
26070
  for (let i = 0; i < 12; i += 1) {
26360
- if (existsSync9(join29(dir, "package.json")) && existsSync9(join29(dir, "souls"))) {
26071
+ if (existsSync9(join24(dir, "package.json")) && existsSync9(join24(dir, "souls"))) {
26361
26072
  return dir;
26362
26073
  }
26363
26074
  const parent = parentDir(dir);
@@ -26960,7 +26671,7 @@ var init_compliance_transport = __esm({
26960
26671
  });
26961
26672
 
26962
26673
  // src/role-run-relocation.ts
26963
- import { join as join30, sep as sep4 } from "node:path";
26674
+ import { dirname as dirname16, join as join25, sep as sep4 } from "node:path";
26964
26675
  function rewriteRunDirectoryPathValue(value, oldRunDirectory, newRunDirectory) {
26965
26676
  if (typeof value !== "string") return value;
26966
26677
  if (value === oldRunDirectory) return newRunDirectory;
@@ -26970,6 +26681,33 @@ function rewriteRunDirectoryPathValue(value, oldRunDirectory, newRunDirectory) {
26970
26681
  }
26971
26682
  return value;
26972
26683
  }
26684
+ async function retainedRunPathsMatch(recordedPath, currentPath, currentRunDirectory) {
26685
+ if (recordedPath === currentPath) return true;
26686
+ if (typeof recordedPath !== "string") return false;
26687
+ const recordedPathIdentity = physicalPathIdentity(recordedPath);
26688
+ const currentPathIdentity = physicalPathIdentity(currentPath);
26689
+ if (recordedPathIdentity === currentPathIdentity) return true;
26690
+ if (currentRunDirectory === void 0) return false;
26691
+ const runDirectory = physicalPathIdentity(currentRunDirectory);
26692
+ const identity = await readRoleRunIdentity(runDirectory);
26693
+ if (identity === void 0) return false;
26694
+ for (let directory = runDirectory; dirname16(directory) !== directory; directory = dirname16(directory)) {
26695
+ const ledgerHome = dirname16(dirname16(directory));
26696
+ if (directory !== activationBookDirectory(ledgerHome, identity.bookKey)) continue;
26697
+ const unbound = roleRunPlacement(ledgerHome, {
26698
+ bookKey: identity.bookKey,
26699
+ subject: { unbound: true },
26700
+ runId: identity.runId,
26701
+ role: identity.role
26702
+ });
26703
+ if (rewriteRunDirectoryPathValue(recordedPathIdentity, unbound.runDirectory, runDirectory) !== currentPathIdentity) {
26704
+ return false;
26705
+ }
26706
+ const placed = await findRoleRunDirectory([directory], identity.runId, identity.role);
26707
+ return placed !== void 0 && physicalPathIdentity(placed) === runDirectory;
26708
+ }
26709
+ return false;
26710
+ }
26973
26711
  function rewriteRunDirectoryPathValueAgainstRewrites(value, rewrites) {
26974
26712
  if (typeof value !== "string" || rewrites.length === 0) return value;
26975
26713
  let best;
@@ -27032,6 +26770,9 @@ var ADMITTED_PAGE_FIELDS, SOURCE_RUN_LOCATOR_FIELDS;
27032
26770
  var init_role_run_relocation = __esm({
27033
26771
  "src/role-run-relocation.ts"() {
27034
26772
  "use strict";
26773
+ init_activation_ledger_topology();
26774
+ init_run_lifecycle();
26775
+ init_role_run_placement();
27035
26776
  init_compliance_transport();
27036
26777
  init_unknown_value();
27037
26778
  ADMITTED_PAGE_FIELDS = [
@@ -27077,8 +26818,8 @@ __export(run_lifecycle_exports, {
27077
26818
  recordCurrentCourt: () => recordCurrentCourt,
27078
26819
  writeRoleRunState: () => writeRoleRunState
27079
26820
  });
27080
- import { chmod, lstat as lstat5, open as open2, readdir as readdir5, readFile as readFile16, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
27081
- import { basename as basename8, join as join31 } from "node:path";
26821
+ import { chmod, lstat as lstat5, open as open2, readdir as readdir4, readFile as readFile15, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
26822
+ import { basename as basename9, join as join26 } from "node:path";
27082
26823
  function buildAutoResumeContinuationPrompt(options) {
27083
26824
  return appendEngineSessionMaterial(
27084
26825
  [RESUME_TRANSPORT_ENVELOPE],
@@ -27091,7 +26832,7 @@ function buildAutoResumeContinuationPrompt(options) {
27091
26832
  async function writeRoleRunState(runDirectory, record) {
27092
26833
  const payload = { ...record, runDirectory };
27093
26834
  await writeFile4(
27094
- join31(runDirectory, RUN_STATE_FILE),
26835
+ join26(runDirectory, RUN_STATE_FILE),
27095
26836
  `${JSON.stringify(payload, null, 2)}
27096
26837
  `,
27097
26838
  "utf8"
@@ -27141,7 +26882,7 @@ function parseCurrentCourtState(raw) {
27141
26882
  async function readRoleRunStateRaw(runDirectory) {
27142
26883
  let raw;
27143
26884
  try {
27144
- raw = JSON.parse(await readFile16(join31(runDirectory, RUN_STATE_FILE), "utf8"));
26885
+ raw = JSON.parse(await readFile15(join26(runDirectory, RUN_STATE_FILE), "utf8"));
27145
26886
  } catch (error) {
27146
26887
  if (errorCodeOf(error) === "ENOENT") return void 0;
27147
26888
  throw error;
@@ -27224,7 +26965,7 @@ async function writeRoleRunStateDisk(runDirectory, disk) {
27224
26965
  ...disk.currentCourt === void 0 ? {} : { currentCourt: disk.currentCourt }
27225
26966
  };
27226
26967
  await writeFile4(
27227
- join31(runDirectory, RUN_STATE_FILE),
26968
+ join26(runDirectory, RUN_STATE_FILE),
27228
26969
  `${JSON.stringify(payload, null, 2)}
27229
26970
  `,
27230
26971
  "utf8"
@@ -27348,7 +27089,7 @@ function isProcessAlive(pid) {
27348
27089
  async function autopsyWriterLock(lockPath) {
27349
27090
  let content;
27350
27091
  try {
27351
- content = await readFile16(lockPath, "utf8");
27092
+ content = await readFile15(lockPath, "utf8");
27352
27093
  } catch (error) {
27353
27094
  if (errorCodeOf(error) === "ENOENT") return { verdict: "absent" };
27354
27095
  return { verdict: "unknown", reason: "unreadable", readFailure: error };
@@ -27407,7 +27148,7 @@ async function createWriterLease(lockPath, runDirectory, reportCleanupFailure) {
27407
27148
  },
27408
27149
  relocate(nextRunDirectory) {
27409
27150
  currentRunDirectory = nextRunDirectory;
27410
- currentLockPath = join31(nextRunDirectory, WRITER_LOCK_FILE);
27151
+ currentLockPath = join26(nextRunDirectory, WRITER_LOCK_FILE);
27411
27152
  },
27412
27153
  async release() {
27413
27154
  if (released) return;
@@ -27446,10 +27187,10 @@ async function acquireRunWriterLease(runDirectory, onCleanupFailure) {
27446
27187
  };
27447
27188
  const reportReadFailure = (error) => {
27448
27189
  reportDiagnostic(
27449
- `writer lease lock read failed (holder liveness unverifiable; lock left in place) at ${join31(runDirectory, WRITER_LOCK_FILE)}: ${describeErrorIdentity(error)}`
27190
+ `writer lease lock read failed (holder liveness unverifiable; lock left in place) at ${join26(runDirectory, WRITER_LOCK_FILE)}: ${describeErrorIdentity(error)}`
27450
27191
  );
27451
27192
  };
27452
- const lockPath = join31(runDirectory, WRITER_LOCK_FILE);
27193
+ const lockPath = join26(runDirectory, WRITER_LOCK_FILE);
27453
27194
  let lastAutopsy = { verdict: "absent" };
27454
27195
  let lastReclaimFailure;
27455
27196
  for (let reclaimsLeft = WRITER_LEASE_RECLAIM_ROUNDS; ; reclaimsLeft -= 1) {
@@ -27506,36 +27247,18 @@ async function acquireRunWriterLease(runDirectory, onCleanupFailure) {
27506
27247
  async function findRunDirectoryById(home, runId, onlyBookKey, onlyRole) {
27507
27248
  if (runId.trim() === "") return void 0;
27508
27249
  const ledgerHome = resolveActivationLedgerHome(home);
27509
- const booksRoot = join31(ledgerHome, "books");
27250
+ const booksRoot = join26(ledgerHome, "books");
27510
27251
  let bookKeys;
27511
27252
  try {
27512
- bookKeys = await readdir5(booksRoot);
27253
+ bookKeys = await readdir4(booksRoot);
27513
27254
  } catch (error) {
27514
27255
  if (errorCodeOf(error) === "ENOENT") return void 0;
27515
27256
  throw error;
27516
27257
  }
27517
- const matches = [];
27518
- for (const bookKey of bookKeys) {
27519
- if (onlyBookKey !== void 0 && bookKey !== onlyBookKey) continue;
27520
- const bookDir = activationBookDirectory(ledgerHome, bookKey);
27521
- let runDirectories;
27522
- try {
27523
- runDirectories = await listBookRunDirectories(bookDir);
27524
- } catch (error) {
27525
- if (errorCodeOf(error) === "ENOENT") continue;
27526
- throw error;
27527
- }
27528
- for (const runDirectory of runDirectories) {
27529
- const entry = basename8(runDirectory);
27530
- if (onlyRole === void 0 && (entry === `${runId}@judge` || entry.startsWith(`${runId}@`)) || entry === `${runId}@${onlyRole}`) {
27531
- matches.push(runDirectory);
27532
- }
27533
- }
27534
- }
27535
- if (matches.length === 0) return void 0;
27536
- if (matches.length === 1) return matches[0];
27537
- throw new Error(
27538
- `ambiguous role run id ${runId}: ${matches.join(", ")}`
27258
+ return findRoleRunDirectory(
27259
+ bookKeys.filter((bookKey) => onlyBookKey === void 0 || bookKey === onlyBookKey).map((bookKey) => activationBookDirectory(ledgerHome, bookKey)),
27260
+ runId,
27261
+ onlyRole
27539
27262
  );
27540
27263
  }
27541
27264
  function parentRunPathFromGatePointerInstruction(instruction) {
@@ -27547,7 +27270,7 @@ async function readRunParentPath(runDirectory) {
27547
27270
  let raw;
27548
27271
  try {
27549
27272
  raw = JSON.parse(
27550
- await readFile16(join31(runDirectory, "admitted-request.json"), "utf8")
27273
+ await readFile15(join26(runDirectory, "admitted-request.json"), "utf8")
27551
27274
  );
27552
27275
  } catch (error) {
27553
27276
  if (errorCodeOf(error) === "ENOENT") return void 0;
@@ -27568,7 +27291,7 @@ async function readRunParentPath(runDirectory) {
27568
27291
  async function runHasFormedSessionPrincipal(runDirectory) {
27569
27292
  const disk = await readRoleRunStateDisk(runDirectory);
27570
27293
  if (disk === void 0) return false;
27571
- const sessionFile = typeof disk.principalWire.sessionFile === "string" && disk.principalWire.sessionFile.trim() !== "" ? disk.principalWire.sessionFile : join31(disk.principalWire.sessionDirectory, "session.jsonl");
27294
+ const sessionFile = typeof disk.principalWire.sessionFile === "string" && disk.principalWire.sessionFile.trim() !== "" ? disk.principalWire.sessionFile : sessionFileIn(disk.principalWire.sessionDirectory);
27572
27295
  try {
27573
27296
  const stat2 = await lstat5(sessionFile);
27574
27297
  return stat2.isFile() && !stat2.isSymbolicLink();
@@ -27586,21 +27309,19 @@ async function findLatestRunIdForSeatTicket(input) {
27586
27309
  let runDirectories;
27587
27310
  try {
27588
27311
  runDirectories = await listBookRunDirectories(
27589
- input.ticketNumber === void 0 ? bookDir : join31(bookDir, String(input.ticketNumber))
27312
+ input.ticketNumber === void 0 ? bookDir : join26(bookDir, String(input.ticketNumber))
27590
27313
  );
27591
27314
  } catch (error) {
27592
27315
  if (errorCodeOf(error) === "ENOENT") return void 0;
27593
27316
  throw error;
27594
27317
  }
27595
- const suffix = `@${input.role}`;
27596
27318
  let best;
27597
27319
  for (const runDirectory of runDirectories) {
27598
- const entry = basename8(runDirectory);
27599
- if (!entry.endsWith(suffix)) continue;
27600
- const runId = entry.slice(0, entry.length - suffix.length);
27601
- if (runId.length === 0) continue;
27320
+ const parsed = parseRunLeaf(basename9(runDirectory));
27321
+ if (parsed === void 0 || parsed.role !== input.role) continue;
27322
+ const runId = parsed.runId;
27602
27323
  const parentPath = await readRunParentPath(runDirectory);
27603
- if (parentPath !== input.parentRunPath && basename8(parentPath ?? "") !== basename8(input.parentRunPath)) continue;
27324
+ if (!await retainedRunPathsMatch(parentPath, input.parentRunPath, input.parentRunPath)) continue;
27604
27325
  if (!await runHasFormedSessionPrincipal(runDirectory)) continue;
27605
27326
  if (best === void 0 || runId > best) best = runId;
27606
27327
  }
@@ -27662,7 +27383,7 @@ async function loadResumableRunRecord(home, runId, authority) {
27662
27383
  let sourceRun;
27663
27384
  try {
27664
27385
  const raw = JSON.parse(
27665
- await readFile16(run.admittedRequestPath, "utf8")
27386
+ await readFile15(run.admittedRequestPath, "utf8")
27666
27387
  );
27667
27388
  if (isRecord(raw)) {
27668
27389
  const record = raw;
@@ -27701,7 +27422,7 @@ async function loadResumableRunRecord(home, runId, authority) {
27701
27422
  if (isReviewerLens(record.lens)) {
27702
27423
  lens = record.lens;
27703
27424
  }
27704
- if (typeof record.prNumber === "number" && Number.isSafeInteger(record.prNumber) && record.prNumber >= 1) {
27425
+ if (isSafePositiveTicketNumber(record.prNumber)) {
27705
27426
  prNumber = record.prNumber;
27706
27427
  }
27707
27428
  if (typeof record.repository === "string" && record.repository.trim() !== "") {
@@ -27719,7 +27440,7 @@ async function loadResumableRunRecord(home, runId, authority) {
27719
27440
  if (typeof record.waitWindowMs === "number" && Number.isSafeInteger(record.waitWindowMs) && record.waitWindowMs >= 1) {
27720
27441
  waitWindowMs = record.waitWindowMs;
27721
27442
  }
27722
- if (typeof record.issueNumber === "number" && Number.isSafeInteger(record.issueNumber) && record.issueNumber >= 1) {
27443
+ if (isSafePositiveTicketNumber(record.issueNumber)) {
27723
27444
  issueNumber = record.issueNumber;
27724
27445
  }
27725
27446
  if (typeof record.caseRunsPath === "string" && record.caseRunsPath.trim() !== "") {
@@ -27727,7 +27448,7 @@ async function loadResumableRunRecord(home, runId, authority) {
27727
27448
  }
27728
27449
  if (isRecord(record.caseIdentity)) {
27729
27450
  const ci = record.caseIdentity;
27730
- if (typeof ci.issueNumber === "number" && Number.isSafeInteger(ci.issueNumber) && ci.issueNumber >= 1 && typeof ci.runsPath === "string" && ci.runsPath.trim() !== "") {
27451
+ if (isSafePositiveTicketNumber(ci.issueNumber) && typeof ci.runsPath === "string" && ci.runsPath.trim() !== "") {
27731
27452
  caseIdentity = { issueNumber: ci.issueNumber, runsPath: ci.runsPath };
27732
27453
  }
27733
27454
  }
@@ -27784,7 +27505,7 @@ async function loadResumableRunRecord(home, runId, authority) {
27784
27505
  let model;
27785
27506
  try {
27786
27507
  const invocationRaw = JSON.parse(
27787
- await readFile16(join31(run.runDirectory, "invocation.json"), "utf8")
27508
+ await readFile15(join26(run.runDirectory, "invocation.json"), "utf8")
27788
27509
  );
27789
27510
  if (isRecord(invocationRaw)) {
27790
27511
  const rec = invocationRaw;
@@ -27812,9 +27533,9 @@ async function loadResumableRunRecord(home, runId, authority) {
27812
27533
  );
27813
27534
  }
27814
27535
  }
27815
- const sourceRunLeaf = basename8(sourceRunPath ?? "").split("@");
27816
- const referencedRunId = sourceRun?.runId ?? sourceRunLeaf[0];
27817
- const referencedRole = sourceRun?.role ?? sourceRunLeaf[1];
27536
+ const sourceRunLeaf = parseRunLeaf(basename9(sourceRunPath ?? ""));
27537
+ const referencedRunId = sourceRun?.runId ?? sourceRunLeaf?.runId;
27538
+ const referencedRole = sourceRun?.role ?? sourceRunLeaf?.role;
27818
27539
  if (referencedRunId !== void 0 && referencedRunId !== "") {
27819
27540
  const currentSourceRunDirectory = await findRunDirectoryById(
27820
27541
  home,
@@ -28151,18 +27872,39 @@ var init_run_lifecycle = __esm({
28151
27872
  }
28152
27873
  });
28153
27874
 
27875
+ // src/atomic-write.ts
27876
+ import { randomUUID as randomUUID7 } from "node:crypto";
27877
+ import { rename as rename2, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
27878
+ import { dirname as dirname17, join as join27 } from "node:path";
27879
+ async function writeFileAtomically(destination, contents, options) {
27880
+ const parent = dirname17(destination);
27881
+ const temporary = join27(parent, `.atomic-write-${randomUUID7()}.tmp`);
27882
+ try {
27883
+ await writeFile5(temporary, contents, options);
27884
+ await rename2(temporary, destination);
27885
+ } catch (error) {
27886
+ await rm3(temporary, { force: true }).catch(() => void 0);
27887
+ throw error;
27888
+ }
27889
+ }
27890
+ var init_atomic_write = __esm({
27891
+ "src/atomic-write.ts"() {
27892
+ "use strict";
27893
+ }
27894
+ });
27895
+
28154
27896
  // src/session-identity.ts
28155
- import { mkdir as mkdir4, readFile as readFile17, rename as rename2, writeFile as writeFile5 } from "node:fs/promises";
28156
- import { dirname as dirname18, join as join32 } from "node:path";
27897
+ import { mkdir as mkdir4, readFile as readFile16 } from "node:fs/promises";
27898
+ import { dirname as dirname18, join as join28 } from "node:path";
28157
27899
  function createSessionIdentityAuthority(authority, sessionBindingFile) {
28158
- const bindingPath = (principal) => join32(authority.decode(principal).sessionDirectory, sessionBindingFile);
27900
+ const bindingPath = (principal) => join28(authority.decode(principal).sessionDirectory, sessionBindingFile);
28159
27901
  return {
28160
27902
  resolveSessionFile(principal) {
28161
27903
  return authority.decode(principal).sessionFile;
28162
27904
  },
28163
27905
  async load(principal) {
28164
27906
  try {
28165
- const value = JSON.parse(await readFile17(bindingPath(principal), "utf8"));
27907
+ const value = JSON.parse(await readFile16(bindingPath(principal), "utf8"));
28166
27908
  if (typeof value !== "object" || value === null || typeof value.sessionId !== "string") {
28167
27909
  throw new Error("durable session binding is invalid");
28168
27910
  }
@@ -28175,10 +27917,8 @@ function createSessionIdentityAuthority(authority, sessionBindingFile) {
28175
27917
  async bind(principal, sessionId) {
28176
27918
  const target = bindingPath(principal);
28177
27919
  await mkdir4(dirname18(target), { recursive: true });
28178
- const temporary = `${target}.${process.pid}.tmp`;
28179
- await writeFile5(temporary, `${JSON.stringify({ sessionId })}
28180
- `, { encoding: "utf8", mode: 384 });
28181
- await rename2(temporary, target);
27920
+ await writeFileAtomically(target, `${JSON.stringify({ sessionId })}
27921
+ `, { mode: 384 });
28182
27922
  }
28183
27923
  };
28184
27924
  }
@@ -28196,6 +27936,7 @@ async function readStoredHostSessionId(host, authority, principal) {
28196
27936
  var init_session_identity = __esm({
28197
27937
  "src/session-identity.ts"() {
28198
27938
  "use strict";
27939
+ init_atomic_write();
28199
27940
  init_host_descriptions();
28200
27941
  }
28201
27942
  });
@@ -28213,7 +27954,7 @@ import {
28213
27954
  rmSync as rmSync2,
28214
27955
  statSync as statSync4
28215
27956
  } from "node:fs";
28216
- import { dirname as dirname19, join as join33 } from "node:path";
27957
+ import { dirname as dirname19, join as join29 } from "node:path";
28217
27958
  function declareHostSessionFailure(error) {
28218
27959
  const message = error instanceof Error ? error.stack || error.message : String(error);
28219
27960
  process.stderr.write(`[host-session] Dossier record failure: ${message}
@@ -28221,7 +27962,7 @@ function declareHostSessionFailure(error) {
28221
27962
  }
28222
27963
  function recordRunStart(runDirectory) {
28223
27964
  try {
28224
- appendFileSync2(join33(runDirectory, ".run-starts"), "\n");
27965
+ appendFileSync2(join29(runDirectory, ".run-starts"), "\n");
28225
27966
  } catch (error) {
28226
27967
  declareHostSessionFailure(error);
28227
27968
  }
@@ -28235,9 +27976,9 @@ var init_host_session_record = __esm({
28235
27976
  });
28236
27977
 
28237
27978
  // src/public-cli/post-admission.ts
28238
- import { randomUUID as randomUUID7 } from "node:crypto";
27979
+ import { randomUUID as randomUUID8 } from "node:crypto";
28239
27980
  import { writeFile as writeFile6 } from "node:fs/promises";
28240
- import { isAbsolute as isAbsolute8, join as join34, resolve as resolve12 } from "node:path";
27981
+ import { isAbsolute as isAbsolute8, join as join30, resolve as resolve11 } from "node:path";
28241
27982
  function describeCaughtError(error) {
28242
27983
  if (error instanceof Error) {
28243
27984
  const code = error.code;
@@ -28463,7 +28204,7 @@ async function settleCompletedHostTurn(input) {
28463
28204
  let stderrLogWriteFailure;
28464
28205
  try {
28465
28206
  await writeFile6(
28466
- join34(admitted.runDirectory, "stderr.log"),
28207
+ join30(admitted.runDirectory, "stderr.log"),
28467
28208
  result.stderr,
28468
28209
  "utf8"
28469
28210
  );
@@ -29058,8 +28799,8 @@ async function runSettledAutoResumeLoop(input) {
29058
28799
  });
29059
28800
  }
29060
28801
  function isAlreadyFrozenSummonsAttachment(runDirectory, attachmentPath) {
29061
- const absolute = isAbsolute8(attachmentPath) ? attachmentPath : resolve12(attachmentPath);
29062
- return pathContainedIn(join34(runDirectory, "attachments"), absolute);
28802
+ const absolute = isAbsolute8(attachmentPath) ? attachmentPath : resolve11(attachmentPath);
28803
+ return pathContainedIn(join30(runDirectory, "attachments"), absolute);
29063
28804
  }
29064
28805
  async function prepareSummonsResumeMaterials(runDirectory, summons) {
29065
28806
  if (summons === void 0) return void 0;
@@ -29155,7 +28896,7 @@ async function runPostAdmissionSeatResume(input) {
29155
28896
  }
29156
28897
  }
29157
28898
  if (openCourtAttemptId !== void 0 || request.summons !== void 0) {
29158
- const courtAttemptId = openCourtAttemptId ?? (turnRequest.courtAttemptId !== void 0 && turnRequest.courtAttemptId.length > 0 ? turnRequest.courtAttemptId : randomUUID7());
28899
+ const courtAttemptId = openCourtAttemptId ?? (turnRequest.courtAttemptId !== void 0 && turnRequest.courtAttemptId.length > 0 ? turnRequest.courtAttemptId : randomUUID8());
29159
28900
  turnRequest = { ...turnRequest, courtAttemptId };
29160
28901
  if (openCourtAttemptId === void 0) {
29161
28902
  const court = {
@@ -29288,7 +29029,7 @@ async function presentResumeFailurePointer(io, thrown, publish) {
29288
29029
  }
29289
29030
  async function writeResumeDiagnosticFile(runDirectory, runId, failure, role) {
29290
29031
  const dir = await ensureRealArtifactsDirectory(runDirectory);
29291
- const path = join34(dir, `resume-diagnostic-${randomUUID7()}.json`);
29032
+ const path = join30(dir, `resume-diagnostic-${randomUUID8()}.json`);
29292
29033
  await writeFile6(
29293
29034
  path,
29294
29035
  `${JSON.stringify({
@@ -29456,35 +29197,14 @@ var init_analyst_book_key = __esm({
29456
29197
  }
29457
29198
  });
29458
29199
 
29459
- // src/atomic-write.ts
29460
- import { randomUUID as randomUUID8 } from "node:crypto";
29461
- import { rename as rename3, rm as rm3, writeFile as writeFile7 } from "node:fs/promises";
29462
- import { dirname as dirname20, join as join35 } from "node:path";
29463
- async function writeFileAtomically(destination, contents) {
29464
- const parent = dirname20(destination);
29465
- const temporary = join35(parent, `.atomic-write-${randomUUID8()}.tmp`);
29466
- try {
29467
- await writeFile7(temporary, contents);
29468
- await rename3(temporary, destination);
29469
- } catch (error) {
29470
- await rm3(temporary, { force: true }).catch(() => void 0);
29471
- throw error;
29472
- }
29473
- }
29474
- var init_atomic_write = __esm({
29475
- "src/atomic-write.ts"() {
29476
- "use strict";
29477
- }
29478
- });
29479
-
29480
29200
  // src/analyst-index.ts
29481
- import { open as open3, readFile as readFile18, unlink as unlink3 } from "node:fs/promises";
29482
- import { dirname as dirname21, join as join36 } from "node:path";
29201
+ import { open as open3, readFile as readFile17, unlink as unlink3 } from "node:fs/promises";
29202
+ import { dirname as dirname20, join as join31 } from "node:path";
29483
29203
  import { setTimeout as sleep } from "node:timers/promises";
29484
29204
  async function withAnalystLibraryIndexLock(ledgerHome, fn) {
29485
29205
  const indexPath = analystLibraryIndexPath(ledgerHome);
29486
- ensureRealDirectoryTree(ledgerHome, dirname21(indexPath));
29487
- const lockPath = join36(dirname21(indexPath), LIBRARY_INDEX_LOCK_NAME);
29206
+ ensureRealDirectoryTree(ledgerHome, dirname20(indexPath));
29207
+ const lockPath = join31(dirname20(indexPath), LIBRARY_INDEX_LOCK_NAME);
29488
29208
  assertLedgerFileInsideHome(lockPath, ledgerHome);
29489
29209
  const startedAt = Date.now();
29490
29210
  while (true) {
@@ -29511,7 +29231,7 @@ async function withAnalystLibraryIndexLock(ledgerHome, fn) {
29511
29231
  }
29512
29232
  }
29513
29233
  function analystLibraryIndexPath(ledgerHome) {
29514
- return join36(ledgerHome, "analyst", "library-index.json");
29234
+ return join31(ledgerHome, "analyst", "library-index.json");
29515
29235
  }
29516
29236
  function rowFromIssueMetricsPage(page) {
29517
29237
  return {
@@ -29602,7 +29322,7 @@ async function readAnalystLibraryIndexPage(ledgerHome) {
29602
29322
  const path = analystLibraryIndexPath(ledgerHome);
29603
29323
  let raw;
29604
29324
  try {
29605
- raw = await readFile18(path, "utf8");
29325
+ raw = await readFile17(path, "utf8");
29606
29326
  } catch (error) {
29607
29327
  if (isMissingPathError(error)) return void 0;
29608
29328
  throw error;
@@ -29618,7 +29338,7 @@ async function readAnalystLibraryIndexPage(ledgerHome) {
29618
29338
  }
29619
29339
  async function writeAnalystLibraryIndexPage(ledgerHome, page) {
29620
29340
  const path = analystLibraryIndexPath(ledgerHome);
29621
- ensureRealDirectoryTree(ledgerHome, dirname21(path));
29341
+ ensureRealDirectoryTree(ledgerHome, dirname20(path));
29622
29342
  assertLedgerFileInsideHome(path, ledgerHome);
29623
29343
  await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
29624
29344
  `);
@@ -29690,123 +29410,395 @@ function absorbRole(accum, stats) {
29690
29410
  accum.successCount += stats.successCount;
29691
29411
  accum.successEligibleCount += stats.successEligibleCount;
29692
29412
  }
29693
- function finishRole(role, accum) {
29694
- return {
29695
- role,
29696
- convergenceRounds: accum.convergenceRounds,
29697
- convergenceRoundsMedian: optionalMedian(accum.convergenceRounds),
29698
- firstPassRate: rateMetric(accum.firstPassLaneCount, accum.appearanceLaneCount),
29699
- successRate: rateMetric(accum.successCount, accum.successEligibleCount)
29413
+ function finishRole(role, accum) {
29414
+ return {
29415
+ role,
29416
+ convergenceRounds: accum.convergenceRounds,
29417
+ convergenceRoundsMedian: optionalMedian(accum.convergenceRounds),
29418
+ firstPassRate: rateMetric(accum.firstPassLaneCount, accum.appearanceLaneCount),
29419
+ successRate: rateMetric(accum.successCount, accum.successEligibleCount)
29420
+ };
29421
+ }
29422
+ function emptyGateOfficerNumeratorAccum() {
29423
+ return { rounds: 0, bounceCount: 0, passCount: 0, wallSum: 0 };
29424
+ }
29425
+ function absorbGateOfficerSummary(accum, summary) {
29426
+ accum.rounds += summary.rounds;
29427
+ accum.bounceCount += summary.bounceCount;
29428
+ accum.passCount += summary.passCount;
29429
+ if (summary.meanOfficerWallMs !== void 0) {
29430
+ accum.wallSum += summary.meanOfficerWallMs * summary.rounds;
29431
+ }
29432
+ }
29433
+ function finishGateOfficerNumerators(officer, accum) {
29434
+ return {
29435
+ officer,
29436
+ rounds: accum.rounds,
29437
+ bounceCount: accum.bounceCount,
29438
+ passCount: accum.passCount,
29439
+ bounceRate: rateMetric(accum.bounceCount, accum.rounds),
29440
+ meanOfficerWallMs: accum.rounds === 0 ? ABSENT : presentMetric(accum.wallSum / accum.rounds)
29441
+ };
29442
+ }
29443
+ async function aggregateGroup(index, input, ensureIssuePage) {
29444
+ const issueEntries = [];
29445
+ const roleAccums = /* @__PURE__ */ new Map();
29446
+ const gateOfficerAccums = /* @__PURE__ */ new Map();
29447
+ let reworkWallMs = 0;
29448
+ let totalWallMs = 0;
29449
+ let hasReworkSample = false;
29450
+ const legWalls = [];
29451
+ for (const ref of input.issues) {
29452
+ const { issueNumber, bookKey } = ref;
29453
+ const row = findAnalystLibraryIndexRow(index, issueNumber, bookKey);
29454
+ if (row === void 0) {
29455
+ issueEntries.push({ issueNumber, status: "absent", bookKey });
29456
+ continue;
29457
+ }
29458
+ const page = await ensureIssuePage({
29459
+ projectRoot: row.projectRoot,
29460
+ issueNumber,
29461
+ bookKey: row.bookKey
29462
+ });
29463
+ issueEntries.push({
29464
+ issueNumber,
29465
+ status: "present",
29466
+ bookKey: row.bookKey,
29467
+ projectRoot: row.projectRoot
29468
+ });
29469
+ const acceptance = page.acceptanceSuccessRework;
29470
+ if (acceptance !== void 0) {
29471
+ for (const roleStats of acceptance.byRole) {
29472
+ const accum = roleAccums.get(roleStats.role) ?? emptyRoleAccum();
29473
+ absorbRole(accum, roleStats);
29474
+ roleAccums.set(roleStats.role, accum);
29475
+ }
29476
+ reworkWallMs += acceptance.rework.reworkWallMs;
29477
+ totalWallMs += acceptance.rework.totalWallMs;
29478
+ hasReworkSample = true;
29479
+ }
29480
+ const legWallClock = page.legWallClock;
29481
+ if (legWallClock !== void 0) {
29482
+ for (const leg of legWallClock.ranking) {
29483
+ legWalls.push(leg.wallMs);
29484
+ }
29485
+ }
29486
+ const gateCycles = page.gateCycles;
29487
+ if (gateCycles !== void 0) {
29488
+ for (const summary of gateCycles.byOfficer) {
29489
+ const accum = gateOfficerAccums.get(summary.officer) ?? emptyGateOfficerNumeratorAccum();
29490
+ absorbGateOfficerSummary(accum, summary);
29491
+ gateOfficerAccums.set(summary.officer, accum);
29492
+ }
29493
+ }
29494
+ }
29495
+ const byRole = [...roleAccums.keys()].sort((a, b) => a.localeCompare(b)).map((role) => finishRole(role, roleAccums.get(role)));
29496
+ const gateCyclesByOfficer = ["inspector", "notary"].filter((officer) => gateOfficerAccums.has(officer)).map(
29497
+ (officer) => finishGateOfficerNumerators(officer, gateOfficerAccums.get(officer))
29498
+ );
29499
+ return {
29500
+ groupLabel: input.groupLabel,
29501
+ issues: issueEntries,
29502
+ byRole,
29503
+ reworkRatio: hasReworkSample ? rateMetric(reworkWallMs, totalWallMs) : ABSENT,
29504
+ medianWallMs: optionalMedian(legWalls),
29505
+ gateCyclesByOfficer
29506
+ };
29507
+ }
29508
+ async function runAnalystCohortMode(ledgerHome, input, ensureIssuePage) {
29509
+ const index = await readAnalystLibraryIndexPage(ledgerHome);
29510
+ const group0 = await aggregateGroup(index, input.groups[0], ensureIssuePage);
29511
+ const group1 = await aggregateGroup(index, input.groups[1], ensureIssuePage);
29512
+ return {
29513
+ mode: "cohort",
29514
+ groups: [group0, group1]
29515
+ };
29516
+ }
29517
+ var ABSENT;
29518
+ var init_analyst_cohort = __esm({
29519
+ "src/analyst-cohort.ts"() {
29520
+ "use strict";
29521
+ init_analyst_index();
29522
+ init_analyst_median();
29523
+ ABSENT = { status: "absent" };
29524
+ }
29525
+ });
29526
+
29527
+ // src/analyst-gate-cycles-read.ts
29528
+ import { readdir as readdir5 } from "node:fs/promises";
29529
+ import { join as join32 } from "node:path";
29530
+ function isParentAttemptBindingRow(row) {
29531
+ return row.type === "custom" && row.customType === AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE;
29532
+ }
29533
+ function intervalRowsForGateCall(rows, callRowIndex) {
29534
+ return intervalRowsAroundAnchor(rows, callRowIndex, isParentAttemptBindingRow).rows;
29535
+ }
29536
+ function normalizeOfficerArg(raw) {
29537
+ if (typeof raw !== "string") return void 0;
29538
+ return OFFICER_ARG_ALIASES[raw.trim()];
29539
+ }
29540
+ function asFindings(value) {
29541
+ return Array.isArray(value) ? value : [];
29542
+ }
29543
+ function optionalDispatchReason(raw) {
29544
+ if (typeof raw !== "string") return void 0;
29545
+ if (raw.trim() === "") return void 0;
29546
+ return raw;
29547
+ }
29548
+ function isGateTerminatingToolName(toolName) {
29549
+ return toolName === "ak_submission_output" || DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== void 0;
29550
+ }
29551
+ function acceptedGateReceiptIds(rows) {
29552
+ const accepted = /* @__PURE__ */ new Set();
29553
+ for (const row of rows) {
29554
+ const message = isRecord(row.message) ? row.message : void 0;
29555
+ if (message?.role !== "toolResult") continue;
29556
+ if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) continue;
29557
+ if (message.isError === false) accepted.add(message.toolCallId);
29558
+ }
29559
+ return accepted;
29560
+ }
29561
+ function readAcceptedGateStatus(args) {
29562
+ if (args === void 0) return "";
29563
+ return typeof args.status === "string" ? args.status : args.status === void 0 ? "" : String(args.status);
29564
+ }
29565
+ function requireAcceptedGateSpan(rows, filePath) {
29566
+ const span = extractSessionTimestampSpan(rows);
29567
+ if (span.startedAt === void 0 || span.endedAt === void 0) {
29568
+ throw new Error(
29569
+ `accepted gate volume missing session timestamp span in ${filePath}`
29570
+ );
29571
+ }
29572
+ const startedMs = Date.parse(span.startedAt);
29573
+ const endedMs = Date.parse(span.endedAt);
29574
+ if (!Number.isFinite(startedMs) || !Number.isFinite(endedMs) || endedMs < startedMs) {
29575
+ throw new Error(
29576
+ `accepted gate volume has unusable timestamp span in ${filePath}`
29577
+ );
29578
+ }
29579
+ return {
29580
+ startedAt: span.startedAt,
29581
+ endedAt: span.endedAt,
29582
+ wallMs: endedMs - startedMs
29583
+ };
29584
+ }
29585
+ function nearestAttemptBindingBefore(rows, beforeIndex) {
29586
+ for (let i = beforeIndex - 1; i >= 0; i -= 1) {
29587
+ const row = rows[i];
29588
+ if (!isParentAttemptBindingRow(row)) continue;
29589
+ if (!isRecord(row.data) || !isRecord(row.data.parent)) continue;
29590
+ const id = row.data.parent.attemptEntryId;
29591
+ const sessionFile = row.data.parent.sessionFile;
29592
+ return {
29593
+ ...typeof id === "string" && id.length > 0 ? { attemptEntryId: id } : {},
29594
+ ...typeof sessionFile === "string" && sessionFile.length > 0 ? { parentSessionFile: sessionFile } : {}
29595
+ };
29596
+ }
29597
+ return {};
29598
+ }
29599
+ function extractAllAcceptedGateToolCalls(rows) {
29600
+ const acceptedIds = acceptedGateReceiptIds(rows);
29601
+ const out = [];
29602
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
29603
+ const row = rows[rowIndex];
29604
+ const message = isRecord(row.message) ? row.message : void 0;
29605
+ if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
29606
+ for (const part of message.content) {
29607
+ if (!isRecord(part) || part.type !== "toolCall") continue;
29608
+ if (typeof part.id !== "string" || part.id.length === 0) continue;
29609
+ if (typeof part.name !== "string" || part.name.length === 0) continue;
29610
+ if (!isGateTerminatingToolName(part.name)) continue;
29611
+ if (!acceptedIds.has(part.id)) continue;
29612
+ const binding = nearestAttemptBindingBefore(rows, rowIndex);
29613
+ out.push({
29614
+ toolName: part.name,
29615
+ args: isRecord(part.arguments) ? part.arguments : void 0,
29616
+ accepted: true,
29617
+ rowIndex,
29618
+ ...binding
29619
+ });
29620
+ }
29621
+ }
29622
+ return out;
29623
+ }
29624
+ function projectAcceptedGateCall(filePath, rows, call, pointerOfficer) {
29625
+ const span = requireAcceptedGateSpan(intervalRowsForGateCall(rows, call.rowIndex), filePath);
29626
+ const status = readAcceptedGateStatus(call.args);
29627
+ const findings = asFindings(call.args?.findings);
29628
+ const findingsCount = findings.length;
29629
+ const bindingFields = {
29630
+ ...call.attemptEntryId === void 0 ? {} : { attemptEntryId: call.attemptEntryId },
29631
+ ...call.parentSessionFile === void 0 ? {} : { parentSessionFile: call.parentSessionFile }
29700
29632
  };
29701
- }
29702
- function emptyGateOfficerNumeratorAccum() {
29703
- return { rounds: 0, bounceCount: 0, passCount: 0, wallSum: 0 };
29704
- }
29705
- function absorbGateOfficerSummary(accum, summary) {
29706
- accum.rounds += summary.rounds;
29707
- accum.bounceCount += summary.bounceCount;
29708
- accum.passCount += summary.passCount;
29709
- if (summary.meanOfficerWallMs !== void 0) {
29710
- accum.wallSum += summary.meanOfficerWallMs * summary.rounds;
29633
+ if (DISPATCH_TOOLS.has(call.toolName)) {
29634
+ if (status !== "dispatch") {
29635
+ return void 0;
29636
+ }
29637
+ const officer2 = normalizeOfficerArg(call.args?.officer);
29638
+ if (officer2 === void 0) {
29639
+ return void 0;
29640
+ }
29641
+ const reason = optionalDispatchReason(call.args?.reason);
29642
+ return {
29643
+ kind: "dispatch",
29644
+ startedAt: span.startedAt,
29645
+ officer: officer2,
29646
+ status,
29647
+ ...reason === void 0 ? {} : { reason },
29648
+ ...bindingFields
29649
+ };
29650
+ }
29651
+ const officer = call.toolName === "ak_submission_output" ? pointerOfficer : OFFICER_TOOL_TO_FACE[call.toolName];
29652
+ if (officer === void 0) {
29653
+ throw new Error(
29654
+ `accepted gate receipt has unknown officer tool ${call.toolName} in ${filePath}`
29655
+ );
29711
29656
  }
29712
- }
29713
- function finishGateOfficerNumerators(officer, accum) {
29714
29657
  return {
29658
+ kind: "officer",
29659
+ startedAt: span.startedAt,
29660
+ endedAt: span.endedAt,
29715
29661
  officer,
29716
- rounds: accum.rounds,
29717
- bounceCount: accum.bounceCount,
29718
- passCount: accum.passCount,
29719
- bounceRate: rateMetric(accum.bounceCount, accum.rounds),
29720
- meanOfficerWallMs: accum.rounds === 0 ? ABSENT : presentMetric(accum.wallSum / accum.rounds)
29662
+ status,
29663
+ findings,
29664
+ findingsCount,
29665
+ officerWallMs: span.wallMs,
29666
+ ...bindingFields
29721
29667
  };
29722
29668
  }
29723
- async function aggregateGroup(index, input, ensureIssuePage) {
29724
- const issueEntries = [];
29725
- const roleAccums = /* @__PURE__ */ new Map();
29726
- const gateOfficerAccums = /* @__PURE__ */ new Map();
29727
- let reworkWallMs = 0;
29728
- let totalWallMs = 0;
29729
- let hasReworkSample = false;
29730
- const legWalls = [];
29731
- for (const ref of input.issues) {
29732
- const { issueNumber, bookKey } = ref;
29733
- const row = findAnalystLibraryIndexRow(index, issueNumber, bookKey);
29734
- if (row === void 0) {
29735
- issueEntries.push({ issueNumber, status: "absent", bookKey });
29736
- continue;
29669
+ async function classifyAuditorVolume(filePath, pointerOfficer) {
29670
+ const rows = await readLedgerSessionJsonl(filePath);
29671
+ const accepted = extractAllAcceptedGateToolCalls(rows);
29672
+ if (accepted.length === 0) return [];
29673
+ const volumes = [];
29674
+ for (const call of accepted) {
29675
+ const projected = call.toolName === "ak_submission_output" && pointerOfficer === void 0 ? void 0 : projectAcceptedGateCall(filePath, rows, call, pointerOfficer);
29676
+ if (projected !== void 0) volumes.push(projected);
29677
+ }
29678
+ return volumes;
29679
+ }
29680
+ function pairGateRounds(volumes) {
29681
+ const ordered = [...volumes].sort((a, b) => {
29682
+ if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
29683
+ if (a.kind !== b.kind) return a.kind === "dispatch" ? -1 : 1;
29684
+ return 0;
29685
+ });
29686
+ const usedOfficerIdx = /* @__PURE__ */ new Set();
29687
+ const rounds = [];
29688
+ for (let i = 0; i < ordered.length; i += 1) {
29689
+ const vol = ordered[i];
29690
+ if (vol.kind !== "dispatch") continue;
29691
+ let match;
29692
+ for (let j = i + 1; j < ordered.length; j += 1) {
29693
+ if (usedOfficerIdx.has(j)) continue;
29694
+ const candidate = ordered[j];
29695
+ if (candidate.kind !== "officer") continue;
29696
+ if (candidate.officer !== vol.officer) continue;
29697
+ if (vol.attemptEntryId === void 0 || candidate.attemptEntryId === void 0 || candidate.attemptEntryId !== vol.attemptEntryId) {
29698
+ continue;
29699
+ }
29700
+ match = { index: j, officer: candidate };
29701
+ break;
29737
29702
  }
29738
- const page = await ensureIssuePage({
29739
- projectRoot: row.projectRoot,
29740
- issueNumber,
29741
- bookKey: row.bookKey
29703
+ if (match === void 0) continue;
29704
+ usedOfficerIdx.add(match.index);
29705
+ rounds.push({
29706
+ roundIndex: rounds.length + 1,
29707
+ officer: match.officer.officer,
29708
+ status: match.officer.status,
29709
+ officerWallMs: match.officer.officerWallMs,
29710
+ officerStartedAt: match.officer.startedAt,
29711
+ officerEndedAt: match.officer.endedAt,
29712
+ findings: match.officer.findings,
29713
+ findingsCount: match.officer.findingsCount,
29714
+ origin: {
29715
+ kind: "historical_dispatch",
29716
+ ...vol.reason === void 0 ? {} : { reason: vol.reason }
29717
+ }
29742
29718
  });
29743
- issueEntries.push({
29744
- issueNumber,
29745
- status: "present",
29746
- bookKey: row.bookKey,
29747
- projectRoot: row.projectRoot
29719
+ }
29720
+ for (let i = 0; i < ordered.length; i += 1) {
29721
+ const vol = ordered[i];
29722
+ if (vol.kind !== "officer" || usedOfficerIdx.has(i)) continue;
29723
+ rounds.push({
29724
+ roundIndex: 0,
29725
+ officer: vol.officer,
29726
+ status: vol.status,
29727
+ officerWallMs: vol.officerWallMs,
29728
+ officerStartedAt: vol.startedAt,
29729
+ officerEndedAt: vol.endedAt,
29730
+ findings: vol.findings,
29731
+ findingsCount: vol.findingsCount,
29732
+ origin: { kind: "direct" }
29748
29733
  });
29749
- const acceptance = page.acceptanceSuccessRework;
29750
- if (acceptance !== void 0) {
29751
- for (const roleStats of acceptance.byRole) {
29752
- const accum = roleAccums.get(roleStats.role) ?? emptyRoleAccum();
29753
- absorbRole(accum, roleStats);
29754
- roleAccums.set(roleStats.role, accum);
29755
- }
29756
- reworkWallMs += acceptance.rework.reworkWallMs;
29757
- totalWallMs += acceptance.rework.totalWallMs;
29758
- hasReworkSample = true;
29734
+ }
29735
+ return rounds.sort((a, b) => a.officerStartedAt.localeCompare(b.officerStartedAt)).map((round, index) => ({ ...round, roundIndex: index + 1 }));
29736
+ }
29737
+ async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, options = {}) {
29738
+ const directories = typeof auditorRolesDirectory === "string" ? [auditorRolesDirectory] : auditorRolesDirectory;
29739
+ const volumes = [];
29740
+ const classifiedOfficerSessions = /* @__PURE__ */ new Set();
29741
+ for (const directory of directories) {
29742
+ let names;
29743
+ try {
29744
+ const entries = await readdir5(directory, { withFileTypes: true });
29745
+ names = entries.filter(
29746
+ (e) => e.isFile() && (e.name.endsWith(".jsonl") || e.name.endsWith(".pointer.json"))
29747
+ ).map((e) => e.name).sort();
29748
+ } catch (error) {
29749
+ if (isEnoent(error)) continue;
29750
+ throw error;
29759
29751
  }
29760
- const legWallClock = page.legWallClock;
29761
- if (legWallClock !== void 0) {
29762
- for (const leg of legWallClock.ranking) {
29763
- legWalls.push(leg.wallMs);
29752
+ for (const name of names) {
29753
+ const path = join32(directory, name);
29754
+ const fromPointer = name.endsWith(".pointer.json");
29755
+ const pointer = fromPointer ? await resolveOfficerSessionFromPointerFile(path) : void 0;
29756
+ const sessionPath = pointer?.sessionFile ?? path;
29757
+ if (fromPointer) {
29758
+ if (classifiedOfficerSessions.has(sessionPath)) continue;
29759
+ classifiedOfficerSessions.add(sessionPath);
29764
29760
  }
29765
- }
29766
- const gateCycles = page.gateCycles;
29767
- if (gateCycles !== void 0) {
29768
- for (const summary of gateCycles.byOfficer) {
29769
- const accum = gateOfficerAccums.get(summary.officer) ?? emptyGateOfficerNumeratorAccum();
29770
- absorbGateOfficerSummary(accum, summary);
29771
- gateOfficerAccums.set(summary.officer, accum);
29761
+ const officer = pointer?.officer === "inspector" || pointer?.officer === "notary" ? pointer.officer : void 0;
29762
+ const classified = await classifyAuditorVolume(sessionPath, officer);
29763
+ for (const volume of classified) {
29764
+ if (options.parentSessionFile !== void 0 && volume.parentSessionFile !== void 0 && !await retainedRunPathsMatch(volume.parentSessionFile, options.parentSessionFile, runDirectoryOfSessionFile(options.parentSessionFile))) {
29765
+ continue;
29766
+ }
29767
+ volumes.push(volume);
29772
29768
  }
29773
29769
  }
29774
29770
  }
29775
- const byRole = [...roleAccums.keys()].sort((a, b) => a.localeCompare(b)).map((role) => finishRole(role, roleAccums.get(role)));
29776
- const gateCyclesByOfficer = ["inspector", "notary"].filter((officer) => gateOfficerAccums.has(officer)).map(
29777
- (officer) => finishGateOfficerNumerators(officer, gateOfficerAccums.get(officer))
29778
- );
29779
- return {
29780
- groupLabel: input.groupLabel,
29781
- issues: issueEntries,
29782
- byRole,
29783
- reworkRatio: hasReworkSample ? rateMetric(reworkWallMs, totalWallMs) : ABSENT,
29784
- medianWallMs: optionalMedian(legWalls),
29785
- gateCyclesByOfficer
29786
- };
29787
- }
29788
- async function runAnalystCohortMode(ledgerHome, input, ensureIssuePage) {
29789
- const index = await readAnalystLibraryIndexPage(ledgerHome);
29790
- const group0 = await aggregateGroup(index, input.groups[0], ensureIssuePage);
29791
- const group1 = await aggregateGroup(index, input.groups[1], ensureIssuePage);
29792
- return {
29793
- mode: "cohort",
29794
- groups: [group0, group1]
29795
- };
29771
+ return pairGateRounds(volumes);
29796
29772
  }
29797
- var ABSENT;
29798
- var init_analyst_cohort = __esm({
29799
- "src/analyst-cohort.ts"() {
29773
+ var DISPATCH_TOOLS, OFFICER_TOOL_TO_FACE, OFFICER_ARG_ALIASES;
29774
+ var init_analyst_gate_cycles_read = __esm({
29775
+ "src/analyst-gate-cycles-read.ts"() {
29800
29776
  "use strict";
29801
- init_analyst_index();
29802
- init_analyst_median();
29803
- ABSENT = { status: "absent" };
29777
+ init_compliance_transport();
29778
+ init_ledger_session_read();
29779
+ init_unknown_value();
29780
+ init_role_run_relocation();
29781
+ init_role_run_placement();
29782
+ init_archivist_record_pointer();
29783
+ DISPATCH_TOOLS = /* @__PURE__ */ new Set(["ak_menxia_output", "ak_gatekeeper_output"]);
29784
+ OFFICER_TOOL_TO_FACE = {
29785
+ ak_jishizhong_output: "inspector",
29786
+ ak_inspector_output: "inspector",
29787
+ ak_fubaolang_output: "notary",
29788
+ ak_notary_output: "notary"
29789
+ };
29790
+ OFFICER_ARG_ALIASES = {
29791
+ jishizhong: "inspector",
29792
+ inspector: "inspector",
29793
+ fubaolang: "notary",
29794
+ notary: "notary"
29795
+ };
29804
29796
  }
29805
29797
  });
29806
29798
 
29807
29799
  // src/analyst-ledger.ts
29808
- import { readdir as readdir6, readFile as readFile19 } from "node:fs/promises";
29809
- import { basename as basename9, join as join37 } from "node:path";
29800
+ import { readdir as readdir6, readFile as readFile18 } from "node:fs/promises";
29801
+ import { basename as basename10, join as join33 } from "node:path";
29810
29802
  async function readExistingRunLifecycleState(runDirectory) {
29811
29803
  return (await readRoleRunIdentity(runDirectory))?.state;
29812
29804
  }
@@ -29826,7 +29818,7 @@ function ghostLeaseCheckFromAutopsy(autopsy) {
29826
29818
  }
29827
29819
  }
29828
29820
  async function classifyGhostCandidate(input) {
29829
- const autopsy = await autopsyWriterLock(join37(input.runDirectory, "writer.lock"));
29821
+ const autopsy = await autopsyWriterLock(join33(input.runDirectory, "writer.lock"));
29830
29822
  const leaseCheck = ghostLeaseCheckFromAutopsy(autopsy);
29831
29823
  if (leaseCheck === void 0) return { kind: "live" };
29832
29824
  return {
@@ -29838,11 +29830,6 @@ async function classifyGhostCandidate(input) {
29838
29830
  }
29839
29831
  };
29840
29832
  }
29841
- function parseRunDirectoryName2(name) {
29842
- const at = name.lastIndexOf("@");
29843
- if (at <= 0 || at === name.length - 1) return void 0;
29844
- return { runId: name.slice(0, at), role: name.slice(at + 1) };
29845
- }
29846
29833
  async function listLedgerBookNames(booksRoot) {
29847
29834
  try {
29848
29835
  const entries = await readdir6(booksRoot, { withFileTypes: true });
@@ -29855,7 +29842,7 @@ async function listLedgerBookNames(booksRoot) {
29855
29842
  async function readInvocationScopeFields(runDirectory) {
29856
29843
  let raw;
29857
29844
  try {
29858
- raw = await readFile19(join37(runDirectory, "invocation.json"), "utf8");
29845
+ raw = await readFile18(join33(runDirectory, "invocation.json"), "utf8");
29859
29846
  } catch (error) {
29860
29847
  if (isMissingPathError(error)) return void 0;
29861
29848
  throw error;
@@ -29888,15 +29875,15 @@ function decideIssueScope(input) {
29888
29875
  }
29889
29876
  async function resolveSessionFile(runDirectory) {
29890
29877
  try {
29891
- const raw = await readFile19(join37(runDirectory, "invocation.json"), "utf8");
29878
+ const raw = await readFile18(join33(runDirectory, "invocation.json"), "utf8");
29892
29879
  const parsed = JSON.parse(raw);
29893
29880
  if (isRecord(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
29894
- return parsed.sessionFile;
29881
+ return typeof parsed.runDirectory === "string" ? rewriteRunDirectoryPathValue(parsed.sessionFile, parsed.runDirectory, runDirectory) : parsed.sessionFile;
29895
29882
  }
29896
29883
  } catch (error) {
29897
29884
  if (!isMissingPathError(error)) throw error;
29898
29885
  }
29899
- return join37(runDirectory, "session", "session.jsonl");
29886
+ return sessionFileOf(runDirectory);
29900
29887
  }
29901
29888
  function attributeSessionRowsForRun(input) {
29902
29889
  if (pathContainedIn(input.runDirectory, input.sessionFile)) {
@@ -30098,9 +30085,9 @@ async function classifyScopedRun(input) {
30098
30085
  }
30099
30086
  let gateCycles;
30100
30087
  try {
30101
- const parentSessionFile = join37(input.runDirectory, "session", "session.jsonl");
30088
+ const parentSessionFile = sessionFileOf(input.runDirectory);
30102
30089
  gateCycles = await readAnalystGateCyclesFromAuditorRoles(
30103
- join37(input.runDirectory, "session", "auditor-roles"),
30090
+ sitianRunVolumeDirectory(input.runDirectory, "auditor-roles"),
30104
30091
  { parentSessionFile }
30105
30092
  );
30106
30093
  } catch (error) {
@@ -30135,7 +30122,7 @@ async function classifyScopedRun(input) {
30135
30122
  async function scanAnalystIssueRuns(input) {
30136
30123
  const ledgerHome = resolveActivationLedgerHome(input.home);
30137
30124
  const scopeTicketNumber = input.ticketNumber;
30138
- const booksRoot = join37(ledgerHome, "books");
30125
+ const booksRoot = join33(ledgerHome, "books");
30139
30126
  let wholeBook = false;
30140
30127
  let scopeRootIdentity;
30141
30128
  let bookNames;
@@ -30168,7 +30155,7 @@ async function scanAnalystIssueRuns(input) {
30168
30155
  const ghostLegs = [];
30169
30156
  const scopeConflicts = [];
30170
30157
  for (const book of bookNames) {
30171
- const bookDir = join37(booksRoot, book);
30158
+ const bookDir = join33(booksRoot, book);
30172
30159
  let runDirectories;
30173
30160
  try {
30174
30161
  runDirectories = await listBookRunDirectories(bookDir);
@@ -30177,8 +30164,8 @@ async function scanAnalystIssueRuns(input) {
30177
30164
  throw error;
30178
30165
  }
30179
30166
  for (const runDirectory of runDirectories) {
30180
- const runName = basename9(runDirectory);
30181
- const parsed = parseRunDirectoryName2(runName);
30167
+ const runName = basename10(runDirectory);
30168
+ const parsed = parseRunLeaf(runName);
30182
30169
  if (parsed === void 0) continue;
30183
30170
  let scopeFields;
30184
30171
  try {
@@ -30228,8 +30215,10 @@ var init_analyst_ledger = __esm({
30228
30215
  init_analyst_book_key();
30229
30216
  init_activation_ledger_topology();
30230
30217
  init_role_run_placement();
30218
+ init_sitian_appender();
30231
30219
  init_run_lifecycle();
30232
30220
  init_run_ticket_number();
30221
+ init_role_run_relocation();
30233
30222
  init_ledger_session_read();
30234
30223
  init_run_terminal_artifacts();
30235
30224
  init_analyst_gate_cycles_read();
@@ -30901,7 +30890,7 @@ var init_analyst_metric_family = __esm({
30901
30890
  });
30902
30891
 
30903
30892
  // src/analyst-page.ts
30904
- import { dirname as dirname22, join as join38 } from "node:path";
30893
+ import { dirname as dirname21, join as join34 } from "node:path";
30905
30894
  function analystIssuePageKey(address) {
30906
30895
  const parts = ["book", address.bookKey];
30907
30896
  if (address.issueNumber !== void 0) {
@@ -30912,7 +30901,7 @@ function analystIssuePageKey(address) {
30912
30901
  return sha256Hex(parts.join("\0")).slice(0, 32);
30913
30902
  }
30914
30903
  function analystIssuePagePath(ledgerHome, address) {
30915
- return join38(ledgerHome, "analyst", "issues", `${analystIssuePageKey(address)}.json`);
30904
+ return join34(ledgerHome, "analyst", "issues", `${analystIssuePageKey(address)}.json`);
30916
30905
  }
30917
30906
  function analystIssuePageAddressFromPage(page) {
30918
30907
  return {
@@ -31023,7 +31012,7 @@ async function buildAnalystIssueMetricsPage(input) {
31023
31012
  }
31024
31013
  async function writeAnalystIssueMetricsPage(ledgerHome, page) {
31025
31014
  const path = analystIssuePagePath(ledgerHome, analystIssuePageAddressFromPage(page));
31026
- ensureRealDirectoryTree(ledgerHome, dirname22(path));
31015
+ ensureRealDirectoryTree(ledgerHome, dirname21(path));
31027
31016
  assertLedgerFileInsideHome(path, ledgerHome);
31028
31017
  await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
31029
31018
  `);
@@ -31148,7 +31137,7 @@ var init_analyst_model_groups = __esm({
31148
31137
  });
31149
31138
 
31150
31139
  // src/analyst-entry.ts
31151
- import { readFile as readFile20 } from "node:fs/promises";
31140
+ import { readFile as readFile19 } from "node:fs/promises";
31152
31141
  function cachedPageMatchesRequestedScope(page, input) {
31153
31142
  if (page.bookKey !== input.bookKey) return false;
31154
31143
  const requestedTicket = input.ticketNumber ?? input.issueNumber;
@@ -31175,7 +31164,7 @@ async function readOrComputeAnalystIssuePage(input, options) {
31175
31164
  ...issueNumber === void 0 && input.bookKey === void 0 ? { scopeRootIdentity: projectRoot } : {}
31176
31165
  });
31177
31166
  try {
31178
- const raw = await readFile20(pagePath, "utf8");
31167
+ const raw = await readFile19(pagePath, "utf8");
31179
31168
  const page = JSON.parse(raw);
31180
31169
  if (cachedPageMatchesRequestedScope(page, { bookKey, ...input })) {
31181
31170
  const ghostScan = await scanAnalystIssueRuns({
@@ -31276,7 +31265,7 @@ async function runAnalystModelGroupsMode(input, home) {
31276
31265
  scopeRootIdentity: projectRoot
31277
31266
  });
31278
31267
  try {
31279
- const raw = await readFile20(pagePath, "utf8");
31268
+ const raw = await readFile19(pagePath, "utf8");
31280
31269
  JSON.parse(raw);
31281
31270
  } catch (error) {
31282
31271
  if (!isMissingPathError(error)) {
@@ -31374,8 +31363,8 @@ var init_analyst_entry = __esm({
31374
31363
  });
31375
31364
 
31376
31365
  // src/public-cli/analyst-run.ts
31377
- import { readFile as readFile21 } from "node:fs/promises";
31378
- import { isAbsolute as isAbsolute10, resolve as resolve13 } from "node:path";
31366
+ import { readFile as readFile20 } from "node:fs/promises";
31367
+ import { isAbsolute as isAbsolute10, resolve as resolve12 } from "node:path";
31379
31368
  function resolveAnalystIssueBookKeyFromCwd(cwd = process.cwd()) {
31380
31369
  try {
31381
31370
  return resolveBookKeyFromGit(cwd);
@@ -31424,10 +31413,10 @@ async function buildAnalystSweepModeInputFromAttachmentPaths(attachmentPaths) {
31424
31413
  );
31425
31414
  }
31426
31415
  const sourcePath = attachmentPaths[0];
31427
- const absolute = isAbsolute10(sourcePath) ? sourcePath : resolve13(sourcePath);
31416
+ const absolute = isAbsolute10(sourcePath) ? sourcePath : resolve12(sourcePath);
31428
31417
  let bytes;
31429
31418
  try {
31430
- bytes = await readFile21(absolute);
31419
+ bytes = await readFile20(absolute);
31431
31420
  } catch (error) {
31432
31421
  throw new CliUsageError(
31433
31422
  `analyst sweep attachment is not a readable regular file: ${sourcePath}`,
@@ -32448,7 +32437,7 @@ var init_cli = __esm({
32448
32437
 
32449
32438
  // src/public-cli/main.ts
32450
32439
  import { existsSync as existsSync11 } from "node:fs";
32451
- import { dirname as dirname23, join as join39 } from "node:path";
32440
+ import { dirname as dirname22, join as join35 } from "node:path";
32452
32441
  import { fileURLToPath as fileURLToPath2 } from "node:url";
32453
32442
 
32454
32443
  // src/public-cli/host-pi-runtime.ts
@@ -32535,10 +32524,10 @@ function linkPackage(packageRoot2, name, targetDir) {
32535
32524
  }
32536
32525
 
32537
32526
  // src/public-cli/main.ts
32538
- var here = dirname23(fileURLToPath2(import.meta.url));
32527
+ var here = dirname22(fileURLToPath2(import.meta.url));
32539
32528
  function resolvePackageRoot(binDir) {
32540
- const canonical = join39(binDir, "..", "..");
32541
- if (existsSync11(join39(canonical, "package.json"))) {
32529
+ const canonical = join35(binDir, "..", "..");
32530
+ if (existsSync11(join35(canonical, "package.json"))) {
32542
32531
  return canonical;
32543
32532
  }
32544
32533
  return binDir;