@akagilnc/pi-workflow-roles 0.1.5365 → 0.1.5368

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.
@@ -3000,6 +3000,7 @@ __export(config_exports, {
3000
3000
  providerConfigured: () => providerConfigured,
3001
3001
  publicCliConfigPath: () => publicCliConfigPath,
3002
3002
  resolveEffectiveSeat: () => resolveEffectiveSeat,
3003
+ resolvePublicAgentDir: () => resolvePublicAgentDir,
3003
3004
  resolvedSeatWithModel: () => resolvedSeatWithModel,
3004
3005
  savePublicCliConfig: () => savePublicCliConfig,
3005
3006
  setAutoResumeLimit: () => setAutoResumeLimit,
@@ -3479,6 +3480,9 @@ function credentialProvidersFromAuthData(data) {
3479
3480
  xai: Object.prototype.hasOwnProperty.call(record4, "xai")
3480
3481
  };
3481
3482
  }
3483
+ function resolvePublicAgentDir(explicit, home) {
3484
+ return explicit ?? process.env.PI_CODING_AGENT_DIR ?? join6(home, ".pi", "agent");
3485
+ }
3482
3486
  async function loadCredentialProviders(agentDir) {
3483
3487
  try {
3484
3488
  const raw = await readFile4(join6(agentDir, "auth.json"), "utf8");
@@ -3639,6 +3643,9 @@ function roleRunPlacement(ledgerHome, input) {
3639
3643
  function roleRunArtifactsDirectory(runDirectory) {
3640
3644
  return join9(runDirectory, "artifacts");
3641
3645
  }
3646
+ function isUnboundRunDirectory(runDirectory) {
3647
+ return runDirectory.replaceAll("\\", "/").includes("/unbound/runs/");
3648
+ }
3642
3649
  function ensureRoleRunDirectory(ledgerHome, directory) {
3643
3650
  return ensureRealDirectoryTree(ledgerHome, directory);
3644
3651
  }
@@ -4979,6 +4986,170 @@ var init_role_turn_host = __esm({
4979
4986
  }
4980
4987
  });
4981
4988
 
4989
+ // src/public-cli/host-providers.ts
4990
+ import { readFileSync } from "node:fs";
4991
+ import { join as join16 } from "node:path";
4992
+ function hostProvidersPath(home) {
4993
+ if (typeof home !== "string" || home.trim() === "") {
4994
+ throw new Error("home must be explicitly provided");
4995
+ }
4996
+ return join16(home, ".ak-roles", "host-providers.json");
4997
+ }
4998
+ function hermesProviderModelsCachePath(home) {
4999
+ return join16(home, ".hermes", "provider_models_cache.json");
5000
+ }
5001
+ function parseHostProvidersTable(value) {
5002
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
5003
+ throw new Error("host-providers.json must be an object");
5004
+ }
5005
+ const out = {};
5006
+ for (const [host, byProvider] of Object.entries(value)) {
5007
+ if (host.trim() === "") {
5008
+ throw new Error("host-providers.json host key must be non-empty");
5009
+ }
5010
+ if (byProvider === null || typeof byProvider !== "object" || Array.isArray(byProvider)) {
5011
+ throw new Error(`host-providers.json[${host}] must be an object`);
5012
+ }
5013
+ const providers = {};
5014
+ for (const [seatProvider, hostProvider] of Object.entries(
5015
+ byProvider
5016
+ )) {
5017
+ if (seatProvider.trim() === "") {
5018
+ throw new Error(
5019
+ `host-providers.json[${host}] seat-provider key must be non-empty`
5020
+ );
5021
+ }
5022
+ if (typeof hostProvider !== "string" || hostProvider.trim() === "") {
5023
+ throw new Error(
5024
+ `host-providers.json[${host}][${seatProvider}] must be a non-empty string`
5025
+ );
5026
+ }
5027
+ providers[seatProvider] = hostProvider;
5028
+ }
5029
+ if (Object.keys(providers).length > 0) {
5030
+ out[host] = providers;
5031
+ }
5032
+ }
5033
+ return out;
5034
+ }
5035
+ function loadHostProvidersTable(home) {
5036
+ const path = hostProvidersPath(home);
5037
+ try {
5038
+ const raw = readFileSync(path, "utf8");
5039
+ return parseHostProvidersTable(JSON.parse(raw));
5040
+ } catch (error) {
5041
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
5042
+ return {};
5043
+ }
5044
+ throw error;
5045
+ }
5046
+ }
5047
+ function hostCatalogOffersModel(catalogModels, seatModel) {
5048
+ return catalogModels.some(
5049
+ (entry) => entry === seatModel || entry.endsWith(`/${seatModel}`)
5050
+ );
5051
+ }
5052
+ function listHermesProvidersForModel(home, seatModel) {
5053
+ const path = hermesProviderModelsCachePath(home);
5054
+ let text;
5055
+ try {
5056
+ text = readFileSync(path, "utf8");
5057
+ } catch (error) {
5058
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
5059
+ return [];
5060
+ }
5061
+ throw error;
5062
+ }
5063
+ const raw = JSON.parse(text);
5064
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
5065
+ throw new Error(
5066
+ `hermes provider_models_cache.json must be an object: ${path}`
5067
+ );
5068
+ }
5069
+ const found = [];
5070
+ for (const [provider, entry] of Object.entries(raw)) {
5071
+ if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
5072
+ continue;
5073
+ }
5074
+ const models = entry.models;
5075
+ if (!Array.isArray(models)) continue;
5076
+ const names = models.filter((m) => typeof m === "string");
5077
+ if (hostCatalogOffersModel(names, seatModel)) {
5078
+ found.push(provider);
5079
+ }
5080
+ }
5081
+ return found.sort();
5082
+ }
5083
+ function listDirectoryProvidersForModel(home, host, seatModel) {
5084
+ if (host === "hermes") {
5085
+ return listHermesProvidersForModel(home, seatModel);
5086
+ }
5087
+ return void 0;
5088
+ }
5089
+ function projectHostFacingProvider(selection, host, table, home) {
5090
+ if (selection === void 0) return void 0;
5091
+ const mapped = table[host]?.[selection.provider];
5092
+ if (mapped !== void 0) {
5093
+ return mapped === selection.provider ? selection : { ...selection, provider: mapped };
5094
+ }
5095
+ const directory = listDirectoryProvidersForModel(home, host, selection.model);
5096
+ if (directory === void 0) {
5097
+ return selection;
5098
+ }
5099
+ if (directory.length === 1) {
5100
+ const only = directory[0];
5101
+ return only === selection.provider ? selection : { ...selection, provider: only };
5102
+ }
5103
+ if (directory.length === 0) {
5104
+ throw new HostProviderResolutionError({
5105
+ message: `host ${host} has no provider offering model ${selection.model}; seat provider was ${selection.provider}`,
5106
+ host,
5107
+ seatProvider: selection.provider,
5108
+ seatModel: selection.model
5109
+ });
5110
+ }
5111
+ throw new HostProviderResolutionError({
5112
+ message: `host ${host} has multiple providers for model ${selection.model}: ${directory.join(", ")}; set host-providers.json[${host}][${selection.provider}] to one of them`,
5113
+ host,
5114
+ seatProvider: selection.provider,
5115
+ seatModel: selection.model,
5116
+ candidates: directory
5117
+ });
5118
+ }
5119
+ function renderHostProvidersTable(table) {
5120
+ const lines = [];
5121
+ for (const host of Object.keys(table).sort()) {
5122
+ const byProvider = table[host];
5123
+ for (const seatProvider of Object.keys(byProvider).sort()) {
5124
+ lines.push(
5125
+ `hostProvider ${host} ${seatProvider} ${byProvider[seatProvider]}`
5126
+ );
5127
+ }
5128
+ }
5129
+ return lines.length === 0 ? "" : `${lines.join("\n")}
5130
+ `;
5131
+ }
5132
+ var HostProviderResolutionError;
5133
+ var init_host_providers = __esm({
5134
+ "src/public-cli/host-providers.ts"() {
5135
+ "use strict";
5136
+ HostProviderResolutionError = class extends Error {
5137
+ host;
5138
+ seatProvider;
5139
+ seatModel;
5140
+ candidates;
5141
+ constructor(options) {
5142
+ super(options.message);
5143
+ this.name = "HostProviderResolutionError";
5144
+ this.host = options.host;
5145
+ this.seatProvider = options.seatProvider;
5146
+ this.seatModel = options.seatModel;
5147
+ this.candidates = options.candidates ?? [];
5148
+ }
5149
+ };
5150
+ }
5151
+ });
5152
+
4982
5153
  // src/public-cli/github-remote.ts
