@akagilnc/pi-workflow-roles 0.1.3826 → 0.1.3873

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 (52) hide show
  1. package/dist/acp-host/production-host.js +22757 -22676
  2. package/dist/canonical-skill-binding.js +0 -3
  3. package/dist/engine-detour-tool.js +2 -2
  4. package/dist/engine-detour.js +23 -7
  5. package/dist/headless-host/production-host.js +4658 -4593
  6. package/dist/host-descriptions.js +5 -2
  7. package/dist/pi/adapter.js +11 -0
  8. package/dist/pi/role-turn-host.js +44 -93
  9. package/dist/public-cli/invocation.js +4 -5
  10. package/dist/public-cli/load-production-acp-host.js +1 -1
  11. package/dist/public-cli/load-production-external-host.js +10 -0
  12. package/dist/public-cli/load-production-headless-host.js +1 -1
  13. package/dist/public-cli/main.js +145 -140
  14. package/dist/public-role-summons.js +7 -49
  15. package/dist/reviewer-agent.js +1 -0
  16. package/dist/reviewer-child-executor.js +3 -2
  17. package/dist/role-activation-flags.js +50 -0
  18. package/dist/role-runtime.js +12 -10
  19. package/dist/worker-role.js +14 -12
  20. package/package.json +1 -1
  21. package/scripts/build-package.mjs +2 -2
  22. package/src/acp-host/production-host.ts +31 -94
  23. package/src/acp-host/role-turn-host.ts +178 -263
  24. package/src/canonical-skill-binding.ts +4 -4
  25. package/src/diagnostic-tail.ts +18 -0
  26. package/src/engine-detour-tool.ts +5 -4
  27. package/src/engine-detour.ts +44 -9
  28. package/src/external-host-turn-loop.ts +172 -0
  29. package/src/headless-host/production-host.ts +10 -7
  30. package/src/headless-host/role-turn-host.ts +271 -263
  31. package/src/host-contracts.ts +6 -0
  32. package/src/host-descriptions.ts +5 -2
  33. package/src/host-session-record.ts +41 -0
  34. package/src/package-resources/method-skill-binding.ts +0 -3
  35. package/src/pi/adapter.ts +13 -0
  36. package/src/pi/role-turn-host.ts +46 -94
  37. package/src/prepared-role-turn.ts +68 -0
  38. package/src/public-cli/cli.ts +11 -20
  39. package/src/public-cli/invocation.ts +4 -5
  40. package/src/public-cli/load-production-acp-host.ts +2 -1
  41. package/src/public-cli/load-production-external-host.ts +17 -0
  42. package/src/public-cli/load-production-headless-host.ts +2 -1
  43. package/src/public-role-summons.ts +12 -69
  44. package/src/reviewer-agent.ts +12 -1
  45. package/src/reviewer-child-executor.ts +10 -2
  46. package/src/role-activation-flags.ts +53 -0
  47. package/src/{acp-host/role-envelope.ts → role-envelope.ts} +41 -98
  48. package/src/role-runtime-dependencies.ts +91 -0
  49. package/src/role-runtime.ts +21 -11
  50. package/src/{acp-host/session-identity.ts → session-identity.ts} +6 -6
  51. package/src/worker-role.ts +14 -13
  52. /package/src/{acp-host/mcp-relay.mjs → mcp-relay.mjs} +0 -0