4983
5154
  function ownerRepoFromGitHubRemoteUrl(remoteUrl) {
4984
5155
  const trimmed = remoteUrl.trim();
@@ -5442,13 +5613,13 @@ var init_session_dialogue = __esm({
5442
5613
 
5443
5614
  // src/ticket-provenance.ts
5444
5615
  import { readFile as readFile12, unlink as unlink2 } from "node:fs/promises";
5445
- import { basename as basename5, dirname as dirname11, join as join16, resolve as resolve9 } from "node:path";
5616
+ import { basename as basename5, dirname as dirname11, join as join17, resolve as resolve9 } from "node:path";
5446
5617
  function dialogueSessionSourceRoots(home) {
5447
5618
  const machineHome = typeof home === "string" && home.trim() !== "" ? home : packageMachineHome();
5448
5619
  return [
5449
- join16(machineHome, ".claude", "projects"),
5450
- join16(machineHome, ".codex", "sessions"),
5451
- join16(machineHome, ".pi", "agent", "sessions")
5620
+ join17(machineHome, ".claude", "projects"),
5621
+ join17(machineHome, ".codex", "sessions"),
5622
+ join17(machineHome, ".pi", "agent", "sessions")
5452
5623
  ];
5453
5624
  }
5454
5625
  function isLedgerRoleSessionFile(absolute, home) {
@@ -5486,7 +5657,7 @@ function ticketProvenanceRecordInput(ticketNumber, cwd, home, runDirectory) {
5486
5657
  };
5487
5658
  }
5488
5659
  async function rehomeUnboundTicketProvenance(runDirectory, ticketNumber, cwd, home) {
5489
- const source = join16(runDirectory, "records.jsonl");
5660
+ const source = join17(runDirectory, "records.jsonl");
5490
5661
  let content;
5491
5662
  try {
5492
5663
  content = await readFile12(source, "utf8");
@@ -5671,7 +5842,7 @@ var init_ticket_provenance = __esm({
5671
5842
  });
5672
5843
 
5673
5844
  // src/notary-source-run.ts
5674
- import { dirname as dirname12, isAbsolute as isAbsolute5, join as join17, resolve as resolve10, basename as basename6 } from "node:path";
5845
+ import { dirname as dirname12, isAbsolute as isAbsolute5, join as join18, resolve as resolve10, basename as basename6 } from "node:path";
5675
5846
  import { lstat, realpath as realpath3 } from "node:fs/promises";
5676
5847
  async function readRetainedIdentity(runDirectory) {
5677
5848
  try {
@@ -5728,11 +5899,11 @@ async function resolveNotarySourceRunLocator(options) {
5728
5899
  const ledgerHome = resolveActivationLedgerHome(options.home);
5729
5900
  const bookKey = resolveBookKeyFromGit(options.projectRoot);
5730
5901
  const bookDirectory = activationBookDirectory(ledgerHome, bookKey);
5731
- const bookRunsRoot = join17(bookDirectory, "runs");
5902
+ const bookRunsRoot = join18(bookDirectory, "runs");
5732
5903
  let candidate;
5733
5904
  const bare = parseRunDirectoryName(raw);
5734
5905
  if (bare !== void 0 && !raw.includes("/") && !raw.includes("\\")) {
5735
- candidate = await findRunDirectoryById(options.home, bare.runId, bookKey, bare.role) ?? join17(bookRunsRoot, `${bare.runId}@${bare.role}`);
5906
+ candidate = await findRunDirectoryById(options.home, bare.runId, bookKey, bare.role) ?? join18(bookRunsRoot, `${bare.runId}@${bare.role}`);
5736
5907
  } else {
5737
5908
  candidate = isAbsolute5(raw) ? raw : resolve10(options.projectRoot, raw);
5738
5909
  const identity2 = parseRunDirectoryName(basename6(candidate));
@@ -6873,7 +7044,7 @@ import {
6873
7044
  writeFile as writeFile4
6874
7045
  } from "node:fs/promises";
6875
7046
  import { tmpdir } from "node:os";
6876
- import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute6, join as join18, resolve as resolve11, sep as sep3 } from "node:path";
7047
+ import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute6, join as join19, resolve as resolve11, sep as sep3 } from "node:path";
6877
7048
  function issueAdmissionPlacement(authority, request) {
6878
7049
  const ledgerHome = resolveActivationLedgerHome(request.home);
6879
7050
  const bookKey = resolveBookKeyFromGit(request.cwd);
@@ -6927,81 +7098,71 @@ async function writeRoleInvocationLedger(source, role, effectiveModel) {
6927
7098
  ...effectiveModelLedgerFields(effectiveModel)
6928
7099
  };
6929
7100
  await writeFile4(
6930
- join18(source.runDirectory, "invocation.json"),
7101
+ join19(source.runDirectory, "invocation.json"),
6931
7102
  `${JSON.stringify(identity, null, 2)}
6932
7103
  `,
6933
7104
  "utf8"
6934
7105
  );
6935
7106
  }
6936
7107
  async function recordEffectiveInvocationModel(runDirectory, model, engine, host, engineModel) {
6937
- const ledgerPath = join18(runDirectory, "invocation.json");
6938
- const current = JSON.parse(await readFile13(ledgerPath, "utf8"));
6939
- const next = { ...current };
6940
- if (model !== void 0) {
6941
- next.provider = model.provider;
6942
- next.model = model.model;
6943
- if (model.thinking === void 0) {
6944
- delete next.thinking;
6945
- } else {
6946
- next.thinking = model.thinking;
7108
+ await updateDurableJsonPage(join19(runDirectory, "invocation.json"), (current) => {
7109
+ const next = { ...current };
7110
+ if (model !== void 0) {
7111
+ next.provider = model.provider;
7112
+ next.model = model.model;
7113
+ if (model.thinking === void 0) {
7114
+ delete next.thinking;
7115
+ } else {
7116
+ next.thinking = model.thinking;
7117
+ }
6947
7118
  }
6948
- }
6949
- if (engine === null) {
6950
- delete next.engine;
6951
- } else if (engine !== void 0) {
6952
- next.engine = engine;
6953
- }
6954
- if (engineModel === null) {
6955
- delete next.engineModel;
6956
- } else if (engineModel !== void 0) {
6957
- next.engineModel = engineModel;
6958
- }
6959
- if (host !== void 0) {
6960
- next.host = host;
6961
- }
6962
- await writeFile4(
6963
- ledgerPath,
6964
- `${JSON.stringify(next, null, 2)}
6965
- `,
6966
- "utf8"
6967
- );
7119
+ if (engine === null) {
7120
+ delete next.engine;
7121
+ } else if (engine !== void 0) {
7122
+ next.engine = engine;
7123
+ }
7124
+ if (engineModel === null) {
7125
+ delete next.engineModel;
7126
+ } else if (engineModel !== void 0) {
7127
+ next.engineModel = engineModel;
7128
+ }
7129
+ if (host !== void 0) {
7130
+ next.host = host;
7131
+ }
7132
+ return next;
7133
+ });
7134
+ }
7135
+ async function updateDurableJsonPage(path, update) {
7136
+ const current = JSON.parse(await readFile13(path, "utf8"));
7137
+ const next = update(current);
7138
+ if (next === void 0) return;
7139
+ await writeFile4(path, `${JSON.stringify(next, null, 2)}
7140
+ `, "utf8");
6968
7141
  }
6969
7142
  async function mergeInvocationIdentityPage(runDirectory, fields) {
6970
- const ledgerPath = join18(runDirectory, "invocation.json");
6971
- const current = JSON.parse(await readFile13(ledgerPath, "utf8"));
6972
- await writeFile4(
6973
- ledgerPath,
6974
- `${JSON.stringify({
6975
- ...current,
6976
- ...fields
6977
- }, null, 2)}
6978
- `,
6979
- "utf8"
6980
- );
7143
+ await updateDurableJsonPage(join19(runDirectory, "invocation.json"), (current) => ({
7144
+ ...current,
7145
+ ...fields
7146
+ }));
6981
7147
  }
6982
7148
  async function persistAdmittedSourceRunPath(admitted, sourceRunPath, auditorSubject) {
6983
7149
  if (sourceRunPath.trim() === "") {
6984
7150
  throw new Error("persistAdmittedSourceRunPath requires a non-empty sourceRunPath");
6985
7151
  }
6986
- const admittedPath = admitted.admittedRequestPath;
6987
- const current = JSON.parse(await readFile13(admittedPath, "utf8"));
6988
- if (typeof current.sourceRunPath === "string" && current.sourceRunPath !== sourceRunPath) {
6989
- throw new Error(
6990
- `persistAdmittedSourceRunPath refuses to replace ${current.sourceRunPath} with ${sourceRunPath}`
6991
- );
6992
- }
6993
- const sameSubject = auditorSubject === void 0 || current.auditorSubject === auditorSubject;
6994
- if (current.sourceRunPath === sourceRunPath && sameSubject) return;
6995
- await writeFile4(
6996
- admittedPath,
6997
- `${JSON.stringify({
7152
+ await updateDurableJsonPage(admitted.admittedRequestPath, (current) => {
7153
+ if (typeof current.sourceRunPath === "string" && current.sourceRunPath !== sourceRunPath) {
7154
+ throw new Error(
7155
+ `persistAdmittedSourceRunPath refuses to replace ${current.sourceRunPath} with ${sourceRunPath}`
7156
+ );
7157
+ }
7158
+ const sameSubject = auditorSubject === void 0 || current.auditorSubject === auditorSubject;
7159
+ if (current.sourceRunPath === sourceRunPath && sameSubject) return void 0;
7160
+ return {
6998
7161
  ...current,
6999
7162
  sourceRunPath,
7000
7163
  ...auditorSubject === void 0 ? {} : { auditorSubject }
7001
- }, null, 2)}
7002
- `,
7003
- "utf8"
7004
- );
7164
+ };
7165
+ });
7005
7166
  }
7006
7167
  async function bindAdmittedTicketNumber(admitted, ticketNumber) {
7007
7168
  if (admitted.ticketNumber === ticketNumber) return;
@@ -7009,22 +7170,17 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
7009
7170
  admitted.ticketNumber = ticketNumber;
7010
7171
  }
7011
7172
  async function recordAdmittedCorrelation(admitted, correlationId) {
7012
- const current = JSON.parse(
7013
- await readFile13(admitted.admittedRequestPath, "utf8")
7014
- );
7015
- const prior = [
7016
- ...Array.isArray(current.correlationIds) ? current.correlationIds.filter(
7017
- (value) => typeof value === "string" && value.trim() !== ""
7018
- ) : [],
7019
- ...typeof current.correlationId === "string" && current.correlationId.trim() !== "" ? [current.correlationId] : []
7020
- ];
7021
- const correlationIds = [.../* @__PURE__ */ new Set([...prior, correlationId])];
7022
- await writeFile4(
7023
- admitted.admittedRequestPath,
7024
- `${JSON.stringify({ ...current, correlationId, correlationIds }, null, 2)}
7025
- `,
7026
- "utf8"
7027
- );
7173
+ let correlationIds = [];
7174
+ await updateDurableJsonPage(admitted.admittedRequestPath, (current) => {
7175
+ const prior = [
7176
+ ...Array.isArray(current.correlationIds) ? current.correlationIds.filter(
7177
+ (value) => typeof value === "string" && value.trim() !== ""
7178
+ ) : [],
7179
+ ...typeof current.correlationId === "string" && current.correlationId.trim() !== "" ? [current.correlationId] : []
7180
+ ];
7181
+ correlationIds = [.../* @__PURE__ */ new Set([...prior, correlationId])];
7182
+ return { ...current, correlationId, correlationIds };
7183
+ });
7028
7184
  await mergeInvocationIdentityPage(admitted.runDirectory, {
7029
7185
  correlationId,
7030
7186
  correlationIds
@@ -7034,7 +7190,7 @@ async function recordAdmittedCorrelation(admitted, correlationId) {
7034
7190
  mutable.correlationIds = correlationIds;
7035
7191
  }
7036
7192
  async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
7037
- if (admitted.ticketNumber === void 0 || !admitted.runDirectory.includes(`${sep3}unbound${sep3}runs${sep3}`)) return void 0;
7193
+ if (admitted.ticketNumber === void 0 || !isUnboundRunDirectory(admitted.runDirectory)) return void 0;
7038
7194
  const oldRunDirectory = admitted.runDirectory;
7039
7195
  const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(oldRunDirectory));
7040
7196
  const target = roleRunPlacement(ledgerHome, {
@@ -7050,7 +7206,7 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
7050
7206
  const childRunIds = parentPage.childDiaristRunIds;
7051
7207
  for (const childRunId of Array.isArray(childRunIds) ? childRunIds : []) {
7052
7208
  if (typeof childRunId !== "string") continue;
7053
- const childDirectory = join18(dirname13(oldRunDirectory), `${childRunId}@diarist`);
7209
+ const childDirectory = join19(dirname13(oldRunDirectory), `${childRunId}@diarist`);
7054
7210
  if (!existsSync4(childDirectory)) continue;
7055
7211
  const childTarget = roleRunPlacement(ledgerHome, {
7056
7212
  bookKey: admitted.bookKey,
@@ -7096,26 +7252,27 @@ async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
7096
7252
  return { oldRunDirectory, newRunDirectory: target.runDirectory };
7097
7253
  }
7098
7254
  async function recordChildDiaristRun(parent, childRunId) {
7099
- const page = JSON.parse(await readFile13(parent.admittedRequestPath, "utf8"));
7100
- const existing = Array.isArray(page.childDiaristRunIds) ? page.childDiaristRunIds.filter((runId) => typeof runId === "string") : [];
7101
- const childDiaristRunIds = existing.includes(childRunId) ? existing : [...existing, childRunId];
7102
- await writeFile4(parent.admittedRequestPath, `${JSON.stringify({ ...page, childDiaristRunIds }, null, 2)}
7103
- `, "utf8");
7255
+ await updateDurableJsonPage(parent.admittedRequestPath, (page) => {
7256
+ const existing = Array.isArray(page.childDiaristRunIds) ? page.childDiaristRunIds.filter((runId) => typeof runId === "string") : [];
7257
+ const childDiaristRunIds = existing.includes(childRunId) ? existing : [...existing, childRunId];
7258
+ return { ...page, childDiaristRunIds };
7259
+ });
7104
7260
  }
7105
7261
  async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
7106
7262
  requireSafePositiveTicketNumber(
7107
7263
  ticketNumber,
7108
7264
  "bindTicketNumberOnRunDirectory"
7109
7265
  );
7110
- const admittedPath = join18(runDirectory, "admitted-request.json");
7111
- const admitted = JSON.parse(await readFile13(admittedPath, "utf8"));
7112
- if (admitted.ticketNumber === ticketNumber) return;
7113
- await writeFile4(
7114
- admittedPath,
7115
- `${JSON.stringify({ ...admitted, ticketNumber }, null, 2)}
7116
- `,
7117
- "utf8"
7118
- );
7266
+ const admittedPath = join19(runDirectory, "admitted-request.json");
7267
+ let unchanged = false;
7268
+ await updateDurableJsonPage(admittedPath, (admitted) => {
7269
+ if (admitted.ticketNumber === ticketNumber) {
7270
+ unchanged = true;
7271
+ return void 0;
7272
+ }
7273
+ return { ...admitted, ticketNumber };
7274
+ });
7275
+ if (unchanged) return;
7119
7276
  await mergeInvocationIdentityPage(runDirectory, { ticketNumber });
7120
7277
  }
7121
7278
  async function recordLaunchedPiIdentity(runDirectory, identity) {
@@ -7127,7 +7284,7 @@ async function recordLaunchedPiIdentity(runDirectory, identity) {
7127
7284
  async function observeLaunchedRolePackageIdentity(packageRoot, selectedRoleEntry) {
7128
7285
  const rolePackageRoot = packageRoot;
7129
7286
  const raw = JSON.parse(
7130
- await readFile13(join18(rolePackageRoot, "package.json"), "utf8")
7287
+ await readFile13(join19(rolePackageRoot, "package.json"), "utf8")
7131
7288
  );
7132
7289
  if (typeof raw.version !== "string" || raw.version.trim() === "") {
7133
7290
  throw new Error(
@@ -7337,18 +7494,22 @@ function requireOptionPath(flag, value) {
7337
7494
  }
7338
7495
  return value;
7339
7496
  }
7497
+ function skillArgTokenFault(value) {
7498
+ if (value === void 0 || value.trim() === "") return "empty";
7499
+ if (/\s/.test(value)) return "whitespace";
7500
+ if (value.startsWith("-")) return "optionLike";
7501
+ return void 0;
7502
+ }
7340
7503
  function requireSkillArgToken(value, messages) {
7341
- if (value === void 0 || value.trim() === "") {
7342
- throw new CliUsageError(messages.empty);
7343
- }
7344
- if (/\s/.test(value)) {
7345
- throw new CliUsageError(messages.whitespace);
7346
- }
7347
- if (value.startsWith("-")) {
7348
- throw new CliUsageError(messages.optionLike);
7349
- }
7504
+ const fault = skillArgTokenFault(value);
7505
+ if (fault !== void 0) throw new CliUsageError(messages[fault]);
7350
7506
  return value;
7351
7507
  }
7508
+ function admittedReviewerBaseFault(value) {
7509
+ const fault = skillArgTokenFault(value);
7510
+ if (fault === void 0) return void 0;
7511
+ return fault === "empty" ? "missing" : "damaged";
7512
+ }
7352
7513
  function requireReviewerBaseRevision(value) {
7353
7514
  return requireSkillArgToken(value, {
7354
7515
  empty: "--base requires a nonempty revision",
@@ -7415,13 +7576,13 @@ async function removePreparedAttachmentDirectory(stagingDirectory) {
7415
7576
  }
7416
7577
  async function withPreparedAttachments(attachmentPaths, use) {
7417
7578
  if (attachmentPaths.length === 0) return await use([]);
7418
- const stagingDirectory = await mkdtemp(join18(tmpdir(), "ak-role-attachments-"));
7579
+ const stagingDirectory = await mkdtemp(join19(tmpdir(), "ak-role-attachments-"));
7419
7580
  const prepared = [];
7420
7581
  let result;
7421
7582
  try {
7422
7583
  for (let index = 0; index < attachmentPaths.length; index += 1) {
7423
7584
  const { absolute, bytes } = await readRegularFileAttachment(attachmentPaths[index]);
7424
- const snapshotPath = join18(stagingDirectory, String(index).padStart(6, "0"));
7585
+ const snapshotPath = join19(stagingDirectory, String(index).padStart(6, "0"));
7425
7586
  await writeFile4(snapshotPath, bytes);
7426
7587
  prepared.push({ absolute, snapshotPath });
7427
7588
  }
@@ -7442,7 +7603,7 @@ async function withPreparedAttachments(attachmentPaths, use) {
7442
7603
  return result;
7443
7604
  }
7444
7605
  async function freezeAttachmentBytes(provenancePath, bytes, destinationDir, index) {
7445
- const frozenPath = join18(
7606
+ const frozenPath = join19(
7446
7607
  destinationDir,
7447
7608
  `${String(index).padStart(2, "0")}-${basename7(provenancePath)}`
7448
7609
  );
@@ -7485,14 +7646,14 @@ async function freezeAttachments(attachmentPaths, attachmentsDirectory) {
7485
7646
  async function freezeAttachmentsIntoRun(attachmentPaths, runDirectory, summonsKey = `s-${Date.now().toString(36)}`) {
7486
7647
  if (attachmentPaths.length === 0) return [];
7487
7648
  const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(runDirectory));
7488
- const attachmentsDirectory = join18(runDirectory, "attachments", summonsKey);
7649
+ const attachmentsDirectory = join19(runDirectory, "attachments", summonsKey);
7489
7650
  ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
7490
7651
  return freezeAttachments(attachmentPaths, attachmentsDirectory);
7491
7652
  }
7492
7653
  async function freezePreparedAttachmentsIntoRun(prepared, runDirectory, summonsKey) {
7493
7654
  if (prepared.length === 0) return [];
7494
7655
  const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(runDirectory));
7495
- const attachmentsDirectory = summonsKey === void 0 ? join18(runDirectory, "attachments") : join18(runDirectory, "attachments", summonsKey);
7656
+ const attachmentsDirectory = summonsKey === void 0 ? join19(runDirectory, "attachments") : join19(runDirectory, "attachments", summonsKey);
7496
7657
  ensureRealDirectoryTree(ledgerHome, attachmentsDirectory);
7497
7658
  const attachments = [];
7498
7659
  for (let index = 0; index < prepared.length; index += 1) {
@@ -7569,16 +7730,13 @@ async function admitPublicRole(role, parsed, env, override) {
7569
7730
  attachmentPaths,
7570
7731
  ...project,
7571
7732
  placedFields: async (placed) => {
7572
- const taskPath = join18(placed.runDirectory, "task.md");
7733
+ const taskPath = join19(placed.runDirectory, "task.md");
7573
7734
  await writeFile4(taskPath, instruction, "utf8");
7574
7735
  return { phase, taskPath };
7575
7736
  }
7576
7737
  });
7577
7738
  }
7578
7739
  case "worker-packet": {
7579
- if (parsed.project !== void 0) {
7580
- requireOptionPath("--project", parsed.project);
7581
- }
7582
7740
  if (instruction.trim() === "") {
7583
7741
  throw new CliUsageError("fixer requires a nonblank repair instruction");
7584
7742
  }
@@ -7615,7 +7773,7 @@ async function admitPublicRole(role, parsed, env, override) {
7615
7773
  placedFields: async (placed) => {
7616
7774
  let prerequisitesPath;
7617
7775
  if (prerequisitesSource !== void 0) {
7618
- prerequisitesPath = join18(placed.runDirectory, "prerequisites.json");
7776
+ prerequisitesPath = join19(placed.runDirectory, "prerequisites.json");
7619
7777
  await writeFile4(
7620
7778
  prerequisitesPath,
7621
7779
  `${JSON.stringify(prerequisites, null, 2)}
@@ -7623,7 +7781,7 @@ async function admitPublicRole(role, parsed, env, override) {
7623
7781
  "utf8"
7624
7782
  );
7625
7783
  }
7626
- const packetPath = join18(placed.runDirectory, "fix-packet.md");
7784
+ const packetPath = join19(placed.runDirectory, "fix-packet.md");
7627
7785
  await writeFile4(packetPath, instruction, "utf8");
7628
7786
  return {
7629
7787
  phase,
@@ -7635,18 +7793,7 @@ async function admitPublicRole(role, parsed, env, override) {
7635
7793
  });
7636
7794
  }
7637
7795
  case "collect-target": {
7638
- if (parsed.project !== void 0) {
7639
- requireOptionPath("--project", parsed.project);
7640
- }
7641
- let explicitPrNumber;
7642
- if (parsed.prNumber !== void 0) {
7643
- try {
7644
- explicitPrNumber = parseCollectorPrNumber(parsed.prNumber);
7645
- } catch (error) {
7646
- const detail = error instanceof Error ? error.message : String(error);
7647
- throw new CliUsageError(detail, { cause: error });
7648
- }
7649
- }
7796
+ const explicitPrNumber = parsed.prNumber;
7650
7797
  const projectRoot = resolve11(parsed.project ?? shared.cwd);
7651
7798
  let repository;
7652
7799
  if (parsed.repo !== void 0) {
@@ -7681,7 +7828,7 @@ async function admitPublicRole(role, parsed, env, override) {
7681
7828
  placedFields: async (placed) => {
7682
7829
  let requestManifestPath;
7683
7830
  if (manifestCanonicalJson !== void 0) {
7684
- requestManifestPath = join18(placed.runDirectory, "request-manifest.json");
7831
+ requestManifestPath = join19(placed.runDirectory, "request-manifest.json");
7685
7832
  await writeFile4(requestManifestPath, manifestCanonicalJson, "utf8");
7686
7833
  }
7687
7834
  return {
@@ -7696,15 +7843,12 @@ async function admitPublicRole(role, parsed, env, override) {
7696
7843
  return { ...admittedCollector, repository };
7697
7844
  }
7698
7845
  case "case-identity": {
7699
- if (parsed.project !== void 0) {
7700
- requireOptionPath("--project", parsed.project);
7701
- }
7702
- const issueNumber = parsed.issueNumber ?? Number.NaN;
7703
- if (!Number.isInteger(issueNumber) || issueNumber < 1 || !DOCTOR_ISSUE_NUMBER_PATTERN.test(String(issueNumber))) {
7846
+ if (parsed.issueNumber === void 0) {
7704
7847
  throw new CliUsageError(
7705
- `doctor --issue must be a positive integer, got ${issueNumber}`
7848
+ `doctor --issue must be a positive integer, got ${Number.NaN}`
7706
7849
  );
7707
7850
  }
7851
+ const issueNumber = parsed.issueNumber;
7708
7852
  let frozenAttachments = [];
7709
7853
  const admittedDoctor = await admitStandardMaterialInvocation("doctor", {
7710
7854
  ...shared,
@@ -7760,22 +7904,21 @@ async function admitPublicRole(role, parsed, env, override) {
7760
7904
  return { ...admittedDoctor, attachments: frozenAttachments };
7761
7905
  }
7762
7906
  case "source-locator": {
7763
- if (parsed.project !== void 0) {
7764
- requireOptionPath("--project", parsed.project);
7765
- }
7766
7907
  const projectRoot = resolve11(parsed.project ?? shared.cwd);
7767
- let sourceRun;
7768
- try {
7769
- sourceRun = await resolveNotarySourceRunLocator({
7770
- projectRoot,
7771
- sourceRun: parsed.sourceRun ?? "",
7772
- home: shared.home
7773
- });
7774
- } catch (error) {
7775
- if (error instanceof NotarySourceRunError) {
7776
- throw new CliUsageError(error.message, { cause: error });
7908
+ let sourceRun = override?.resolvedSourceRun;
7909
+ if (sourceRun === void 0) {
7910
+ try {
7911
+ sourceRun = await resolveNotarySourceRunLocator({
7912
+ projectRoot,
7913
+ sourceRun: parsed.sourceRun ?? "",
7914
+ home: shared.home
7915
+ });
7916
+ } catch (error) {
7917
+ if (error instanceof NotarySourceRunError) {
7918
+ throw new CliUsageError(error.message, { cause: error });
7919
+ }
7920
+ throw error;
7777
7921
  }
7778
- throw error;
7779
7922
  }
7780
7923
  const inheritedTicketNumber = await readBoardTicketNumber(sourceRun.runDirectory);
7781
7924
  const knownTicketNumber = inheritedTicketNumber ?? shared.assertedTicketNumber;
@@ -7793,9 +7936,6 @@ async function admitPublicRole(role, parsed, env, override) {
7793
7936
  });
7794
7937
  }
7795
7938
  case "gleaner": {
7796
- if (parsed.project !== void 0) {
7797
- requireOptionPath("--project", parsed.project);
7798
- }
7799
7939
  const baseRevision = parsed.baseRevision ?? "";
7800
7940
  if (baseRevision.trim() === "") {
7801
7941
  throw new CliUsageError("--base requires a nonempty revision");
@@ -7810,16 +7950,19 @@ async function admitPublicRole(role, parsed, env, override) {
7810
7950
  });
7811
7951
  }
7812
7952
  case "review-basis": {
7813
- const lens = requireReviewerLens(parsed.lens);
7814
- if (parsed.project !== void 0) {
7815
- requireOptionPath("--project", parsed.project);
7953
+ if (parsed.lens === void 0) {
7954
+ throw new CliUsageError("--lens requires completeness or correctness");
7955
+ }
7956
+ if (parsed.baseRevision === void 0) {
7957
+ throw new CliUsageError("--base requires a nonempty revision");
7816
7958
  }
7817
- const baseRevision = requireReviewerBaseRevision(parsed.baseRevision);
7818
7959
  const rawRefs = parsed.authorityRefs ?? [];
7819
7960
  if (rawRefs.length === 0) {
7820
7961
  throw new CliUsageError("reviewer requires --authority-ref <ref>");
7821
7962
  }
7822
- const authorityRefs = Object.freeze(rawRefs.map((ref) => requireAuthorityRef(ref)));
7963
+ const lens = parsed.lens;
7964
+ const baseRevision = parsed.baseRevision;
7965
+ const authorityRefs = Object.freeze([...rawRefs]);
7823
7966
  const admittedReviewer = await admitStandardMaterialInvocation("reviewer", {
7824
7967
  ...shared,
7825
7968
  instruction,
@@ -7834,9 +7977,6 @@ async function admitPublicRole(role, parsed, env, override) {
7834
7977
  return { ...admittedReviewer, authorityRefs };
7835
7978
  }
7836
7979
  case "merge-envelope": {
7837
- if (parsed.project !== void 0) {
7838
- requireOptionPath("--project", parsed.project);
7839
- }
7840
7980
  if (instruction.trim() === "") {
7841
7981
  throw new CliUsageError("merger requires a nonblank task instruction");
7842
7982
  }
@@ -7871,7 +8011,7 @@ async function admitPublicRole(role, parsed, env, override) {
7871
8011
  resolutionScope: [...derived.resolutionScope],
7872
8012
  authorizedChecks: []
7873
8013
  });
7874
- const mergerInputPath = join18(placed.runDirectory, "merger-input.json");
8014
+ const mergerInputPath = join19(placed.runDirectory, "merger-input.json");
7875
8015
  await writeFile4(
7876
8016
  mergerInputPath,
7877
8017
  `${JSON.stringify(mergerInput, null, 2)}
@@ -7898,9 +8038,6 @@ function admissionSubject(ticketNumber) {
7898
8038
  return { ticketNumber: fields.ticketNumber };
7899
8039
  }
7900
8040
  async function placeRoleAdmission(options) {
7901
- if (options.project !== void 0) {
7902
- requireOptionPath("--project", options.project);
7903
- }
7904
8041
  const projectRoot = resolve11(options.project ?? options.cwd);
7905
8042
  const runId = options.runId ?? (options.createRunId ?? uuidv7)();
7906
8043
  const ticketFields = ticketAdmissionFields(options.assertedTicketNumber);
@@ -7945,7 +8082,7 @@ function persistedAttachmentRefs(attachments) {
7945
8082
  }));
7946
8083
  }
7947
8084
  async function persistPlacedAdmission(admitted, placed, model) {
7948
- const admittedRequestPath = join18(placed.runDirectory, "admitted-request.json");
8085
+ const admittedRequestPath = join19(placed.runDirectory, "admitted-request.json");
7949
8086
  await writeAdmittedRequestPersistence(admittedRequestPath, admitted, {
7950
8087
  sessionDirectory: placed.sessionDirectory,
7951
8088
  sessionFile: placed.sessionFile
@@ -7998,7 +8135,7 @@ async function admitStandardMaterialInvocation(role, options) {
7998
8135
  attachments: persistedAttachmentRefs(placed.attachments),
7999
8136
  ...placed.ticketFields
8000
8137
  };
8001
- const admittedRequestPath = defer ? join18(placed.runDirectory, "admitted-request.json") : await persistPlacedAdmission(admitted, placed, options.model);
8138
+ const admittedRequestPath = defer ? join19(placed.runDirectory, "admitted-request.json") : await persistPlacedAdmission(admitted, placed, options.model);
8002
8139
  return {
8003
8140
  role,
8004
8141
  runId: placed.runId,
@@ -8076,7 +8213,7 @@ async function materializeCountersignInvocation(admitted, options) {
8076
8213
  });
8077
8214
  const placement = placed;
8078
8215
  admitted.runDirectory = placement.runDirectory;
8079
- admitted.admittedRequestPath = join18(
8216
+ admitted.admittedRequestPath = join19(
8080
8217
  placement.runDirectory,
8081
8218
  "admitted-request.json"
8082
8219
  );
@@ -8103,7 +8240,7 @@ async function materializeCountersignInvocation(admitted, options) {
8103
8240
  async function loadAdmittedJudgeRequest(runDirectory) {
8104
8241
  try {
8105
8242
  const raw = JSON.parse(
8106
- await readFile13(join18(runDirectory, "admitted-request.json"), "utf8")
8243
+ await readFile13(join19(runDirectory, "admitted-request.json"), "utf8")
8107
8244
  );
8108
8245
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
8109
8246
  const record4 = raw;
@@ -8192,7 +8329,7 @@ function parseDoctorIssueNumber(raw) {
8192
8329
  }
8193
8330
  async function resolveDoctorCaseRunsPath(options) {
8194
8331
  const ledgerHome = resolveActivationLedgerHome(options.home);
8195
- const defaultRuns = join18(
8332
+ const defaultRuns = join19(
8196
8333
  activationBookDirectory(ledgerHome, options.bookKey),
8197
8334
  String(options.issueNumber),
8198
8335
  "runs"
@@ -8286,11 +8423,11 @@ function parseAnalystCohortIssueToken(raw, flag) {
8286
8423
  `${flag} requires a comma-separated list of N or book:N`
8287
8424
  );
8288
8425
  }
8289
- const sep6 = trimmed.lastIndexOf(":");
8290
- if (sep6 > 0) {
8291
- const rhs = trimmed.slice(sep6 + 1);
8426
+ const sep5 = trimmed.lastIndexOf(":");
8427
+ if (sep5 > 0) {
8428
+ const rhs = trimmed.slice(sep5 + 1);
8292
8429
  if (ANALYST_TICKET_NUMBER_PATTERN.test(rhs)) {
8293
- const bookKey = trimmed.slice(0, sep6);
8430
+ const bookKey = trimmed.slice(0, sep5);
8294
8431
  if (bookKey.trim() === "") {
8295
8432
  throw new CliUsageError(
8296
8433
  `${flag} book:N requires a non-empty book key, got ${raw}`
@@ -8513,15 +8650,15 @@ var init_invocation = __esm({
8513
8650
 
8514
8651
  // src/public-cli/load-production-acp-host.ts
8515
8652
  import { existsSync as existsSync5 } from "node:fs";
8516
- import { join as join19 } from "node:path";
8653
+ import { join as join20 } from "node:path";
8517
8654
  import { pathToFileURL } from "node:url";
8518
8655
  async function loadProductionAcpHostFactory(packageRoot, host) {
8519
8656
  const description = lookupHostDescription(host);
8520
8657
  if (description === void 0) {
8521
8658
  throw new Error(`unregistered host: ${host}`);
8522
8659
  }
8523
- const built = join19(packageRoot, "dist/acp-host/production-host.js");
8524
- const source = join19(packageRoot, "src/acp-host/production-host.ts");
8660
+ const built = join20(packageRoot, "dist/acp-host/production-host.js");
8661
+ const source = join20(packageRoot, "src/acp-host/production-host.ts");
8525
8662
  const target = existsSync5(built) ? built : source;
8526
8663
  const href = pathToFileURL(target).href;
8527
8664
  const mod = await import(href);
@@ -8537,15 +8674,15 @@ var init_load_production_acp_host = __esm({
8537
8674
 
8538
8675
  // src/public-cli/load-production-headless-host.ts
8539
8676
  import { existsSync as existsSync6 } from "node:fs";
8540
- import { join as join20 } from "node:path";
8677
+ import { join as join21 } from "node:path";
8541
8678
  import { pathToFileURL as pathToFileURL2 } from "node:url";
8542
8679
  async function loadProductionHeadlessHostFactory(packageRoot, host) {
8543
8680
  const description = lookupHeadlessHostDescription(host);
8544
8681
  if (description === void 0) {
8545
8682
  throw new Error(`unregistered headless host: ${host}`);
8546
8683
  }
8547
- const built = join20(packageRoot, "dist/headless-host/production-host.js");
8548
- const source = join20(packageRoot, "src/headless-host/production-host.ts");
8684
+ const built = join21(packageRoot, "dist/headless-host/production-host.js");
8685
+ const source = join21(packageRoot, "src/headless-host/production-host.ts");
8549
8686
  const target = existsSync6(built) ? built : source;
8550
8687
  const href = pathToFileURL2(target).href;
8551
8688
  const mod = await import(href);
@@ -8670,179 +8807,45 @@ var init_role_turn_host_resolution = __esm({
8670
8807
  }
8671
8808
  });
8672
8809
 
8673
- // src/public-cli/host-providers.ts
8674
- var host_providers_exports = {};
8675
- __export(host_providers_exports, {
8676
- HostProviderResolutionError: () => HostProviderResolutionError,
8677
- hermesProviderModelsCachePath: () => hermesProviderModelsCachePath,
8678
- hostCatalogOffersModel: () => hostCatalogOffersModel,
8679
- hostProvidersPath: () => hostProvidersPath,
8680
- listHermesProvidersForModel: () => listHermesProvidersForModel,
8681
- loadHostProvidersTable: () => loadHostProvidersTable,
8682
- parseHostProvidersTable: () => parseHostProvidersTable,
8683
- projectHostFacingProvider: () => projectHostFacingProvider,
8684
- renderHostProvidersTable: () => renderHostProvidersTable
8810
+ // src/public-cli/role-seat-runtime.ts
8811
+ var role_seat_runtime_exports = {};
8812
+ __export(role_seat_runtime_exports, {
8813
+ openRoleSeatRuntime: () => openRoleSeatRuntime
8685
8814
  });
8686
- import { readFileSync } from "node:fs";
8687
- import { join as join21 } from "node:path";
8688
- function hostProvidersPath(home) {
8689
- if (typeof home !== "string" || home.trim() === "") {
8690
- throw new Error("home must be explicitly provided");
8691
- }
8692
- return join21(home, ".ak-roles", "host-providers.json");
8693
- }
8694
- function hermesProviderModelsCachePath(home) {
8695
- return join21(home, ".hermes", "provider_models_cache.json");
8696
- }
8697
- function parseHostProvidersTable(value) {
8698
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
8699
- throw new Error("host-providers.json must be an object");
8700
- }
8701
- const out = {};
8702
- for (const [host, byProvider] of Object.entries(value)) {
8703
- if (host.trim() === "") {
8704
- throw new Error("host-providers.json host key must be non-empty");
8705
- }
8706
- if (byProvider === null || typeof byProvider !== "object" || Array.isArray(byProvider)) {
8707
- throw new Error(`host-providers.json[${host}] must be an object`);
8708
- }
8709
- const providers = {};
8710
- for (const [seatProvider, hostProvider] of Object.entries(
8711
- byProvider
8712
- )) {
8713
- if (seatProvider.trim() === "") {
8714
- throw new Error(
8715
- `host-providers.json[${host}] seat-provider key must be non-empty`
8716
- );
8717
- }
8718
- if (typeof hostProvider !== "string" || hostProvider.trim() === "") {
8719
- throw new Error(
8720
- `host-providers.json[${host}][${seatProvider}] must be a non-empty string`
8721
- );
8722
- }
8723
- providers[seatProvider] = hostProvider;
8724
- }
8725
- if (Object.keys(providers).length > 0) {
8726
- out[host] = providers;
8727
- }
8728
- }
8729
- return out;
8730
- }
8731
- function loadHostProvidersTable(home) {
8732
- const path = hostProvidersPath(home);
8733
- try {
8734
- const raw = readFileSync(path, "utf8");
8735
- return parseHostProvidersTable(JSON.parse(raw));
8736
- } catch (error) {
8737
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
8738
- return {};
8739
- }
8740
- throw error;
8741
- }
8742
- }
8743
- function hostCatalogOffersModel(catalogModels, seatModel) {
8744
- return catalogModels.some(
8745
- (entry) => entry === seatModel || entry.endsWith(`/${seatModel}`)
8815
+ function openRoleSeatRuntime(input) {
8816
+ const hostAdapters = composeRoleTurnHostAdapters(
8817
+ input.resolution,
8818
+ input.principalAuthority
8746
8819
  );
8747
- }
8748
- function listHermesProvidersForModel(home, seatModel) {
8749
- const path = hermesProviderModelsCachePath(home);
8750
- let text;
8751
- try {
8752
- text = readFileSync(path, "utf8");
8753
- } catch (error) {
8754
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
8755
- return [];
8756
- }
8757
- throw error;
8758
- }
8759
- const raw = JSON.parse(text);
8760
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
8761
- throw new Error(
8762
- `hermes provider_models_cache.json must be an object: ${path}`
8763
- );
8764
- }
8765
- const found = [];
8766
- for (const [provider, entry] of Object.entries(raw)) {
8767
- if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
8768
- continue;
8769
- }
8770
- const models = entry.models;
8771
- if (!Array.isArray(models)) continue;
8772
- const names = models.filter((m) => typeof m === "string");
8773
- if (hostCatalogOffersModel(names, seatModel)) {
8774
- found.push(provider);
8775
- }
8776
- }
8777
- return found.sort();
8778
- }
8779
- function listDirectoryProvidersForModel(home, host, seatModel) {
8780
- if (host === "hermes") {
8781
- return listHermesProvidersForModel(home, seatModel);
8782
- }
8783
- return void 0;
8784
- }
8785
- function projectHostFacingProvider(selection, host, table, home) {
8786
- if (selection === void 0) return void 0;
8787
- const mapped = table[host]?.[selection.provider];
8788
- if (mapped !== void 0) {
8789
- return mapped === selection.provider ? selection : { ...selection, provider: mapped };
8790
- }
8791
- const directory = listDirectoryProvidersForModel(home, host, selection.model);
8792
- if (directory === void 0) {
8793
- return selection;
8794
- }
8795
- if (directory.length === 1) {
8796
- const only = directory[0];
8797
- return only === selection.provider ? selection : { ...selection, provider: only };
8798
- }
8799
- if (directory.length === 0) {
8800
- throw new HostProviderResolutionError({
8801
- message: `host ${host} has no provider offering model ${selection.model}; seat provider was ${selection.provider}`,
8802
- host,
8803
- seatProvider: selection.provider,
8804
- seatModel: selection.model
8805
- });
8806
- }
8807
- throw new HostProviderResolutionError({
8808
- message: `host ${host} has multiple providers for model ${selection.model}: ${directory.join(", ")}; set host-providers.json[${host}][${selection.provider}] to one of them`,
8809
- host,
8810
- seatProvider: selection.provider,
8811
- seatModel: selection.model,
8812
- candidates: directory
8820
+ const roleTurnHost = selectRoleTurnHost(hostAdapters, {
8821
+ role: input.role,
8822
+ seat: input.seat
8813
8823
  });
8824
+ input.afterHost?.();
8825
+ const seatWithModel = resolvedSeatWithModel(input.seat);
8826
+ if (seatWithModel === void 0) return { ok: false };
8827
+ const projected = input.hostFacingModel ?? projectHostFacingProvider(
8828
+ seatWithModel.selection,
8829
+ seatWithModel.host,
8830
+ loadHostProvidersTable(input.home),
8831
+ input.home
8832
+ );
8833
+ return {
8834
+ ok: true,
8835
+ roleTurnHost,
8836
+ hostAdapters,
8837
+ ...projected === void 0 ? {} : { model: projected },
8838
+ ...pickEngineAxis(seatWithModel),
8839
+ host: seatWithModel.host
8840
+ };
8814
8841
  }
8815
- function renderHostProvidersTable(table) {
8816
- const lines = [];
8817
- for (const host of Object.keys(table).sort()) {
8818
- const byProvider = table[host];
8819
- for (const seatProvider of Object.keys(byProvider).sort()) {
8820
- lines.push(
8821
- `hostProvider ${host} ${seatProvider} ${byProvider[seatProvider]}`
8822
- );
8823
- }
8824
- }
8825
- return lines.length === 0 ? "" : `${lines.join("\n")}
8826
- `;
8827
- }
8828
- var HostProviderResolutionError;
8829
- var init_host_providers = __esm({
8830
- "src/public-cli/host-providers.ts"() {
8842
+ var init_role_seat_runtime = __esm({
8843
+ "src/public-cli/role-seat-runtime.ts"() {
8831
8844
  "use strict";
8832
- HostProviderResolutionError = class extends Error {
8833
- host;
8834
- seatProvider;
8835
- seatModel;
8836
- candidates;
8837
- constructor(options) {
8838
- super(options.message);
8839
- this.name = "HostProviderResolutionError";
8840
- this.host = options.host;
8841
- this.seatProvider = options.seatProvider;
8842
- this.seatModel = options.seatModel;
8843
- this.candidates = options.candidates ?? [];
8844
- }
8845
- };
8845
+ init_engine_material();
8846
+ init_config();
8847
+ init_host_providers();
8848
+ init_role_turn_host_resolution();
8846
8849
  }
8847
8850
  });
8848
8851
 
@@ -12340,75 +12343,326 @@ var init_submission_gate = __esm({
12340
12343
  }
12341
12344
  });
12342
12345
 
12343
- // src/session-identity.ts
12344
- import { mkdir as mkdir2, readFile as readFile17, rename as rename3, writeFile as writeFile6 } from "node:fs/promises";
12345
- import { dirname as dirname18, join as join29 } from "node:path";
12346
- function createSessionIdentityAuthority(authority, sessionBindingFile) {
12347
- const bindingPath = (principal) => join29(authority.decode(principal).sessionDirectory, sessionBindingFile);
12348
- return {
12349
- resolveSessionFile(principal) {
12350
- return authority.decode(principal).sessionFile;
12351
- },
12352
- async load(principal) {
12353
- try {
12354
- const value = JSON.parse(await readFile17(bindingPath(principal), "utf8"));
12355
- if (typeof value !== "object" || value === null || typeof value.sessionId !== "string") {
12356
- throw new Error("durable session binding is invalid");
12357
- }
12358
- return value.sessionId;
12359
- } catch (error) {
12360
- if (error.code === "ENOENT") return void 0;
12361
- throw error;
12362
- }
12363
- },
12364
- async bind(principal, sessionId) {
12365
- const target = bindingPath(principal);
12366
- await mkdir2(dirname18(target), { recursive: true });
12367
- const temporary = `${target}.${process.pid}.tmp`;
12368
- await writeFile6(temporary, `${JSON.stringify({ sessionId })}
12369
- `, { encoding: "utf8", mode: 384 });
12370
- await rename3(temporary, target);
12371
- }
12372
- };
12346
+ // src/public-cli/machine-method-skills.ts
12347
+ import { accessSync, constants as constants2, statSync as statSync3 } from "node:fs";
12348
+ import { lstat as lstat4, mkdir as mkdir2, symlink } from "node:fs/promises";
12349
+ import { join as join29 } from "node:path";
12350
+ import { spawnSync } from "node:child_process";
12351
+ function skillRoot(home) {
12352
+ return join29(home, ".agents/skills");
12373
12353
  }
12374
- async function readStoredHostSessionId(host, authority, principal) {
12375
- if (host === void 0 || host === DEFAULT_ROLE_TURN_HOST) return void 0;
12376
- const description = lookupHostDescription(host) ?? lookupHeadlessHostDescription(host);
12377
- if (description === void 0) return void 0;
12378
- const sessionId = await createSessionIdentityAuthority(
12379
- authority,
12380
- description.sessionBindingFile
12381
- ).load(principal);
12382
- if (sessionId === void 0 || sessionId === "") return void 0;
12383
- return sessionId;
12354
+ function installedMethodSkillPath(home, name) {
12355
+ return installedSkillPath(skillRoot(home), name);
12384
12356
  }
12385
- var init_session_identity = __esm({
12386
- "src/session-identity.ts"() {
12387
- "use strict";
12388
- init_host_descriptions();
12357
+ function installedSkillPath(root, name) {
12358
+ const path = join29(root, name, "SKILL.md");
12359
+ try {
12360
+ if (!statSync3(path).isFile()) return void 0;
12361
+ accessSync(path, constants2.R_OK);
12362
+ return path;
12363
+ } catch (error) {
12364
+ const code = error.code;
12365
+ if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM" || code === "ELOOP") return void 0;
12366
+ throw error;
12389
12367
  }
12390
- });
12391
-
12392
- // src/public-cli/process-cancel.ts
12393
- function processCancelSignalName(signal) {
12394
- if (signal === void 0 || signal.aborted !== true) return void 0;
12395
- const reason = signal.reason;
12396
- if (reason === "SIGTERM" || reason === "SIGINT" || reason === "SIGHUP") {
12397
- return reason;
12368
+ }
12369
+ function linkedSkillRoot(home, host) {
12370
+ if (host === "claude" || host === "claude-code") {
12371
+ return join29(process.env.CLAUDE_CONFIG_DIR?.trim() || join29(home, ".claude"), "skills");
12398
12372
  }
12373
+ if (host === "hermes") return join29(home, ".hermes/skills");
12399
12374
  return void 0;
12400
12375
  }
12401
- function processCancelDiagnostic(signalName) {
12402
- return `ak-role terminated by ${signalName}`;
12376
+ async function occupied(path) {
12377
+ try {
12378
+ await lstat4(path);
12379
+ return true;
12380
+ } catch (error) {
12381
+ if (error.code !== "ENOENT") throw error;
12382
+ return false;
12383
+ }
12403
12384
  }
12404
- var init_process_cancel = __esm({
12405
- "src/public-cli/process-cancel.ts"() {
12406
- "use strict";
12385
+ function warnOccupied(path, stdout) {
12386
+ stdout(`Warning: ${path} is already occupied; left untouched.
12387
+ `);
12388
+ }
12389
+ async function warnMissingMethodSkills(home, host, role, skills, stdout) {
12390
+ const missing = [];
12391
+ const linkedRoot = linkedSkillRoot(home, host);
12392
+ for (const skill of skills) {
12393
+ if (installedMethodSkillPath(home, skill) === void 0 || linkedRoot !== void 0 && installedSkillPath(linkedRoot, skill) === void 0) missing.push(skill);
12394
+ }
12395
+ for (const skill of missing) {
12396
+ stdout(`Warning: required machine Skill "${skill}" is missing for ${role}; its method guidance may be unavailable and reduce work quality. Run \`ak-role setup\` to install required Skills.
12397
+ `);
12398
+ }
12399
+ }
12400
+ function runSkillsCli(args, home) {
12401
+ const result = spawnSync("npx", ["--yes", "skills", ...args], {
12402
+ stdio: "inherit",
12403
+ env: { ...process.env, HOME: home }
12404
+ });
12405
+ if (result.error !== void 0) throw result.error;
12406
+ return result.status === 0;
12407
+ }
12408
+ function addSkills(source, skills, home) {
12409
+ if (skills.length === 0) return true;
12410
+ return runSkillsCli([
12411
+ "add",
12412
+ source,
12413
+ ...skills.flatMap((skill) => ["--skill", skill]),
12414
+ "--agent",
12415
+ "codex",
12416
+ "--global",
12417
+ "--yes"
12418
+ ], home);
12419
+ }
12420
+ function updateRequiredSkills(home) {
12421
+ const names = packagedMethodSkillNames();
12422
+ if (names.length === 0) return true;
12423
+ return runSkillsCli(["update", "-g", "-y", ...names], home);
12424
+ }
12425
+ async function runMachineSkillSetup(home, stdout) {
12426
+ const canonical = skillRoot(home);
12427
+ const missingBySource = /* @__PURE__ */ new Map();
12428
+ let unsourced = false;
12429
+ for (const name of packagedMethodSkillNames()) {
12430
+ const path = join29(canonical, name);
12431
+ if (await occupied(path)) {
12432
+ warnOccupied(path, stdout);
12433
+ continue;
12434
+ }
12435
+ const source = SKILL_SOURCE[name];
12436
+ if (source === void 0) {
12437
+ unsourced = true;
12438
+ stdout(`Warning: required machine Skill "${name}" has no install source; setup did not install it.
12439
+ `);
12440
+ continue;
12441
+ }
12442
+ const missing = missingBySource.get(source) ?? [];
12443
+ missing.push(name);
12444
+ missingBySource.set(source, missing);
12445
+ }
12446
+ for (const [source, missing] of missingBySource) {
12447
+ if (!addSkills(source, missing, home)) return 1;
12448
+ }
12449
+ if (unsourced) return 1;
12450
+ for (const host of ["claude-code", "hermes"]) {
12451
+ const root = linkedSkillRoot(home, host);
12452
+ const description = host === "claude-code" ? HEADLESS_HOST_DESCRIPTIONS.claude : HOST_DESCRIPTIONS.hermes;
12453
+ try {
12454
+ accessSync(resolveHostBinary(description, home), constants2.X_OK);
12455
+ } catch (error) {
12456
+ if (["ENOENT", "ENOTDIR", "EACCES"].includes(error.code ?? "")) continue;
12457
+ throw error;
12458
+ }
12459
+ for (const name of packagedMethodSkillNames()) {
12460
+ const target = join29(canonical, name);
12461
+ if (installedMethodSkillPath(home, name) === void 0) continue;
12462
+ const link = join29(root, name);
12463
+ if (await occupied(link)) {
12464
+ warnOccupied(link, stdout);
12465
+ continue;
12466
+ }
12467
+ await mkdir2(root, { recursive: true });
12468
+ await symlink(target, link, "dir");
12469
+ }
12470
+ }
12471
+ if (!updateRequiredSkills(home)) return 1;
12472
+ stdout("Machine method Skills setup finished. Existing same-name Skills were left untouched.\n");
12473
+ return 0;
12474
+ }
12475
+ var SKILL_SOURCE;
12476
+ var init_machine_method_skills = __esm({
12477
+ "src/public-cli/machine-method-skills.ts"() {
12478
+ "use strict";
12479
+ init_host_descriptions();
12480
+ init_packaged_role_registry();
12481
+ SKILL_SOURCE = {
12482
+ tdd: "mattpocock/skills",
12483
+ "diagnosing-bugs": "mattpocock/skills",
12484
+ "resolving-merge-conflicts": "mattpocock/skills",
12485
+ "ak-cross-m-review": "Akagilnc/ak-cross-m-review"
12486
+ };
12487
+ }
12488
+ });
12489
+
12490
+ // src/public-cli/turn-request.ts
12491
+ function projectPublicTurnAxes(env) {
12492
+ return {
12493
+ packageRoot: env.packageRoot,
12494
+ home: env.home,
12495
+ agentDir: env.agentDir,
12496
+ ...env.model === void 0 ? {} : { model: env.model },
12497
+ ...pickEngineAxis(env),
12498
+ ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs }
12499
+ };
12500
+ }
12501
+ function projectRoleTurnRequest(admitted, roleDetails, options) {
12502
+ const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
12503
+ if (cwd === void 0) throw new Error("admitted invocation missing working directory");
12504
+ if (admitted.principal === void 0) throw new Error("admitted invocation missing principal");
12505
+ return {
12506
+ principal: admitted.principal,
12507
+ activation: roleDetails.activation,
12508
+ methods: roleDetails.methods ?? [],
12509
+ continuation: options.continuation,
12510
+ ...options.model === void 0 ? {} : { model: options.model },
12511
+ ...pickEngineAxis(options),
12512
+ cwd,
12513
+ home: options.home,
12514
+ agentDir: options.agentDir,
12515
+ runDirectory: admitted.runDirectory,
12516
+ ...options.correlationId === void 0 || options.correlationId.trim() === "" ? {} : { correlationId: options.correlationId },
12517
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
12518
+ ...options.courtAttemptId === void 0 || options.courtAttemptId.length === 0 ? {} : { courtAttemptId: options.courtAttemptId },
12519
+ ...options.invocationScopeId === void 0 || options.invocationScopeId.length === 0 ? {} : { invocationScopeId: options.invocationScopeId },
12520
+ ...options.stationChild === void 0 ? {} : { stationChild: options.stationChild }
12521
+ };
12522
+ }
12523
+ function packagedSettleSkill(admitted) {
12524
+ const record4 = packagedRoleMetadata(admitted.role);
12525
+ if (record4 === void 0) return void 0;
12526
+ if ("applyMethod" in record4 && record4.applyMethod !== void 0) {
12527
+ return "phase" in admitted && admitted.phase === "apply" ? record4.applyMethod : void 0;
12528
+ }
12529
+ if ("settleMethod" in record4 && record4.settleMethod !== void 0) return record4.settleMethod;
12530
+ return void 0;
12531
+ }
12532
+ function readAdmittedPath2(admitted, path) {
12533
+ let current = admitted;
12534
+ for (const key of path.split(".")) {
12535
+ if (current === null || typeof current !== "object") return void 0;
12536
+ current = current[key];
12537
+ }
12538
+ return current;
12539
+ }
12540
+ function activationForAdmitted(admitted) {
12541
+ if (packagedRoleMetadata(admitted.role) === void 0) {
12542
+ throw new Error(`no turn projection for ${admitted.role}`);
12543
+ }
12544
+ const activation = { role: admitted.role };
12545
+ for (const spec of packagedRoleActivationFlags(admitted.role)) {
12546
+ let value = readAdmittedPath2(admitted, spec.from ?? spec.field);
12547
+ if (spec.fallback === "gate-pointer") {
12548
+ const trimmed = typeof value === "string" ? value.trim() : "";
12549
+ value = trimmed !== "" ? trimmed : parentRunPathFromGatePointerInstruction(admitted.instruction);
12550
+ if (typeof value !== "string" || value === "") continue;
12551
+ }
12552
+ if (value === void 0) continue;
12553
+ if (spec.text === true) {
12554
+ if (typeof value !== "number") continue;
12555
+ value = String(value);
12556
+ }
12557
+ activation[spec.field] = value;
12558
+ }
12559
+ return activation;
12560
+ }
12561
+ function requiredMethodSkills(admitted) {
12562
+ const record4 = packagedRoleMetadata(admitted.role);
12563
+ const names = [];
12564
+ if (record4 !== void 0 && "methodSkills" in record4 && record4.methodSkills !== void 0) {
12565
+ names.push(...record4.methodSkills);
12566
+ }
12567
+ const apply = packagedSettleSkill(admitted);
12568
+ if (apply !== void 0 && !names.includes(apply)) names.push(apply);
12569
+ return names;
12570
+ }
12571
+ function methodBindings(admitted, home, host) {
12572
+ if (host !== void 0 && host !== "pi") return [];
12573
+ return requiredMethodSkills(admitted).flatMap((name) => {
12574
+ const path = installedMethodSkillPath(home, name);
12575
+ return path === void 0 ? [] : [{
12576
+ kind: "skill",
12577
+ path
12578
+ }];
12579
+ });
12580
+ }
12581
+ function admittedSeatTurnDetails(admitted, home, host) {
12582
+ return {
12583
+ activation: activationForAdmitted(admitted),
12584
+ methods: methodBindings(admitted, home, host)
12585
+ };
12586
+ }
12587
+ var init_turn_request = __esm({
12588
+ "src/public-cli/turn-request.ts"() {
12589
+ "use strict";
12590
+ init_engine_material();
12591
+ init_packaged_role_registry();
12592
+ init_machine_method_skills();
12593
+ init_run_lifecycle();
12594
+ }
12595
+ });
12596
+
12597
+ // src/session-identity.ts
12598
+ import { mkdir as mkdir3, readFile as readFile17, rename as rename3, writeFile as writeFile6 } from "node:fs/promises";
12599
+ import { dirname as dirname18, join as join30 } from "node:path";
12600
+ function createSessionIdentityAuthority(authority, sessionBindingFile) {
12601
+ const bindingPath = (principal) => join30(authority.decode(principal).sessionDirectory, sessionBindingFile);
12602
+ return {
12603
+ resolveSessionFile(principal) {
12604
+ return authority.decode(principal).sessionFile;
12605
+ },
12606
+ async load(principal) {
12607
+ try {
12608
+ const value = JSON.parse(await readFile17(bindingPath(principal), "utf8"));
12609
+ if (typeof value !== "object" || value === null || typeof value.sessionId !== "string") {
12610
+ throw new Error("durable session binding is invalid");
12611
+ }
12612
+ return value.sessionId;
12613
+ } catch (error) {
12614
+ if (error.code === "ENOENT") return void 0;
12615
+ throw error;
12616
+ }
12617
+ },
12618
+ async bind(principal, sessionId) {
12619
+ const target = bindingPath(principal);
12620
+ await mkdir3(dirname18(target), { recursive: true });
12621
+ const temporary = `${target}.${process.pid}.tmp`;
12622
+ await writeFile6(temporary, `${JSON.stringify({ sessionId })}
12623
+ `, { encoding: "utf8", mode: 384 });
12624
+ await rename3(temporary, target);
12625
+ }
12626
+ };
12627
+ }
12628
+ async function readStoredHostSessionId(host, authority, principal) {
12629
+ if (host === void 0 || host === DEFAULT_ROLE_TURN_HOST) return void 0;
12630
+ const description = lookupHostDescription(host) ?? lookupHeadlessHostDescription(host);
12631
+ if (description === void 0) return void 0;
12632
+ const sessionId = await createSessionIdentityAuthority(
12633
+ authority,
12634
+ description.sessionBindingFile
12635
+ ).load(principal);
12636
+ if (sessionId === void 0 || sessionId === "") return void 0;
12637
+ return sessionId;
12638
+ }
12639
+ var init_session_identity = __esm({
12640
+ "src/session-identity.ts"() {
12641
+ "use strict";
12642
+ init_host_descriptions();
12643
+ }
12644
+ });
12645
+
12646
+ // src/public-cli/process-cancel.ts
12647
+ function processCancelSignalName(signal) {
12648
+ if (signal === void 0 || signal.aborted !== true) return void 0;
12649
+ const reason = signal.reason;
12650
+ if (reason === "SIGTERM" || reason === "SIGINT" || reason === "SIGHUP") {
12651
+ return reason;
12652
+ }
12653
+ return void 0;
12654
+ }
12655
+ function processCancelDiagnostic(signalName) {
12656
+ return `ak-role terminated by ${signalName}`;
12657
+ }
12658
+ var init_process_cancel = __esm({
12659
+ "src/public-cli/process-cancel.ts"() {
12660
+ "use strict";
12407
12661
  }
12408
12662
  });
12409
12663
 
12410
12664
  // src/host-session-record.ts
12411
- import { spawnSync } from "node:child_process";
12665
+ import { spawnSync as spawnSync2 } from "node:child_process";
12412
12666
  import {
12413
12667
  appendFileSync as appendFileSync2,
12414
12668
  copyFileSync,
@@ -12419,10 +12673,10 @@ import {
12419
12673
  mkdirSync as mkdirSync3,
12420
12674
  readdirSync as readdirSync2,
12421
12675
  rmSync,
12422
- statSync as statSync3
12676
+ statSync as statSync4
12423
12677
  } from "node:fs";
12424
12678
  import { homedir } from "node:os";
12425
- import { dirname as dirname19, join as join30 } from "node:path";
12679
+ import { dirname as dirname19, join as join31 } from "node:path";
12426
12680
  function declareHostSessionFailure(error) {
12427
12681
  const message = error instanceof Error ? error.stack || error.message : String(error);
12428
12682
  process.stderr.write(`[host-session] Dossier record failure: ${message}
@@ -12447,12 +12701,12 @@ function findCodexRollout(sessionsDir, sessionId) {
12447
12701
  return;
12448
12702
  }
12449
12703
  for (const entry of entries) {
12450
- const fullPath = join30(dir, entry.name);
12704
+ const fullPath = join31(dir, entry.name);
12451
12705
  if (entry.isDirectory()) {
12452
12706
  scan(fullPath, depth + 1);
12453
12707
  } else if (entry.isFile() && entry.name.endsWith(".jsonl") && entry.name.includes(sessionId)) {
12454
12708
  try {
12455
- const stat2 = statSync3(fullPath);
12709
+ const stat2 = statSync4(fullPath);
12456
12710
  matches.push({ path: fullPath, mtime: stat2.mtimeMs });
12457
12711
  } catch {
12458
12712
  matches.push({ path: fullPath, mtime: 0 });
@@ -12471,25 +12725,25 @@ function sanitizeClaudeCwd(cwd) {
12471
12725
  function resolveNativeSessionPath(options) {
12472
12726
  const home = options.home || homedir();
12473
12727
  if (options.host === "claude") {
12474
- const configDir = process.env.CLAUDE_CONFIG_DIR || join30(home, ".claude");
12728
+ const configDir = process.env.CLAUDE_CONFIG_DIR || join31(home, ".claude");
12475
12729
  const sanitizedCwd = sanitizeClaudeCwd(options.cwd);
12476
- return join30(configDir, "projects", sanitizedCwd, `${options.sessionId}.jsonl`);
12730
+ return join31(configDir, "projects", sanitizedCwd, `${options.sessionId}.jsonl`);
12477
12731
  }
12478
12732
  if (options.host === "codex") {
12479
12733
  return findCodexRollout(codexSessionsDirectory(home), options.sessionId);
12480
12734
  }
12481
12735
  if (options.host === "grok-build") {
12482
- const grokHome = process.env.GROK_HOME || join30(home, ".grok");
12483
- return join30(grokHome, "sessions", encodeURIComponent(options.cwd), options.sessionId);
12736
+ const grokHome = process.env.GROK_HOME || join31(home, ".grok");
12737
+ return join31(grokHome, "sessions", encodeURIComponent(options.cwd), options.sessionId);
12484
12738
  }
12485
12739
  return void 0;
12486
12740
  }
12487
12741
  function codexSessionsDirectory(home) {
12488
- return join30(process.env.CODEX_HOME || join30(home || homedir(), ".codex"), "sessions");
12742
+ return join31(process.env.CODEX_HOME || join31(home || homedir(), ".codex"), "sessions");
12489
12743
  }
12490
12744
  function recordRunStart(runDirectory) {
12491
12745
  try {
12492
- appendFileSync2(join30(runDirectory, ".run-starts"), "\n");
12746
+ appendFileSync2(join31(runDirectory, ".run-starts"), "\n");
12493
12747
  } catch (error) {
12494
12748
  declareHostSessionFailure(error);
12495
12749
  }
@@ -12513,12 +12767,12 @@ function resolveHostDossierLandingPath(options) {
12513
12767
  } catch {
12514
12768
  }
12515
12769
  }
12516
- const startsPath = join30(dirname19(options.sessionDirectory), ".run-starts");
12770
+ const startsPath = join31(dirname19(options.sessionDirectory), ".run-starts");
12517
12771
  let starts = 0;
12518
12772
  if (existsSync9(startsPath)) starts = readFileSync3(startsPath, "utf8").length;
12519
12773
  const ordinal = Math.max(maxOrdinal + 1, starts, options.continuation.kind === "resume" ? 2 : 1);
12520
12774
  const baseName = `${options.host}-${sanitizedModel}-${ordinal}`;
12521
- const landingPath = options.host === "grok-build" ? join30(options.sessionDirectory, baseName) : join30(options.sessionDirectory, `${baseName}.jsonl`);
12775
+ const landingPath = options.host === "grok-build" ? join31(options.sessionDirectory, baseName) : join31(options.sessionDirectory, `${baseName}.jsonl`);
12522
12776
  return { landingPath, ordinal, sanitizedModel };
12523
12777
  }
12524
12778
  function recordNativeSessionPointer(options) {
@@ -12544,25 +12798,25 @@ function recordNativeSessionPointer(options) {
12544
12798
  }
12545
12799
  function copyFileCloneOrFallback(src, dest) {
12546
12800
  try {
12547
- const res = spawnSync("cp", ["-c", src, dest]);
12801
+ const res = spawnSync2("cp", ["-c", src, dest]);
12548
12802
  if (res.status === 0) return;
12549
12803
  } catch {
12550
12804
  }
12551
12805
  copyFileSync(src, dest);
12552
12806
  }
12553
12807
  function copyGrokDossier(srcDir, destDir) {
12554
- const chatHistorySrc = join30(srcDir, "chat_history.jsonl");
12808
+ const chatHistorySrc = join31(srcDir, "chat_history.jsonl");
12555
12809
  if (!existsSync9(chatHistorySrc)) {
12556
12810
  throw new Error(`Grok native chat_history.jsonl missing at ${chatHistorySrc}`);
12557
12811
  }
12558
12812
  mkdirSync3(destDir, { recursive: true });
12559
- const chatHistoryDest = join30(destDir, "chat_history.jsonl");
12813
+ const chatHistoryDest = join31(destDir, "chat_history.jsonl");
12560
12814
  copyFileCloneOrFallback(chatHistorySrc, chatHistoryDest);
12561
- const usageSrc = join30(srcDir, "usage.json");
12815
+ const usageSrc = join31(srcDir, "usage.json");
12562
12816
  if (!existsSync9(usageSrc)) {
12563
12817
  throw new Error(`Grok native usage.json missing at ${usageSrc}`);
12564
12818
  }
12565
- copyFileCloneOrFallback(usageSrc, join30(destDir, "usage.json"));
12819
+ copyFileCloneOrFallback(usageSrc, join31(destDir, "usage.json"));
12566
12820
  }
12567
12821
  function copyAndRecordHostDossier(options) {
12568
12822
  if (options.host === "pi" || options.host === "hermes") {
@@ -12637,7 +12891,7 @@ function copyAndRecordHostDossier(options) {
12637
12891
  }
12638
12892
  try {
12639
12893
  mkdirSync3(options.sessionDirectory, { recursive: true });
12640
- closeSync(openSync(join30(options.sessionDirectory, `${options.host}-${sanitizedModel}-${ordinal}.failed`), "a"));
12894
+ closeSync(openSync(join31(options.sessionDirectory, `${options.host}-${sanitizedModel}-${ordinal}.failed`), "a"));
12641
12895
  } catch {
12642
12896
  }
12643
12897
  sitianReportSafe({
@@ -12670,8 +12924,8 @@ var init_host_session_record = __esm({
12670
12924
  // src/public-cli/auto-resume.ts
12671
12925
  import { constants as fsConstants2 } from "node:fs";
12672
12926
  import { randomUUID as randomUUID6 } from "node:crypto";
12673
- import { lstat as lstat4, mkdir as mkdir3, open } from "node:fs/promises";
12674
- import { join as join31 } from "node:path";
12927
+ import { lstat as lstat5, mkdir as mkdir4, open } from "node:fs/promises";
12928
+ import { join as join32 } from "node:path";
12675
12929
  async function persistReturnedRunState(admitted, options) {
12676
12930
  if (options?.lawful === true) {
12677
12931
  await markRunTerminal(admitted.runDirectory);
@@ -12705,20 +12959,20 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
12705
12959
  }
12706
12960
  }
12707
12961
  async function ensureRealArtifactsDirectory(runDirectory) {
12708
- const runStat = await lstat4(runDirectory);
12962
+ const runStat = await lstat5(runDirectory);
12709
12963
  if (runStat.isSymbolicLink() || !runStat.isDirectory()) {
12710
12964
  throw new Error("run artifact retention: run directory is not a real directory");
12711
12965
  }
12712
12966
  const artifactsDir = roleRunArtifactsDirectory(runDirectory);
12713
12967
  try {
12714
- const existing = await lstat4(artifactsDir);
12968
+ const existing = await lstat5(artifactsDir);
12715
12969
  if (existing.isSymbolicLink() || !existing.isDirectory()) {
12716
12970
  throw new Error("run artifact retention: artifacts path is not a real directory");
12717
12971
  }
12718
12972
  } catch (error) {
12719
12973
  if (!isMissingPathError5(error)) throw error;
12720
- await mkdir3(artifactsDir, { recursive: true });
12721
- const created = await lstat4(artifactsDir);
12974
+ await mkdir4(artifactsDir, { recursive: true });
12975
+ const created = await lstat5(artifactsDir);
12722
12976
  if (created.isSymbolicLink() || !created.isDirectory()) {
12723
12977
  throw new Error("run artifact retention: artifacts directory is not a real directory");
12724
12978
  }
@@ -12740,7 +12994,7 @@ function jsonSafeReplacer() {
12740
12994
  };
12741
12995
  }
12742
12996
  async function writeHardenedArtifactFile(artifactsDir, namePrefix, payload) {
12743
- const filePath = join31(artifactsDir, `${namePrefix}-${randomUUID6()}.json`);
12997
+ const filePath = join32(artifactsDir, `${namePrefix}-${randomUUID6()}.json`);
12744
12998
  const body = `${JSON.stringify(payload, jsonSafeReplacer(), 2)}
12745
12999
  `;
12746
13000
  const noFollowFlag = typeof fsConstants2.O_NOFOLLOW === "number" ? fsConstants2.O_NOFOLLOW : 0;
@@ -12995,7 +13249,7 @@ var init_auto_resume = __esm({
12995
13249
  // src/public-cli/post-admission.ts
12996
13250
  import { randomUUID as randomUUID7 } from "node:crypto";
12997
13251
  import { writeFile as writeFile7 } from "node:fs/promises";
12998
- import { isAbsolute as isAbsolute7, join as join32, resolve as resolve13 } from "node:path";
13252
+ import { isAbsolute as isAbsolute7, join as join33, resolve as resolve13 } from "node:path";
12999
13253
  function describeCaughtError(error) {
13000
13254
  if (error instanceof Error) {
13001
13255
  const code = error.code;
@@ -13090,12 +13344,10 @@ async function recordBestEffortPostDispatchDiagnostic(admitted, env, diagnostic,
13090
13344
  } catch (appendError) {
13091
13345
  try {
13092
13346
  const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
13093
- await writeFile7(
13094
- join32(artifactsDir, `post-admission-diagnostic-${randomUUID7()}.json`),
13095
- `${JSON.stringify({ version: 1, ...payload }, null, 2)}
13096
- `,
13097
- { encoding: "utf8", flag: "wx" }
13098
- );
13347
+ await writeHardenedArtifactFile(artifactsDir, "post-admission-diagnostic", {
13348
+ version: 1,
13349
+ ...payload
13350
+ });
13099
13351
  } catch (artifactError) {
13100
13352
  retentionFailure = `post-dispatch diagnostic durable retention failed on both channels (best-effort continue): dossier=${describeErrorIdentity(appendError)}; artifact=${describeErrorIdentity(artifactError)}`;
13101
13353
  }
@@ -13232,7 +13484,7 @@ async function dispatchPostAdmissionTurn(input) {
13232
13484
  const rows = await readRecordedSubmissionRows(
13233
13485
  admitted.projectRoot,
13234
13486
  admitted.runId,
13235
- { home: homeFromRunDirectory(admitted.runDirectory), sessionParent: join32(admitted.runDirectory, "session", "session.jsonl") }
13487
+ { home: homeFromRunDirectory(admitted.runDirectory), sessionParent: join33(admitted.runDirectory, "session", "session.jsonl") }
13236
13488
  );
13237
13489
  let ticketNumber;
13238
13490
  for (const row of rows) {
@@ -13359,7 +13611,7 @@ async function dispatchPostAdmissionTurn(input) {
13359
13611
  let stderrLogWriteFailure;
13360
13612
  try {
13361
13613
  await writeFile7(
13362
- join32(admitted.runDirectory, "stderr.log"),
13614
+ join33(admitted.runDirectory, "stderr.log"),
13363
13615
  result.stderr,
13364
13616
  "utf8"
13365
13617
  );
@@ -13593,13 +13845,8 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
13593
13845
  prompt = "";
13594
13846
  }
13595
13847
  return {
13596
- packageRoot: env.packageRoot,
13597
- home: env.home,
13848
+ ...projectPublicTurnAxes(env),
13598
13849
  ...env.host === void 0 ? {} : { host: env.host },
13599
- agentDir: env.agentDir,
13600
- ...env.model === void 0 ? {} : { model: env.model },
13601
- ...pickEngineAxis(env),
13602
- ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs },
13603
13850
  ...env.correlationId === void 0 && admitted.correlationId === void 0 ? {} : { correlationId: env.correlationId ?? admitted.correlationId },
13604
13851
  continuation: {
13605
13852
  kind: "resume",
@@ -13612,13 +13859,8 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
13612
13859
  function roleTurnOptions(env, admitted, continuation) {
13613
13860
  const correlationId = env.correlationId ?? admitted.correlationId;
13614
13861
  return {
13615
- packageRoot: env.packageRoot,
13616
- home: env.home,
13862
+ ...projectPublicTurnAxes(env),
13617
13863
  ...env.host === void 0 ? {} : { host: env.host },
13618
- agentDir: env.agentDir,
13619
- ...env.model === void 0 ? {} : { model: env.model },
13620
- ...pickEngineAxis(env),
13621
- ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs },
13622
13864
  ...correlationId === void 0 || correlationId.trim() === "" ? {} : { correlationId },
13623
13865
  continuation,
13624
13866
  ...env.stationChild === void 0 ? {} : { stationChild: env.stationChild }
@@ -13636,9 +13878,46 @@ async function dispatchAfterWriterLease(input) {
13636
13878
  }
13637
13879
  }
13638
13880
  }
13881
+ async function runSettledAutoResumeLoop(input) {
13882
+ const adapters = withOnceSuccessfulBeforeDispatch(input.adapters);
13883
+ const dispatchEnv = input.dispatchEnv ?? input.env;
13884
+ return runWithAutoResumeLoop({
13885
+ admitted: input.admitted,
13886
+ principalAuthority: input.env.principalAuthority,
13887
+ io: input.io,
13888
+ sessionAppender: input.env.sessionAppender,
13889
+ autoResumeLimit: input.env.autoResumeLimit,
13890
+ ...input.env.signal === void 0 ? {} : { signal: input.env.signal },
13891
+ buildInitialPayload: input.buildInitialPayload,
13892
+ buildResumePayload: input.buildResumePayload,
13893
+ dispatch: async (payload, lease, _isFirst, attemptIo) => dispatchAfterWriterLease({
13894
+ ...lease === void 0 ? {} : { lease },
13895
+ build: () => input.toRequest(payload),
13896
+ dispatch: async (request) => {
13897
+ const result = await dispatchPostAdmissionTurn({
13898
+ admitted: input.admitted,
13899
+ env: dispatchEnv,
13900
+ io: attemptIo,
13901
+ request,
13902
+ ...lease === void 0 ? {} : { lease },
13903
+ adapters,
13904
+ persistRunState: false,
13905
+ ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine }
13906
+ });
13907
+ return settleDeferredPersist(
13908
+ input.admitted,
13909
+ input.env.principalAuthority,
13910
+ adapters,
13911
+ attemptIo,
13912
+ result
13913
+ );
13914
+ }
13915
+ })
13916
+ });
13917
+ }
13639
13918
  function isAlreadyFrozenSummonsAttachment(runDirectory, attachmentPath) {
13640
13919
  const absolute = isAbsolute7(attachmentPath) ? attachmentPath : resolve13(attachmentPath);
13641
- return pathContainedIn(join32(runDirectory, "attachments"), absolute);
13920
+ return pathContainedIn(join33(runDirectory, "attachments"), absolute);
13642
13921
  }
13643
13922
  async function prepareSummonsResumeMaterials(runDirectory, summons) {
13644
13923
  if (summons === void 0) return void 0;
@@ -13749,60 +14028,34 @@ async function runPostAdmissionSeatResume(input) {
13749
14028
  try {
13750
14029
  if (env.stationChild === true) {
13751
14030
  let firstTurn;
13752
- const stationAdapters = withOnceSuccessfulBeforeDispatch(adapters);
13753
14031
  const invocationScopeId = mintEngineDetourInvocationScope({
13754
14032
  ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine }
13755
14033
  });
13756
- return await runWithAutoResumeLoop({
14034
+ return await runSettledAutoResumeLoop({
13757
14035
  admitted: loaded.admitted,
13758
- principalAuthority: env.principalAuthority,
14036
+ env,
13759
14037
  io: input.io,
13760
- sessionAppender: env.sessionAppender,
13761
- autoResumeLimit: env.autoResumeLimit,
13762
- ...env.signal === void 0 ? {} : { signal: env.signal },
14038
+ adapters,
14039
+ ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine },
13763
14040
  buildInitialPayload: () => ({ resumeTurn: false }),
13764
14041
  buildResumePayload: () => ({ resumeTurn: true }),
13765
- // Same as public manual resume: prior-court sealed acceptance is not a
13766
- // redispatch brake (#833). New-court station-child turns still auto-resume.
13767
- dispatch: async (payload, lease, _isFirst, attemptIo) => dispatchAfterWriterLease({
13768
- ...lease === void 0 ? {} : { lease },
13769
- build: async () => {
13770
- if (payload.resumeTurn && firstTurn !== void 0) {
13771
- return {
13772
- ...firstTurn,
13773
- continuation: {
13774
- kind: "resume",
13775
- prompt: RESUME_TRANSPORT_ENVELOPE
13776
- }
13777
- };
13778
- }
13779
- const turnRequest = withEngineDetourInvocationScope(
13780
- await buildRequestAfterLease(),
13781
- invocationScopeId
13782
- );
13783
- firstTurn = turnRequest;
13784
- return turnRequest;
13785
- },
13786
- dispatch: async (turnRequest) => {
13787
- const result = await dispatchPostAdmissionTurn({
13788
- admitted: loaded.admitted,
13789
- env,
13790
- io: attemptIo,
13791
- request: turnRequest,
13792
- ...lease === void 0 ? {} : { lease },
13793
- adapters: stationAdapters,
13794
- persistRunState: false,
13795
- ...input.effectiveEngine === void 0 ? {} : { effectiveEngine: input.effectiveEngine }
13796
- });
13797
- return settleDeferredPersist(
13798
- loaded.admitted,
13799
- env.principalAuthority,
13800
- stationAdapters,
13801
- attemptIo,
13802
- result
13803
- );
14042
+ toRequest: async (payload) => {
14043
+ if (payload.resumeTurn && firstTurn !== void 0) {
14044
+ return {
14045
+ ...firstTurn,
14046
+ continuation: {
14047
+ kind: "resume",
14048
+ prompt: RESUME_TRANSPORT_ENVELOPE
14049
+ }
14050
+ };
13804
14051
  }
13805
- })
14052
+ const turnRequest = withEngineDetourInvocationScope(
14053
+ await buildRequestAfterLease(),
14054
+ invocationScopeId
14055
+ );
14056
+ firstTurn = turnRequest;
14057
+ return turnRequest;
14058
+ }
13806
14059
  });
13807
14060
  }
13808
14061
  const resumed = await runPostAdmissionManualResume({
@@ -13893,7 +14146,7 @@ async function presentResumeFailurePointer(io, thrown, publish) {
13893
14146
  }
13894
14147
  async function writeResumeDiagnosticFile(runDirectory, runId, failure, role) {
13895
14148
  const dir = await ensureRealArtifactsDirectory(runDirectory);
13896
- const path = join32(dir, `resume-diagnostic-${randomUUID7()}.json`);
14149
+ const path = join33(dir, `resume-diagnostic-${randomUUID7()}.json`);
13897
14150
  await writeFile7(
13898
14151
  path,
13899
14152
  `${JSON.stringify({
@@ -13934,38 +14187,25 @@ async function runPostAdmissionOneShot(input) {
13934
14187
  }
13935
14188
  async function runPostAdmissionResumable(input) {
13936
14189
  const { admitted, env, io, buildInitialRequest, buildResumeRequest, effectiveEngine } = input;
13937
- const adapters = withOnceSuccessfulBeforeDispatch(input.adapters);
13938
14190
  const invocationScopeId = mintEngineDetourInvocationScope({
13939
14191
  ...effectiveEngine === void 0 ? {} : { effectiveEngine }
13940
14192
  });
13941
14193
  const buildScopedInitial = () => withEngineDetourInvocationScope(buildInitialRequest(), invocationScopeId);
13942
14194
  const buildScopedResume = () => withEngineDetourInvocationScope(buildResumeRequest(), invocationScopeId);
13943
- return runWithAutoResumeLoop({
14195
+ return runSettledAutoResumeLoop({
13944
14196
  admitted,
13945
- principalAuthority: env.principalAuthority,
14197
+ env,
13946
14198
  io,
13947
- sessionAppender: env.sessionAppender,
13948
- autoResumeLimit: env.autoResumeLimit,
13949
- ...env.signal === void 0 ? {} : { signal: env.signal },
14199
+ adapters: input.adapters,
14200
+ ...effectiveEngine === void 0 ? {} : { effectiveEngine },
14201
+ // Ordinary in-call retry keeps the admitted correlation when one was stored.
14202
+ dispatchEnv: {
14203
+ ...env,
14204
+ ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
14205
+ },
13950
14206
  buildInitialPayload: buildScopedInitial,
13951
14207
  buildResumePayload: buildScopedResume,
13952
- dispatch: async (request, lease, _isFirst, attemptIo) => {
13953
- const result = await dispatchPostAdmissionTurn({
13954
- admitted,
13955
- env: {
13956
- ...env,
13957
- ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
13958
- },
13959
- io: attemptIo,
13960
- request,
13961
- ...lease === void 0 ? {} : { lease },
13962
- adapters,
13963
- persistRunState: false,
13964
- // #600: every attempt (initial + auto-resume) writes seat engine when present.
13965
- ...effectiveEngine === void 0 ? {} : { effectiveEngine }
13966
- });
13967
- return settleDeferredPersist(admitted, env.principalAuthority, adapters, attemptIo, result);
13968
- }
14208
+ toRequest: async (request) => request
13969
14209
  });
13970
14210
  }
13971
14211
  async function runPostAdmissionManualResume(input) {
@@ -13976,326 +14216,86 @@ async function runPostAdmissionManualResume(input) {
13976
14216
  adapters,
13977
14217
  effectiveEngine,
13978
14218
  buildRequestAfterLease
13979
- } = input;
13980
- let request = input.request;
13981
- const effectiveModel = env.model;
13982
- const invocationScopeId = mintEngineDetourInvocationScope({
13983
- ...effectiveEngine === void 0 ? {} : { effectiveEngine }
13984
- });
13985
- if (request === void 0) {
13986
- if (buildRequestAfterLease === void 0) {
13987
- throw new Error(
13988
- "runPostAdmissionManualResume requires request or buildRequestAfterLease"
13989
- );
13990
- }
13991
- request = await buildRequestAfterLease();
13992
- }
13993
- request = withEngineDetourInvocationScope(request, invocationScopeId);
13994
- const result = await dispatchPostAdmissionTurn({
13995
- admitted,
13996
- env: {
13997
- ...env,
13998
- ...effectiveModel === void 0 ? {} : { model: effectiveModel },
13999
- ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
14000
- },
14001
- io,
14002
- request,
14003
- adapters,
14004
- ...effectiveEngine === void 0 ? {} : { effectiveEngine }
14005
- });
14006
- if (result.terminal !== void 0 && isLawfulTypedTerminalOutcome(result.terminal.roleOutcome)) {
14007
- io.stdout(formatTerminalResult(result.terminal));
14008
- }
14009
- if (result.terminal !== void 0) {
14010
- result.terminal.autoResumeCount = 0;
14011
- }
14012
- return result;
14013
- }
14014
- var POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE;
14015
- var init_post_admission = __esm({
14016
- "src/public-cli/post-admission.ts"() {
14017
- "use strict";
14018
- init_run_lifecycle();
14019
- init_cli_errors();
14020
- init_invocation();
14021
- init_submission_ledger();
14022
- init_run_ticket_number();
14023
- init_activation_ledger_topology();
14024
- init_engine_material();
14025
- init_session_identity();
14026
- init_role_run_relocation();
14027
- init_packaged_role_registry();
14028
- init_engine_detour_usage();
14029
- init_run_lifecycle();
14030
- init_process_cancel();
14031
- init_activation_ledger_topology();
14032
- init_host_session_record();
14033
- init_settlement();
14034
- init_terminal();
14035
- init_auto_resume();
14036
- POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE = "ak_post_admission_cleanup_diagnostic";
14037
- }
14038
- });
14039
-
14040
- // src/public-cli/seat-ticket-binding.ts
14041
- async function tryResumeSameTicketSeatRun(input) {
14042
- if (input.freshSummons === true) return void 0;
14043
- if (input.parentRunPath.trim() === "") return void 0;
14044
- const previousRunId = await findLatestRunIdForSeatTicket({
14045
- home: input.home,
14046
- bookKey: resolveBookKeyFromGit(input.projectRoot),
14047
- role: input.role,
14048
- parentRunPath: input.parentRunPath,
14049
- ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
14050
- });
14051
- if (previousRunId === void 0) return void 0;
14052
- return await input.resume(previousRunId, input.summons);
14053
- }
14054
- var init_seat_ticket_binding = __esm({
14055
- "src/public-cli/seat-ticket-binding.ts"() {
14056
- "use strict";
14057
- init_activation_ledger_git();
14058
- init_run_lifecycle();
14059
- }
14060
- });
14061
-
14062
- // src/public-cli/machine-method-skills.ts
14063
- import { accessSync, constants as constants2, statSync as statSync4 } from "node:fs";
14064
- import { lstat as lstat5, mkdir as mkdir4, symlink } from "node:fs/promises";
14065
- import { join as join33 } from "node:path";
14066
- import { spawnSync as spawnSync2 } from "node:child_process";
14067
- function skillRoot(home) {
14068
- return join33(home, ".agents/skills");
14069
- }
14070
- function installedMethodSkillPath(home, name) {
14071
- return installedSkillPath(skillRoot(home), name);
14072
- }
14073
- function installedSkillPath(root, name) {
14074
- const path = join33(root, name, "SKILL.md");
14075
- try {
14076
- if (!statSync4(path).isFile()) return void 0;
14077
- accessSync(path, constants2.R_OK);
14078
- return path;
14079
- } catch (error) {
14080
- const code = error.code;
14081
- if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM" || code === "ELOOP") return void 0;
14082
- throw error;
14083
- }
14084
- }
14085
- function linkedSkillRoot(home, host) {
14086
- if (host === "claude" || host === "claude-code") {
14087
- return join33(process.env.CLAUDE_CONFIG_DIR?.trim() || join33(home, ".claude"), "skills");
14088
- }
14089
- if (host === "hermes") return join33(home, ".hermes/skills");
14090
- return void 0;
14091
- }
14092
- async function occupied(path) {
14093
- try {
14094
- await lstat5(path);
14095
- return true;
14096
- } catch (error) {
14097
- if (error.code !== "ENOENT") throw error;
14098
- return false;
14099
- }
14100
- }
14101
- function warnOccupied(path, stdout) {
14102
- stdout(`Warning: ${path} is already occupied; left untouched.
14103
- `);
14104
- }
14105
- async function warnMissingMethodSkills(home, host, role, skills, stdout) {
14106
- const missing = [];
14107
- const linkedRoot = linkedSkillRoot(home, host);
14108
- for (const skill of skills) {
14109
- if (installedMethodSkillPath(home, skill) === void 0 || linkedRoot !== void 0 && installedSkillPath(linkedRoot, skill) === void 0) missing.push(skill);
14110
- }
14111
- for (const skill of missing) {
14112
- stdout(`Warning: required machine Skill "${skill}" is missing for ${role}; its method guidance may be unavailable and reduce work quality. Run \`ak-role setup\` to install required Skills.
14113
- `);
14114
- }
14115
- }
14116
- function runSkillsCli(args, home) {
14117
- const result = spawnSync2("npx", ["--yes", "skills", ...args], {
14118
- stdio: "inherit",
14119
- env: { ...process.env, HOME: home }
14120
- });
14121
- if (result.error !== void 0) throw result.error;
14122
- return result.status === 0;
14123
- }
14124
- function addSkills(source, skills, home) {
14125
- if (skills.length === 0) return true;
14126
- return runSkillsCli([
14127
- "add",
14128
- source,
14129
- ...skills.flatMap((skill) => ["--skill", skill]),
14130
- "--agent",
14131
- "codex",
14132
- "--global",
14133
- "--yes"
14134
- ], home);
14135
- }
14136
- function updateRequiredSkills(home) {
14137
- const names = packagedMethodSkillNames();
14138
- if (names.length === 0) return true;
14139
- return runSkillsCli(["update", "-g", "-y", ...names], home);
14140
- }
14141
- async function runMachineSkillSetup(home, stdout) {
14142
- const canonical = skillRoot(home);
14143
- const missingBySource = /* @__PURE__ */ new Map();
14144
- let unsourced = false;
14145
- for (const name of packagedMethodSkillNames()) {
14146
- const path = join33(canonical, name);
14147
- if (await occupied(path)) {
14148
- warnOccupied(path, stdout);
14149
- continue;
14150
- }
14151
- const source = SKILL_SOURCE[name];
14152
- if (source === void 0) {
14153
- unsourced = true;
14154
- stdout(`Warning: required machine Skill "${name}" has no install source; setup did not install it.
14155
- `);
14156
- continue;
14157
- }
14158
- const missing = missingBySource.get(source) ?? [];
14159
- missing.push(name);
14160
- missingBySource.set(source, missing);
14161
- }
14162
- for (const [source, missing] of missingBySource) {
14163
- if (!addSkills(source, missing, home)) return 1;
14164
- }
14165
- if (unsourced) return 1;
14166
- for (const host of ["claude-code", "hermes"]) {
14167
- const root = linkedSkillRoot(home, host);
14168
- const description = host === "claude-code" ? HEADLESS_HOST_DESCRIPTIONS.claude : HOST_DESCRIPTIONS.hermes;
14169
- try {
14170
- accessSync(resolveHostBinary(description, home), constants2.X_OK);
14171
- } catch (error) {
14172
- if (["ENOENT", "ENOTDIR", "EACCES"].includes(error.code ?? "")) continue;
14173
- throw error;
14174
- }
14175
- for (const name of packagedMethodSkillNames()) {
14176
- const target = join33(canonical, name);
14177
- if (installedMethodSkillPath(home, name) === void 0) continue;
14178
- const link = join33(root, name);
14179
- if (await occupied(link)) {
14180
- warnOccupied(link, stdout);
14181
- continue;
14182
- }
14183
- await mkdir4(root, { recursive: true });
14184
- await symlink(target, link, "dir");
14219
+ } = input;
14220
+ let request = input.request;
14221
+ const effectiveModel = env.model;
14222
+ const invocationScopeId = mintEngineDetourInvocationScope({
14223
+ ...effectiveEngine === void 0 ? {} : { effectiveEngine }
14224
+ });
14225
+ if (request === void 0) {
14226
+ if (buildRequestAfterLease === void 0) {
14227
+ throw new Error(
14228
+ "runPostAdmissionManualResume requires request or buildRequestAfterLease"
14229
+ );
14185
14230
  }
14231
+ request = await buildRequestAfterLease();
14186
14232
  }
14187
- if (!updateRequiredSkills(home)) return 1;
14188
- stdout("Machine method Skills setup finished. Existing same-name Skills were left untouched.\n");
14189
- return 0;
14233
+ request = withEngineDetourInvocationScope(request, invocationScopeId);
14234
+ const result = await dispatchPostAdmissionTurn({
14235
+ admitted,
14236
+ env: {
14237
+ ...env,
14238
+ ...effectiveModel === void 0 ? {} : { model: effectiveModel },
14239
+ ...admitted.correlationId === void 0 ? {} : { correlationId: admitted.correlationId }
14240
+ },
14241
+ io,
14242
+ request,
14243
+ adapters,
14244
+ ...effectiveEngine === void 0 ? {} : { effectiveEngine }
14245
+ });
14246
+ if (result.terminal !== void 0 && isLawfulTypedTerminalOutcome(result.terminal.roleOutcome)) {
14247
+ io.stdout(formatTerminalResult(result.terminal));
14248
+ }
14249
+ if (result.terminal !== void 0) {
14250
+ result.terminal.autoResumeCount = 0;
14251
+ }
14252
+ return result;
14190
14253
  }
14191
- var SKILL_SOURCE;
14192
- var init_machine_method_skills = __esm({
14193
- "src/public-cli/machine-method-skills.ts"() {
14254
+ var POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE;
14255
+ var init_post_admission = __esm({
14256
+ "src/public-cli/post-admission.ts"() {
14194
14257
  "use strict";
14195
- init_host_descriptions();
14258
+ init_run_lifecycle();
14259
+ init_cli_errors();
14260
+ init_turn_request();
14261
+ init_invocation();
14262
+ init_submission_ledger();
14263
+ init_run_ticket_number();
14264
+ init_activation_ledger_topology();
14265
+ init_engine_material();
14266
+ init_session_identity();
14267
+ init_role_run_relocation();
14196
14268
  init_packaged_role_registry();
14197
- SKILL_SOURCE = {
14198
- tdd: "mattpocock/skills",
14199
- "diagnosing-bugs": "mattpocock/skills",
14200
- "resolving-merge-conflicts": "mattpocock/skills",
14201
- "ak-cross-m-review": "Akagilnc/ak-cross-m-review"
14202
- };
14269
+ init_engine_detour_usage();
14270
+ init_run_lifecycle();
14271
+ init_process_cancel();
14272
+ init_activation_ledger_topology();
14273
+ init_host_session_record();
14274
+ init_settlement();
14275
+ init_terminal();
14276
+ init_auto_resume();
14277
+ POST_ADMISSION_CLEANUP_DIAGNOSTIC_ENTRY_TYPE = "ak_post_admission_cleanup_diagnostic";
14203
14278
  }
14204
14279
  });
14205
14280
 
14206
- // src/public-cli/turn-request.ts
14207
- function projectRoleTurnRequest(admitted, roleDetails, options) {
14208
- const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
14209
- if (cwd === void 0) throw new Error("admitted invocation missing working directory");
14210
- if (admitted.principal === void 0) throw new Error("admitted invocation missing principal");
14211
- return {
14212
- principal: admitted.principal,
14213
- activation: roleDetails.activation,
14214
- methods: roleDetails.methods ?? [],
14215
- continuation: options.continuation,
14216
- ...options.model === void 0 ? {} : { model: options.model },
14217
- ...pickEngineAxis(options),
14218
- cwd,
14219
- home: options.home,
14220
- agentDir: options.agentDir,
14221
- runDirectory: admitted.runDirectory,
14222
- ...options.correlationId === void 0 || options.correlationId.trim() === "" ? {} : { correlationId: options.correlationId },
14223
- ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
14224
- ...options.courtAttemptId === void 0 || options.courtAttemptId.length === 0 ? {} : { courtAttemptId: options.courtAttemptId },
14225
- ...options.invocationScopeId === void 0 || options.invocationScopeId.length === 0 ? {} : { invocationScopeId: options.invocationScopeId },
14226
- ...options.stationChild === void 0 ? {} : { stationChild: options.stationChild }
14227
- };
14228
- }
14229
- function packagedSettleSkill(admitted) {
14230
- const record4 = packagedRoleMetadata(admitted.role);
14231
- if (record4 === void 0) return void 0;
14232
- if ("applyMethod" in record4 && record4.applyMethod !== void 0) {
14233
- return "phase" in admitted && admitted.phase === "apply" ? record4.applyMethod : void 0;
14234
- }
14235
- if ("settleMethod" in record4 && record4.settleMethod !== void 0) return record4.settleMethod;
14236
- return void 0;
14237
- }
14238
- function readAdmittedPath2(admitted, path) {
14239
- let current = admitted;
14240
- for (const key of path.split(".")) {
14241
- if (current === null || typeof current !== "object") return void 0;
14242
- current = current[key];
14243
- }
14244
- return current;
14245
- }
14246
- function activationForAdmitted(admitted) {
14247
- if (packagedRoleMetadata(admitted.role) === void 0) {
14248
- throw new Error(`no turn projection for ${admitted.role}`);
14249
- }
14250
- const activation = { role: admitted.role };
14251
- for (const spec of packagedRoleActivationFlags(admitted.role)) {
14252
- let value = readAdmittedPath2(admitted, spec.from ?? spec.field);
14253
- if (spec.fallback === "gate-pointer") {
14254
- const trimmed = typeof value === "string" ? value.trim() : "";
14255
- value = trimmed !== "" ? trimmed : parentRunPathFromGatePointerInstruction(admitted.instruction);
14256
- if (typeof value !== "string" || value === "") continue;
14257
- }
14258
- if (value === void 0) continue;
14259
- if (spec.text === true) {
14260
- if (typeof value !== "number") continue;
14261
- value = String(value);
14262
- }
14263
- activation[spec.field] = value;
14264
- }
14265
- return activation;
14266
- }
14267
- function requiredMethodSkills(admitted) {
14268
- const record4 = packagedRoleMetadata(admitted.role);
14269
- const names = [];
14270
- if (record4 !== void 0 && "methodSkills" in record4 && record4.methodSkills !== void 0) {
14271
- names.push(...record4.methodSkills);
14272
- }
14273
- const apply = packagedSettleSkill(admitted);
14274
- if (apply !== void 0 && !names.includes(apply)) names.push(apply);
14275
- return names;
14276
- }
14277
- function methodBindings(admitted, home, host) {
14278
- if (host !== void 0 && host !== "pi") return [];
14279
- return requiredMethodSkills(admitted).flatMap((name) => {
14280
- const path = installedMethodSkillPath(home, name);
14281
- return path === void 0 ? [] : [{
14282
- kind: "skill",
14283
- path
14284
- }];
14281
+ // src/public-cli/seat-ticket-binding.ts
14282
+ async function tryResumeSameTicketSeatRun(input) {
14283
+ if (input.freshSummons === true) return void 0;
14284
+ if (input.parentRunPath.trim() === "") return void 0;
14285
+ const previousRunId = await findLatestRunIdForSeatTicket({
14286
+ home: input.home,
14287
+ bookKey: resolveBookKeyFromGit(input.projectRoot),
14288
+ role: input.role,
14289
+ parentRunPath: input.parentRunPath,
14290
+ ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
14285
14291
  });
14292
+ if (previousRunId === void 0) return void 0;
14293
+ return await input.resume(previousRunId, input.summons);
14286
14294
  }
14287
- function admittedSeatTurnDetails(admitted, home, host) {
14288
- return {
14289
- activation: activationForAdmitted(admitted),
14290
- methods: methodBindings(admitted, home, host)
14291
- };
14292
- }
14293
- var init_turn_request = __esm({
14294
- "src/public-cli/turn-request.ts"() {
14295
+ var init_seat_ticket_binding = __esm({
14296
+ "src/public-cli/seat-ticket-binding.ts"() {
14295
14297
  "use strict";
14296
- init_engine_material();
14297
- init_packaged_role_registry();
14298
- init_machine_method_skills();
14298
+ init_activation_ledger_git();
14299
14299
  init_run_lifecycle();
14300
14300
  }
14301
14301
  });
@@ -14410,7 +14410,7 @@ __export(instruction_seat_run_exports, {
14410
14410
  runPublicInstructionSeat: () => runPublicInstructionSeat,
14411
14411
  runPublicInstructionSeatResume: () => runPublicInstructionSeatResume
14412
14412
  });
14413
- import { dirname as dirname20, resolve as resolve14, sep as sep4 } from "node:path";
14413
+ import { dirname as dirname20, resolve as resolve14 } from "node:path";
14414
14414
  function unreadablePostSubmissionStatus(admitted, terminal) {
14415
14415
  if (terminal?.roleOutcome.kind !== "accepted") return void 0;
14416
14416
  const route = POST_SUBMISSION_ROUTING[admitted.role];
@@ -14642,27 +14642,43 @@ async function runOmittedLensBatch(argv, parsed, env, io) {
14642
14642
  io.stdout(formatTerminalResult(terminal));
14643
14643
  return { exitCode: failed ? 1 : 0, terminal };
14644
14644
  }
14645
+ function resumeSameParentInstructionSeat(input) {
14646
+ return tryResumeSameTicketSeatRun({
14647
+ home: input.env.home,
14648
+ projectRoot: input.projectRoot,
14649
+ role: input.role,
14650
+ parentRunPath: input.parentRunPath,
14651
+ ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber },
14652
+ freshSummons: input.env.freshSummons,
14653
+ summons: input.summons,
14654
+ resume: (runId, materials) => runPublicInstructionSeatResume(
14655
+ { runId, ...materials === void 0 ? {} : { summons: materials } },
14656
+ input.env,
14657
+ input.io
14658
+ )
14659
+ });
14660
+ }
14661
+ function sameParentInstruction(env, fallback) {
14662
+ const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
14663
+ if (resumeInstruction === void 0) return fallback;
14664
+ return { instruction: resumeInstruction, instructionEmpty: false };
14665
+ }
14645
14666
  async function runCountersignBody(parsed, env, io) {
14646
14667
  const gateParentRunPath = typeof env.parentRunPath === "string" && env.parentRunPath.trim() !== "" ? env.parentRunPath : void 0;
14647
14668
  if (gateParentRunPath !== void 0) {
14648
14669
  const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction ?? parsed.instruction ?? "";
14649
- const resumed = await tryResumeSameTicketSeatRun({
14650
- home: env.home,
14670
+ const resumed = await resumeSameParentInstructionSeat({
14671
+ env,
14672
+ io,
14651
14673
  projectRoot: resolve14(parsed.project ?? env.cwd),
14652
14674
  role: "countersign",
14653
14675
  parentRunPath: gateParentRunPath,
14654
14676
  ...isSafePositiveTicketNumber(env.boundTicketNumber) ? { ticketNumber: env.boundTicketNumber } : {},
14655
- freshSummons: env.freshSummons,
14656
14677
  summons: {
14657
14678
  sourceRunPath: gateParentRunPath,
14658
14679
  instruction: resumeInstruction,
14659
14680
  instructionEmpty: resumeInstruction.trim() === ""
14660
- },
14661
- resume: (runId, materials) => runPublicInstructionSeatResume(
14662
- { runId, ...materials === void 0 ? {} : { summons: materials } },
14663
- env,
14664
- io
14665
- )
14681
+ }
14666
14682
  });
14667
14683
  if (resumed != null) return resumed;
14668
14684
  }
@@ -14694,12 +14710,7 @@ async function runCountersignBody(parsed, env, io) {
14694
14710
  admitted = { ...admitted, sourceRunPath: gateParentRunPath };
14695
14711
  }
14696
14712
  const turnProjection = {
14697
- packageRoot: env.packageRoot,
14698
- home: env.home,
14699
- agentDir: env.agentDir,
14700
- ...env.model === void 0 ? {} : { model: env.model },
14701
- ...pickEngineAxis(env),
14702
- ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs },
14713
+ ...projectPublicTurnAxes(env),
14703
14714
  ...env.correlationId === void 0 || env.correlationId.trim() === "" ? {} : { correlationId: env.correlationId },
14704
14715
  continuation: {
14705
14716
  kind: "initial",
@@ -14770,17 +14781,18 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14770
14781
  let auditorSubject;
14771
14782
  let auditorSource;
14772
14783
  let auditorTicket;
14784
+ let resolvedNotarySource;
14773
14785
  if (record4.sameParent === "subject-source") {
14774
- if (!isAuditorSoulRole(parsed.subject)) {
14786
+ if (parsed.subject === void 0) {
14775
14787
  presentStructuralRejection(new CliUsageError("auditor --subject requires judge|doctor"), io);
14776
14788
  return { exitCode: 2 };
14777
14789
  }
14778
14790
  auditorSubject = parsed.subject;
14779
- const source = typeof parsed.sourceRun === "string" ? parsed.sourceRun.trim() : "";
14780
- if (source === "") {
14791
+ if (parsed.sourceRun === void 0) {
14781
14792
  presentStructuralRejection(new CliUsageError("auditor --source-run requires a run locator"), io);
14782
14793
  return { exitCode: 2 };
14783
14794
  }
14795
+ const source = parsed.sourceRun;
14784
14796
  try {
14785
14797
  const resolved = await resolveNotarySourceRunLocator({ projectRoot, sourceRun: source, home: env.home });
14786
14798
  auditorSource = resolved.runDirectory;
@@ -14791,26 +14803,23 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14791
14803
  }
14792
14804
  if (auditorSource === void 0) return { exitCode: 2 };
14793
14805
  const sourceDirectory = auditorSource;
14794
- const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
14795
14806
  const summons = {
14796
- ...resumeInstruction === void 0 ? { instruction: parsed.instruction ?? "", instructionEmpty: (parsed.instruction ?? "").trim() === "" } : { instruction: resumeInstruction, instructionEmpty: false },
14807
+ ...sameParentInstruction(env, {
14808
+ instruction: parsed.instruction ?? "",
14809
+ instructionEmpty: (parsed.instruction ?? "").trim() === ""
14810
+ }),
14797
14811
  attachmentPaths: parsed.attachmentPaths ?? []
14798
14812
  };
14799
14813
  const resumed = await withAuditorSoulEnv({
14800
14814
  subject: auditorSubject,
14801
14815
  sourceRunDirectory: auditorSource,
14802
- run: () => tryResumeSameTicketSeatRun({
14803
- home: env.home,
14816
+ run: () => resumeSameParentInstructionSeat({
14817
+ env,
14818
+ io,
14804
14819
  projectRoot,
14805
14820
  role,
14806
14821
  parentRunPath: sourceDirectory,
14807
- freshSummons: env.freshSummons,
14808
- summons,
14809
- resume: (runId, materials) => runPublicInstructionSeatResume(
14810
- { runId, ...materials === void 0 ? {} : { summons: materials } },
14811
- env,
14812
- io
14813
- )
14822
+ summons
14814
14823
  })
14815
14824
  });
14816
14825
  if (resumed != null) return resumed;
@@ -14818,24 +14827,21 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14818
14827
  if (record4.sameParent === "gate-pointer") {
14819
14828
  const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction ?? "");
14820
14829
  if (parentRunPath !== void 0) {
14821
- const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
14822
14830
  const summons = {
14823
14831
  sourceRunPath: parentRunPath,
14824
- ...resumeInstruction === void 0 ? { instruction: parsed.instruction ?? "", instructionEmpty: (parsed.instruction ?? "").trim() === "" } : { instruction: resumeInstruction, instructionEmpty: false },
14832
+ ...sameParentInstruction(env, {
14833
+ instruction: parsed.instruction ?? "",
14834
+ instructionEmpty: (parsed.instruction ?? "").trim() === ""
14835
+ }),
14825
14836
  attachmentPaths: parsed.attachmentPaths ?? []
14826
14837
  };
14827
- const resumed = await tryResumeSameTicketSeatRun({
14828
- home: env.home,
14838
+ const resumed = await resumeSameParentInstructionSeat({
14839
+ env,
14840
+ io,
14829
14841
  projectRoot,
14830
14842
  role,
14831
14843
  parentRunPath,
14832
- freshSummons: env.freshSummons,
14833
- summons,
14834
- resume: (runId, materials) => runPublicInstructionSeatResume(
14835
- { runId, ...materials === void 0 ? {} : { summons: materials } },
14836
- env,
14837
- io
14838
- )
14844
+ summons
14839
14845
  });
14840
14846
  if (resumed != null) return resumed;
14841
14847
  }
@@ -14861,28 +14867,28 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14861
14867
  sourceRun: source,
14862
14868
  ...resumeInstruction === void 0 ? {} : { instruction: resumeInstruction, instructionEmpty: false }
14863
14869
  };
14864
- const resumed = await tryResumeSameTicketSeatRun({
14865
- home: env.home,
14870
+ resolvedNotarySource = source;
14871
+ const resumed = await resumeSameParentInstructionSeat({
14872
+ env,
14873
+ io,
14866
14874
  projectRoot,
14867
14875
  role,
14868
14876
  parentRunPath: source.runDirectory,
14869
- freshSummons: env.freshSummons,
14870
- summons,
14871
- resume: (runId, materials) => runPublicInstructionSeatResume(
14872
- { runId, ...materials === void 0 ? {} : { summons: materials } },
14873
- env,
14874
- io
14875
- )
14877
+ summons
14876
14878
  });
14877
14879
  if (resumed != null) return resumed;
14878
14880
  }
14879
14881
  let admitted;
14880
14882
  try {
14883
+ const admissionOverride = {
14884
+ ...auditorTicket === void 0 ? {} : { assertedTicketNumber: auditorTicket },
14885
+ ...resolvedNotarySource === void 0 ? {} : { resolvedSourceRun: resolvedNotarySource }
14886
+ };
14881
14887
  admitted = await admitPublicRole(
14882
14888
  role,
14883
14889
  parsed,
14884
14890
  env,
14885
- auditorTicket === void 0 ? void 0 : { assertedTicketNumber: auditorTicket }
14891
+ auditorTicket === void 0 && resolvedNotarySource === void 0 ? void 0 : admissionOverride
14886
14892
  );
14887
14893
  } catch (error) {
14888
14894
  const rejected = usageExit(error, io);
@@ -14920,7 +14926,7 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
14920
14926
  thrown: error
14921
14927
  }, seatAdapters(admitted, env), env.principalAuthority, io);
14922
14928
  }
14923
- if (outcome.admitted?.runDirectory.includes(`${sep4}unbound${sep4}runs${sep4}`)) {
14929
+ if (outcome.admitted !== void 0 && isUnboundRunDirectory(outcome.admitted.runDirectory)) {
14924
14930
  await recordChildDiaristRun(admitted, outcome.admitted.runId);
14925
14931
  }
14926
14932
  if (outcome.failedWithoutEscalate !== void 0) {
@@ -15269,6 +15275,7 @@ var AUDITED_ROLES, SECRETARIAT_STATUS_REASK, COUNTERSIGN_STATUS_REASK, WORKER_RO
15269
15275
  var init_instruction_seat_run = __esm({
15270
15276
  "src/public-cli/instruction-seat-run.ts"() {
15271
15277
  "use strict";
15278
+ init_role_run_placement();
15272
15279
  init_compliance_transport();
15273
15280
  init_archivist_record_pointer();
15274
15281
  init_doctor_auditor();
@@ -17466,7 +17473,6 @@ __export(cli_exports, {
17466
17473
  runAkRole: () => runAkRole
17467
17474
  });
17468
17475
  import { realpath as realpath5 } from "node:fs/promises";
17469
- import { join as join37 } from "node:path";
17470
17476
  function publicSeatArgv(owner) {
17471
17477
  return {
17472
17478
  parse: (args) => parsePublicSeatArgv(owner, args),
@@ -17505,50 +17511,42 @@ function takePublicGlobalFlag(argv, index, options) {
17505
17511
  return void 0;
17506
17512
  }
17507
17513
  function createRoleEnvironment(env, options, afterHost) {
17508
- const role = options.role;
17509
17514
  const extraPiArgs = env.extraPiArgs;
17510
17515
  const timeoutMs = env.timeoutMs;
17511
- const hostAdapters = composeRoleTurnHostAdapters(
17512
- {
17516
+ const opened = openRoleSeatRuntime({
17517
+ resolution: {
17513
17518
  packageRoot: env.packageRoot,
17514
17519
  ...env.roleTurnHost === void 0 ? {} : { roleTurnHost: env.roleTurnHost },
17515
17520
  ...env.hostAdapters === void 0 ? {} : { hostAdapters: env.hostAdapters },
17516
17521
  ...extraPiArgs === void 0 ? {} : { extraPiArgs },
17517
17522
  ...timeoutMs === void 0 ? {} : { timeoutMs }
17518
17523
  },
17519
- env.principalAuthority
17520
- );
17521
- const roleTurnHost = selectRoleTurnHost(hostAdapters, {
17522
- role,
17523
- seat: options.seat
17524
+ principalAuthority: env.principalAuthority,
17525
+ role: options.role,
17526
+ seat: options.seat,
17527
+ home: options.home,
17528
+ ...afterHost === void 0 ? {} : { afterHost }
17524
17529
  });
17525
- afterHost?.();
17526
- const seatWithModel = resolvedSeatWithModel(options.seat);
17527
- if (seatWithModel === void 0) {
17530
+ if (!opened.ok) {
17528
17531
  throw new CliUsageError(
17529
17532
  missingResolvedSeatModelMessage(options.seat.seat, "invocation-or-config")
17530
17533
  );
17531
17534
  }
17532
- const hostFacingSelection = projectHostFacingProvider(
17533
- seatWithModel.selection,
17534
- seatWithModel.host,
17535
- loadHostProvidersTable(options.home),
17536
- options.home
17537
- );
17538
17535
  return {
17539
17536
  home: options.home,
17540
17537
  principalAuthority: env.principalAuthority,
17541
17538
  agentDir: options.agentDir,
17542
17539
  sessionAppender: appendPiSessionCustomEntry,
17543
17540
  packageRoot: env.packageRoot,
17544
- roleTurnHost,
17545
- hostAdapters,
17541
+ roleTurnHost: opened.roleTurnHost,
17542
+ hostAdapters: opened.hostAdapters,
17546
17543
  cwd: options.cwd,
17547
17544
  ...options.credentials === void 0 ? {} : { credentials: options.credentials },
17548
17545
  ...env.correlationId === void 0 ? {} : { correlationId: env.correlationId },
17549
- ...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
17550
- ...projectSeatEngine(options.seat),
17551
- ...projectSeatHost(options.seat),
17546
+ ...opened.model === void 0 ? {} : { model: opened.model },
17547
+ ...opened.engine === void 0 ? {} : { engine: opened.engine },
17548
+ ...opened.engineModel === void 0 ? {} : { engineModel: opened.engineModel },
17549
+ host: opened.host,
17552
17550
  ...timeoutMs === void 0 ? {} : { timeoutMs },
17553
17551
  ...env.createRunId === void 0 ? {} : { createRunId: env.createRunId },
17554
17552
  ...options.config?.autoResumeLimit === void 0 ? {} : { autoResumeLimit: options.config.autoResumeLimit },
@@ -17557,15 +17555,19 @@ function createRoleEnvironment(env, options, afterHost) {
17557
17555
  ...env.signal === void 0 ? {} : { signal: env.signal }
17558
17556
  };
17559
17557
  }
17560
- async function dispatchPublicRoleCommand(env, home, io, parsed, role, parse, run) {
17561
- const agentDir = resolveAgentDir(env, home);
17558
+ async function loadPublicRoleDispatchParts(env, home) {
17559
+ const agentDir = resolvePublicAgentDir(env.agentDir, home);
17562
17560
  const cwd = env.cwd ?? process.cwd();
17563
17561
  const config = await loadAndValidateConfig(home, env.packageRoot);
17564
17562
  const credentials = env.credentials ?? await loadCredentialProviders(agentDir);
17563
+ return { agentDir, cwd, config, credentials };
17564
+ }
17565
+ async function dispatchPublicRoleCommand(env, home, io, parsed, role, parse, run) {
17566
+ const parts = await loadPublicRoleDispatchParts(env, home);
17565
17567
  const seat = resolveEffectiveSeat(
17566
- config,
17568
+ parts.config,
17567
17569
  role,
17568
- credentials,
17570
+ parts.credentials,
17569
17571
  invocationFromParsed(parsed)
17570
17572
  );
17571
17573
  let parsedRoleArgv;
@@ -17573,7 +17575,15 @@ async function dispatchPublicRoleCommand(env, home, io, parsed, role, parse, run
17573
17575
  parsed.args,
17574
17576
  createRoleEnvironment(
17575
17577
  env,
17576
- { role, home, agentDir, cwd, credentials, seat, config },
17578
+ {
17579
+ role,
17580
+ home,
17581
+ agentDir: parts.agentDir,
17582
+ cwd: parts.cwd,
17583
+ credentials: parts.credentials,
17584
+ seat,
17585
+ config: parts.config
17586
+ },
17577
17587
  () => {
17578
17588
  parsedRoleArgv = parse(parsed.args);
17579
17589
  }
@@ -17604,9 +17614,6 @@ function defaultIo() {
17604
17614
  function resolveHome(env) {
17605
17615
  return env.home ?? packageMachineHome();
17606
17616
  }
17607
- function resolveAgentDir(env, home) {
17608
- return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join37(home, ".pi", "agent");
17609
- }
17610
17617
  function parseThinking(value) {
17611
17618
  return value;
17612
17619
  }
@@ -17725,12 +17732,6 @@ function requireCallableSeat(seat, axis, verb) {
17725
17732
  throw new CliUsageError(`unknown ${axis}-axis seat: ${seat}`);
17726
17733
  }
17727
17734
  }
17728
- function projectSeatEngine(seat) {
17729
- return pickEngineAxis(seat);
17730
- }
17731
- function projectSeatHost(seat) {
17732
- return { host: seat.host };
17733
- }
17734
17735
  function loadAndValidateConfig(home, packageRoot) {
17735
17736
  return loadPublicCliConfig(home).then((config) => {
17736
17737
  try {
@@ -18176,7 +18177,7 @@ async function runAkRole(argv, env) {
18176
18177
  throw new CliUsageError("roles takes no arguments");
18177
18178
  }
18178
18179
  const config = await loadAndValidateConfig(home, env.packageRoot);
18179
- const credentials = env.credentials ?? await loadCredentialProviders(resolveAgentDir(env, home));
18180
+ const credentials = env.credentials ?? await loadCredentialProviders(resolvePublicAgentDir(env.agentDir, home));
18180
18181
  const seats = effectiveSeatConfigurations(
18181
18182
  config,
18182
18183
  credentials,
@@ -18216,16 +18217,13 @@ async function runAkRole(argv, env) {
18216
18217
  runId: resumeRequest.runId,
18217
18218
  authority: env.principalAuthority ?? piDurablePrincipalAuthority
18218
18219
  };
18219
- const agentDir = resolveAgentDir(env, home);
18220
- const cwd = env.cwd ?? process.cwd();
18221
- const config = await loadAndValidateConfig(home, env.packageRoot);
18222
- const credentials = env.credentials ?? await loadCredentialProviders(agentDir);
18220
+ const parts = await loadPublicRoleDispatchParts(env, home);
18223
18221
  const resumeRole = await peekRoleRunRole(home, resumeRequest.runId);
18224
18222
  const seatRole = resumeRole ?? "judge";
18225
18223
  const seat = resolveEffectiveSeat(
18226
- config,
18224
+ parts.config,
18227
18225
  seatRole,
18228
- credentials,
18226
+ parts.credentials,
18229
18227
  invocationFromParsed(parsed)
18230
18228
  );
18231
18229
  const result = await runPublicInstructionSeatResume(
@@ -18233,11 +18231,11 @@ async function runAkRole(argv, env) {
18233
18231
  createRoleEnvironment(env, {
18234
18232
  role: seatRole,
18235
18233
  home,
18236
- agentDir,
18237
- cwd,
18238
- credentials,
18234
+ agentDir: parts.agentDir,
18235
+ cwd: parts.cwd,
18236
+ credentials: parts.credentials,
18239
18237
  seat,
18240
- config
18238
+ config: parts.config
18241
18239
  }),
18242
18240
  io
18243
18241
  );
@@ -18251,15 +18249,20 @@ async function runAkRole(argv, env) {
18251
18249
  };
18252
18250
  const parentRole = await peekRoleRunRole(home, parentRunId);
18253
18251
  if (parentRole === void 0) break;
18254
- const parentSeat = resolveEffectiveSeat(config, parentRole, credentials, invocationFromParsed(parsed));
18252
+ const parentSeat = resolveEffectiveSeat(
18253
+ parts.config,
18254
+ parentRole,
18255
+ parts.credentials,
18256
+ invocationFromParsed(parsed)
18257
+ );
18255
18258
  const parentEnv = createRoleEnvironment(env, {
18256
18259
  role: parentRole,
18257
18260
  home,
18258
- agentDir,
18259
- cwd,
18260
- credentials,
18261
+ agentDir: parts.agentDir,
18262
+ cwd: parts.cwd,
18263
+ credentials: parts.credentials,
18261
18264
  seat: parentSeat,
18262
- config
18265
+ config: parts.config
18263
18266
  });
18264
18267
  current = await continueParentAfterChild(parentRunId, current.admitted, parentEnv, io);
18265
18268
  }
@@ -18342,6 +18345,7 @@ var init_cli = __esm({
18342
18345
  init_machine_method_skills();
18343
18346
  init_post_admission();
18344
18347
  init_role_turn_host();
18348
+ init_role_seat_runtime();
18345
18349
  init_role_turn_host_resolution();
18346
18350
  init_invocation();
18347
18351
  init_option_definitions();
@@ -18377,7 +18381,7 @@ __export(public_role_summons_exports, {
18377
18381
  import { execFile as execFile3 } from "node:child_process";
18378
18382
  import { existsSync as existsSync10 } from "node:fs";
18379
18383
  import { realpath as realpath6 } from "node:fs/promises";
18380
- import { join as join38 } from "node:path";
18384
+ import { join as join37 } from "node:path";
18381
18385
  import { promisify as promisify3 } from "node:util";
18382
18386
  function createCapturingIo() {
18383
18387
  const chunks = [];
@@ -18401,7 +18405,7 @@ function parentDir(path) {
18401
18405
  function walkPackageRoot(start) {
18402
18406
  let dir = start;
18403
18407
  for (let i = 0; i < 12; i += 1) {
18404
- if (existsSync10(join38(dir, "package.json")) && existsSync10(join38(dir, "souls"))) {
18408
+ if (existsSync10(join37(dir, "package.json")) && existsSync10(join37(dir, "souls"))) {
18405
18409
  return dir;
18406
18410
  }
18407
18411
  const parent = parentDir(dir);
@@ -18442,12 +18446,6 @@ async function resolveSummonHome(options) {
18442
18446
  if (fromCwd !== void 0 && fromCwd.length > 0) return fromCwd;
18443
18447
  return packageMachineHome2();
18444
18448
  }
18445
- function projectSeatEngine2(seat) {
18446
- return pickEngineAxis(seat);
18447
- }
18448
- function projectSeatHost2(seat) {
18449
- return seat.host === void 0 ? {} : { host: seat.host };
18450
- }
18451
18449
  function hostSelectionFailureFromUnknown(error) {
18452
18450
  if (typeof error !== "object" || error === null) return void 0;
18453
18451
  if (error.name !== "HostSelectionError") return void 0;
@@ -18458,44 +18456,36 @@ async function createSummonEnv(options, afterHost) {
18458
18456
  const [
18459
18457
  { piDurablePrincipalAuthority: piDurablePrincipalAuthority2 },
18460
18458
  { appendPiSessionCustomEntry: appendPiSessionCustomEntry2 },
18461
- { resolveRoleTurnHost: resolveRoleTurnHost2 },
18462
- { missingResolvedSeatModelMessage: missingResolvedSeatModelMessage2, resolvedSeatWithModel: resolvedSeatWithModel2 }
18459
+ { openRoleSeatRuntime: openRoleSeatRuntime2 },
18460
+ { missingResolvedSeatModelMessage: missingResolvedSeatModelMessage2 }
18463
18461
  ] = await Promise.all([
18464
18462
  Promise.resolve().then(() => (init_durable_principal(), durable_principal_exports)),
18465
18463
  Promise.resolve().then(() => (init_role_turn_host(), role_turn_host_exports)),
18466
- Promise.resolve().then(() => (init_role_turn_host_resolution(), role_turn_host_resolution_exports)),
18464
+ Promise.resolve().then(() => (init_role_seat_runtime(), role_seat_runtime_exports)),
18467
18465
  Promise.resolve().then(() => (init_config(), config_exports))
18468
18466
  ]);
18469
18467
  const principalAuthority = options.principalAuthority ?? piDurablePrincipalAuthority2;
18470
- const roleTurnHost = resolveRoleTurnHost2(
18471
- {
18468
+ const opened = openRoleSeatRuntime2({
18469
+ resolution: {
18472
18470
  packageRoot: options.packageRoot,
18473
18471
  ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
18474
18472
  ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
18475
18473
  ...options.extraPiArgs === void 0 || options.extraPiArgs.length === 0 ? {} : { extraPiArgs: options.extraPiArgs },
18476
18474
  ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
18477
18475
  },
18478
- { role: options.role, seat: options.seat, principalAuthority }
18479
- );
18480
- afterHost?.();
18481
- const seatWithModel = resolvedSeatWithModel2(options.seat);
18482
- if (seatWithModel === void 0) {
18476
+ principalAuthority,
18477
+ role: options.role,
18478
+ seat: options.seat,
18479
+ home: options.home,
18480
+ ...afterHost === void 0 ? {} : { afterHost },
18481
+ ...options.hostFacingModel === void 0 ? {} : { hostFacingModel: options.hostFacingModel }
18482
+ });
18483
+ if (!opened.ok) {
18483
18484
  return {
18484
18485
  ok: false,
18485
18486
  missingModelMessage: missingResolvedSeatModelMessage2(options.role)
18486
18487
  };
18487
18488
  }
18488
- const hostName = seatWithModel.host ?? "pi";
18489
- let hostFacingSelection = options.hostFacingModel;
18490
- if (hostFacingSelection === void 0) {
18491
- const { loadHostProvidersTable: loadHostProvidersTable2, projectHostFacingProvider: projectHostFacingProvider2 } = await Promise.resolve().then(() => (init_host_providers(), host_providers_exports));
18492
- hostFacingSelection = projectHostFacingProvider2(
18493
- seatWithModel.selection,
18494
- hostName,
18495
- loadHostProvidersTable2(options.home),
18496
- options.home
18497
- );
18498
- }
18499
18489
  return {
18500
18490
  ok: true,
18501
18491
  env: {
@@ -18504,12 +18494,13 @@ async function createSummonEnv(options, afterHost) {
18504
18494
  agentDir: options.agentDir,
18505
18495
  sessionAppender: appendPiSessionCustomEntry2,
18506
18496
  packageRoot: options.packageRoot,
18507
- roleTurnHost,
18497
+ roleTurnHost: opened.roleTurnHost,
18508
18498
  cwd: options.cwd,
18509
18499
  credentials: options.credentials,
18510
- ...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
18511
- ...projectSeatEngine2(seatWithModel),
18512
- ...projectSeatHost2(seatWithModel),
18500
+ ...opened.model === void 0 ? {} : { model: opened.model },
18501
+ ...opened.engine === void 0 ? {} : { engine: opened.engine },
18502
+ ...opened.engineModel === void 0 ? {} : { engineModel: opened.engineModel },
18503
+ host: opened.host,
18513
18504
  ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }
18514
18505
  }
18515
18506
  };
@@ -18517,13 +18508,14 @@ async function createSummonEnv(options, afterHost) {
18517
18508
  async function summonPublicRole(options) {
18518
18509
  const packageRoot = resolveSummonsPackageRoot(options.packageRoot);
18519
18510
  const home = await resolveSummonHome(options);
18520
- const agentDir = options.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join38(home, ".pi", "agent");
18521
18511
  const {
18522
18512
  loadCredentialProviders: loadCredentialProviders2,
18523
18513
  loadPublicCliConfig: loadPublicCliConfig2,
18524
18514
  resolveEffectiveSeat: resolveEffectiveSeat2,
18515
+ resolvePublicAgentDir: resolvePublicAgentDir2,
18525
18516
  validatePublicCliConfigAxes: validatePublicCliConfigAxes2
18526
18517
  } = await Promise.resolve().then(() => (init_config(), config_exports));
18518
+ const agentDir = resolvePublicAgentDir2(options.agentDir, home);
18527
18519
  const credentials = options.credentials ?? await loadCredentialProviders2(agentDir);
18528
18520
  const config = await loadPublicCliConfig2(home);
18529
18521
  validatePublicCliConfigAxes2(config, packageRoot);
@@ -18880,7 +18872,6 @@ var AK_ROLE_PACKAGE_ROOT_ENV, execFileAsync3;
18880
18872
  var init_public_role_summons = __esm({
18881
18873
  "src/public-role-summons.ts"() {
18882
18874
  "use strict";
18883
- init_engine_material();
18884
18875
  AK_ROLE_PACKAGE_ROOT_ENV = "AK_ROLE_PACKAGE_ROOT";
18885
18876
  execFileAsync3 = promisify3(execFile3);
18886
18877
  }
@@ -19025,11 +19016,11 @@ var init_compliance_transport = __esm({
19025
19016
  });
19026
19017
 
19027
19018
  // src/role-run-relocation.ts
19028
- import { join as join39, sep as sep5 } from "node:path";
19019
+ import { join as join38, sep as sep4 } from "node:path";
19029
19020
  function rewriteRunDirectoryPathValue(value, oldRunDirectory, newRunDirectory) {
19030
19021
  if (typeof value !== "string") return value;
19031
19022
  if (value === oldRunDirectory) return newRunDirectory;
19032
- const prefix = `${oldRunDirectory}${sep5}`;
19023
+ const prefix = `${oldRunDirectory}${sep4}`;
19033
19024
  if (value.startsWith(prefix)) {
19034
19025
  return `${newRunDirectory}${value.slice(oldRunDirectory.length)}`;
19035
19026
  }
@@ -19039,7 +19030,7 @@ function rewriteRunDirectoryPathValueAgainstRewrites(value, rewrites) {
19039
19030
  if (typeof value !== "string" || rewrites.length === 0) return value;
19040
19031
  let best;
19041
19032
  for (const rewrite of rewrites) {
19042
- if (value === rewrite.oldRunDirectory || value.startsWith(`${rewrite.oldRunDirectory}${sep5}`)) {
19033
+ if (value === rewrite.oldRunDirectory || value.startsWith(`${rewrite.oldRunDirectory}${sep4}`)) {
19043
19034
  if (best === void 0 || rewrite.oldRunDirectory.length > best.oldRunDirectory.length) {
19044
19035
  best = rewrite;
19045
19036
  }
@@ -19153,7 +19144,7 @@ __export(run_lifecycle_exports, {
19153
19144
  writeRoleRunState: () => writeRoleRunState
19154
19145
  });
19155
19146
  import { chmod, lstat as lstat6, open as open3, readdir as readdir7, readFile as readFile22, unlink as unlink5, writeFile as writeFile8 } from "node:fs/promises";
19156
- import { basename as basename10, join as join40 } from "node:path";
19147
+ import { basename as basename10, join as join39 } from "node:path";
19157
19148
  function buildAutoResumeContinuationPrompt(options) {
19158
19149
  return appendEngineSessionMaterial(
19159
19150
  [RESUME_TRANSPORT_ENVELOPE],
@@ -19179,7 +19170,7 @@ function renderResumeCommand(runId) {
19179
19170
  async function writeRoleRunState(runDirectory, record4) {
19180
19171
  const payload = { ...record4, runDirectory };
19181
19172
  await writeFile8(
19182
- join40(runDirectory, RUN_STATE_FILE),
19173
+ join39(runDirectory, RUN_STATE_FILE),
19183
19174
  `${JSON.stringify(payload, null, 2)}
19184
19175
  `,
19185
19176
  "utf8"
@@ -19229,7 +19220,7 @@ function parseCurrentCourtState(raw) {
19229
19220
  async function readRoleRunStateRaw(runDirectory) {
19230
19221
  let raw;
19231
19222
  try {
19232
- raw = JSON.parse(await readFile22(join40(runDirectory, RUN_STATE_FILE), "utf8"));
19223
+ raw = JSON.parse(await readFile22(join39(runDirectory, RUN_STATE_FILE), "utf8"));
19233
19224
  } catch (error) {
19234
19225
  if (errorCodeOf(error) === "ENOENT") return void 0;
19235
19226
  throw error;
@@ -19323,7 +19314,7 @@ async function writeRoleRunStateDisk(runDirectory, disk) {
19323
19314
  ...disk.currentCourt === void 0 ? {} : { currentCourt: disk.currentCourt }
19324
19315
  };
19325
19316
  await writeFile8(
19326
- join40(runDirectory, RUN_STATE_FILE),
19317
+ join39(runDirectory, RUN_STATE_FILE),
19327
19318
  `${JSON.stringify(payload, null, 2)}
19328
19319
  `,
19329
19320
  "utf8"
@@ -19546,7 +19537,7 @@ async function createWriterLease(lockPath, runDirectory, reportCleanupFailure) {
19546
19537
  },
19547
19538
  relocate(nextRunDirectory) {
19548
19539
  currentRunDirectory = nextRunDirectory;
19549
- currentLockPath = join40(nextRunDirectory, WRITER_LOCK_FILE);
19540
+ currentLockPath = join39(nextRunDirectory, WRITER_LOCK_FILE);
19550
19541
  },
19551
19542
  async release() {
19552
19543
  if (released) return;
@@ -19585,10 +19576,10 @@ async function acquireRunWriterLease(runDirectory, onCleanupFailure) {
19585
19576
  };
19586
19577
  const reportReadFailure = (error) => {
19587
19578
  reportDiagnostic(
19588
- `writer lease lock read failed (holder liveness unverifiable; lock left in place) at ${join40(runDirectory, WRITER_LOCK_FILE)}: ${describeErrorIdentity(error)}`
19579
+ `writer lease lock read failed (holder liveness unverifiable; lock left in place) at ${join39(runDirectory, WRITER_LOCK_FILE)}: ${describeErrorIdentity(error)}`
19589
19580
  );
19590
19581
  };
19591
- const lockPath = join40(runDirectory, WRITER_LOCK_FILE);
19582
+ const lockPath = join39(runDirectory, WRITER_LOCK_FILE);
19592
19583
  let lastAutopsy = { verdict: "absent" };
19593
19584
  let lastReclaimFailure;
19594
19585
  for (let reclaimsLeft = WRITER_LEASE_RECLAIM_ROUNDS; ; reclaimsLeft -= 1) {
@@ -19643,7 +19634,7 @@ async function acquireRunWriterLease(runDirectory, onCleanupFailure) {
19643
19634
  async function findRunDirectoryById(home, runId, onlyBookKey, onlyRole) {
19644
19635
  if (runId.trim() === "") return void 0;
19645
19636
  const ledgerHome = resolveActivationLedgerHome(home);
19646
- const booksRoot = join40(ledgerHome, "books");
19637
+ const booksRoot = join39(ledgerHome, "books");
19647
19638
  let bookKeys;
19648
19639
  try {
19649
19640
  bookKeys = await readdir7(booksRoot);
@@ -19684,7 +19675,7 @@ async function readRunParentPath(runDirectory) {
19684
19675
  let raw;
19685
19676
  try {
19686
19677
  raw = JSON.parse(
19687
- await readFile22(join40(runDirectory, "admitted-request.json"), "utf8")
19678
+ await readFile22(join39(runDirectory, "admitted-request.json"), "utf8")
19688
19679
  );
19689
19680
  } catch (error) {
19690
19681
  if (errorCodeOf(error) === "ENOENT") return void 0;
@@ -19705,7 +19696,7 @@ async function readRunParentPath(runDirectory) {
19705
19696
  async function runHasFormedSessionPrincipal(runDirectory) {
19706
19697
  const disk = await readRoleRunStateDisk(runDirectory);
19707
19698
  if (disk === void 0) return false;
19708
- const sessionFile = typeof disk.principalWire.sessionFile === "string" && disk.principalWire.sessionFile.trim() !== "" ? disk.principalWire.sessionFile : join40(disk.principalWire.sessionDirectory, "session.jsonl");
19699
+ const sessionFile = typeof disk.principalWire.sessionFile === "string" && disk.principalWire.sessionFile.trim() !== "" ? disk.principalWire.sessionFile : join39(disk.principalWire.sessionDirectory, "session.jsonl");
19709
19700
  try {
19710
19701
  const stat2 = await lstat6(sessionFile);
19711
19702
  return stat2.isFile() && !stat2.isSymbolicLink();
@@ -19723,7 +19714,7 @@ async function findLatestRunIdForSeatTicket(input) {
19723
19714
  let runDirectories;
19724
19715
  try {
19725
19716
  runDirectories = await listBookRunDirectories(
19726
- input.ticketNumber === void 0 ? bookDir : join40(bookDir, String(input.ticketNumber))
19717
+ input.ticketNumber === void 0 ? bookDir : join39(bookDir, String(input.ticketNumber))
19727
19718
  );
19728
19719
  } catch (error) {
19729
19720
  if (errorCodeOf(error) === "ENOENT") return void 0;
@@ -19921,7 +19912,7 @@ async function loadResumableRunRecord(home, runId, authority) {
19921
19912
  let model;
19922
19913
  try {
19923
19914
  const invocationRaw = JSON.parse(
19924
- await readFile22(join40(run.runDirectory, "invocation.json"), "utf8")
19915
+ await readFile22(join39(run.runDirectory, "invocation.json"), "utf8")
19925
19916
  );
19926
19917
  if (invocationRaw !== null && typeof invocationRaw === "object" && !Array.isArray(invocationRaw)) {
19927
19918
  const rec = invocationRaw;
@@ -20113,14 +20104,10 @@ function admitResumedRole(loaded) {
20113
20104
  }
20114
20105
  case "review-basis": {
20115
20106
  const rawBase = fields.baseRevision;
20116
- if (rawBase === void 0 || rawBase.trim() === "") {
20117
- throw new CliUsageError(
20118
- `role run admitted reviewer base revision is missing: ${runId}`
20119
- );
20120
- }
20121
- if (/\s/.test(rawBase) || rawBase.startsWith("-")) {
20107
+ const baseFault = admittedReviewerBaseFault(rawBase);
20108
+ if (baseFault !== void 0 || rawBase === void 0) {
20122
20109
  throw new CliUsageError(
20123
- `role run admitted reviewer base revision is damaged: ${runId}`
20110
+ baseFault === "damaged" ? `role run admitted reviewer base revision is damaged: ${runId}` : `role run admitted reviewer base revision is missing: ${runId}`
20124
20111
  );
20125
20112
  }
20126
20113
  const lens = fields.lens;
@@ -20290,7 +20277,7 @@ var init_run_lifecycle = __esm({
20290
20277
 
20291
20278
  // src/archivist-record-topology.ts
20292
20279
  import { createHash as createHash4 } from "node:crypto";
20293
- import { join as join41 } from "node:path";
20280
+ import { join as join40 } from "node:path";
20294
20281
  function resolveNavigatorWorkSubjectPlacement(input) {
20295
20282
  let ledgerHome;
20296
20283
  if (input.parentSessionFile !== void 0 && input.parentSessionFile.length > 0) {
@@ -20303,7 +20290,7 @@ function resolveNavigatorWorkSubjectPlacement(input) {
20303
20290
  const digest = createHash4("sha256").update(input.subject).digest("hex").slice(0, 32);
20304
20291
  return {
20305
20292
  ledgerHome,
20306
- sessionDir: join41(
20293
+ sessionDir: join40(
20307
20294
  activationBookDirectory(ledgerHome, resolveBookKeyFromGit(input.cwd)),
20308
20295
  NAVIGATOR_RECORD_KIND,
20309
20296
  digest
@@ -20375,10 +20362,10 @@ import {
20375
20362
  statSync as statSync6,
20376
20363
  writeFileSync as writeFileSync2
20377
20364
  } from "node:fs";
20378
- import { dirname as dirname23, resolve as resolve16, join as join42 } from "node:path";
20365
+ import { dirname as dirname23, resolve as resolve16, join as join41 } from "node:path";
20379
20366
  import { StringDecoder } from "node:string_decoder";
20380
20367
  function readCurrentSession(sessionDir) {
20381
- const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
20368
+ const ledger = join41(sessionDir, CURRENT_SESSION_LEDGER);
20382
20369
  try {
20383
20370
  const value = JSON.parse(readFileSync4(ledger, "utf8"));
20384
20371
  if (typeof value !== "object" || value === null || typeof value.sessionFile !== "string" || value.sessionFile.length === 0) {
@@ -20393,7 +20380,7 @@ function readCurrentSession(sessionDir) {
20393
20380
  }
20394
20381
  }
20395
20382
  function writeCurrentSession(sessionDir, sessionFile) {
20396
- const ledger = join42(sessionDir, CURRENT_SESSION_LEDGER);
20383
+ const ledger = join41(sessionDir, CURRENT_SESSION_LEDGER);
20397
20384
  try {
20398
20385
  writeFileSync2(ledger, `${JSON.stringify({ sessionFile })}
20399
20386
  `, { flag: "wx" });
@@ -20409,7 +20396,7 @@ function isCurrentSessionClaimRace(error) {
20409
20396
  return errnoCode(error.cause) === "EEXIST";
20410
20397
  }
20411
20398
  function currentSessionLedgerPath(sessionDir) {
20412
- return join42(sessionDir, CURRENT_SESSION_LEDGER);
20399
+ return join41(sessionDir, CURRENT_SESSION_LEDGER);
20413
20400
  }
20414
20401
  function readBoundedSessionHeader(filePath) {
20415
20402
  const fd = openSync2(filePath, "r");
@@ -20496,7 +20483,7 @@ function mostRecentNavigatorSessionFile(sessionDir, cwd) {
20496
20483
  const matched = [];
20497
20484
  for (const name of names) {
20498
20485
  if (!name.endsWith(".jsonl")) continue;
20499
- const filePath = join42(absoluteSessionDir, name);
20486
+ const filePath = join41(absoluteSessionDir, name);
20500
20487
  let st;
20501
20488
  try {
20502
20489
  st = statSync6(filePath);
@@ -20608,7 +20595,7 @@ function createRecordSessionOpen(options, host = piRecordSessionHost) {
20608
20595
  if (!physicallyContainedIn(ledgerHome, parentResolved)) {
20609
20596
  throw new Error("Durable record ownership requires a parent session inside the ledger home");
20610
20597
  }
20611
- sessionDir = join42(dirname23(parentResolved), options.kind);
20598
+ sessionDir = join41(dirname23(parentResolved), options.kind);
20612
20599
  parentSession = parentFile;
20613
20600
  mayResumeSameNest = options.kind === WORKER_SUBMISSION_GATE_KIND;
20614
20601
  }
@@ -21747,7 +21734,7 @@ init_sitian_facade();
21747
21734
  init_submission_ledger();
21748
21735
  import { randomUUID as randomUUID8 } from "node:crypto";
21749
21736
  import { readFileSync as readFileSync6, writeSync as writeSync2 } from "node:fs";
21750
- import { join as join44 } from "node:path";
21737
+ import { join as join43 } from "node:path";
21751
21738
  import { Value as Value4 } from "typebox/value";
21752
21739
 
21753
21740
  // src/activation-trace.ts
@@ -22780,11 +22767,11 @@ function reliableWindow(cwd, baseline, head) {
22780
22767
  const raw = git2(cwd, ["log", "--format=%P%x1e%s", range]);
22781
22768
  if (raw.length === 0) return [];
22782
22769
  return raw.split("\n").flatMap((line2) => {
22783
- const sep6 = line2.indexOf("");
22784
- if (sep6 < 0) return [];
22770
+ const sep5 = line2.indexOf("");
22771
+ if (sep5 < 0) return [];
22785
22772
  return [{
22786
- subject: line2.slice(sep6 + 1),
22787
- merge: line2.slice(0, sep6).trim().includes(" ")
22773
+ subject: line2.slice(sep5 + 1),
22774
+ merge: line2.slice(0, sep5).trim().includes(" ")
22788
22775
  }];
22789
22776
  });
22790
22777
  }
@@ -23633,7 +23620,7 @@ function readDiaristTicketAssertion(submitted) {
23633
23620
  function readRoleRunCoordinates(ctx, label) {
23634
23621
  const runDirectory = runDirectoryFromHostContext(ctx);
23635
23622
  if (runDirectory === void 0) throw new Error(`${label} requires AK_ROLE_RUN_DIR`);
23636
- const admittedPath = join44(runDirectory, "admitted-request.json");
23623
+ const admittedPath = join43(runDirectory, "admitted-request.json");
23637
23624
  const admitted = JSON.parse(readFileSync6(admittedPath, "utf8"));
23638
23625
  if (typeof admitted.projectRoot !== "string" || admitted.projectRoot.trim() === "") {
23639
23626
  throw new Error(`${label} admitted-request missing projectRoot (${admittedPath})`);
@@ -24563,7 +24550,7 @@ init_packaged_role_registry();
24563
24550
  import { randomUUID as randomUUID9 } from "node:crypto";
24564
24551
  import { appendFile as appendFile3, mkdir as mkdir5, writeFile as writeFile9 } from "node:fs/promises";
24565
24552
  import { createServer } from "node:net";
24566
- import { dirname as dirname25, join as join45 } from "node:path";
24553
+ import { dirname as dirname25, join as join44 } from "node:path";
24567
24554
  import { fileURLToPath as fileURLToPath2 } from "node:url";
24568
24555
  init_role_activation_flags();
24569
24556
  init_submission_correctable_error();
@@ -24609,7 +24596,7 @@ async function prepareRoleEnvelope(options) {
24609
24596
  const hostAbort = new AbortController();
24610
24597
  const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID9();
24611
24598
  await mkdir5(request.runDirectory, { recursive: true });
24612
- let sessionFile = options.sessionFile ?? join45(request.runDirectory, "session", "session.jsonl");
24599
+ let sessionFile = options.sessionFile ?? join44(request.runDirectory, "session", "session.jsonl");
24613
24600
  await mkdir5(dirname25(sessionFile), { recursive: true });
24614
24601
  if (request.continuation.kind !== "resume") {
24615
24602
  try {
@@ -25133,7 +25120,7 @@ import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
25133
25120
  import { randomUUID as randomUUID10 } from "node:crypto";
25134
25121
  import { existsSync as existsSync15 } from "node:fs";
25135
25122
  import { writeFile as writeFile10 } from "node:fs/promises";
25136
- import { dirname as dirname26, isAbsolute as isAbsolute12, join as join46, resolve as resolve21 } from "node:path";
25123
+ import { dirname as dirname26, isAbsolute as isAbsolute12, join as join45, resolve as resolve21 } from "node:path";
25137
25124
 
25138
25125
  // src/external-host-turn-loop.ts
25139
25126
  var EXTERNAL_ROLE_TURN_ROUND_LIMIT = 8;
@@ -25583,7 +25570,7 @@ function formatCodexFailurePayload(payload) {
25583
25570
  function cwdIsGitWorkTree(cwd) {
25584
25571
  let dir = cwd;
25585
25572
  for (; ; ) {
25586
- if (existsSync15(join46(dir, ".git"))) return true;
25573
+ if (existsSync15(join45(dir, ".git"))) return true;
25587
25574
  const parent = dirname26(dir);
25588
25575
  if (parent === dir) return false;
25589
25576
  dir = parent;
@@ -25794,13 +25781,13 @@ function createHeadlessRoleTurnHost(config) {
25794
25781
  await config.sessionIdentity.bind(request.principal, sessionId);
25795
25782
  }
25796
25783
  const env = { ...process.env, ...config.env ?? {} };
25797
- const systemPromptPath = join46(request.runDirectory, "headless-system-prompt.txt");
25784
+ const systemPromptPath = join45(request.runDirectory, "headless-system-prompt.txt");
25798
25785
  await writeFile10(systemPromptPath, systemPrompt, "utf8");
25799
25786
  let mcpConfigPath;
25800
25787
  let outputSchemaPath;
25801
25788
  if (codex) {
25802
25789
  if (prepared.terminatingToolName !== NAVIGATOR_OUTPUT_TOOL_NAME) {
25803
- outputSchemaPath = join46(request.runDirectory, "headless-output-schema.json");
25790
+ outputSchemaPath = join45(request.runDirectory, "headless-output-schema.json");
25804
25791
  await writeFile10(
25805
25792
  outputSchemaPath,
25806
25793
  `${JSON.stringify(closeJsonSchemaForCodex(prepared.jsonSchema), null, 2)}
@@ -25809,7 +25796,7 @@ function createHeadlessRoleTurnHost(config) {
25809
25796
  );
25810
25797
  }
25811
25798
  } else {
25812
- mcpConfigPath = join46(request.runDirectory, "headless-mcp-config.json");
25799
+ mcpConfigPath = join45(request.runDirectory, "headless-mcp-config.json");
25813
25800
  await writeFile10(
25814
25801
  mcpConfigPath,
25815
25802
  `${JSON.stringify(headlessMcpConfigDocument(prepared.mcpServers), null, 2)}
@@ -26073,7 +26060,7 @@ function createHeadlessRoleTurnHost(config) {
26073
26060
  host: config.hostName,
26074
26061
  sessionId: exitedSessionId,
26075
26062
  cwd: request.cwd,
26076
- sessionDirectory: join46(request.runDirectory, "session"),
26063
+ sessionDirectory: join45(request.runDirectory, "session"),
26077
26064
  sessionParent,
26078
26065
  continuation: request.continuation,
26079
26066
  ...request.model !== void 0 ? { model: request.model } : {},