@@ -15090,6 +15090,12 @@ var init_diarist_contracts = __esm({
15090
15090
  function packagedRoleMetadata(role) {
15091
15091
  return PACKAGED_ROLE_REGISTRY.find((entry) => entry.role === role);
15092
15092
  }
15093
+ function packagedRoleInputFlag(role) {
15094
+ return packagedRoleMetadata(role)?.inputFlag;
15095
+ }
15096
+ function packagedRolePhaseFlag(role) {
15097
+ return packagedRoleMetadata(role)?.phaseFlag;
15098
+ }
15093
15099
  var NOTARY_SESSION_MATERIALS, INSPECTOR_SESSION_MATERIALS, AUDITOR_PUBLIC_SESSION_MATERIALS, PUBLIC_ROLE_RECORDS, PACKAGED_ROLE_REGISTRY;
15094
15100
  var init_packaged_role_registry = __esm({
15095
15101
  "src/packaged-role-registry.ts"() {
@@ -15527,9 +15533,11 @@ var init_host_descriptions = __esm({
15527
15533
  binaryFromHome: Object.freeze([".local", "bin", "claude"]),
15528
15534
  sessionBindingFile: "claude-headless-session.json",
15529
15535
  fixedArgs: Object.freeze([
15530
- // One result envelope (not stream-json): typed receipt only; no event-stream copy.
15536
+ // Live NDJSON events → sitian host-session records (#811); last line is the result receipt.
15531
15537
  "--output-format",
15532
- "json",
15538
+ "stream-json",
15539
+ // Intermediate assistant/tool/system events require verbose with stream-json.
15540
+ "--verbose",
15533
15541
  "--permission-mode",
15534
15542
  "bypassPermissions",
15535
15543
  // Empty sources: no user/project/local operator surface (envelope owns materials).
@@ -16180,7 +16188,7 @@ async function loadProductionAcpHostFactory(packageRoot2, host) {
16180
16188
  const href = pathToFileURL(target).href;
16181
16189
  const mod = await import(href);
16182
16190
  const create = mod.createProductionAcpRoleTurnHost;
16183
- return (options) => create({ ...options, description });
16191
+ return (options) => create({ ...options, description, hostName: host });
16184
16192
  }
16185
16193
  var init_load_production_acp_host = __esm({
16186
16194
  "src/public-cli/load-production-acp-host.ts"() {
@@ -16204,7 +16212,7 @@ async function loadProductionHeadlessHostFactory(packageRoot2, host) {
16204
16212
  const href = pathToFileURL2(target).href;
16205
16213
  const mod = await import(href);
16206
16214
  const create = mod.createProductionHeadlessRoleTurnHost;
16207
- return (options) => create({ ...options, description });
16215
+ return (options) => create({ ...options, description, hostName: host });
16208
16216
  }
16209
16217
  var init_load_production_headless_host = __esm({
16210
16218
  "src/public-cli/load-production-headless-host.ts"() {
@@ -16224,6 +16232,17 @@ async function loadProductionExternalHostFactory(packageRoot2, host) {
16224
16232
  }
16225
16233
  throw new Error(`unregistered host: ${host}`);
16226
16234
  }
16235
+ function createLazyProductionExternalHost(options) {
16236
+ let hostPromise;
16237
+ return {
16238
+ executeTurn: async (request) => {
16239
+ hostPromise ??= loadProductionExternalHostFactory(options.packageRoot, options.hostName).then(
16240
+ (create) => create({ packageRoot: options.packageRoot, principalAuthority: options.principalAuthority })
16241
+ );
16242
+ return (await hostPromise).executeTurn(request);
16243
+ }
16244
+ };
16245
+ }
16227
16246
  var init_load_production_external_host = __esm({
16228
16247
  "src/public-cli/load-production-external-host.ts"() {
16229
16248
  "use strict";
@@ -16258,11 +16277,17 @@ var init_host_contracts = __esm({
16258
16277
  });
16259
16278
 
16260
16279
  // src/engine-detour.ts
16280
+ function normalizeEngineName(engine) {
16281
+ if (engine === void 0) return void 0;
16282
+ const trimmed = engine.trim();
16283
+ return trimmed === "" ? void 0 : trimmed;
16284
+ }
16261
16285
  function applyEngineChildEnv(childEnv, engine) {
16262
16286
  delete childEnv[AK_ROLE_ENGINE_ENV];
16263
- if (engine !== void 0 && engine.trim() !== "") {
16264
- childEnv[AK_ROLE_ENGINE_ENV] = engine.trim();
16265
- } else {
16287
+ const normalized = normalizeEngineName(engine);
16288
+ if (normalized !== void 0) {
16289
+ childEnv[AK_ROLE_ENGINE_ENV] = normalized;
16290
+ } else if (childEnv !== process.env) {
16266
16291
  childEnv[AK_ROLE_ENGINE_ENV] = void 0;
16267
16292
  }
16268
16293
  }
@@ -16275,6 +16300,50 @@ var init_engine_detour = __esm({
16275
16300
  }
16276
16301
  });
16277
16302
 
16303
+ // src/role-activation-flags.ts
16304
+ function projectActivationFlags(request) {
16305
+ const activation = request.activation;
16306
+ const flags = /* @__PURE__ */ new Map([["ak-role", activation.role]]);
16307
+ const inputFlag = packagedRoleInputFlag(activation.role);
16308
+ const phaseFlag = packagedRolePhaseFlag(activation.role);
16309
+ if ("phase" in activation && phaseFlag !== void 0) flags.set(phaseFlag, activation.phase);
16310
+ if (inputFlag !== void 0) {
16311
+ const path = "taskPath" in activation ? activation.taskPath : "packetPath" in activation ? activation.packetPath : "casePath" in activation ? activation.casePath : "inputPath" in activation ? activation.inputPath : "sourceRun" in activation ? activation.sourceRun : void 0;
16312
+ if (path !== void 0) flags.set(inputFlag, path);
16313
+ }
16314
+ if (activation.role === "fixer" && activation.prerequisitesPath !== void 0) {
16315
+ flags.set("ak-fixer-prerequisites", activation.prerequisitesPath);
16316
+ }
16317
+ if (activation.role === "reviewer") {
16318
+ flags.set("ak-review-base", activation.baseRevision);
16319
+ flags.set("ak-review-authority-refs", JSON.stringify(activation.authorityRefs));
16320
+ if (activation.ticketNumber !== void 0) {
16321
+ flags.set("ak-review-ticket-number", String(activation.ticketNumber));
16322
+ }
16323
+ }
16324
+ if (activation.role === "notary" && activation.ticketNumber !== void 0) {
16325
+ flags.set("ak-notary-ticket-number", String(activation.ticketNumber));
16326
+ }
16327
+ if (activation.role === "gleaner-left") {
16328
+ flags.set("ak-gleaner-left-base", activation.baseRevision);
16329
+ }
16330
+ if (activation.role === "collector") {
16331
+ flags.set("ak-collector-repo", activation.repo);
16332
+ if (activation.pr !== void 0) flags.set("ak-collector-pr", activation.pr);
16333
+ if (activation.requestManifestPath !== void 0) {
16334
+ flags.set("ak-collector-request-manifest", activation.requestManifestPath);
16335
+ }
16336
+ if (activation.waitMs !== void 0) flags.set("ak-collector-wait-ms", activation.waitMs);
16337
+ }
16338
+ return flags;
16339
+ }
16340
+ var init_role_activation_flags = __esm({
16341
+ "src/role-activation-flags.ts"() {
16342
+ "use strict";
16343
+ init_packaged_role_registry();
16344
+ }
16345
+ });
16346
+
16278
16347
  // src/sitian-contracts.ts
16279
16348
  function attachDirectErrnoCode(error, cause) {
16280
16349
  if (cause === null || typeof cause !== "object" || !("code" in cause)) return;
@@ -16584,7 +16653,7 @@ var init_sitian_facade = __esm({
16584
16653
  import { execFile, spawn } from "node:child_process";
16585
16654
  import { constants } from "node:fs";
16586
16655
  import { access, appendFile, readFile as readFile3, realpath } from "node:fs/promises";
16587
- import { delimiter as delimiter2, isAbsolute as isAbsolute3, join as join10, resolve as resolve4 } from "node:path";
16656
+ import { basename as basename4, delimiter as delimiter2, dirname as dirname6, isAbsolute as isAbsolute3, join as join10, resolve as resolve4 } from "node:path";
16588
16657
  import { platform } from "node:process";
16589
16658
  import { promisify } from "node:util";
16590
16659
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -16604,84 +16673,14 @@ function buildSeatModelCliArgs(model) {
16604
16673
  ...model.thinking === void 0 ? [] : ["--thinking", model.thinking]
16605
16674
  ];
16606
16675
  }
16607
- function buildActivationFlagArgs(activation) {
16608
- switch (activation.role) {
16609
- case "judge":
16610
- return ["--ak-role", "judge"];
16611
- case "coder":
16612
- return [
16613
- "--ak-role",
16614
- "coder",
16615
- "--ak-coder-phase",
16616
- activation.phase,
16617
- "--ak-coder-task",
16618
- activation.taskPath
16619
- ];
16620
- case "fixer":
16621
- return [
16622
- "--ak-role",
16623
- "fixer",
16624
- "--ak-fixer-phase",
16625
- activation.phase,
16626
- "--ak-fix-packet",
16627
- activation.packetPath,
16628
- ...activation.prerequisitesPath === void 0 ? [] : ["--ak-fixer-prerequisites", activation.prerequisitesPath]
16629
- ];
16630
- case "reviewer":
16631
- return [
16632
- "--ak-role",
16633
- "reviewer",
16634
- "--ak-review-base",
16635
- activation.baseRevision,
16636
- ...activation.authorityRefs.length === 0 ? [] : ["--ak-review-authority-refs", JSON.stringify([...activation.authorityRefs])],
16637
- ...activation.ticketNumber === void 0 ? [] : ["--ak-review-ticket-number", String(activation.ticketNumber)]
16638
- ];
16639
- case "merger":
16640
- return ["--ak-role", "merger", "--ak-merger-input", activation.inputPath];
16641
- case "collector":
16642
- return [
16643
- "--ak-role",
16644
- "collector",
16645
- "--ak-collector-repo",
16646
- activation.repo,
16647
- ...activation.pr === void 0 ? [] : ["--ak-collector-pr", activation.pr],
16648
- ...activation.requestManifestPath === void 0 ? [] : ["--ak-collector-request-manifest", activation.requestManifestPath],
16649
- ...activation.waitMs === void 0 ? [] : ["--ak-collector-wait-ms", activation.waitMs]
16650
- ];
16651
- case "doctor":
16652
- return ["--ak-role", "doctor", "--ak-doctor-case", activation.casePath];
16653
- case "notary":
16654
- return [
16655
- "--ak-role",
16656
- "notary",
16657
- "--ak-notary-source-run",
16658
- activation.sourceRun,
16659
- ...activation.ticketNumber === void 0 ? [] : ["--ak-notary-ticket-number", String(activation.ticketNumber)]
16660
- ];
16661
- case "countersign":
16662
- return ["--ak-role", "countersign"];
16663
- case "gleaner-left":
16664
- return [
16665
- "--ak-role",
16666
- "gleaner-left",
16667
- "--ak-gleaner-left-base",
16668
- activation.baseRevision
16669
- ];
16670
- case "inspector":
16671
- return ["--ak-role", "inspector"];
16672
- case "gatekeeper":
16673
- return ["--ak-role", "gatekeeper"];
16674
- case "navigator":
16675
- return ["--ak-role", "navigator"];
16676
- case "auditor":
16677
- return ["--ak-role", "auditor"];
16678
- case "diarist":
16679
- return ["--ak-role", "diarist"];
16680
- default: {
16681
- const _exhaustive = activation;
16682
- return _exhaustive;
16683
- }
16676
+ function activationFlagsToPiArgv(flags) {
16677
+ const args = [];
16678
+ for (const [name, value] of flags) {
16679
+ if (value === false) continue;
16680
+ args.push(`--${name}`);
16681
+ if (value !== true) args.push(String(value));
16684
16682
  }
16683
+ return args;
16685
16684
  }
16686
16685
  function buildMethodArgs(methods) {
16687
16686
  const skillArgs = [];
@@ -16692,12 +16691,26 @@ function buildMethodArgs(methods) {
16692
16691
  }
16693
16692
  return skillArgs;
16694
16693
  }
16694
+ function applyPiNativeSkillInvocation(methods, prompt) {
16695
+ const skills = methods.filter((method) => method.kind === "skill");
16696
+ if (skills.length !== 1) return prompt;
16697
+ const name = basename4(dirname6(skills[0].path));
16698
+ if (name.length === 0) return prompt;
16699
+ const token = `/skill:${name}`;
16700
+ const trimmed = prompt.trimStart();
16701
+ if (trimmed === token || trimmed.startsWith(`${token} `) || trimmed.startsWith(`${token}
16702
+ `)) {
16703
+ return prompt;
16704
+ }
16705
+ return prompt.length === 0 ? token : `${token} ${prompt}`;
16706
+ }
16695
16707
  function buildPiTurnExtraArgs(request, authority, extraPiArgs = []) {
16696
16708
  const { sessionFile, sessionDirectory } = authority.decode(request.principal);
16697
- const prompt = request.continuation.kind === "initial" || request.continuation.kind === "resume" ? request.continuation.prompt : (() => {
16709
+ const rawPrompt = request.continuation.kind === "initial" || request.continuation.kind === "resume" ? request.continuation.prompt : (() => {
16698
16710
  const _exhaustive = request.continuation;
16699
16711
  return _exhaustive;
16700
16712
  })();
16713
+ const prompt = applyPiNativeSkillInvocation(request.methods, rawPrompt);
16701
16714
  return [
16702
16715
  "--no-skills",
16703
16716
  ...buildMethodArgs(request.methods),
@@ -16709,7 +16722,8 @@ function buildPiTurnExtraArgs(request, authority, extraPiArgs = []) {
16709
16722
  "--session-dir",
16710
16723
  sessionDirectory,
16711
16724
  ...extraPiArgs,
16712
- ...buildActivationFlagArgs(request.activation),
16725
+ // Envelope assembly = projectActivationFlags; pi only renders argv pairs.
16726
+ ...activationFlagsToPiArgv(projectActivationFlags(request)),
16713
16727
  "--mode",
16714
16728
  "json",
16715
16729
  ...buildSeatModelCliArgs(request.model),
@@ -16926,6 +16940,7 @@ var init_role_turn_host = __esm({
16926
16940
  "use strict";
16927
16941
  init_host_contracts();
16928
16942
  init_engine_detour();
16943
+ init_role_activation_flags();
16929
16944
  init_sitian_facade();
16930
16945
  INTERNAL_ROLE_ENTRYPOINT_RELATIVE2 = "extensions/role-runtime.ts";
16931
16946
  execFileAsync = promisify(execFile);
@@ -17173,7 +17188,7 @@ var init_terminating_tools = __esm({
17173
17188
 
17174
17189
  // src/doctor-evidence.ts
17175
17190
  import { readdir, readFile as readFile5, realpath as realpath2, stat } from "node:fs/promises";
17176
- import { dirname as dirname6, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
17191
+ import { dirname as dirname7, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
17177
17192
  function record2(value) {
17178
17193
  return typeof value === "object" && value !== null && !Array.isArray(value);
17179
17194
  }
@@ -17212,7 +17227,7 @@ async function stableRunsIdentity(root) {
17212
17227
  } catch (error) {
17213
17228
  if (!isMissingPathError(error)) throw error;
17214
17229
  }
17215
- const parent = dirname6(cursor);
17230
+ const parent = dirname7(cursor);
17216
17231
  if (parent === cursor) return root;
17217
17232
  cursor = parent;
17218
17233
  }
@@ -19025,7 +19040,7 @@ __export(notary_source_run_exports, {
19025
19040
  loadNotarySourceRunLocator: () => loadNotarySourceRunLocator,
19026
19041
  resolveNotarySourceRunLocator: () => resolveNotarySourceRunLocator
19027
19042
  });
19028
- import { dirname as dirname7, isAbsolute as isAbsolute5, join as join14, resolve as resolve6, basename as basename4 } from "node:path";
19043
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join14, resolve as resolve6, basename as basename5 } from "node:path";
19029
19044
  import { lstat as lstat2, realpath as realpath3 } from "node:fs/promises";
19030
19045
  function parseRunDirectoryName(name) {
19031
19046
  const match = RUN_DIR_NAME.exec(name);
@@ -19056,10 +19071,10 @@ async function requireRunDirectory(candidate, display) {
19056
19071
  `notary --source-run must be a run directory: ${display}`
19057
19072
  );
19058
19073
  }
19059
- const identity = parseRunDirectoryName(basename4(real));
19074
+ const identity = parseRunDirectoryName(basename5(real));
19060
19075
  if (identity === void 0) {
19061
19076
  throw new NotarySourceRunError(
19062
- `notary --source-run must be named <runId>@<role>: ${basename4(real)}`
19077
+ `notary --source-run must be named <runId>@<role>: ${basename5(real)}`
19063
19078
  );
19064
19079
  }
19065
19080
  return real;
@@ -19080,9 +19095,9 @@ async function resolveNotarySourceRunLocator(options) {
19080
19095
  candidate = isAbsolute5(raw) ? raw : resolve6(options.projectRoot, raw);
19081
19096
  }
19082
19097
  const real = await requireRunDirectory(candidate, raw);
19083
- const identity = parseRunDirectoryName(basename4(real));
19098
+ const identity = parseRunDirectoryName(basename5(real));
19084
19099
  const runsRootIdentity = physicalPathIdentity(bookRunsRoot);
19085
- const parentIdentity = physicalPathIdentity(dirname7(real));
19100
+ const parentIdentity = physicalPathIdentity(dirname8(real));
19086
19101
  if (parentIdentity !== runsRootIdentity) {
19087
19102
  throw new NotarySourceRunError(
19088
19103
  "notary --source-run must resolve to a retained run under the project machine-ledger book"
@@ -19117,7 +19132,7 @@ async function resolveNotarySourceRunLocator(options) {
19117
19132
  }
19118
19133
  async function loadNotarySourceRunLocator(path) {
19119
19134
  const real = await requireRunDirectory(path, path);
19120
- const identity = parseRunDirectoryName(basename4(real));
19135
+ const identity = parseRunDirectoryName(basename5(real));
19121
19136
  const runState = await readRoleRunIdentity(real);
19122
19137
  if (runState === void 0) {
19123
19138
  throw new NotarySourceRunError(
@@ -20215,7 +20230,7 @@ import {
20215
20230
  realpath as realpath4,
20216
20231
  writeFile as writeFile4
20217
20232
  } from "node:fs/promises";
20218
- import { basename as basename5, isAbsolute as isAbsolute6, join as join15, resolve as resolve7, sep as sep3 } from "node:path";
20233
+ import { basename as basename6, isAbsolute as isAbsolute6, join as join15, resolve as resolve7, sep as sep3 } from "node:path";
20219
20234
  function issueAdmissionPlacement(authority, request) {
20220
20235
  const principal = authority.issue(request);
20221
20236
  const { sessionDirectory, sessionFile } = authority.decode(principal);
@@ -20609,7 +20624,7 @@ async function freezeRegularFileAttachment(sourcePath, destinationDir, index) {
20609
20624
  );
20610
20625
  }
20611
20626
  const bytes = await readFile9(absolute);
20612
- const name = `${String(index).padStart(2, "0")}-${basename5(absolute)}`;
20627
+ const name = `${String(index).padStart(2, "0")}-${basename6(absolute)}`;
20613
20628
  const frozenPath = join15(destinationDir, name);
20614
20629
  await writeFile4(frozenPath, bytes);
20615
20630
  return {
@@ -22044,9 +22059,7 @@ async function admitMergerInvocation(options) {
22044
22059
  };
22045
22060
  }
22046
22061
  function buildMergerTransportPrompt(admitted, engineMaterial) {
22047
- const lines = [
22048
- `/skill:resolving-merge-conflicts ${admitted.instruction}`
22049
- ];
22062
+ const lines = [admitted.instruction];
22050
22063
  if (admitted.attachments.length > 0) {
22051
22064
  lines.push("");
22052
22065
  lines.push("\u5DF2\u53D7\u7406\u9644\u4EF6\uFF08\u51BB\u7ED3\u5FEB\u7167\u8DEF\u5F84\uFF09\uFF1A");
@@ -23054,7 +23067,7 @@ var init_analyst_gate_cycles_read = __esm({
23054
23067
 
23055
23068
  // src/run-terminal-artifacts.ts
23056
23069
  import { readdir as readdir4, readFile as readFile12 } from "node:fs/promises";
23057
- import { basename as basename6, dirname as dirname8, join as join18 } from "node:path";
23070
+ import { basename as basename7, dirname as dirname9, join as join18 } from "node:path";
23058
23071
  function isMissingPathError2(error) {
23059
23072
  return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
23060
23073
  }
@@ -23135,7 +23148,7 @@ async function listUniqueErrorFallbackPaths(directories) {
23135
23148
  return found;
23136
23149
  }
23137
23150
  function runIdFromRunDirectory(runDirectory) {
23138
- const name = basename6(runDirectory);
23151
+ const name = basename7(runDirectory);
23139
23152
  const at = name.lastIndexOf("@");
23140
23153
  if (at <= 0 || at === name.length - 1) return void 0;
23141
23154
  return name.slice(0, at);
@@ -23161,7 +23174,7 @@ async function readRunTerminalArtifact(runDirectory) {
23161
23174
  if (read3 !== void 0) return read3;
23162
23175
  }
23163
23176
  const expectedRunId = runIdFromRunDirectory(runDirectory);
23164
- for (const path of await listUniqueErrorFallbackPaths([dirname8(runDirectory)])) {
23177
+ for (const path of await listUniqueErrorFallbackPaths([dirname9(runDirectory)])) {
23165
23178
  const read3 = await readTerminalArtifactAtPath(path, "error.json");
23166
23179
  if (read3 === void 0) continue;
23167
23180
  if (read3.status === "present") {
@@ -23292,15 +23305,15 @@ var init_submission_ledger = __esm({
23292
23305
  // src/session-opening-materials.ts
23293
23306
  import { existsSync as existsSync7 } from "node:fs";
23294
23307
  import { readFile as readFile13 } from "node:fs/promises";
23295
- import { dirname as dirname9, join as join19 } from "node:path";
23308
+ import { dirname as dirname10, join as join19 } from "node:path";
23296
23309
  import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "node:url";
23297
23310
  function resolvePackageRootDir(moduleUrl = import.meta.url) {
23298
- let dir = dirname9(fileURLToPath(moduleUrl));
23311
+ let dir = dirname10(fileURLToPath(moduleUrl));
23299
23312
  for (let i = 0; i < 8; i += 1) {
23300
23313
  if (existsSync7(join19(dir, "package.json")) && existsSync7(join19(dir, "souls"))) {
23301
23314
  return dir;
23302
23315
  }
23303
- const parent = dirname9(dir);
23316
+ const parent = dirname10(dir);
23304
23317
  if (parent === dir) break;
23305
23318
  dir = parent;
23306
23319
  }
@@ -23964,7 +23977,7 @@ var init_terminal = __esm({
23964
23977
  // src/public-cli/settlement.ts
23965
23978
  import { randomUUID as randomUUID3 } from "node:crypto";
23966
23979
  import { appendFile as appendFile2, readFile as readFile15, readdir as readdir5, writeFile as writeFile5 } from "node:fs/promises";
23967
- import { dirname as dirname10, join as join21 } from "node:path";
23980
+ import { dirname as dirname11, join as join21 } from "node:path";
23968
23981
  function sealedLedgerHome(admitted) {
23969
23982
  return homeFromRunDirectory(admitted.runDirectory);
23970
23983
  }
@@ -24358,7 +24371,7 @@ async function readSitianRetainedAuditorProviderStop(sessionFile) {
24358
24371
  kind: "auditor",
24359
24372
  sessionParent: sessionFile,
24360
24373
  // Path is driven by sessionParent when under ledger home; cwd is a fallback only.
24361
- cwd: dirname10(sessionFile)
24374
+ cwd: dirname11(sessionFile)
24362
24375
  });
24363
24376
  const { records: records2 } = await readSitianRecords(recordFile);
24364
24377
  for (let i = records2.length - 1; i >= 0; i -= 1) {
@@ -24384,7 +24397,7 @@ async function readSessionProviderStop(sessionFile) {
24384
24397
  }
24385
24398
  }
24386
24399
  async function readBoundEvidenceChildKnownFailure(sessionFile) {
24387
- const childDirectory = join21(dirname10(sessionFile), "evidence-children");
24400
+ const childDirectory = join21(dirname11(sessionFile), "evidence-children");
24388
24401
  let names;
24389
24402
  try {
24390
24403
  names = await readdir5(childDirectory);
@@ -24449,7 +24462,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
24449
24462
  latestParentUserIndex = i;
24450
24463
  break;
24451
24464
  }
24452
- const childDirectories = [join21(dirname10(sessionFile), "auditor-roles")];
24465
+ const childDirectories = [join21(dirname11(sessionFile), "auditor-roles")];
24453
24466
  const valid = [];
24454
24467
  let sawAnyDirectory = false;
24455
24468
  for (const childDirectory of childDirectories) {
@@ -26023,7 +26036,7 @@ function publicationAttemptFromError(path, error) {
26023
26036
  }
26024
26037
  function uniqueFailureFallbackDirs(runDirectory, baseDir) {
26025
26038
  const dirs = [];
26026
- for (const dir of [baseDir, runDirectory, dirname10(runDirectory)]) {
26039
+ for (const dir of [baseDir, runDirectory, dirname11(runDirectory)]) {
26027
26040
  if (!dirs.includes(dir)) dirs.push(dir);
26028
26041
  }
26029
26042
  return dirs;
@@ -26479,7 +26492,7 @@ var init_case_dossier_delivery = __esm({
26479
26492
 
26480
26493
  // src/host-transition-prior-native.ts
26481
26494
  import { access as access2, readdir as readdir6 } from "node:fs/promises";
26482
- import { dirname as dirname11, join as join23 } from "node:path";
26495
+ import { dirname as dirname12, join as join23 } from "node:path";
26483
26496
  function isEnoent2(error) {
26484
26497
  return typeof error === "object" && error !== null && error.code === "ENOENT";
26485
26498
  }
@@ -26493,7 +26506,7 @@ async function listPiNativeRecordPaths(sessionFile) {
26493
26506
  }
26494
26507
  }
26495
26508
  async function listSitianRecordPaths(sessionParent) {
26496
- const sessionRoot = dirname11(sessionParent);
26509
+ const sessionRoot = dirname12(sessionParent);
26497
26510
  let entries;
26498
26511
  try {
26499
26512
  entries = await readdir6(sessionRoot, { withFileTypes: true });
@@ -29875,9 +29888,9 @@ var init_analyst_book_key = __esm({
29875
29888
  // src/atomic-write.ts
29876
29889
  import { randomUUID as randomUUID6 } from "node:crypto";
29877
29890
  import { rename, rm, writeFile as writeFile8 } from "node:fs/promises";
29878
- import { dirname as dirname12, join as join27 } from "node:path";
29891
+ import { dirname as dirname13, join as join27 } from "node:path";
29879
29892
  async function writeFileAtomically(destination, contents) {
29880
- const parent = dirname12(destination);
29893
+ const parent = dirname13(destination);
29881
29894
  const temporary = join27(parent, `.atomic-write-${randomUUID6()}.tmp`);
29882
29895
  try {
29883
29896
  await writeFile8(temporary, contents);
@@ -29895,7 +29908,7 @@ var init_atomic_write = __esm({
29895
29908
 
29896
29909
  // src/analyst-index.ts
29897
29910
  import { open as open3, readFile as readFile17, unlink as unlink4 } from "node:fs/promises";
29898
- import { dirname as dirname13, join as join28 } from "node:path";
29911
+ import { dirname as dirname14, join as join28 } from "node:path";
29899
29912
  function sleep(ms) {
29900
29913
  return new Promise((resolve11) => {
29901
29914
  setTimeout(resolve11, ms);
@@ -29903,8 +29916,8 @@ function sleep(ms) {
29903
29916
  }
29904
29917
  async function withAnalystLibraryIndexLock(ledgerHome, fn) {
29905
29918
  const indexPath = analystLibraryIndexPath(ledgerHome);
29906
- ensureRealDirectoryTree(ledgerHome, dirname13(indexPath));
29907
- const lockPath = join28(dirname13(indexPath), LIBRARY_INDEX_LOCK_NAME);
29919
+ ensureRealDirectoryTree(ledgerHome, dirname14(indexPath));
29920
+ const lockPath = join28(dirname14(indexPath), LIBRARY_INDEX_LOCK_NAME);
29908
29921
  assertLedgerFileInsideHome(lockPath, ledgerHome);
29909
29922
  const startedAt = Date.now();
29910
29923
  while (true) {
@@ -30040,7 +30053,7 @@ async function readAnalystLibraryIndexPage(ledgerHome) {
30040
30053
  }
30041
30054
  async function writeAnalystLibraryIndexPage(ledgerHome, page) {
30042
30055
  const path = analystLibraryIndexPath(ledgerHome);
30043
- ensureRealDirectoryTree(ledgerHome, dirname13(path));
30056
+ ensureRealDirectoryTree(ledgerHome, dirname14(path));
30044
30057
  assertLedgerFileInsideHome(path, ledgerHome);
30045
30058
  await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
30046
30059
  `);
@@ -31417,7 +31430,7 @@ var init_analyst_metric_family = __esm({
31417
31430
 
31418
31431
  // src/analyst-page.ts
31419
31432
  import { createHash as createHash5 } from "node:crypto";
31420
- import { dirname as dirname14, join as join30 } from "node:path";
31433
+ import { dirname as dirname15, join as join30 } from "node:path";
31421
31434
  function analystIssuePageKey(address) {
31422
31435
  const parts = ["book", address.bookKey];
31423
31436
  if (address.issueNumber !== void 0) {
@@ -31547,7 +31560,7 @@ async function buildAnalystIssueMetricsPage(input) {
31547
31560
  }
31548
31561
  async function writeAnalystIssueMetricsPage(ledgerHome, page) {
31549
31562
  const path = analystIssuePagePath(ledgerHome, analystIssuePageAddressFromPage(page));
31550
- ensureRealDirectoryTree(ledgerHome, dirname14(path));
31563
+ ensureRealDirectoryTree(ledgerHome, dirname15(path));
31551
31564
  assertLedgerFileInsideHome(path, ledgerHome);
31552
31565
  await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
31553
31566
  `);
@@ -32007,23 +32020,15 @@ function resolveRoleTurnHost(env, options) {
32007
32020
  { name: "pi", create: () => ({ ok: true, host: piHost }) },
32008
32021
  ...packagedExternalHostNames().map((name) => ({
32009
32022
  name,
32010
- create: () => {
32011
- let hostPromise;
32012
- return {
32013
- ok: true,
32014
- host: {
32015
- executeTurn: async (request) => {
32016
- hostPromise ??= loadProductionExternalHostFactory(env.packageRoot, name).then(
32017
- (create) => create({
32018
- packageRoot: env.packageRoot,
32019
- principalAuthority: options.principalAuthority
32020
- })
32021
- );
32022
- return (await hostPromise).executeTurn(request);
32023
- }
32024
- }
32025
- };
32026
- }
32023
+ create: () => ({
32024
+ ok: true,
32025
+ // Factory loads outside the public bin static graph (ADR 0052 peer-free discovery).
32026
+ host: createLazyProductionExternalHost({
32027
+ packageRoot: env.packageRoot,
32028
+ hostName: name,
32029
+ principalAuthority: options.principalAuthority
32030
+ })
32031
+ })
32027
32032
  }))
32028
32033
  ];
32029
32034
  const hostName = options.seat.host;
@@ -33065,7 +33070,7 @@ var init_cli = __esm({
33065
33070
 
33066
33071
  // src/public-cli/main.ts
33067
33072
  import { existsSync as existsSync8 } from "node:fs";
33068
- import { dirname as dirname15, join as join32 } from "node:path";
33073
+ import { dirname as dirname16, join as join32 } from "node:path";
33069
33074
  import { fileURLToPath as fileURLToPath2 } from "node:url";
33070
33075
 
33071
33076
  // src/public-cli/host-pi-runtime.ts
@@ -33152,7 +33157,7 @@ function linkPackage(packageRoot2, name, targetDir) {
33152
33157
  }
33153
33158
 
33154
33159
  // src/public-cli/main.ts
33155
- var here = dirname15(fileURLToPath2(import.meta.url));
33160
+ var here = dirname16(fileURLToPath2(import.meta.url));
33156
33161
  function resolvePackageRoot(binDir) {
33157
33162
  const canonical = join32(binDir, "..", "..");
33158
33163
  if (existsSync8(join32(canonical, "package.json"))) {
@@ -100,24 +100,17 @@ async function createSummonEnv(options) {
100
100
  let roleTurnHost = piHost;
101
101
  if (hostName !== "pi") {
102
102
  const { lookupHostFamily } = await import("./host-descriptions.js");
103
- const { loadProductionExternalHostFactory } = await import("./public-cli/load-production-external-host.js");
103
+ const { createLazyProductionExternalHost } = await import("./public-cli/load-production-external-host.js");
104
104
  if (lookupHostFamily(hostName) === void 0) {
105
105
  throw new Error(
106
106
  `public role summons host unregistered: host=${hostName} seat=${options.role}`
107
107
  );
108
108
  }
109
- let hostPromise;
110
- roleTurnHost = {
111
- executeTurn: async (request) => {
112
- hostPromise ??= loadProductionExternalHostFactory(options.packageRoot, hostName).then(
113
- (create) => create({
114
- packageRoot: options.packageRoot,
115
- principalAuthority
116
- })
117
- );
118
- return (await hostPromise).executeTurn(request);
119
- }
120
- };
109
+ roleTurnHost = createLazyProductionExternalHost({
110
+ packageRoot: options.packageRoot,
111
+ hostName,
112
+ principalAuthority
113
+ });
121
114
  }
122
115
  const { loadHostProvidersTable, projectHostFacingProvider } = await import("./public-cli/host-providers.js");
123
116
  const hostFacingSelection = options.seat.selection === void 0 ? void 0 : projectHostFacingProvider(
@@ -151,8 +144,7 @@ async function summonPublicRole(options) {
151
144
  } = await import("./public-cli/config.js");
152
145
  const credentials = options.credentials ?? await loadCredentialProviders(agentDir);
153
146
  const config = await loadPublicCliConfig(home);
154
- const invocation = options.host === void 0 ? void 0 : { host: options.host };
155
- const seat = resolveEffectiveSeat(config, options.role, credentials, invocation);
147
+ const seat = resolveEffectiveSeat(config, options.role, credentials);
156
148
  const env = {
157
149
  ...await createSummonEnv({
158
150
  role: options.role,
@@ -264,38 +256,6 @@ async function summonPublicRole(options) {
264
256
  ...stderr === void 0 || stderr === "" ? {} : { stderr }
265
257
  };
266
258
  }
267
- async function parentInvocationHost(sourceRunDirectory) {
268
- const { readFile } = await import("node:fs/promises");
269
- const path = join(sourceRunDirectory, "invocation.json");
270
- let text;
271
- try {
272
- text = await readFile(path, "utf8");
273
- } catch (error) {
274
- const code = error instanceof Error && "code" in error ? error.code : void 0;
275
- throw new Error(
276
- `parent invocation.json required for gate source run at ${path}: ${code ?? (error instanceof Error ? error.message : String(error))}`,
277
- { cause: error }
278
- );
279
- }
280
- let raw;
281
- try {
282
- raw = JSON.parse(text);
283
- } catch (error) {
284
- throw new Error(
285
- `parent invocation.json unreadable at ${path}: ${error instanceof Error ? error.message : String(error)}`,
286
- { cause: error }
287
- );
288
- }
289
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
290
- throw new Error(`parent invocation.json has non-object shape at ${path}`);
291
- }
292
- const host = raw.host;
293
- if (host === void 0) return void 0;
294
- if (typeof host !== "string" || host.trim() === "") {
295
- throw new Error(`parent invocation.json host must be a non-empty string at ${path}`);
296
- }
297
- return host;
298
- }
299
259
  async function summonGateOfficer(options) {
300
260
  let home = options.home;
301
261
  if (home === void 0) {
@@ -309,7 +269,6 @@ async function summonGateOfficer(options) {
309
269
  submission: options.submission
310
270
  });
311
271
  }
312
- const parentHost = await parentInvocationHost(options.sourceRunDirectory);
313
272
  const common = {
314
273
  cwd: options.cwd,
315
274
  ...home === void 0 ? {} : { home },
@@ -318,7 +277,6 @@ async function summonGateOfficer(options) {
318
277
  ...options.signal === void 0 ? {} : { signal: options.signal },
319
278
  ...options.reask === void 0 ? {} : { reviewReask: options.reask },
320
279
  ...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction },
321
- ...parentHost === void 0 ? {} : { host: parentHost },
322
280
  ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
323
281
  ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
324
282
  };