@oxagen/cli 2.1.4-724 → 2.1.4-926

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/oxagen.mjs +1300 -505
  2. package/package.json +1 -1
package/oxagen.mjs CHANGED
@@ -7374,6 +7374,9 @@ function principalsFor(cedar, harness, agent) {
7374
7374
  function isOxagenTool(toolName3) {
7375
7375
  return toolName3.startsWith(OXAGEN_TOOL_PREFIX);
7376
7376
  }
7377
+ function kernelDecides(toolName3, oxagenServerVerified2) {
7378
+ return isOxagenTool(toolName3) && oxagenServerVerified2 === true;
7379
+ }
7377
7380
  function mcpActionFor(toolName3) {
7378
7381
  if (!toolName3.startsWith(MCP_PREFIX)) return void 0;
7379
7382
  const id2 = toolName3.slice(MCP_PREFIX.length);
@@ -7447,7 +7450,7 @@ function hookRequest(call2, tools) {
7447
7450
  return { action, tool: BUILTIN_TOOLS[action], argSets, errors: [] };
7448
7451
  }
7449
7452
  function hookCallClass(call2, tools) {
7450
- if (isOxagenTool(call2.toolName)) return null;
7453
+ if (kernelDecides(call2.toolName, call2.oxagenServerVerified)) return null;
7451
7454
  const request3 = hookRequest(call2, tools);
7452
7455
  const targets = [];
7453
7456
  for (const args of request3.argSets) {
@@ -7458,7 +7461,7 @@ function hookCallClass(call2, tools) {
7458
7461
  return { action: request3.action, tool: request3.tool, targets };
7459
7462
  }
7460
7463
  function evaluateHookCall(call2) {
7461
- if (isOxagenTool(call2.toolName)) return null;
7464
+ if (kernelDecides(call2.toolName, call2.oxagenServerVerified)) return null;
7462
7465
  const request3 = hookRequest(call2, call2.cedar.tools);
7463
7466
  const { action } = request3;
7464
7467
  const principals = principalsFor(call2.cedar, call2.harness, call2.agent);
@@ -7790,8 +7793,8 @@ function candidatePaths(path2, context) {
7790
7793
  const base2 = fold(lib.normalize(root)).replace(/\/+$/, "");
7791
7794
  return resolved.startsWith(`${base2}/`) ? resolved.slice(base2.length + 1) : void 0;
7792
7795
  };
7793
- const relative10 = cwd !== void 0 ? under2(cwd) : void 0;
7794
- if (relative10 !== void 0) out.push(relative10);
7796
+ const relative11 = cwd !== void 0 ? under2(cwd) : void 0;
7797
+ if (relative11 !== void 0) out.push(relative11);
7795
7798
  const fromHome = home !== void 0 ? under2(home) : void 0;
7796
7799
  if (fromHome !== void 0) out.push(`~/${fromHome}`);
7797
7800
  return out;
@@ -8002,7 +8005,7 @@ function evaluatePreToolUse(input) {
8002
8005
  input.now,
8003
8006
  input.mandateConfirmedAt
8004
8007
  );
8005
- const staleSafe = readOnly && (bundle2.cedar === void 0 || input.cedar === void 0 || isOxagenTool(toolName3) || cedarReadOnly(
8008
+ const staleSafe = readOnly && (bundle2.cedar === void 0 || input.cedar === void 0 || kernelDecides(toolName3, input.cedar.oxagenServerVerified) || cedarReadOnly(
8006
8009
  bundle2.cedar,
8007
8010
  toolName3,
8008
8011
  input.cedar.harness,
@@ -8126,7 +8129,8 @@ function cedarReadOnly(cedarBundle, toolName3, harness, action) {
8126
8129
  function decideWithCedar(input) {
8127
8130
  const cedarBundle = input.bundle.cedar;
8128
8131
  if (cedarBundle === void 0 || input.cedar === void 0) return void 0;
8129
- if (isOxagenTool(input.toolName)) return void 0;
8132
+ if (kernelDecides(input.toolName, input.cedar.oxagenServerVerified))
8133
+ return void 0;
8130
8134
  const { runtime, harness, agent, skill, action, harness_tool, facts } = input.cedar;
8131
8135
  const readOnly = cedarReadOnly(cedarBundle, input.toolName, harness, action);
8132
8136
  if (runtime === null) {
@@ -8164,6 +8168,7 @@ function decideWithCedar(input) {
8164
8168
  ...action !== void 0 ? { action } : {},
8165
8169
  ...skill !== void 0 ? { skill } : {},
8166
8170
  ...facts !== void 0 ? { facts } : {},
8171
+ ...input.cedar.oxagenServerVerified !== void 0 ? { oxagenServerVerified: input.cedar.oxagenServerVerified } : {},
8167
8172
  now: input.now
8168
8173
  });
8169
8174
  } catch (error) {
@@ -8750,6 +8755,18 @@ function commandHookEntry(config, timeoutS, harness = "claude-code", absentAnswe
8750
8755
  timeout: timeoutS
8751
8756
  };
8752
8757
  }
8758
+ function steerWaitEntry(config) {
8759
+ return {
8760
+ type: "command",
8761
+ command: `${config.hookCommand} ${hookMarker(config.enrollmentId)} ${STEER_WAIT_FLAG}`,
8762
+ async: true,
8763
+ asyncRewake: true,
8764
+ timeout: STEER_WAIT_TIMEOUT_S
8765
+ };
8766
+ }
8767
+ function isSteerWaitEntry(entry2) {
8768
+ return entry2.type === "command" && typeof entry2.command === "string" && entry2.command.endsWith(` ${STEER_WAIT_FLAG}`);
8769
+ }
8753
8770
  function hookMarker(enrollmentId) {
8754
8771
  return `--enrollment ${enrollmentId}`;
8755
8772
  }
@@ -8790,7 +8807,8 @@ function tachoHookEntries(config) {
8790
8807
  const out = {};
8791
8808
  for (const event of COMMAND_HOOK_EVENTS) {
8792
8809
  out[event] = [
8793
- { hooks: [commandHookEntry(config, COMMAND_HOOK_TIMEOUTS_S[event])] }
8810
+ { hooks: [commandHookEntry(config, COMMAND_HOOK_TIMEOUTS_S[event])] },
8811
+ ...STEER_WAIT_EVENTS.includes(event) ? [{ hooks: [steerWaitEntry(config)] }] : []
8794
8812
  ];
8795
8813
  }
8796
8814
  for (const event of SPOOLED_HOOK_EVENTS) {
@@ -8943,7 +8961,12 @@ function tachoHookPresence(existing, enrollmentId) {
8943
8961
  if (ours.length > 0) {
8944
8962
  present.push(event);
8945
8963
  const type = writtenHookType(event);
8946
- if (ours.some((group) => group.hooks.some((entry2) => entry2.type !== type)))
8964
+ if (ours.some(
8965
+ (group) => group.hooks.some((entry2) => entry2.type !== type)
8966
+ ) || // An enrollment before the steer waiter wrote none on the events
8967
+ // where a session goes idle, so a steer sent then waits for a person
8968
+ // to type. `oxagen agent enroll` writes it.
8969
+ STEER_WAIT_EVENTS.includes(event) && !ours.some((group) => group.hooks.some(isSteerWaitEntry)))
8947
8970
  stale.push(event);
8948
8971
  } else {
8949
8972
  missing.push(event);
@@ -8968,7 +8991,7 @@ function renderManagedSettings(config) {
8968
8991
  disableBypassPermissionsMode: "disable"
8969
8992
  };
8970
8993
  }
8971
- var COMMAND_HOOK_EVENTS, SPOOLED_HOOK_EVENTS, SESSION_END_TIMEOUT_S, HTTP_HOOK_EVENTS, RETIRED_HOOK_EVENTS, ALL_HOOK_EVENTS, HTTP_TIMEOUT_S, TACHO_LOCAL_TOKEN_ENV, TACHO_ENROLLMENT_ENV, COMMAND_HOOK_TIMEOUTS_S, ANY_ENROLLMENT, entryPatterns, TACHO_ENV_KEYS, STATIC_TACHO_ENV;
8994
+ var COMMAND_HOOK_EVENTS, SPOOLED_HOOK_EVENTS, SESSION_END_TIMEOUT_S, HTTP_HOOK_EVENTS, RETIRED_HOOK_EVENTS, ALL_HOOK_EVENTS, HTTP_TIMEOUT_S, TACHO_LOCAL_TOKEN_ENV, TACHO_ENROLLMENT_ENV, STEER_WAIT_EVENTS, STEER_WAIT_FLAG, STEER_WAIT_TIMEOUT_S, COMMAND_HOOK_TIMEOUTS_S, ANY_ENROLLMENT, entryPatterns, TACHO_ENV_KEYS, STATIC_TACHO_ENV;
8972
8995
  var init_settings_writer = __esm({
8973
8996
  "../../packages/tacho/src/host/settings-writer.ts"() {
8974
8997
  "use strict";
@@ -9021,6 +9044,12 @@ var init_settings_writer = __esm({
9021
9044
  HTTP_TIMEOUT_S = 5;
9022
9045
  TACHO_LOCAL_TOKEN_ENV = "TACHO_LOCAL_TOKEN";
9023
9046
  TACHO_ENROLLMENT_ENV = "TACHO_ENROLLMENT";
9047
+ STEER_WAIT_EVENTS = [
9048
+ "SessionStart",
9049
+ "Stop"
9050
+ ];
9051
+ STEER_WAIT_FLAG = "--await-steer";
9052
+ STEER_WAIT_TIMEOUT_S = 86400;
9024
9053
  COMMAND_HOOK_TIMEOUTS_S = {
9025
9054
  SessionStart: 10,
9026
9055
  UserPromptSubmit: 10,
@@ -10329,14 +10358,14 @@ function psExecWithin(timeoutMs) {
10329
10358
  return (command2, args) => psExec(command2, args, timeoutMs);
10330
10359
  }
10331
10360
  function psExecAsync(command2, args) {
10332
- return new Promise((resolve22) => {
10361
+ return new Promise((resolve23) => {
10333
10362
  execFile(
10334
10363
  command2,
10335
10364
  args,
10336
10365
  { encoding: "utf8", env: PS_ENV, timeout: PROCESS_START_TIMEOUT_MS },
10337
10366
  (error, stdout) => {
10338
10367
  const code = error?.code;
10339
- resolve22({
10368
+ resolve23({
10340
10369
  status: error === null ? 0 : typeof code === "number" ? code : null,
10341
10370
  stdout: typeof stdout === "string" ? stdout : "",
10342
10371
  stderr: ""
@@ -12280,7 +12309,7 @@ function enrollmentFromArgv(argv) {
12280
12309
  return parsed2.success ? parsed2.data : void 0;
12281
12310
  }
12282
12311
  function postUnix(options) {
12283
- return new Promise((resolve22, reject) => {
12312
+ return new Promise((resolve23, reject) => {
12284
12313
  const req = request(
12285
12314
  {
12286
12315
  ...options.socketPath !== void 0 ? { socketPath: options.socketPath } : { host: "127.0.0.1", port: options.loopbackPort },
@@ -12312,7 +12341,7 @@ function postUnix(options) {
12312
12341
  });
12313
12342
  res.on("end", () => {
12314
12343
  clearTimeout(deadline);
12315
- resolve22({
12344
+ resolve23({
12316
12345
  status: res.statusCode ?? 0,
12317
12346
  body: Buffer.concat(chunks).toString("utf8")
12318
12347
  });
@@ -12791,6 +12820,9 @@ async function runTachoHook(deps) {
12791
12820
  const killMs = harnessKillMs(harness, input.hook_event_name, cursorEvent);
12792
12821
  const elapsed = deps.elapsedMs ?? (() => 0);
12793
12822
  const responseBudget = () => responseBudgetMs(killMs, elapsed());
12823
+ const answerBy = () => ({
12824
+ answer_by: now() + responseBudget()
12825
+ });
12794
12826
  const workOrder = workOrderIdOf(deps.env[WORK_ORDER_ENV]);
12795
12827
  const env = {
12796
12828
  ...snapshotEnv(deps.env, DEFAULT_SECRET_ENV_PATTERN),
@@ -12830,7 +12862,8 @@ async function runTachoHook(deps) {
12830
12862
  payload: raw,
12831
12863
  env,
12832
12864
  hook_id: hookId,
12833
- ...label2
12865
+ ...label2,
12866
+ ...answerBy()
12834
12867
  }),
12835
12868
  connectTimeoutMs: deps.connectTimeoutMs ?? 50,
12836
12869
  responseTimeoutMs: responseBudget()
@@ -12878,7 +12911,13 @@ async function runTachoHook(deps) {
12878
12911
  Authorization: `Bearer ${host.local_token}`,
12879
12912
  "x-tacho-envelope": "1"
12880
12913
  },
12881
- body: JSON.stringify({ payload: raw, env, hook_id: hookId, ...label2 }),
12914
+ body: JSON.stringify({
12915
+ payload: raw,
12916
+ env,
12917
+ hook_id: hookId,
12918
+ ...label2,
12919
+ ...answerBy()
12920
+ }),
12882
12921
  connectTimeoutMs: deps.connectTimeoutMs ?? 50,
12883
12922
  responseTimeoutMs: responseBudget()
12884
12923
  });
@@ -12984,14 +13023,136 @@ var init_hook_client = __esm({
12984
13023
  }
12985
13024
  });
12986
13025
 
13026
+ // ../../packages/tacho/src/claude-code/steer-wait.ts
13027
+ function sessionOf(stdin) {
13028
+ let payload;
13029
+ try {
13030
+ payload = JSON.parse(stdin);
13031
+ } catch {
13032
+ return void 0;
13033
+ }
13034
+ if (typeof payload !== "object" || payload === null) return void 0;
13035
+ const fields = payload;
13036
+ if (fields["agent_id"] !== void 0) return void 0;
13037
+ const sessionId = fields["session_id"];
13038
+ return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : void 0;
13039
+ }
13040
+ function readAnswer(body2) {
13041
+ let answer;
13042
+ try {
13043
+ answer = JSON.parse(body2);
13044
+ } catch {
13045
+ return "wait";
13046
+ }
13047
+ if (typeof answer !== "object" || answer === null) return "wait";
13048
+ const fields = answer;
13049
+ const text5 = fields["text"];
13050
+ if (typeof text5 === "string" && text5.length > 0) return text5;
13051
+ return fields["done"] === true ? "done" : "wait";
13052
+ }
13053
+ async function runSteerWait(deps) {
13054
+ const now = deps.now ?? (() => Date.now());
13055
+ const sleep2 = deps.sleep ?? ((ms) => new Promise((resolve23) => setTimeout(resolve23, ms)));
13056
+ const post2 = deps.post ?? postUnix;
13057
+ const sessionId = sessionOf(deps.stdin);
13058
+ if (sessionId === void 0) return DONE;
13059
+ const useTcp = deps.platform === "win32";
13060
+ const startedAt = now();
13061
+ const deadline = startedAt + (deps.lifetimeMs ?? STEER_WAIT_TIMEOUT_S * 1e3 - STEER_WAIT_EXIT_MARGIN_MS);
13062
+ const body2 = JSON.stringify({
13063
+ session_id: sessionId,
13064
+ harness: deps.harness,
13065
+ started_at: startedAt
13066
+ });
13067
+ let failures = 0;
13068
+ const backOff = async () => {
13069
+ failures += 1;
13070
+ await sleep2(
13071
+ Math.min(
13072
+ STEER_WAIT_RETRY_MS * 2 ** (failures - 1),
13073
+ STEER_WAIT_MAX_RETRY_MS
13074
+ )
13075
+ );
13076
+ };
13077
+ while (now() < deadline) {
13078
+ const routing = readHostRouting(deps.paths.hostFile);
13079
+ if (routing === void 0) return DONE;
13080
+ if (useTcp && routing.port === void 0) return DONE;
13081
+ const askedAt = now();
13082
+ let result2;
13083
+ try {
13084
+ result2 = await post2({
13085
+ ...useTcp ? { loopbackPort: routing.port } : { socketPath: deps.paths.socket },
13086
+ path: `/steer-wait/${routing.host_enrollment_id}`,
13087
+ headers: { Authorization: `Bearer ${routing.local_token}` },
13088
+ body: body2,
13089
+ connectTimeoutMs: 1e3,
13090
+ responseTimeoutMs: STEER_WAIT_REQUEST_MS
13091
+ });
13092
+ } catch {
13093
+ await backOff();
13094
+ continue;
13095
+ }
13096
+ if (result2.status === 404) return DONE;
13097
+ if (result2.status !== 200) {
13098
+ await backOff();
13099
+ continue;
13100
+ }
13101
+ failures = 0;
13102
+ const answer = readAnswer(result2.body);
13103
+ if (answer === "done") return DONE;
13104
+ if (answer !== "wait") return { exitCode: 2, stderr: `${answer}
13105
+ ` };
13106
+ if (now() - askedAt < STEER_WAIT_MIN_HOLD_MS)
13107
+ await sleep2(STEER_WAIT_MIN_HOLD_MS);
13108
+ }
13109
+ return DONE;
13110
+ }
13111
+ async function runSteerWaitProcess(argv, stdin) {
13112
+ const harness = harnessFromArgv(argv);
13113
+ let result2;
13114
+ try {
13115
+ result2 = await runSteerWait({
13116
+ paths: agentPathsForEnrollment(
13117
+ tachoHome(process.env),
13118
+ enrollmentFromArgv(argv),
13119
+ harness
13120
+ ),
13121
+ stdin,
13122
+ harness,
13123
+ platform: process.platform
13124
+ });
13125
+ } catch {
13126
+ result2 = DONE;
13127
+ }
13128
+ if (result2.stderr.length > 0) process.stderr.write(result2.stderr);
13129
+ process.exitCode = result2.exitCode;
13130
+ }
13131
+ var STEER_WAIT_REQUEST_MS, STEER_WAIT_RETRY_MS, STEER_WAIT_MAX_RETRY_MS, STEER_WAIT_MIN_HOLD_MS, STEER_WAIT_EXIT_MARGIN_MS, DONE;
13132
+ var init_steer_wait = __esm({
13133
+ "../../packages/tacho/src/claude-code/steer-wait.ts"() {
13134
+ "use strict";
13135
+ init_agents();
13136
+ init_paths();
13137
+ init_settings_writer();
13138
+ init_hook_client();
13139
+ STEER_WAIT_REQUEST_MS = 35e3;
13140
+ STEER_WAIT_RETRY_MS = 2e3;
13141
+ STEER_WAIT_MAX_RETRY_MS = 3e4;
13142
+ STEER_WAIT_MIN_HOLD_MS = 1e3;
13143
+ STEER_WAIT_EXIT_MARGIN_MS = 6e4;
13144
+ DONE = { exitCode: 0, stderr: "" };
13145
+ }
13146
+ });
13147
+
12987
13148
  // ../../packages/tacho/src/claude-code/hook-process.ts
12988
13149
  async function readStdin(source = process.stdin, deadlineMs = STDIN_READ_DEADLINE_MS, maxBytes = MAX_HOOK_STDIN_BYTES) {
12989
13150
  const chunks = [];
12990
13151
  let bytes = 0;
12991
13152
  let overflowed = false;
12992
13153
  let timer;
12993
- const deadline = new Promise((resolve22) => {
12994
- timer = setTimeout(() => resolve22("timeout"), deadlineMs);
13154
+ const deadline = new Promise((resolve23) => {
13155
+ timer = setTimeout(() => resolve23("timeout"), deadlineMs);
12995
13156
  timer.unref?.();
12996
13157
  });
12997
13158
  const read2 = (async () => {
@@ -13032,6 +13193,11 @@ function runHookCall(payload, argv, env = process.env) {
13032
13193
  });
13033
13194
  }
13034
13195
  async function runHookProcess(argv = process.argv) {
13196
+ if (argv.includes(STEER_WAIT_FLAG)) {
13197
+ const read2 = await readStdin();
13198
+ await runSteerWaitProcess(argv, read2.text);
13199
+ return;
13200
+ }
13035
13201
  const agent = agentFromArgv(argv);
13036
13202
  let stdin = "";
13037
13203
  try {
@@ -13083,8 +13249,10 @@ var init_hook_process = __esm({
13083
13249
  "use strict";
13084
13250
  init_agents();
13085
13251
  init_paths();
13252
+ init_settings_writer();
13086
13253
  init_ids();
13087
13254
  init_hook_client();
13255
+ init_steer_wait();
13088
13256
  MAX_HOOK_STDIN_BYTES = 8 * 1024 * 1024;
13089
13257
  STDIN_READ_DEADLINE_MS = 2e3;
13090
13258
  }
@@ -18978,6 +19146,47 @@ var init_registry = __esm({
18978
19146
  if (over > 0) this.expiredOnSeal.splice(0, over);
18979
19147
  return withdrawn;
18980
19148
  }
19149
+ /**
19150
+ * Take every queued message whose deadline passed off its session's queue,
19151
+ * and hand each to `takeExpiredOnSeal` as `expired`. A boundary drops such
19152
+ * a message too, but an agent idle at its prompt reaches no boundary, and
19153
+ * its steer read `received` long past its expiry. Answers how many went.
19154
+ */
19155
+ expireQueuedPrompts(now) {
19156
+ let expired = 0;
19157
+ let room = MAX_EXPIRED_ON_SEAL - this.expiredOnSeal.length;
19158
+ for (const record of this.sessions.values()) {
19159
+ const kept = [];
19160
+ for (const message of record.control.messages) {
19161
+ const due = !(message.expiresAt === null || Date.parse(message.expiresAt) >= now);
19162
+ if (!due) {
19163
+ kept.push(message);
19164
+ continue;
19165
+ }
19166
+ if (!this.expiredOnSeal.some((ack) => ack.command_id === message.id)) {
19167
+ if (room <= 0) {
19168
+ kept.push(message);
19169
+ continue;
19170
+ }
19171
+ this.expiredOnSeal.push({
19172
+ command_id: message.id,
19173
+ status: "expired",
19174
+ session_uuid: record.recorder.sessionUuid,
19175
+ detail: "expired before a boundary"
19176
+ });
19177
+ room -= 1;
19178
+ }
19179
+ expired += 1;
19180
+ }
19181
+ if (kept.length !== record.control.messages.length)
19182
+ record.control.messages.splice(
19183
+ 0,
19184
+ record.control.messages.length,
19185
+ ...kept
19186
+ );
19187
+ }
19188
+ return expired;
19189
+ }
18981
19190
  /**
18982
19191
  * The `expired` acknowledgements for messages whose session sealed before
18983
19192
  * a boundary delivered them, drained. The daemon sends them with the rest.
@@ -19384,7 +19593,7 @@ async function statIfExists(path2) {
19384
19593
  }
19385
19594
  }
19386
19595
  function yieldTurn() {
19387
- return new Promise((resolve22) => setImmediate(resolve22));
19596
+ return new Promise((resolve23) => setImmediate(resolve23));
19388
19597
  }
19389
19598
  async function readAt(path2, offset, length) {
19390
19599
  const handle = await fs.open(path2, "r");
@@ -20388,7 +20597,7 @@ async function runBackfill(request3, deps) {
20388
20597
  const aborted = () => deps.signal?.aborted === true;
20389
20598
  const between = async () => {
20390
20599
  if (aborted()) throw new Stopped();
20391
- await new Promise((resolve22) => setImmediate(resolve22));
20600
+ await new Promise((resolve23) => setImmediate(resolve23));
20392
20601
  if (deps.now() - checkedAt < CHECK_EVERY_MS) return;
20393
20602
  checkedAt = deps.now();
20394
20603
  deps.progress?.({ finished: false, ...counts2() });
@@ -20410,7 +20619,7 @@ async function runBackfill(request3, deps) {
20410
20619
  else pending.push(candidate);
20411
20620
  if (aborted()) throw new Stopped();
20412
20621
  if (index % LOCAL_CHECKS_PER_TURN === LOCAL_CHECKS_PER_TURN - 1)
20413
- await new Promise((resolve22) => setImmediate(resolve22));
20622
+ await new Promise((resolve23) => setImmediate(resolve23));
20414
20623
  }
20415
20624
  const server = await askServer(pending, deps);
20416
20625
  for (const candidate of pending) {
@@ -20852,7 +21061,7 @@ async function resultAgentIds(path2) {
20852
21061
  await readSlices(path2, SEAL_SLICE_BYTES, async (lines) => {
20853
21062
  for (const line of lines)
20854
21063
  if (line.text !== void 0) resultAgentIdsOf(line.text, out);
20855
- await new Promise((resolve22) => setImmediate(resolve22));
21064
+ await new Promise((resolve23) => setImmediate(resolve23));
20856
21065
  });
20857
21066
  } catch {
20858
21067
  }
@@ -21400,6 +21609,20 @@ function stripClaudeCodeMcpConfig(existing, enrollmentId, restore = {}) {
21400
21609
  function claudeCodeMcpPresence(existing, enrollmentId) {
21401
21610
  return oxagenMcpPresence(existing, enrollmentId);
21402
21611
  }
21612
+ function isEnrolledOxagenEntry(entry2, enrollmentId, enrolled) {
21613
+ const server = asRecord(entry2);
21614
+ if (server === void 0) return false;
21615
+ const args = Array.isArray(server.args) ? server.args : [];
21616
+ const at2 = args.indexOf("mcp-stdio");
21617
+ const env = asRecord(server.env);
21618
+ return (enrolled.shimCommand === void 0 || server.command === enrolled.shimCommand) && at2 >= 0 && JSON.stringify(args.slice(at2)) === JSON.stringify([
21619
+ "mcp-stdio",
21620
+ "--enrollment",
21621
+ enrollmentId,
21622
+ "--port",
21623
+ String(enrolled.port)
21624
+ ]) && env?.["TACHO_LOCAL_TOKEN"] === enrolled.localToken;
21625
+ }
21403
21626
  function claudeCodeSessionHasOxagenTools(check2) {
21404
21627
  if (!check2.hasGatewayKey || check2.registeredAt === void 0) return false;
21405
21628
  const registered = Date.parse(check2.registeredAt);
@@ -21409,6 +21632,12 @@ function claudeCodeSessionHasOxagenTools(check2) {
21409
21632
  const userConfig = check2.readUserConfig();
21410
21633
  if (!claudeCodeMcpPresence(userConfig, check2.enrollmentId).present)
21411
21634
  return false;
21635
+ if (check2.enrolled !== void 0 && !isEnrolledOxagenEntry(
21636
+ member2(member2(userConfig, "mcpServers"), OXAGEN_MCP_SERVER_KEY),
21637
+ check2.enrollmentId,
21638
+ check2.enrolled
21639
+ ))
21640
+ return false;
21412
21641
  return check2.cwd === void 0 || !shadowedInProject(
21413
21642
  userConfig,
21414
21643
  check2.cwd,
@@ -23946,9 +24175,9 @@ function failure3(problem, count12) {
23946
24175
  }
23947
24176
  function codexAppServerClient(options) {
23948
24177
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
23949
- return (requests) => new Promise((resolve22) => {
24178
+ return (requests) => new Promise((resolve23) => {
23950
24179
  if (requests.length === 0) {
23951
- resolve22({ answers: [] });
24180
+ resolve23({ answers: [] });
23952
24181
  return;
23953
24182
  }
23954
24183
  let child;
@@ -23961,7 +24190,7 @@ function codexAppServerClient(options) {
23961
24190
  ...invocation.windowsVerbatimArguments === true ? { windowsVerbatimArguments: true } : {}
23962
24191
  });
23963
24192
  } catch (error) {
23964
- resolve22(
24193
+ resolve23(
23965
24194
  failure3(
23966
24195
  `could not run \`codex app-server\`: ${error instanceof Error ? error.message : String(error)}`,
23967
24196
  requests.length
@@ -23986,7 +24215,7 @@ function codexAppServerClient(options) {
23986
24215
  child.stdin.end();
23987
24216
  child.kill();
23988
24217
  const said = stderr.trim();
23989
- resolve22(
24218
+ resolve23(
23990
24219
  problem === void 0 ? { answers } : {
23991
24220
  answers,
23992
24221
  problem: said.length === 0 ? problem : `${problem}: ${said}`
@@ -24941,7 +25170,7 @@ import { readFileSync as readFileSync10 } from "node:fs";
24941
25170
  import { dirname as dirname9, resolve as resolve3 } from "node:path";
24942
25171
  import { fileURLToPath } from "node:url";
24943
25172
  function readVersion() {
24944
- if (true) return "2.1.4-724";
25173
+ if (true) return "2.1.4-926";
24945
25174
  try {
24946
25175
  const here = dirname9(fileURLToPath(import.meta.url));
24947
25176
  const pkg = JSON.parse(
@@ -25203,11 +25432,11 @@ function harnessFacts(exec4, name, platform = process.platform, env = process.en
25203
25432
  path2 ??= shellExecutable(exec4("sh", ["-lc", `command -v ${name}`]));
25204
25433
  }
25205
25434
  if (path2 === void 0) {
25206
- const sep12 = platform === "win32" ? "\\" : "/";
25435
+ const sep13 = platform === "win32" ? "\\" : "/";
25207
25436
  const names2 = platform === "win32" ? [`${name}.exe`, `${name}.cmd`] : [name];
25208
25437
  outer: for (const dir of wellKnownBinDirs(home, platform, env)) {
25209
25438
  for (const file of names2) {
25210
- const candidate = `${dir}${sep12}${file}`;
25439
+ const candidate = `${dir}${sep13}${file}`;
25211
25440
  if (exists(candidate)) {
25212
25441
  path2 = candidate;
25213
25442
  break outer;
@@ -26304,6 +26533,29 @@ function loadOrCreateDeviceKey(path2) {
26304
26533
  writeSensitiveFileAtomic(path2, deviceKeyPem(key));
26305
26534
  return { key, created: true };
26306
26535
  }
26536
+ function credentialDigest(credential) {
26537
+ return createHash4("sha256").update(credential, "utf8").digest("hex");
26538
+ }
26539
+ function deviceKeyProofMessage(claims) {
26540
+ return JSON.stringify([
26541
+ DEVICE_KEY_PROOF_DOMAIN,
26542
+ claims.credentialDigest,
26543
+ claims.devicePublicKey,
26544
+ claims.hostname,
26545
+ claims.osUser,
26546
+ claims.platform,
26547
+ [...claims.harnesses],
26548
+ claims.signedAtUnixS
26549
+ ]);
26550
+ }
26551
+ function signDeviceKeyProof(key, claims) {
26552
+ return {
26553
+ signedAtUnixS: claims.signedAtUnixS,
26554
+ signature: key.sign(
26555
+ deviceKeyProofMessage({ ...claims, devicePublicKey: key.publicKey })
26556
+ )
26557
+ };
26558
+ }
26307
26559
  function verifyDeviceSignature(publicKey, message, signatureBase64) {
26308
26560
  if (!publicKey.startsWith("ed25519:")) return false;
26309
26561
  const raw = Buffer.from(publicKey.slice("ed25519:".length), "base64");
@@ -26323,12 +26575,13 @@ function verifyDeviceSignature(publicKey, message, signatureBase64) {
26323
26575
  return false;
26324
26576
  }
26325
26577
  }
26326
- var SPKI_ED25519_PREFIX_BYTES;
26578
+ var SPKI_ED25519_PREFIX_BYTES, DEVICE_KEY_PROOF_DOMAIN;
26327
26579
  var init_device_key = __esm({
26328
26580
  "../../packages/tacho/src/host/device-key.ts"() {
26329
26581
  "use strict";
26330
26582
  init_fs();
26331
26583
  SPKI_ED25519_PREFIX_BYTES = 12;
26584
+ DEVICE_KEY_PROOF_DOMAIN = "oxagen.tacho.device-key-proof.v1";
26332
26585
  }
26333
26586
  });
26334
26587
 
@@ -27441,7 +27694,7 @@ ${lines.join("\n")}
27441
27694
  async bodiesForAsync(events) {
27442
27695
  const found = /* @__PURE__ */ new Map();
27443
27696
  for (let at2 = 0; at2 < events.length; at2 += BODY_READ_SLICE) {
27444
- if (at2 > 0) await new Promise((resolve22) => setImmediate(resolve22));
27697
+ if (at2 > 0) await new Promise((resolve23) => setImmediate(resolve23));
27445
27698
  let slice = events.slice(at2, at2 + BODY_READ_SLICE);
27446
27699
  for (let attempt = 0; attempt < 2 && slice.length > 0; attempt += 1) {
27447
27700
  const stale = /* @__PURE__ */ new Set();
@@ -27638,7 +27891,7 @@ ${lines.join("\n")}
27638
27891
  let blanked = 0;
27639
27892
  let moved = false;
27640
27893
  for (let next = 0; next < found.length; ) {
27641
- if (next > 0) await new Promise((resolve22) => setImmediate(resolve22));
27894
+ if (next > 0) await new Promise((resolve23) => setImmediate(resolve23));
27642
27895
  const slice = this.blankSlice(path2, found, next, idems);
27643
27896
  if (slice === void 0) break;
27644
27897
  blanked += slice.blanked;
@@ -30417,8 +30670,8 @@ function harnessFileProblems(harnesses, deps) {
30417
30670
  if (harnesses.includes("codex"))
30418
30671
  check2(deps.paths.codexHooks, deps.readCodexHooks, hooksShapeProblem);
30419
30672
  if (harnesses.includes("cursor")) {
30420
- const relative10 = absoluteHookCommandProblem(deps.runtime.hookCommand);
30421
- if (relative10 !== void 0) problems.push(relative10);
30673
+ const relative11 = absoluteHookCommandProblem(deps.runtime.hookCommand);
30674
+ if (relative11 !== void 0) problems.push(relative11);
30422
30675
  for (const path2 of deps.paths.cursorHooks)
30423
30676
  check2(path2, () => deps.readCursorHooks(path2), cursorHooksShapeProblem);
30424
30677
  }
@@ -30760,9 +31013,22 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
30760
31013
  let response;
30761
31014
  let tenant;
30762
31015
  let agentId;
31016
+ const deviceKeyProof = signDeviceKeyProof(key, {
31017
+ credentialDigest: credentialDigest(
31018
+ credentials2 ? credentials2.token : options.enrollmentToken ?? ""
31019
+ ),
31020
+ hostname: facts.hostname,
31021
+ osUser: facts.osUser,
31022
+ platform: facts.platform,
31023
+ harnesses: facts.harnesses,
31024
+ signedAtUnixS: Math.floor(deps.now() / 1e3)
31025
+ });
30763
31026
  try {
30764
31027
  if (credentials2) {
30765
- response = await callEnrollment(deps, credentials2, facts);
31028
+ response = await callEnrollment(deps, credentials2, {
31029
+ ...facts,
31030
+ deviceKeyProof
31031
+ });
30766
31032
  tenant = {
30767
31033
  orgSlug: credentials2.org,
30768
31034
  workspaceSlug: credentials2.workspace
@@ -30772,6 +31038,7 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
30772
31038
  const answer = await callTokenEnrollment(deps, apiUrl, {
30773
31039
  token: options.enrollmentToken,
30774
31040
  ...facts,
31041
+ deviceKeyProof,
30775
31042
  ...remote !== void 0 ? { repositoryRemote: remote } : {}
30776
31043
  });
30777
31044
  response = answer;
@@ -33098,7 +33365,7 @@ function runLineOf(raw) {
33098
33365
  return void 0;
33099
33366
  }
33100
33367
  function streamDaemon(options) {
33101
- return new Promise((resolve22, reject) => {
33368
+ return new Promise((resolve23, reject) => {
33102
33369
  const req = request2(
33103
33370
  {
33104
33371
  ...options.socketPath !== void 0 ? { socketPath: options.socketPath } : { host: "127.0.0.1", port: options.loopbackPort },
@@ -33126,7 +33393,7 @@ function streamDaemon(options) {
33126
33393
  });
33127
33394
  res.on("end", () => {
33128
33395
  if (buffered.length > 0) options.onLine(buffered);
33129
- resolve22(res.statusCode ?? 0);
33396
+ resolve23(res.statusCode ?? 0);
33130
33397
  });
33131
33398
  res.on("error", reject);
33132
33399
  }
@@ -33299,7 +33566,7 @@ function spawnAgent(command2, args, options) {
33299
33566
  process.platform,
33300
33567
  options.env
33301
33568
  );
33302
- return new Promise((resolve22) => {
33569
+ return new Promise((resolve23) => {
33303
33570
  const child = spawn2(invocation.command, invocation.args, {
33304
33571
  cwd: options.cwd,
33305
33572
  env: options.env,
@@ -33315,7 +33582,7 @@ function spawnAgent(command2, args, options) {
33315
33582
  process.off("SIGINT", stay);
33316
33583
  process.off("SIGTERM", forward);
33317
33584
  process.off("SIGHUP", forward);
33318
- resolve22(exit);
33585
+ resolve23(exit);
33319
33586
  };
33320
33587
  if (options.onSpawn !== void 0) child.once("spawn", options.onSpawn);
33321
33588
  child.once("error", (error) => done({ code: null, signal: null, error }));
@@ -37805,17 +38072,17 @@ async function startContainedBridge(options) {
37805
38072
  "upgrade",
37806
38073
  (_request, socket) => socket.end("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n")
37807
38074
  );
37808
- await new Promise((resolve22, reject) => {
38075
+ await new Promise((resolve23, reject) => {
37809
38076
  server.once("error", reject);
37810
38077
  server.listen(options.socketPath, () => {
37811
38078
  chmodSync6(options.socketPath, 384);
37812
- resolve22();
38079
+ resolve23();
37813
38080
  });
37814
38081
  });
37815
38082
  return {
37816
38083
  close: async () => {
37817
38084
  server.closeAllConnections();
37818
- await new Promise((resolve22) => server.close(() => resolve22()));
38085
+ await new Promise((resolve23) => server.close(() => resolve23()));
37819
38086
  }
37820
38087
  };
37821
38088
  }
@@ -37843,7 +38110,7 @@ var init_bridge = __esm({
37843
38110
 
37844
38111
  // ../../packages/tacho/src/contained/workspace.ts
37845
38112
  import { lstatSync as lstatSync6, readFileSync as readFileSync14, readdirSync as readdirSync11, realpathSync as realpathSync3 } from "node:fs";
37846
- import { isAbsolute as isAbsolute3, join as join23, relative as relative2, sep as sep2 } from "node:path";
38113
+ import { isAbsolute as isAbsolute3, join as join23, relative as relative2, resolve as resolve9, sep as sep2 } from "node:path";
37847
38114
  function within(root, path2) {
37848
38115
  const rel = relative2(root, path2);
37849
38116
  return rel === "" || !isAbsolute3(rel) && rel !== ".." && !rel.startsWith(`..${sep2}`);
@@ -37905,6 +38172,54 @@ function validateContainedWorkspace(workspace, sessionDirectory, mountInfo = rea
37905
38172
  };
37906
38173
  visit2(root);
37907
38174
  }
38175
+ function gitDirectoryMounts(workspace) {
38176
+ const root = realpathSync3(workspace);
38177
+ const dotGit = join23(root, ".git");
38178
+ let stat7;
38179
+ try {
38180
+ stat7 = lstatSync6(dotGit);
38181
+ } catch {
38182
+ throw new Error(
38183
+ "Contained repository has no .git at its root; launch from the repository root"
38184
+ );
38185
+ }
38186
+ if (stat7.isSymbolicLink())
38187
+ throw new Error(
38188
+ "Contained repository's .git is a symbolic link; replace it with the directory it points to before launch"
38189
+ );
38190
+ const mounts = [dotGit];
38191
+ if (stat7.isDirectory()) return mounts;
38192
+ if (!stat7.isFile())
38193
+ throw new Error(
38194
+ "Contained repository's .git is neither a directory nor a file"
38195
+ );
38196
+ const pointer = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync14(dotGit, "utf8"));
38197
+ if (pointer === null)
38198
+ throw new Error(
38199
+ "Contained repository's .git file names no git directory"
38200
+ );
38201
+ const addInside = (path2) => {
38202
+ let real;
38203
+ try {
38204
+ real = realpathSync3(path2);
38205
+ } catch {
38206
+ return void 0;
38207
+ }
38208
+ if (within(root, real) && !mounts.includes(real)) mounts.push(real);
38209
+ return real;
38210
+ };
38211
+ const gitDir = addInside(resolve9(root, pointer[1]));
38212
+ if (gitDir !== void 0) {
38213
+ let common;
38214
+ try {
38215
+ common = readFileSync14(join23(gitDir, "commondir"), "utf8").trim();
38216
+ } catch {
38217
+ common = void 0;
38218
+ }
38219
+ if (common) addInside(resolve9(gitDir, common));
38220
+ }
38221
+ return mounts;
38222
+ }
37908
38223
  var CREDENTIAL_PATHS;
37909
38224
  var init_workspace = __esm({
37910
38225
  "../../packages/tacho/src/contained/workspace.ts"() {
@@ -37921,8 +38236,74 @@ var init_workspace = __esm({
37921
38236
  }
37922
38237
  });
37923
38238
 
38239
+ // ../../packages/tacho/src/collector/hardened-git.ts
38240
+ function hardenedGitArgs(cwd, args, globals = []) {
38241
+ const subcommand = args[0];
38242
+ const end = args.indexOf("--");
38243
+ const options = end < 0 ? args : args.slice(0, end);
38244
+ const extra = subcommand !== void 0 && DIFF_SUBCOMMANDS.has(subcommand) ? DIFF_FLAGS.filter((flag2) => !options.includes(flag2)) : [];
38245
+ return [
38246
+ "-C",
38247
+ cwd,
38248
+ ...HARDENED_GIT_CONFIG,
38249
+ ...globals,
38250
+ ...options,
38251
+ ...extra,
38252
+ ...end < 0 ? [] : args.slice(end)
38253
+ ];
38254
+ }
38255
+ function hardenedGitShellPrefix() {
38256
+ return ["git", ...HARDENED_GIT_CONFIG.map(shellQuote2)].join(" ");
38257
+ }
38258
+ function shellQuote2(value) {
38259
+ return /^[A-Za-z0-9_./=:-]+$/.test(value) ? value : `'${value.replace(/'/g, "'\\''")}'`;
38260
+ }
38261
+ var HARDENED_GIT_CONFIG, HARDENED_GIT_ENV, DIFF_SUBCOMMANDS, DIFF_FLAGS;
38262
+ var init_hardened_git = __esm({
38263
+ "../../packages/tacho/src/collector/hardened-git.ts"() {
38264
+ "use strict";
38265
+ HARDENED_GIT_CONFIG = [
38266
+ "-c",
38267
+ "core.fsmonitor=false",
38268
+ "-c",
38269
+ "core.hooksPath=/dev/null",
38270
+ "-c",
38271
+ "diff.external=",
38272
+ "-c",
38273
+ "core.pager=cat",
38274
+ "-c",
38275
+ "log.showSignature=false"
38276
+ ];
38277
+ HARDENED_GIT_ENV = {
38278
+ GIT_CONFIG_NOSYSTEM: "1",
38279
+ GIT_TERMINAL_PROMPT: "0"
38280
+ };
38281
+ DIFF_SUBCOMMANDS = /* @__PURE__ */ new Set(["diff", "show", "log"]);
38282
+ DIFF_FLAGS = ["--no-ext-diff", "--no-textconv"];
38283
+ }
38284
+ });
38285
+
37924
38286
  // ../../packages/tacho/src/contained/profile.ts
37925
38287
  import { createHash as createHash6 } from "node:crypto";
38288
+ import { isAbsolute as isAbsolute4, join as join24, relative as relative3, sep as sep3 } from "node:path";
38289
+ function containerPath(workspace, path2) {
38290
+ const inside2 = relative3(workspace, path2);
38291
+ if (inside2 === "" || isAbsolute4(inside2) || inside2 === ".." || inside2.startsWith(`..${sep3}`))
38292
+ throw new Error(
38293
+ "A contained git mount must lie inside the workspace it protects"
38294
+ );
38295
+ return `/workspace/${inside2.split(sep3).join("/")}`;
38296
+ }
38297
+ function gitMountPairs(spec) {
38298
+ if (!spec.gitMounts.includes(join24(spec.workspace, ".git")))
38299
+ throw new Error(
38300
+ "Contained execution must mount the repository's .git read-only"
38301
+ );
38302
+ return spec.gitMounts.map((src) => ({
38303
+ src: mountPath(src),
38304
+ dst: containerPath(spec.workspace, src)
38305
+ }));
38306
+ }
37926
38307
  function mountPath(path2) {
37927
38308
  if (!path2.startsWith("/") || /[,\r\n\0]/.test(path2)) {
37928
38309
  throw new Error(
@@ -37940,6 +38321,7 @@ function containerArguments(spec) {
37940
38321
  throw new Error("Contained execution requires an unprivileged Linux user");
37941
38322
  if (!CONTAINED_HARNESSES.includes(spec.harness))
37942
38323
  throw new Error("Unsupported contained harness");
38324
+ const gitMounts = gitMountPairs(spec);
37943
38325
  return [
37944
38326
  "create",
37945
38327
  "--name",
@@ -37968,6 +38350,10 @@ function containerArguments(spec) {
37968
38350
  `type=bind,src=${mountPath(spec.workspace)},dst=/workspace`,
37969
38351
  "--mount",
37970
38352
  `type=bind,src=${mountPath(spec.sessionDirectory)},dst=/opt/oxagen/session,readonly`,
38353
+ ...gitMounts.flatMap(({ src, dst }) => [
38354
+ "--mount",
38355
+ `type=bind,src=${src},dst=${dst},readonly`
38356
+ ]),
37971
38357
  "--workdir",
37972
38358
  "/workspace",
37973
38359
  "--env",
@@ -37990,12 +38376,24 @@ function measureContainer(raw, spec, configuration) {
37990
38376
  const mounts = value?.Mounts;
37991
38377
  const containerId = value?.Id ?? "";
37992
38378
  const expectedCommand = ["/opt/oxagen/entry.mjs", spec.harness, ...spec.args];
38379
+ let gitMounts;
38380
+ try {
38381
+ gitMounts = gitMountPairs(spec);
38382
+ } catch {
38383
+ gitMounts = void 0;
38384
+ }
37993
38385
  const safe = /^([a-f0-9]{64})$/.test(containerId) && value?.Image === spec.image && host?.NetworkMode === "none" && host.ReadonlyRootfs === true && host.Privileged === false && (host.CapAdd?.length ?? 0) === 0 && host.CapDrop?.includes("ALL") === true && host.SecurityOpt?.some(
37994
38386
  (option) => option === "no-new-privileges" || option === "no-new-privileges=true"
37995
- ) === true && host.PidMode === "" && host.IpcMode === "private" && host.UsernsMode === "" && host.CgroupnsMode === "private" && (host.Devices?.length ?? 0) === 0 && (host.DeviceRequests?.length ?? 0) === 0 && config?.User === `${spec.uid}:${spec.gid}` && config.WorkingDir === "/workspace" && JSON.stringify(config.Entrypoint) === JSON.stringify(["/usr/local/bin/node"]) && JSON.stringify(config.Cmd) === JSON.stringify(expectedCommand) && mounts?.length === 2 && mounts.some(
38387
+ ) === true && host.PidMode === "" && host.IpcMode === "private" && host.UsernsMode === "" && host.CgroupnsMode === "private" && (host.Devices?.length ?? 0) === 0 && (host.DeviceRequests?.length ?? 0) === 0 && config?.User === `${spec.uid}:${spec.gid}` && config.WorkingDir === "/workspace" && JSON.stringify(config.Entrypoint) === JSON.stringify(["/usr/local/bin/node"]) && JSON.stringify(config.Cmd) === JSON.stringify(expectedCommand) && gitMounts !== void 0 && mounts?.length === 2 + gitMounts.length && mounts.some(
37996
38388
  (mount) => mount.Type === "bind" && mount.Source === spec.workspace && mount.Destination === "/workspace" && mount.RW === true
37997
38389
  ) && mounts.some(
37998
38390
  (mount) => mount.Type === "bind" && mount.Source === spec.sessionDirectory && mount.Destination === "/opt/oxagen/session" && mount.RW === false
38391
+ ) && // Each git mount read-only where it was asked for, so the agent cannot
38392
+ // write the configuration the daemon's host-side git reads (F-2284).
38393
+ gitMounts.every(
38394
+ ({ src, dst }) => mounts.some(
38395
+ (mount) => mount.Type === "bind" && mount.Source === src && mount.Destination === dst && mount.RW === false
38396
+ )
37999
38397
  );
38000
38398
  if (!safe)
38001
38399
  throw new Error(
@@ -38064,7 +38462,7 @@ import {
38064
38462
  writeFileSync as writeFileSync2
38065
38463
  } from "node:fs";
38066
38464
  import { tmpdir } from "node:os";
38067
- import { isAbsolute as isAbsolute4, join as join24 } from "node:path";
38465
+ import { isAbsolute as isAbsolute5, join as join25 } from "node:path";
38068
38466
  import { promisify } from "node:util";
38069
38467
  function reason(error) {
38070
38468
  return error instanceof Error ? error.message : String(error);
@@ -38077,13 +38475,13 @@ async function launchContainedAgent(options) {
38077
38475
  throw new Error(
38078
38476
  "Contained execution requires an unprivileged Linux runner with Docker"
38079
38477
  );
38080
- if (!isAbsolute4(options.request.workspace))
38478
+ if (!isAbsolute5(options.request.workspace))
38081
38479
  throw new Error("Contained workspace must be an absolute repository path");
38082
38480
  const workspace = realpathSync4(options.request.workspace);
38083
38481
  const root = await exec(
38084
38482
  "git",
38085
- ["-C", workspace, "rev-parse", "--show-toplevel"],
38086
- { timeout: 15e3 }
38483
+ hardenedGitArgs(workspace, ["rev-parse", "--show-toplevel"]),
38484
+ { timeout: 15e3, env: { ...process.env, ...HARDENED_GIT_ENV } }
38087
38485
  );
38088
38486
  if (realpathSync4(root.stdout.trim()) !== workspace)
38089
38487
  throw new Error("Contained workspace must be the repository root");
@@ -38103,7 +38501,7 @@ async function launchContainedAgent(options) {
38103
38501
  if (digest6 === void 0)
38104
38502
  throw new Error("The operator's contained image is not installed");
38105
38503
  const sessionId = `contained-${randomBytes8(16).toString("hex")}`;
38106
- const directory = mkdtempSync(join24(tmpdir(), "oxagen-contained-"));
38504
+ const directory = mkdtempSync(join25(tmpdir(), "oxagen-contained-"));
38107
38505
  chmodSync7(directory, 448);
38108
38506
  let prepared;
38109
38507
  let containerCreated = false;
@@ -38116,6 +38514,7 @@ async function launchContainedAgent(options) {
38116
38514
  "Contained configuration must be outside the writable repository"
38117
38515
  );
38118
38516
  validateContainedWorkspace(workspace, directory);
38517
+ const gitMounts = gitDirectoryMounts(workspace);
38119
38518
  prepared = await options.prepare({ sessionId, directory, workspace });
38120
38519
  const entries2 = Object.entries(prepared.files).sort(
38121
38520
  ([a], [b3]) => a.localeCompare(b3)
@@ -38123,7 +38522,7 @@ async function launchContainedAgent(options) {
38123
38522
  for (const [name2, contents] of entries2) {
38124
38523
  if (!/^[a-z0-9.-]+$/.test(name2))
38125
38524
  throw new Error("Invalid contained configuration filename");
38126
- writeFileSync2(join24(directory, name2), contents, {
38525
+ writeFileSync2(join25(directory, name2), contents, {
38127
38526
  mode: 256,
38128
38527
  flag: "wx"
38129
38528
  });
@@ -38136,7 +38535,8 @@ async function launchContainedAgent(options) {
38136
38535
  uid: process.getuid?.() ?? 0,
38137
38536
  gid: process.getgid?.() ?? 0,
38138
38537
  harness: options.request.harness,
38139
- args: options.request.args
38538
+ args: options.request.args,
38539
+ gitMounts
38140
38540
  };
38141
38541
  await exec("docker", containerArguments(spec), { timeout: 3e4 });
38142
38542
  containerCreated = true;
@@ -38152,7 +38552,7 @@ async function launchContainedAgent(options) {
38152
38552
  admitted = true;
38153
38553
  if (options.signal?.aborted)
38154
38554
  throw new Error("Contained run cancelled before start");
38155
- exitCode = await new Promise((resolve22, reject) => {
38555
+ exitCode = await new Promise((resolve23, reject) => {
38156
38556
  const child = spawn3("docker", ["start", "--attach", name], {
38157
38557
  stdio: ["ignore", "pipe", "pipe"]
38158
38558
  });
@@ -38175,7 +38575,7 @@ async function launchContainedAgent(options) {
38175
38575
  child.once("error", reject);
38176
38576
  child.once("close", (code) => {
38177
38577
  options.signal?.removeEventListener("abort", stop);
38178
- resolve22(code ?? 1);
38578
+ resolve23(code ?? 1);
38179
38579
  });
38180
38580
  });
38181
38581
  return { sessionId, exitCode, measurement };
@@ -38204,6 +38604,7 @@ var init_launcher = __esm({
38204
38604
  init_zod();
38205
38605
  init_configuration();
38206
38606
  init_workspace();
38607
+ init_hardened_git();
38207
38608
  init_profile();
38208
38609
  exec = promisify(execFile2);
38209
38610
  imageInspectSchema = external_exports.array(external_exports.object({ Id: external_exports.string().optional() }));
@@ -38264,16 +38665,16 @@ async function startSandboxGateway(options, port = SANDBOX_GATEWAY_PORT) {
38264
38665
  "upgrade",
38265
38666
  (_request, socket) => socket.end("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n")
38266
38667
  );
38267
- await new Promise((resolve22, reject) => {
38668
+ await new Promise((resolve23, reject) => {
38268
38669
  server.once("error", reject);
38269
- server.listen(port, "127.0.0.1", () => resolve22());
38670
+ server.listen(port, "127.0.0.1", () => resolve23());
38270
38671
  });
38271
38672
  const address = server.address();
38272
38673
  return {
38273
38674
  port: typeof address === "object" && address !== null ? address.port : port,
38274
38675
  close: async () => {
38275
38676
  server.closeAllConnections();
38276
- await new Promise((resolve22) => server.close(() => resolve22()));
38677
+ await new Promise((resolve23) => server.close(() => resolve23()));
38277
38678
  }
38278
38679
  };
38279
38680
  }
@@ -38520,8 +38921,8 @@ var init_privilege = __esm({
38520
38921
 
38521
38922
  // ../../packages/tacho/src/contained/sandbox/launcher.ts
38522
38923
  import { randomBytes as randomBytes9 } from "node:crypto";
38523
- import { join as join25 } from "node:path";
38524
- function shellQuote2(value) {
38924
+ import { join as join26 } from "node:path";
38925
+ function shellQuote3(value) {
38525
38926
  return `'${value.replace(/'/g, `'\\''`)}'`;
38526
38927
  }
38527
38928
  function sandboxHarnessEnvironment(request3, gatewayPort) {
@@ -38547,7 +38948,7 @@ function ptyCommand(argv) {
38547
38948
  "-f",
38548
38949
  "-e",
38549
38950
  "-c",
38550
- `exec ${argv.map(shellQuote2).join(" ")}`,
38951
+ `exec ${argv.map(shellQuote3).join(" ")}`,
38551
38952
  "/dev/null"
38552
38953
  ]
38553
38954
  };
@@ -38610,7 +39011,7 @@ async function launchSandboxAgent(options) {
38610
39011
  { ...asAgent, cwd: SANDBOX_AGENT_HOME, timeoutMs: 15 * 6e4 }
38611
39012
  );
38612
39013
  for (const [name, contents] of Object.entries(claudeCodeUserState())) {
38613
- const path2 = join25(SANDBOX_AGENT_HOME, name);
39014
+ const path2 = join26(SANDBOX_AGENT_HOME, name);
38614
39015
  system.writeFile(path2, contents, 384);
38615
39016
  system.chown(path2, SANDBOX_AGENT_UID, SANDBOX_AGENT_GID);
38616
39017
  }
@@ -38772,9 +39173,9 @@ var init_system = __esm({
38772
39173
  ...options.env !== void 0 ? { env: options.env } : {},
38773
39174
  stdio: ["pipe", "pipe", "inherit"]
38774
39175
  });
38775
- const exited = new Promise((resolve22) => {
38776
- child.once("error", () => resolve22(1));
38777
- child.once("close", (code) => resolve22(code ?? 1));
39176
+ const exited = new Promise((resolve23) => {
39177
+ child.once("error", () => resolve23(1));
39178
+ child.once("close", (code) => resolve23(code ?? 1));
38778
39179
  });
38779
39180
  return {
38780
39181
  pid: child.pid,
@@ -38816,10 +39217,10 @@ var init_system = __esm({
38816
39217
  });
38817
39218
 
38818
39219
  // ../../packages/tacho/src/contained/runner.ts
38819
- import { join as join26 } from "node:path";
39220
+ import { join as join27 } from "node:path";
38820
39221
  function containedHookEnv(harness, workspace) {
38821
- const home = join26(workspace, ".oxagen-contained", "home");
38822
- return harness === "codex" ? { CODEX_HOME: join26(home, ".codex") } : { CLAUDE_CONFIG_DIR: join26(home, ".claude") };
39222
+ const home = join27(workspace, ".oxagen-contained", "home");
39223
+ return harness === "codex" ? { CODEX_HOME: join27(home, ".codex") } : { CLAUDE_CONFIG_DIR: join27(home, ".claude") };
38823
39224
  }
38824
39225
  function containedLaunchEndpoint(host) {
38825
39226
  const ingest = new URL(host.endpoints.ingest);
@@ -39017,7 +39418,7 @@ function createContainedRunner(options) {
39017
39418
  sessionUuid2 = started.recorder.sessionUuid;
39018
39419
  active2.set(sessionUuid2, controller);
39019
39420
  const bridge = await startContainedBridge({
39020
- socketPath: join26(directory, "bridge.sock"),
39421
+ socketPath: join27(directory, "bridge.sock"),
39021
39422
  ...bridgeRoutes({
39022
39423
  sessionId,
39023
39424
  workspace,
@@ -39101,7 +39502,7 @@ function createContainedRunner(options) {
39101
39502
  const abort = () => controller.abort();
39102
39503
  signal?.addEventListener("abort", abort, { once: true });
39103
39504
  if (signal?.aborted) abort();
39104
- const env = { CLAUDE_CONFIG_DIR: join26(SANDBOX_AGENT_HOME, ".claude") };
39505
+ const env = { CLAUDE_CONFIG_DIR: join27(SANDBOX_AGENT_HOME, ".claude") };
39105
39506
  let sessionUuid2;
39106
39507
  let launchedSessionId;
39107
39508
  let opened = false;
@@ -39236,7 +39637,7 @@ var init_runner = __esm({
39236
39637
 
39237
39638
  // ../../packages/tacho/src/collector/detector.ts
39238
39639
  import { promises as fs3 } from "node:fs";
39239
- import { basename as basename5, join as join27 } from "node:path";
39640
+ import { basename as basename5, join as join28 } from "node:path";
39240
39641
  async function eachLimited(items, limit, task) {
39241
39642
  let next = 0;
39242
39643
  const workers = Array.from(
@@ -39262,7 +39663,7 @@ async function scanProject(dir) {
39262
39663
  await eachLimited(names2, SCAN_CONCURRENCY, async (name) => {
39263
39664
  const match = SESSION_FILE.exec(name);
39264
39665
  if (match === null) return;
39265
- const path2 = join27(dir, name);
39666
+ const path2 = join28(dir, name);
39266
39667
  try {
39267
39668
  const st = await fs3.stat(path2);
39268
39669
  out.push({ sessionId: match[1], path: path2, mtimeMs: st.mtimeMs });
@@ -39303,7 +39704,7 @@ var init_detector = __esm({
39303
39704
  continue;
39304
39705
  }
39305
39706
  await eachLimited(names2, SCAN_CONCURRENCY, async (name) => {
39306
- const dir = join27(root, name);
39707
+ const dir = join28(root, name);
39307
39708
  try {
39308
39709
  const st = await fs3.stat(dir);
39309
39710
  if (st.isDirectory()) dirs.push({ dir, mtimeMs: st.mtimeMs });
@@ -39543,7 +39944,7 @@ var init_detector = __esm({
39543
39944
  transcript_path: transcript.path,
39544
39945
  transcript_mtime: new Date(transcript.mtimeMs).toISOString(),
39545
39946
  claude_pids: processes.map((p) => p.pid),
39546
- project: basename5(join27(transcript.path, ".."))
39947
+ project: basename5(join28(transcript.path, ".."))
39547
39948
  }
39548
39949
  })
39549
39950
  );
@@ -39621,14 +40022,15 @@ async function git2(exec4, cwd, args, okStatus = [0]) {
39621
40022
  }
39622
40023
  async function runGit(exec4, cwd, args) {
39623
40024
  try {
39624
- return await exec4("git", [
39625
- "-C",
39626
- cwd,
39627
- "--no-optional-locks",
39628
- "-c",
39629
- "core.quotePath=false",
39630
- ...args
39631
- ]);
40025
+ return await exec4(
40026
+ "git",
40027
+ hardenedGitArgs(cwd, args, [
40028
+ "--no-optional-locks",
40029
+ "-c",
40030
+ "core.quotePath=false"
40031
+ ]),
40032
+ { env: HARDENED_GIT_ENV }
40033
+ );
39632
40034
  } catch (error) {
39633
40035
  return {
39634
40036
  status: null,
@@ -39899,6 +40301,7 @@ var init_git_facts = __esm({
39899
40301
  init_digest();
39900
40302
  init_envelope();
39901
40303
  init_remote();
40304
+ init_hardened_git();
39902
40305
  EMPTY_TREE_OBJECT = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
39903
40306
  MAX_STDOUT_BYTES = 2 * 1024 * 1024;
39904
40307
  MAX_CHANGED_PATHS = 2e3;
@@ -39967,7 +40370,7 @@ import {
39967
40370
  rm,
39968
40371
  unlink
39969
40372
  } from "node:fs/promises";
39970
- import { dirname as dirname16, join as join28 } from "node:path";
40373
+ import { dirname as dirname16, join as join29 } from "node:path";
39971
40374
  function byPath(a, b3) {
39972
40375
  return a.path < b3.path ? -1 : a.path > b3.path ? 1 : 0;
39973
40376
  }
@@ -40010,7 +40413,7 @@ async function contentHash(absolutePath, kind, keep) {
40010
40413
  if (keep !== void 0) {
40011
40414
  try {
40012
40415
  await mkdir(keep.dir, { recursive: true, mode: 448 });
40013
- const temp2 = join28(keep.dir, `.partial-${randomUUID3()}`);
40416
+ const temp2 = join29(keep.dir, `.partial-${randomUUID3()}`);
40014
40417
  copy = {
40015
40418
  temp: temp2,
40016
40419
  handle: await open3(temp2, "wx", keep.executable ? 448 : 384)
@@ -40054,7 +40457,7 @@ async function settleCopy(temp, name) {
40054
40457
  if (temp === void 0) return;
40055
40458
  if (name !== void 0)
40056
40459
  try {
40057
- await rename(temp, join28(dirname16(temp), name));
40460
+ await rename(temp, join29(dirname16(temp), name));
40058
40461
  return;
40059
40462
  } catch {
40060
40463
  }
@@ -40070,7 +40473,7 @@ async function copiedBytes(dir) {
40070
40473
  let total2 = 0;
40071
40474
  for (const name of names2) {
40072
40475
  try {
40073
- total2 += (await lstat(join28(dir, name))).size;
40476
+ total2 += (await lstat(join29(dir, name))).size;
40074
40477
  } catch {
40075
40478
  }
40076
40479
  }
@@ -40086,7 +40489,7 @@ async function removeCopiesOutside(root, live) {
40086
40489
  const keep = new Set(live());
40087
40490
  await Promise.all(
40088
40491
  names2.filter((name) => !keep.has(name)).map(
40089
- (name) => rm(join28(root, name), { recursive: true, force: true }).catch(
40492
+ (name) => rm(join29(root, name), { recursive: true, force: true }).catch(
40090
40493
  () => void 0
40091
40494
  )
40092
40495
  )
@@ -40193,7 +40596,7 @@ async function contributionOf(exec4, cwd, root, repoRelative, entry2, copies) {
40193
40596
  let copy = null;
40194
40597
  if (entry2 !== null) {
40195
40598
  if (copies === void 0 || !COPY_NAME.test(entry2[0])) return void 0;
40196
- copy = join28(copies, entry2[0]);
40599
+ copy = join29(copies, entry2[0]);
40197
40600
  const kept = await statOf(copy);
40198
40601
  if (kept === void 0 || kept === "absent" || kept.kind !== "file")
40199
40602
  return void 0;
@@ -40595,7 +40998,7 @@ var init_session_changes = __esm({
40595
40998
  });
40596
40999
 
40597
41000
  // ../../packages/tacho/src/collector/session-commits.ts
40598
- import { join as join29 } from "node:path";
41001
+ import { join as join30 } from "node:path";
40599
41002
  function parseMeta(stdout) {
40600
41003
  const out = [];
40601
41004
  for (const record of stdout.split("\0")) {
@@ -40636,7 +41039,9 @@ async function patchIds(exec4, cwd, shas) {
40636
41039
  const out = /* @__PURE__ */ new Map();
40637
41040
  if (shas.length === 0) return out;
40638
41041
  try {
40639
- const result2 = await exec4("sh", ["-c", PATCH_IDS, "sh", cwd, ...shas]);
41042
+ const result2 = await exec4("sh", ["-c", PATCH_IDS, "sh", cwd, ...shas], {
41043
+ env: HARDENED_GIT_ENV
41044
+ });
40640
41045
  if (result2.status !== 0) return out;
40641
41046
  for (const line of (result2.stdout ?? "").split("\n")) {
40642
41047
  const [patchId, sha2] = line.trim().split(" ");
@@ -40716,7 +41121,7 @@ async function readSessionCommits(exec4, cwd, input) {
40716
41121
  const test = input.tests[commit.sha];
40717
41122
  const toolUseId = callAt(times.get(commit.sha), calls);
40718
41123
  const written2 = input.written;
40719
- const outside = merge || written2 === void 0 || root === void 0 ? void 0 : files2.some((file) => !written2.has(join29(root, file.path)));
41124
+ const outside = merge || written2 === void 0 || root === void 0 ? void 0 : files2.some((file) => !written2.has(join30(root, file.path)));
40720
41125
  return {
40721
41126
  sha: commit.sha,
40722
41127
  parent_shas: commit.parents.slice(0, MAX_COMMIT_PARENTS),
@@ -40747,22 +41152,24 @@ var init_session_commits = __esm({
40747
41152
  init_envelope();
40748
41153
  init_timestamp();
40749
41154
  init_git_facts();
41155
+ init_hardened_git();
40750
41156
  init_session_changes();
40751
41157
  META_FORMAT = "--format=%H%x1f%P%x1f%at%x1f%ct%x1f%s";
40752
41158
  PATCH_IDS = [
40753
41159
  'cd "$1" && shift &&',
40754
- "git --no-optional-locks -c core.quotePath=false",
41160
+ hardenedGitShellPrefix(),
41161
+ "--no-optional-locks -c core.quotePath=false",
40755
41162
  "-c diff.noprefix=false -c diff.mnemonicPrefix=false",
40756
41163
  "log --no-walk=unsorted --ignore-missing -p --no-color --no-ext-diff",
40757
41164
  '--no-textconv --find-renames --format="commit %H" "$@" --',
40758
- "| git patch-id --stable"
41165
+ `| ${hardenedGitShellPrefix()} patch-id --stable`
40759
41166
  ].join(" ");
40760
41167
  }
40761
41168
  });
40762
41169
 
40763
41170
  // ../../packages/tacho/src/collector/worktree-snapshot.ts
40764
41171
  import { lstat as lstat2 } from "node:fs/promises";
40765
- import { join as join30 } from "node:path";
41172
+ import { join as join31 } from "node:path";
40766
41173
  function headerPath(prefix, path2) {
40767
41174
  const name = `${prefix}${path2}`;
40768
41175
  let quoted3 = false;
@@ -40837,7 +41244,7 @@ async function worktreeFingerprint(status2, root) {
40837
41244
  const path2 = statusPath(record);
40838
41245
  if (path2 === null) return "";
40839
41246
  try {
40840
- const info = await lstat2(join30(root, path2));
41247
+ const info = await lstat2(join31(root, path2));
40841
41248
  return `${info.size}:${info.mtimeMs}:${info.ctimeMs}`;
40842
41249
  } catch {
40843
41250
  return "absent";
@@ -40866,14 +41273,15 @@ async function readWorktreeSnapshot(exec4, cwd, baseline, measured) {
40866
41273
  let directory = cwd;
40867
41274
  const read2 = async (args, statuses = [0]) => {
40868
41275
  try {
40869
- const result2 = await exec4("git", [
40870
- "-C",
40871
- directory,
40872
- "--no-optional-locks",
40873
- "-c",
40874
- "core.quotePath=false",
40875
- ...args
40876
- ]);
41276
+ const result2 = await exec4(
41277
+ "git",
41278
+ hardenedGitArgs(directory, args, [
41279
+ "--no-optional-locks",
41280
+ "-c",
41281
+ "core.quotePath=false"
41282
+ ]),
41283
+ { env: HARDENED_GIT_ENV }
41284
+ );
40877
41285
  return result2.status !== null && statuses.includes(result2.status) ? result2.stdout : void 0;
40878
41286
  } catch {
40879
41287
  return void 0;
@@ -40943,7 +41351,7 @@ async function readWorktreeSnapshot(exec4, cwd, baseline, measured) {
40943
41351
  }
40944
41352
  let present;
40945
41353
  try {
40946
- present = (await lstat2(join30(root, path2))).isFile();
41354
+ present = (await lstat2(join31(root, path2))).isFile();
40947
41355
  } catch {
40948
41356
  present = false;
40949
41357
  }
@@ -41036,6 +41444,7 @@ var WORKTREE_PATCH_MAX_BYTES, WORKTREE_UNTRACKED_MAX, HASH, WORKTREE_FINGERPRINT
41036
41444
  var init_worktree_snapshot = __esm({
41037
41445
  "../../packages/tacho/src/collector/worktree-snapshot.ts"() {
41038
41446
  "use strict";
41447
+ init_hardened_git();
41039
41448
  WORKTREE_PATCH_MAX_BYTES = 256 * 1024;
41040
41449
  WORKTREE_UNTRACKED_MAX = 32;
41041
41450
  HASH = /^[a-f0-9]{40,64}$/i;
@@ -41044,10 +41453,10 @@ var init_worktree_snapshot = __esm({
41044
41453
  });
41045
41454
 
41046
41455
  // ../../packages/tacho/src/collector/git-lane.ts
41047
- import { join as join31 } from "node:path";
41456
+ import { join as join32 } from "node:path";
41048
41457
  function copiesDirOf(root, session) {
41049
41458
  const uuid = session.recorder.sessionUuid;
41050
- return /^[0-9a-f-]{36}$/i.test(uuid) ? join31(root, uuid) : void 0;
41459
+ return /^[0-9a-f-]{36}$/i.test(uuid) ? join32(root, uuid) : void 0;
41051
41460
  }
41052
41461
  function holdsBaseline(session) {
41053
41462
  return session.baselineCommit !== void 0 || Object.keys(session.baselines ?? {}).length > 0;
@@ -41846,7 +42255,7 @@ var init_interjection2 = __esm({
41846
42255
  });
41847
42256
 
41848
42257
  // ../../packages/tacho/src/collector/recall-hints.ts
41849
- import { isAbsolute as isAbsolute5, relative as relative3, resolve as resolve9, sep as sep3 } from "node:path";
42258
+ import { isAbsolute as isAbsolute6, relative as relative4, resolve as resolve10, sep as sep4 } from "node:path";
41850
42259
  function retryDelay(failures) {
41851
42260
  return Math.min(
41852
42261
  REPOSITORY_RETRY_FIRST_MS * 2 ** (failures - 1),
@@ -41861,10 +42270,10 @@ function inFront(list2, entry2, max2) {
41861
42270
  return [entry2, ...list2.filter((held) => held !== entry2)].slice(0, max2);
41862
42271
  }
41863
42272
  function relativeTo(root, path2) {
41864
- const inside2 = relative3(root, path2);
41865
- if (inside2 === ".." || inside2.startsWith(`..${sep3}`)) return void 0;
41866
- if (isAbsolute5(inside2)) return void 0;
41867
- return inside2.split(sep3).join("/");
42273
+ const inside2 = relative4(root, path2);
42274
+ if (inside2 === ".." || inside2.startsWith(`..${sep4}`)) return void 0;
42275
+ if (isAbsolute6(inside2)) return void 0;
42276
+ return inside2.split(sep4).join("/");
41868
42277
  }
41869
42278
  function recalledToolName(seen) {
41870
42279
  const rest = seen.startsWith(MCP_PREFIX2) ? seen.slice(MCP_PREFIX2.length) : "";
@@ -41882,7 +42291,7 @@ function noteRecallHints(record, toolName3, toolInput) {
41882
42291
  const value = toolInput?.[key];
41883
42292
  if (typeof value !== "string" || value.length === 0) continue;
41884
42293
  const cwd = record.cwd;
41885
- const absolute = isAbsolute5(value) ? resolve9(value) : cwd !== void 0 && isAbsolute5(cwd) ? resolve9(cwd, value) : void 0;
42294
+ const absolute = isAbsolute6(value) ? resolve10(value) : cwd !== void 0 && isAbsolute6(cwd) ? resolve10(cwd, value) : void 0;
41886
42295
  if (absolute !== void 0)
41887
42296
  hints.paths = inFront(hints.paths, absolute, RECALL_PATHS_KEPT);
41888
42297
  }
@@ -41971,7 +42380,8 @@ function notePolicyRunCall(record, call2) {
41971
42380
  {
41972
42381
  harness: call2.harness,
41973
42382
  toolName: call2.toolName,
41974
- ...call2.toolInput !== void 0 ? { toolInput: call2.toolInput } : {}
42383
+ ...call2.toolInput !== void 0 ? { toolInput: call2.toolInput } : {},
42384
+ ...call2.oxagenServerVerified !== void 0 ? { oxagenServerVerified: call2.oxagenServerVerified } : {}
41975
42385
  },
41976
42386
  call2.cedar.tools
41977
42387
  );
@@ -41995,7 +42405,7 @@ var init_policy_run = __esm({
41995
42405
 
41996
42406
  // ../../packages/tacho/src/collector/hook-handler.ts
41997
42407
  import { homedir as homedir4 } from "node:os";
41998
- import { dirname as dirname17, isAbsolute as isAbsolute6 } from "node:path";
42408
+ import { dirname as dirname17, isAbsolute as isAbsolute7 } from "node:path";
41999
42409
  function containmentUnmet(view, record) {
42000
42410
  return view.verified && view.bundle.mode === "enforce" && view.bundle.containment?.required === true && view.launchedContained?.(record.harnessSessionId) !== true;
42001
42411
  }
@@ -42119,9 +42529,13 @@ function deliversMessages(harness, hookEventName) {
42119
42529
  return hookEventName === "SessionStart" || hookEventName === "Stop" || hookEventName === "PreToolUse";
42120
42530
  return MESSAGE_BOUNDARIES.has(hookEventName);
42121
42531
  }
42532
+ function answerInTime(deps, now) {
42533
+ return deps.answerBy === void 0 || now + DRAIN_ANSWER_MARGIN_MS <= deps.answerBy;
42534
+ }
42122
42535
  function drainMessages(record, deps, events, used = 0) {
42123
42536
  const delivered = [];
42124
42537
  const now = deps.now();
42538
+ if (!answerInTime(deps, now)) return delivered;
42125
42539
  const max2 = hookAnswerMaxChars(record.harness);
42126
42540
  const queue = record.control.messages.splice(0);
42127
42541
  for (const [index, message] of queue.entries()) {
@@ -42202,6 +42616,22 @@ function drainContinuation(record, events) {
42202
42616
  );
42203
42617
  return RESUMED_TEXT;
42204
42618
  }
42619
+ function drainForWaiter(record, deps, events) {
42620
+ if (record.control.paused !== null || record.control.cancelled !== null)
42621
+ return [];
42622
+ if (record.harness !== void 0 && record.harness !== "claude-code")
42623
+ return [];
42624
+ const owed = record.control.resumeOwed === void 0 ? 0 : RESUMED_TEXT.length + CONTEXT_JOINER.length;
42625
+ const texts = drainMessages(
42626
+ record,
42627
+ deps,
42628
+ events,
42629
+ WAKE_LEAD.length + CONTEXT_JOINER.length + owed
42630
+ ).map((message) => message.text);
42631
+ const continuation = drainContinuation(record, events);
42632
+ if (continuation !== void 0) texts.push(continuation);
42633
+ return texts;
42634
+ }
42205
42635
  function drainMidTurn(input, record, deps, events, replay, used = 0) {
42206
42636
  if (replay !== void 0 || input.agent_id !== void 0 || !deliversMessages(record.harness, input.hook_event_name))
42207
42637
  return [];
@@ -42252,11 +42682,12 @@ async function handleHookEvent(raw, env, deps, replay, harness, agent, hookId) {
42252
42682
  ...hookKey === void 0 ? {} : { hookKey }
42253
42683
  };
42254
42684
  }
42255
- async function cedarCallFor(view, record, input, deps, action) {
42685
+ async function cedarCallFor(view, record, input, deps, toolName3, action) {
42256
42686
  if (view.bundle.cedar === void 0) return void 0;
42257
42687
  const custom2 = record.customAgent;
42258
42688
  const facts = policyRunFacts(record);
42259
42689
  return {
42690
+ ...oxagenServerVerified(view, record, input, deps, toolName3) ? { oxagenServerVerified: true } : {},
42260
42691
  // No loader means no evaluator: a mutating tool is refused rather than
42261
42692
  // decided without the bundle's policies.
42262
42693
  runtime: deps.cedar !== void 0 ? await deps.cedar() : null,
@@ -42270,6 +42701,22 @@ async function cedarCallFor(view, record, input, deps, action) {
42270
42701
  facts
42271
42702
  };
42272
42703
  }
42704
+ function oxagenServerVerified(view, record, input, deps, toolName3) {
42705
+ if (!isOxagenTool(toolName3) || deps.oxagenServerServes === void 0)
42706
+ return false;
42707
+ if (record.customAgent !== void 0) return false;
42708
+ if ((record.harness ?? "claude-code") !== "claude-code") return false;
42709
+ if (view.launchedContained?.(record.harnessSessionId) === true) return false;
42710
+ const cwd = record.cwd ?? input.cwd;
42711
+ try {
42712
+ return deps.oxagenServerServes({
42713
+ startedAt: record.startedAt,
42714
+ ...cwd !== void 0 ? { cwd } : {}
42715
+ });
42716
+ } catch {
42717
+ return false;
42718
+ }
42719
+ }
42273
42720
  function evaluationRequestFor(view, toolName3, toolInput, record, deps, input, cedar) {
42274
42721
  return {
42275
42722
  ...cedar !== void 0 ? { cedar } : {},
@@ -42301,7 +42748,14 @@ async function decideToolCall(view, record, input, deps, replay, call2) {
42301
42748
  record,
42302
42749
  deps,
42303
42750
  input,
42304
- await cedarCallFor(current2, record, input, deps, call2.action)
42751
+ await cedarCallFor(
42752
+ current2,
42753
+ record,
42754
+ input,
42755
+ deps,
42756
+ call2.toolName,
42757
+ call2.action
42758
+ )
42305
42759
  )
42306
42760
  );
42307
42761
  let current = view;
@@ -42488,7 +42942,9 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
42488
42942
  const block = operatorBlock(view, record);
42489
42943
  const steering = block === void 0 && replay === void 0 ? await runSteeringBundle(record, deps) ?? view.bundle : view.bundle;
42490
42944
  const context = steering.context.system;
42491
- const messages = block === void 0 && replay === void 0 ? drainMessages(record, deps, events, context?.length ?? 0) : [];
42945
+ if (block === void 0 && replay === void 0)
42946
+ await placeSessionSkills(view, record, deps, env);
42947
+ const messages = block === void 0 && replay === void 0 && input.agent_id === void 0 ? drainMessages(record, deps, events, context?.length ?? 0) : [];
42492
42948
  const additional = block === void 0 ? [context ?? "", ...messages.map((m) => m.text)].filter((s2) => s2.length > 0).join(CONTEXT_JOINER) : "";
42493
42949
  const delivered = replay === void 0 ? void 0 : readDeliveredContext(replay.deliveredContext);
42494
42950
  const deliveryAttrs = replay === void 0 ? {
@@ -42537,8 +42993,6 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
42537
42993
  record
42538
42994
  };
42539
42995
  }
42540
- if (replay === void 0)
42541
- await placeSessionSkills(view, record, deps, env);
42542
42996
  const manifest = steering.context.manifest;
42543
42997
  if (manifest !== void 0 && (replay === void 0 || delivered?.bundle_etag === steering.etag && manifest.text_digest === (delivered.digest ?? null))) {
42544
42998
  events.push(
@@ -42577,7 +43031,7 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
42577
43031
  events.push(...asked);
42578
43032
  const block = promptBlock(view, record);
42579
43033
  const notice = block === void 0 && timedOut !== void 0 ? INTERJECTION_TIMED_OUT_TEXT : void 0;
42580
- const messages = block === void 0 && replay === void 0 && deliversMessages(record.harness, input.hook_event_name) ? drainMessages(record, deps, events, notice?.length ?? 0) : [];
43034
+ const messages = block === void 0 && replay === void 0 && input.agent_id === void 0 && deliversMessages(record.harness, input.hook_event_name) ? drainMessages(record, deps, events, notice?.length ?? 0) : [];
42581
43035
  const delivered = [
42582
43036
  ...notice !== void 0 ? [notice] : [],
42583
43037
  ...messages.map((m) => m.text)
@@ -42590,7 +43044,8 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
42590
43044
  delivered.join(CONTEXT_JOINER).length,
42591
43045
  hookAnswerMaxChars(record.harness)
42592
43046
  ) : void 0;
42593
- if (block === void 0) record.control.resumeOwed = void 0;
43047
+ if (block === void 0 && input.agent_id === void 0)
43048
+ record.control.resumeOwed = void 0;
42594
43049
  if (block === void 0) notePrompt(record, promptText(input));
42595
43050
  const handed = [
42596
43051
  ...delivered,
@@ -42809,7 +43264,9 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
42809
43264
  cedar: view.bundle.cedar,
42810
43265
  harness: record.customAgent !== void 0 ? "custom" : record.harness ?? "claude-code",
42811
43266
  toolName: input.tool_name,
42812
- ...input.tool_input !== void 0 ? { toolInput: input.tool_input } : {}
43267
+ ...input.tool_input !== void 0 ? { toolInput: input.tool_input } : {},
43268
+ // Counted unless the kernel decided it, as the hook judged it.
43269
+ ...oxagenServerVerified(view, record, input, deps, input.tool_name) ? { oxagenServerVerified: true } : {}
42813
43270
  });
42814
43271
  if (input.hook_event_name === "PostToolUseFailure")
42815
43272
  noteToolFailure(record, input.tool_name);
@@ -42896,7 +43353,7 @@ function writtenPath(input) {
42896
43353
  return void 0;
42897
43354
  if (!FILE_WRITING_TOOLS.has(input.tool_name ?? "")) return void 0;
42898
43355
  const path2 = input.tool_input?.["file_path"] ?? input.tool_input?.["notebook_path"];
42899
- if (typeof path2 !== "string" || !isAbsolute6(path2)) return void 0;
43356
+ if (typeof path2 !== "string" || !isAbsolute7(path2)) return void 0;
42900
43357
  return path2;
42901
43358
  }
42902
43359
  function noteActivity(record, input, payload, at2, created) {
@@ -42935,7 +43392,7 @@ function recallView(record) {
42935
43392
  }
42936
43393
  };
42937
43394
  }
42938
- var CONTAINMENT_REQUIRED_REASON, MESSAGE_BOUNDARIES, RESUMED_TEXT, ADDITIONAL_CONTEXT_MAX_CHARS, CONTEXT_JOINER, TOOL_CALL_HOOK_EVENTS, CREDENTIAL_BASIS_READ_ERROR_ATTR, MAX_BASIS_READ_ERROR_CHARS, RECALL_HEADING, FILE_WRITING_TOOLS, recallDirs;
43395
+ var CONTAINMENT_REQUIRED_REASON, MESSAGE_BOUNDARIES, RESUMED_TEXT, ADDITIONAL_CONTEXT_MAX_CHARS, CONTEXT_JOINER, DRAIN_ANSWER_MARGIN_MS, WAKE_LEAD, TOOL_CALL_HOOK_EVENTS, CREDENTIAL_BASIS_READ_ERROR_ATTR, MAX_BASIS_READ_ERROR_CHARS, RECALL_HEADING, FILE_WRITING_TOOLS, recallDirs;
42939
43396
  var init_hook_handler = __esm({
42940
43397
  "../../packages/tacho/src/collector/hook-handler.ts"() {
42941
43398
  "use strict";
@@ -42947,6 +43404,7 @@ var init_hook_handler = __esm({
42947
43404
  init_timestamp();
42948
43405
  init_wire();
42949
43406
  init_bundle();
43407
+ init_hook();
42950
43408
  init_registry();
42951
43409
  init_session_activity();
42952
43410
  init_reflection_ask();
@@ -42965,6 +43423,8 @@ var init_hook_handler = __esm({
42965
43423
  RESUMED_TEXT = "Resumed by the operator. Continue the task.";
42966
43424
  ADDITIONAL_CONTEXT_MAX_CHARS = hookAnswerMaxChars(void 0);
42967
43425
  CONTEXT_JOINER = "\n\n";
43426
+ DRAIN_ANSWER_MARGIN_MS = 750;
43427
+ WAKE_LEAD = "A message reached you through Oxagen while you were idle at your prompt. Read it and act on it now.";
42968
43428
  TOOL_CALL_HOOK_EVENTS = /* @__PURE__ */ new Set([
42969
43429
  "PreToolUse",
42970
43430
  "PermissionRequest",
@@ -42984,6 +43444,133 @@ var init_hook_handler = __esm({
42984
43444
  }
42985
43445
  });
42986
43446
 
43447
+ // ../../packages/tacho/src/collector/steer-waiters.ts
43448
+ function owesText(session) {
43449
+ return session.control.messages.length > 0 || session.control.resumeOwed !== void 0;
43450
+ }
43451
+ var STEER_WAIT_HOLD_MS, STEER_WAIT_BUSY_KEPT, STEER_WAIT_RELEASING_EVENTS, SteerWaiters;
43452
+ var init_steer_waiters = __esm({
43453
+ "../../packages/tacho/src/collector/steer-waiters.ts"() {
43454
+ "use strict";
43455
+ STEER_WAIT_HOLD_MS = 25e3;
43456
+ STEER_WAIT_BUSY_KEPT = 4096;
43457
+ STEER_WAIT_RELEASING_EVENTS = /* @__PURE__ */ new Set([
43458
+ "UserPromptSubmit",
43459
+ "PreToolUse",
43460
+ "PostToolUse",
43461
+ "PostToolUseFailure",
43462
+ "SessionEnd"
43463
+ ]);
43464
+ SteerWaiters = class {
43465
+ constructor(deps) {
43466
+ this.deps = deps;
43467
+ this.holdMs = deps.holdMs ?? STEER_WAIT_HOLD_MS;
43468
+ }
43469
+ deps;
43470
+ waiting = /* @__PURE__ */ new Map();
43471
+ /** When each session last showed its agent working, by key, oldest first. */
43472
+ busyAt = /* @__PURE__ */ new Map();
43473
+ holdMs;
43474
+ /** How many waiters hold a request now. */
43475
+ get size() {
43476
+ return this.waiting.size;
43477
+ }
43478
+ /**
43479
+ * Hold one waiter request for the session `key` names. `signal` aborts
43480
+ * when the waiter's connection closes. `startedAt` is when the waiter
43481
+ * started; one whose session was busy since is told to stop.
43482
+ */
43483
+ wait(key, signal, startedAt) {
43484
+ this.waiting.get(key)?.settle({ done: true });
43485
+ const busy = this.busyAt.get(key);
43486
+ if (startedAt !== void 0 && busy !== void 0 && busy >= startedAt)
43487
+ return Promise.resolve({ done: true });
43488
+ const session = this.deps.find(key);
43489
+ if (session !== void 0 && (session.sealed || session.pendingTerminal === true))
43490
+ return Promise.resolve({ done: true });
43491
+ return new Promise((resolve23) => {
43492
+ let settled2 = false;
43493
+ const timer = setTimeout(() => waiter.settle({ wait: true }), this.holdMs);
43494
+ timer.unref?.();
43495
+ const onAbort = () => waiter.settle({ done: true });
43496
+ const waiter = {
43497
+ delivering: false,
43498
+ released: false,
43499
+ signal,
43500
+ settle: (answer) => {
43501
+ if (settled2) return;
43502
+ settled2 = true;
43503
+ clearTimeout(timer);
43504
+ signal.removeEventListener("abort", onAbort);
43505
+ if (this.waiting.get(key) === waiter) this.waiting.delete(key);
43506
+ resolve23(answer);
43507
+ }
43508
+ };
43509
+ if (signal.aborted) {
43510
+ waiter.settle({ done: true });
43511
+ return;
43512
+ }
43513
+ signal.addEventListener("abort", onAbort, { once: true });
43514
+ this.waiting.set(key, waiter);
43515
+ this.tryDeliver(key);
43516
+ });
43517
+ }
43518
+ /**
43519
+ * The session is working again (`at`), or ended: its waiter stops, and so
43520
+ * does any waiter that started before `at` and asks again later.
43521
+ */
43522
+ release(key, at2) {
43523
+ if (at2 !== void 0) {
43524
+ this.busyAt.delete(key);
43525
+ this.busyAt.set(key, at2);
43526
+ for (const oldest of this.busyAt.keys()) {
43527
+ if (this.busyAt.size <= STEER_WAIT_BUSY_KEPT) break;
43528
+ this.busyAt.delete(oldest);
43529
+ }
43530
+ }
43531
+ const waiter = this.waiting.get(key);
43532
+ if (waiter === void 0) return;
43533
+ if (waiter.delivering) waiter.released = true;
43534
+ else waiter.settle({ done: true });
43535
+ }
43536
+ /** Messages may have been queued: offer them to every waiter. */
43537
+ nudge() {
43538
+ for (const key of [...this.waiting.keys()]) this.tryDeliver(key);
43539
+ }
43540
+ /**
43541
+ * The daemon is stopping: every waiter is told to ask again, so it reaches
43542
+ * the next daemon rather than leave its idle session with no waiter.
43543
+ */
43544
+ releaseAll() {
43545
+ for (const waiter of [...this.waiting.values()])
43546
+ waiter.settle({ wait: true });
43547
+ }
43548
+ tryDeliver(key) {
43549
+ const waiter = this.waiting.get(key);
43550
+ if (waiter === void 0 || waiter.delivering) return;
43551
+ const session = this.deps.find(key);
43552
+ if (session === void 0 || !owesText(session)) return;
43553
+ waiter.delivering = true;
43554
+ const alive = () => this.waiting.get(key) === waiter && !waiter.released && !waiter.signal.aborted;
43555
+ this.deps.deliver(session, alive).then(
43556
+ (text5) => {
43557
+ waiter.delivering = false;
43558
+ if (text5 !== void 0) waiter.settle({ text: text5 });
43559
+ else if (waiter.released) waiter.settle({ done: true });
43560
+ },
43561
+ (error) => {
43562
+ waiter.delivering = false;
43563
+ this.deps.log?.(
43564
+ `steer waiter: delivery failed: ${error instanceof Error ? error.message : String(error)}`
43565
+ );
43566
+ if (waiter.released) waiter.settle({ done: true });
43567
+ }
43568
+ );
43569
+ }
43570
+ };
43571
+ }
43572
+ });
43573
+
42987
43574
  // ../../packages/tacho/src/collector/hook-id-journal.ts
42988
43575
  import { appendFileSync as appendFileSync3, existsSync as existsSync18, readFileSync as readFileSync16, rmSync as rmSync7 } from "node:fs";
42989
43576
  function hookIdJournalEntry(session, key, at2, events) {
@@ -43119,12 +43706,13 @@ function applyToSession(record, command2, deps, undo) {
43119
43706
  const effect = record.control.pauseEffect;
43120
43707
  record.control.paused = null;
43121
43708
  record.control.pauseEffect = void 0;
43122
- if (effect === "refused") record.control.resumeOwed = command2.id;
43709
+ if (effect === "refused" || effect === "stopped")
43710
+ record.control.resumeOwed = command2.id;
43123
43711
  events.push(applied(record.recorder, command2, "session_resumed"));
43124
43712
  return effect === "stopped" ? {
43125
43713
  events,
43126
43714
  status: "applied",
43127
- detail: "The agent ended its turn while paused and stays idle until its next prompt."
43715
+ detail: RESUMED_IDLE_DETAIL
43128
43716
  } : { events, status: "applied" };
43129
43717
  }
43130
43718
  case "cancel":
@@ -43417,7 +44005,7 @@ function sealCommands(commands, deps, now) {
43417
44005
  }
43418
44006
  };
43419
44007
  }
43420
- var HANDLED_COMMANDS_KEPT, HandledCommands, MAX_ACK_DETAIL_CHARS;
44008
+ var RESUMED_IDLE_DETAIL, HANDLED_COMMANDS_KEPT, HandledCommands, MAX_ACK_DETAIL_CHARS;
43421
44009
  var init_inbox = __esm({
43422
44010
  "../../packages/tacho/src/collector/inbox.ts"() {
43423
44011
  "use strict";
@@ -43425,6 +44013,7 @@ var init_inbox = __esm({
43425
44013
  init_wire();
43426
44014
  init_interjection2();
43427
44015
  init_registry();
44016
+ RESUMED_IDLE_DETAIL = "The agent ended its turn while paused. A Claude Code agent is woken to continue. Any other agent stays idle until its next prompt.";
43428
44017
  HANDLED_COMMANDS_KEPT = 1024;
43429
44018
  HandledCommands = class {
43430
44019
  constructor(limit = HANDLED_COMMANDS_KEPT) {
@@ -43529,7 +44118,7 @@ function recordOnChain(chain, seal2, record) {
43529
44118
  }
43530
44119
  function onSessionQueue(exclusive, session, apply) {
43531
44120
  if (exclusive !== void 0) return exclusive(session, apply);
43532
- return new Promise((resolve22) => resolve22(apply()));
44121
+ return new Promise((resolve23) => resolve23(apply()));
43533
44122
  }
43534
44123
  var init_chain_write = __esm({
43535
44124
  "../../packages/tacho/src/collector/chain-write.ts"() {
@@ -43541,7 +44130,7 @@ var init_chain_write = __esm({
43541
44130
  import { randomBytes as randomBytes10, createHash as createHash9 } from "node:crypto";
43542
44131
  import { Readable } from "node:stream";
43543
44132
  import { pipeline } from "node:stream/promises";
43544
- import { resolve as resolve10 } from "node:path";
44133
+ import { resolve as resolve11 } from "node:path";
43545
44134
  function logLine(event, fields) {
43546
44135
  const pairs = Object.entries(fields).filter(
43547
44136
  (field) => field[1] !== void 0
@@ -43638,7 +44227,7 @@ function createGithubProxy(deps) {
43638
44227
  }
43639
44228
  function receiptMatches(host, repository, cwd, harness) {
43640
44229
  return cwd !== void 0 && (host.github_repositories ?? []).some(
43641
- (receipt) => receipt.repository.toLowerCase() === repository.toLowerCase() && resolve10(receipt.cwd) === resolve10(cwd) && receipt.harness === harness
44230
+ (receipt) => receipt.repository.toLowerCase() === repository.toLowerCase() && resolve11(receipt.cwd) === resolve11(cwd) && receipt.harness === harness
43642
44231
  );
43643
44232
  }
43644
44233
  function issue(input) {
@@ -43669,7 +44258,7 @@ function createGithubProxy(deps) {
43669
44258
  }
43670
44259
  };
43671
44260
  const matches = deps.registry.live().filter(
43672
- (s2) => !s2.pendingTerminal && s2.cwd && resolve10(s2.cwd) === resolve10(input.cwd) && deps.registry.agentOf(s2).harness === input.harness
44261
+ (s2) => !s2.pendingTerminal && s2.cwd && resolve11(s2.cwd) === resolve11(input.cwd) && deps.registry.agentOf(s2).harness === input.harness
43673
44262
  );
43674
44263
  if (matches.length !== 1)
43675
44264
  return {
@@ -44135,7 +44724,7 @@ var init_hook_queues = __esm({
44135
44724
 
44136
44725
  // ../../packages/tacho/src/collector/memory-capture/memory-reader.ts
44137
44726
  import { createRequire as createRequire2 } from "node:module";
44138
- import { isAbsolute as isAbsolute7, join as join32, sep as sep4 } from "node:path";
44727
+ import { isAbsolute as isAbsolute8, join as join33, sep as sep5 } from "node:path";
44139
44728
  function claudeCodeLocation(projectsDir, memoryDir) {
44140
44729
  return {
44141
44730
  harness: "claude-code",
@@ -44147,13 +44736,13 @@ function claudeCodeLocation(projectsDir, memoryDir) {
44147
44736
  }
44148
44737
  function claudeCodeMemoryLocations(configDir, projectDirs = []) {
44149
44738
  const locations = [
44150
- claudeCodeLocation(() => join32(configDir, "projects"), "memory"),
44151
- claudeCodeLocation(() => join32(configDir, "agent-memory"), "")
44739
+ claudeCodeLocation(() => join33(configDir, "projects"), "memory"),
44740
+ claudeCodeLocation(() => join33(configDir, "agent-memory"), "")
44152
44741
  ];
44153
44742
  for (const dir of projectDirs.slice(0, MEMORY_PROJECT_DIRS_MAX))
44154
44743
  locations.push(
44155
- claudeCodeLocation(() => join32(dir, ".claude", "agent-memory"), ""),
44156
- claudeCodeLocation(() => join32(dir, ".claude", "agent-memory-local"), "")
44744
+ claudeCodeLocation(() => join33(dir, ".claude", "agent-memory"), ""),
44745
+ claudeCodeLocation(() => join33(dir, ".claude", "agent-memory-local"), "")
44157
44746
  );
44158
44747
  return locations;
44159
44748
  }
@@ -44165,7 +44754,7 @@ function projectDirsOf(sessions) {
44165
44754
  if (session.harness !== void 0 && session.harness !== "claude-code")
44166
44755
  continue;
44167
44756
  for (const dir of [session.cwd, ...Object.keys(session.baselines ?? {})])
44168
- if (dir !== void 0 && isAbsolute7(dir)) dirs.add(dir);
44757
+ if (dir !== void 0 && isAbsolute8(dir)) dirs.add(dir);
44169
44758
  if (dirs.size >= MEMORY_PROJECT_DIRS_MAX) break;
44170
44759
  }
44171
44760
  return [...dirs].slice(0, MEMORY_PROJECT_DIRS_MAX);
@@ -44338,13 +44927,13 @@ function createMemoryReader(deps) {
44338
44927
  const projects = await list2(top);
44339
44928
  let complete = projects.complete;
44340
44929
  for (const project2 of projects.names) {
44341
- const dir = location.memoryDir === "" ? join32(top, project2) : join32(top, project2, location.memoryDir);
44930
+ const dir = location.memoryDir === "" ? join33(top, project2) : join33(top, project2, location.memoryDir);
44342
44931
  const files2 = await list2(dir);
44343
44932
  if (!files2.complete) complete = false;
44344
44933
  for (const name of files2.names) {
44345
44934
  if (!name.endsWith(location.extension)) continue;
44346
44935
  if (location.skip.includes(name)) continue;
44347
- const path2 = join32(dir, name);
44936
+ const path2 = join33(dir, name);
44348
44937
  const file = await readAt2(location.harness, path2);
44349
44938
  if (file.kind === "absent" || file.kind === "empty") continue;
44350
44939
  paths.push(path2);
@@ -44430,14 +45019,14 @@ var init_memory_reader = __esm({
44430
45019
  MEMORY_TYPE_PATTERN = /^[a-z][a-z0-9_-]{0,31}$/;
44431
45020
  MEMORY_PROJECT_DIRS_MAX = 200;
44432
45021
  HARNESS_MEMORY_LOCATIONS = [
44433
- claudeCodeLocation((home) => join32(home, ".claude", "projects"), "memory"),
44434
- claudeCodeLocation((home) => join32(home, ".claude", "agent-memory"), "")
45022
+ claudeCodeLocation((home) => join33(home, ".claude", "projects"), "memory"),
45023
+ claudeCodeLocation((home) => join33(home, ".claude", "agent-memory"), "")
44435
45024
  ];
44436
45025
  FRONTMATTER = /^---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/;
44437
45026
  FRONTMATTER_LINE = /^([ \t]*)([A-Za-z_][\w-]*)[ \t]*:[ \t]*(.*)$/;
44438
45027
  keyOf = (harness, path2) => `${harness}
44439
45028
  ${path2}`;
44440
- withSep = (dir) => dir.endsWith(sep4) ? dir : `${dir}${sep4}`;
45029
+ withSep = (dir) => dir.endsWith(sep5) ? dir : `${dir}${sep5}`;
44441
45030
  }
44442
45031
  });
44443
45032
 
@@ -44873,10 +45462,10 @@ function createMemoryRecall(deps) {
44873
45462
  if (now() < pausedUntil) return [];
44874
45463
  const controller = new AbortController();
44875
45464
  let timer;
44876
- const timedOut = new Promise((resolve22) => {
45465
+ const timedOut = new Promise((resolve23) => {
44877
45466
  timer = setTimeout(() => {
44878
45467
  controller.abort();
44879
- resolve22(
45468
+ resolve23(
44880
45469
  failed3(
44881
45470
  `the control plane took longer than ${timeoutMs} ms to answer`
44882
45471
  )
@@ -44923,10 +45512,10 @@ var init_memory_recall = __esm({
44923
45512
  });
44924
45513
 
44925
45514
  // ../../packages/tacho/src/collector/memory-capture/memory-uses.ts
44926
- import { basename as basename6, dirname as dirname18, isAbsolute as isAbsolute8, join as join33, resolve as resolve11 } from "node:path";
45515
+ import { basename as basename6, dirname as dirname18, isAbsolute as isAbsolute9, join as join34, resolve as resolve12 } from "node:path";
44927
45516
  function memoryFileOf(path2, locations, home) {
44928
- if (!isAbsolute8(path2)) return void 0;
44929
- const file = resolve11(path2);
45517
+ if (!isAbsolute9(path2)) return void 0;
45518
+ const file = resolve12(path2);
44930
45519
  const name = basename6(file);
44931
45520
  const folder = dirname18(file);
44932
45521
  for (const location of locations) {
@@ -44935,15 +45524,15 @@ function memoryFileOf(path2, locations, home) {
44935
45524
  const projectDir = location.memoryDir === "" ? folder : dirname18(folder);
44936
45525
  if (location.memoryDir !== "" && basename6(folder) !== location.memoryDir)
44937
45526
  continue;
44938
- if (dirname18(projectDir) !== resolve11(location.projectsDir(home))) continue;
45527
+ if (dirname18(projectDir) !== resolve12(location.projectsDir(home))) continue;
44939
45528
  return { harness: location.harness, path: file };
44940
45529
  }
44941
45530
  return void 0;
44942
45531
  }
44943
45532
  function pathOf(word, cwd, home) {
44944
- const expanded = /^(?:~|\$HOME|\$\{HOME\})\//.test(word) ? join33(home, word.slice(word.indexOf("/") + 1)) : word;
44945
- if (isAbsolute8(expanded)) return expanded;
44946
- if (cwd !== void 0 && isAbsolute8(cwd)) return resolve11(cwd, expanded);
45533
+ const expanded = /^(?:~|\$HOME|\$\{HOME\})\//.test(word) ? join34(home, word.slice(word.indexOf("/") + 1)) : word;
45534
+ if (isAbsolute9(expanded)) return expanded;
45535
+ if (cwd !== void 0 && isAbsolute9(cwd)) return resolve12(cwd, expanded);
44947
45536
  return void 0;
44948
45537
  }
44949
45538
  function stringMember(input, key) {
@@ -45197,7 +45786,7 @@ ${use.path}`;
45197
45786
  });
45198
45787
 
45199
45788
  // ../../packages/tacho/src/collector/memory-capture/stella-store.ts
45200
- import { dirname as dirname19, isAbsolute as isAbsolute9, join as join34, resolve as resolve12 } from "node:path";
45789
+ import { dirname as dirname19, isAbsolute as isAbsolute10, join as join35, resolve as resolve13 } from "node:path";
45201
45790
  function queryStellaStore(path2, afterSeq, limit) {
45202
45791
  const db = new (nodeSqlite()).DatabaseSync(path2, { readOnly: true });
45203
45792
  try {
@@ -45284,10 +45873,10 @@ function stellaRunOf(use, runs, now) {
45284
45873
  return void 0;
45285
45874
  }
45286
45875
  async function stellaStoreOf(dir, exists) {
45287
- if (!isAbsolute9(dir)) return void 0;
45288
- let at2 = resolve12(dir);
45876
+ if (!isAbsolute10(dir)) return void 0;
45877
+ let at2 = resolve13(dir);
45289
45878
  for (let depth = 0; depth < WORKSPACE_SEARCH_DEPTH; depth += 1) {
45290
- const candidate = join34(at2, STELLA_CONTEXT_DB);
45879
+ const candidate = join35(at2, STELLA_CONTEXT_DB);
45291
45880
  if (await exists(candidate)) return candidate;
45292
45881
  const up = dirname19(at2);
45293
45882
  if (up === at2) return void 0;
@@ -45300,7 +45889,7 @@ var init_stella_store = __esm({
45300
45889
  "../../packages/tacho/src/collector/memory-capture/stella-store.ts"() {
45301
45890
  "use strict";
45302
45891
  init_memory_reader();
45303
- STELLA_CONTEXT_DB = join34(".stella", "private", "context.db");
45892
+ STELLA_CONTEXT_DB = join35(".stella", "private", "context.db");
45304
45893
  STELLA_MEMORIES_VIEW = "export_memories_v1";
45305
45894
  STELLA_USES_VIEW = "export_memory_uses_v1";
45306
45895
  STELLA_USES_PER_READ = 5e3;
@@ -45962,7 +46551,7 @@ var init_cloud_link = __esm({
45962
46551
 
45963
46552
  // ../../packages/tacho/src/collector/local-servers/digest.ts
45964
46553
  import { createHash as createHash10 } from "node:crypto";
45965
- import { join as join35 } from "node:path";
46554
+ import { join as join36 } from "node:path";
45966
46555
  function rememberBounded(map, key, value) {
45967
46556
  if (!map.has(key) && map.size >= MAX_REMEMBERED_DIGESTS) {
45968
46557
  const oldest = map.keys().next();
@@ -45999,7 +46588,7 @@ function npmNameSegment(name) {
45999
46588
  return name.startsWith("@") ? `@${encodeURIComponent(name.slice(1))}` : encodeURIComponent(name);
46000
46589
  }
46001
46590
  async function whichOnPath(command2, pathValue, search) {
46002
- const candidates = command2.includes("/") || command2.includes("\\") ? [command2] : (pathValue ?? "").split(search.delimiter).filter((dir) => dir.length > 0).map((dir) => join35(dir, command2));
46591
+ const candidates = command2.includes("/") || command2.includes("\\") ? [command2] : (pathValue ?? "").split(search.delimiter).filter((dir) => dir.length > 0).map((dir) => join36(dir, command2));
46003
46592
  for (const candidate of candidates) {
46004
46593
  for (const extension of search.extensions) {
46005
46594
  if (await search.isExecutable(candidate + extension))
@@ -46637,8 +47226,8 @@ async function withSession(options, work) {
46637
47226
  if (failure4 !== void 0) return Promise.reject(failure4);
46638
47227
  const id2 = nextId;
46639
47228
  nextId += 1;
46640
- return new Promise((resolve22, reject) => {
46641
- pending.set(id2, { method, resolve: resolve22, reject });
47229
+ return new Promise((resolve23, reject) => {
47230
+ pending.set(id2, { method, resolve: resolve23, reject });
46642
47231
  send5({ id: id2, method, params });
46643
47232
  });
46644
47233
  }
@@ -46782,16 +47371,16 @@ var init_screen = __esm({
46782
47371
 
46783
47372
  // ../../packages/tacho/src/collector/local-servers/local-servers.ts
46784
47373
  function abortableSleep(ms, signal) {
46785
- return new Promise((resolve22) => {
47374
+ return new Promise((resolve23) => {
46786
47375
  if (signal.aborted) {
46787
- resolve22();
47376
+ resolve23();
46788
47377
  return;
46789
47378
  }
46790
47379
  const timer = setTimeout(done, ms);
46791
47380
  function done() {
46792
47381
  clearTimeout(timer);
46793
47382
  signal.removeEventListener("abort", done);
46794
- resolve22();
47383
+ resolve23();
46795
47384
  }
46796
47385
  signal.addEventListener("abort", done, { once: true });
46797
47386
  });
@@ -47119,7 +47708,7 @@ var init_machine = __esm({
47119
47708
  });
47120
47709
 
47121
47710
  // ../../packages/tacho/src/collector/push-basis.ts
47122
- import { resolve as resolve13 } from "node:path";
47711
+ import { resolve as resolve14 } from "node:path";
47123
47712
  function gitPushTarget(command2) {
47124
47713
  const tokens = tokenizeSimpleCommand(command2);
47125
47714
  if (tokens === void 0 || tokens[0] !== "git") return void 0;
@@ -47166,7 +47755,7 @@ async function pushCredentialBasis(command2, cwd, deps) {
47166
47755
  return TACHO_CREDENTIAL_HARNESS_HELD;
47167
47756
  const target2 = gitPushTarget(command2);
47168
47757
  if (target2 === void 0) return TACHO_CREDENTIAL_HARNESS_HELD;
47169
- const dir = target2.chdir.reduce((from, to) => resolve13(from, to), cwd);
47758
+ const dir = target2.chdir.reduce((from, to) => resolve14(from, to), cwd);
47170
47759
  const receipt = receiptFor(receipts, dir);
47171
47760
  if (receipt === void 0) return TACHO_CREDENTIAL_HARNESS_HELD;
47172
47761
  const remote = target2.remote ?? await defaultPushRemote(dir, deps);
@@ -47180,7 +47769,7 @@ function receiptFor(receipts, dir) {
47180
47769
  let found;
47181
47770
  let depth = -1;
47182
47771
  for (const entry2 of receipts) {
47183
- const root = resolve13(entry2.cwd);
47772
+ const root = resolve14(entry2.cwd);
47184
47773
  if (!isWithin(root, dir) || root.length <= depth) continue;
47185
47774
  found = entry2;
47186
47775
  depth = root.length;
@@ -47197,7 +47786,7 @@ async function containedPushBasis(command2, cwd, repository, deps) {
47197
47786
  const target2 = gitPushTarget(command2);
47198
47787
  if (cwd === void 0 || target2 === void 0)
47199
47788
  return TACHO_CREDENTIAL_HARNESS_HELD;
47200
- const dir = target2.chdir.reduce((from, to) => resolve13(from, to), cwd);
47789
+ const dir = target2.chdir.reduce((from, to) => resolve14(from, to), cwd);
47201
47790
  if (!isWithin(cwd, dir)) return TACHO_CREDENTIAL_HARNESS_HELD;
47202
47791
  const remote = target2.remote ?? await defaultPushRemote(dir, deps);
47203
47792
  const urls = await pushUrls(dir, remote, deps);
@@ -47205,7 +47794,9 @@ async function containedPushBasis(command2, cwd, repository, deps) {
47205
47794
  return urls.length > 0 && urls.every((url) => githubRepositoryOf(url) === wanted) ? TACHO_CREDENTIAL_GATEWAY_BROKERED : TACHO_CREDENTIAL_HARNESS_HELD;
47206
47795
  }
47207
47796
  async function gitOut(dir, args, deps) {
47208
- const result2 = await deps.execAsync("git", ["-C", dir, ...args]);
47797
+ const result2 = await deps.execAsync("git", hardenedGitArgs(dir, args), {
47798
+ env: HARDENED_GIT_ENV
47799
+ });
47209
47800
  return result2.status === 0 ? result2.stdout.trim() : void 0;
47210
47801
  }
47211
47802
  async function defaultPushRemote(dir, deps) {
@@ -47236,6 +47827,7 @@ var init_push_basis = __esm({
47236
47827
  "use strict";
47237
47828
  init_tools();
47238
47829
  init_wire();
47830
+ init_hardened_git();
47239
47831
  init_recall_hints();
47240
47832
  PUSH_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
47241
47833
  "--repo",
@@ -47290,9 +47882,9 @@ import {
47290
47882
  writeFile
47291
47883
  } from "node:fs/promises";
47292
47884
  import { homedir as homedir5 } from "node:os";
47293
- import { dirname as dirname20, join as join36 } from "node:path";
47885
+ import { dirname as dirname20, join as join37 } from "node:path";
47294
47886
  function stagingFolder(root, name) {
47295
- return join36(root, `.${name}${STAGING_SUFFIX}`);
47887
+ return join37(root, `.${name}${STAGING_SUFFIX}`);
47296
47888
  }
47297
47889
  function isStagingName(name) {
47298
47890
  return name.startsWith(".") && name.endsWith(STAGING_SUFFIX);
@@ -47335,17 +47927,17 @@ function envDir(env, key) {
47335
47927
  function skillsRoot(harness, env = process.env, home = homedir5()) {
47336
47928
  switch (harness) {
47337
47929
  case "claude-code":
47338
- return join36(
47339
- envDir(env, "CLAUDE_CONFIG_DIR") ?? join36(home, ".claude"),
47930
+ return join37(
47931
+ envDir(env, "CLAUDE_CONFIG_DIR") ?? join37(home, ".claude"),
47340
47932
  "skills"
47341
47933
  );
47342
47934
  case "codex": {
47343
47935
  const codexHome = envDir(env, "CODEX_HOME");
47344
- return codexHome === null ? join36(home, ".agents", "skills") : join36(codexHome, "skills");
47936
+ return codexHome === null ? join37(home, ".agents", "skills") : join37(codexHome, "skills");
47345
47937
  }
47346
47938
  case "stella":
47347
- return join36(
47348
- envDir(env, "STELLA_HOME") ?? join36(home, ".stella"),
47939
+ return join37(
47940
+ envDir(env, "STELLA_HOME") ?? join37(home, ".stella"),
47349
47941
  "skills"
47350
47942
  );
47351
47943
  case "cursor":
@@ -47406,7 +47998,7 @@ async function readMarker(folder) {
47406
47998
  if (!entries2.includes(SESSION_MARKER)) return { state: "foreign" };
47407
47999
  try {
47408
48000
  const parsed2 = JSON.parse(
47409
- await readFile2(join36(folder, SESSION_MARKER), "utf8")
48001
+ await readFile2(join37(folder, SESSION_MARKER), "utf8")
47410
48002
  );
47411
48003
  return isMarker(parsed2) ? { state: "ours", marker: parsed2 } : { state: "foreign" };
47412
48004
  } catch {
@@ -47423,22 +48015,22 @@ function liveSessions(marker, now) {
47423
48015
  return live;
47424
48016
  }
47425
48017
  async function writeMarker(folder, marker) {
47426
- const temp = join36(folder, MARKER_TEMP);
48018
+ const temp = join37(folder, MARKER_TEMP);
47427
48019
  await writeFile(temp, `${JSON.stringify(marker, null, 2)}
47428
48020
  `);
47429
- await rename2(temp, join36(folder, SESSION_MARKER));
48021
+ await rename2(temp, join37(folder, SESSION_MARKER));
47430
48022
  }
47431
48023
  async function writeSkill(root, skill, marker) {
47432
- const folder = join36(root, skill.name);
48024
+ const folder = join37(root, skill.name);
47433
48025
  const staging = stagingFolder(root, skill.name);
47434
48026
  await rm2(folder, { recursive: true, force: true });
47435
48027
  await rm2(staging, { recursive: true, force: true });
47436
48028
  await mkdir2(staging);
47437
48029
  await writeMarker(staging, { digest: UNFINISHED_DIGEST, sessions: {} });
47438
48030
  await rename2(staging, folder);
47439
- await writeFile(join36(folder, "SKILL.md"), skillMarkdown(skill));
48031
+ await writeFile(join37(folder, "SKILL.md"), skillMarkdown(skill));
47440
48032
  for (const file of skill.files) {
47441
- const target2 = join36(folder, file.path);
48033
+ const target2 = join37(folder, file.path);
47442
48034
  await mkdir2(dirname20(target2), { recursive: true });
47443
48035
  await writeFile(target2, file.content);
47444
48036
  }
@@ -47467,7 +48059,7 @@ async function placeSkills(root, sessionId, skills, now = /* @__PURE__ */ new Da
47467
48059
  result2.warnings.push(refusal);
47468
48060
  continue;
47469
48061
  }
47470
- const folder = join36(root, skill.name);
48062
+ const folder = join37(root, skill.name);
47471
48063
  if (taken.has(skill.name)) {
47472
48064
  result2.skipped.push(skill.name);
47473
48065
  result2.warnings.push(
@@ -47532,7 +48124,7 @@ async function removeSkills(root, sessionId, now = /* @__PURE__ */ new Date()) {
47532
48124
  throw error;
47533
48125
  }
47534
48126
  for (const name of names2.sort(compareText)) {
47535
- const folder = join36(root, name);
48127
+ const folder = join37(root, name);
47536
48128
  if (isStagingName(name)) {
47537
48129
  await rm2(folder, { recursive: true, force: true });
47538
48130
  continue;
@@ -47609,15 +48201,15 @@ function sessionSkills(options) {
47609
48201
  async function inTurn(task) {
47610
48202
  const before = tail;
47611
48203
  let release2 = () => void 0;
47612
- const mine = new Promise((resolve22) => {
47613
- release2 = resolve22;
48204
+ const mine = new Promise((resolve23) => {
48205
+ release2 = resolve23;
47614
48206
  });
47615
48207
  tail = before.then(() => mine);
47616
- const turn = await new Promise((resolve22) => {
47617
- const timer = setTimeout(() => resolve22(false), waitMs);
48208
+ const turn = await new Promise((resolve23) => {
48209
+ const timer = setTimeout(() => resolve23(false), waitMs);
47618
48210
  void before.then(() => {
47619
48211
  clearTimeout(timer);
47620
- resolve22(true);
48212
+ resolve23(true);
47621
48213
  });
47622
48214
  });
47623
48215
  try {
@@ -48944,10 +49536,10 @@ async function readableBody(body2, encoding, maxOutputLength) {
48944
49536
  if (decode === void 0) return void 0;
48945
49537
  try {
48946
49538
  return await new Promise(
48947
- (resolve22, reject) => decode(
49539
+ (resolve23, reject) => decode(
48948
49540
  body2,
48949
49541
  { maxOutputLength },
48950
- (error, result2) => error === null ? resolve22(result2) : reject(error)
49542
+ (error, result2) => error === null ? resolve23(result2) : reject(error)
48951
49543
  )
48952
49544
  );
48953
49545
  } catch {
@@ -49392,7 +49984,7 @@ function createModelProxy(deps) {
49392
49984
  res.end(error.body);
49393
49985
  }
49394
49986
  function readBody3(req, attempt) {
49395
- return new Promise((resolve22, reject) => {
49987
+ return new Promise((resolve23, reject) => {
49396
49988
  const chunks = [];
49397
49989
  let size = 0;
49398
49990
  let over = false;
@@ -49403,13 +49995,13 @@ function createModelProxy(deps) {
49403
49995
  if (size > maxRequestBytes) {
49404
49996
  over = true;
49405
49997
  chunks.length = 0;
49406
- resolve22("too_large");
49998
+ resolve23("too_large");
49407
49999
  return;
49408
50000
  }
49409
50001
  chunks.push(chunk2);
49410
50002
  });
49411
50003
  req.on("end", () => {
49412
- if (!over) resolve22(Buffer.concat(chunks));
50004
+ if (!over) resolve23(Buffer.concat(chunks));
49413
50005
  });
49414
50006
  req.on("error", reject);
49415
50007
  req.on("aborted", () => reject(new Error("client aborted the request")));
@@ -49420,12 +50012,12 @@ function createModelProxy(deps) {
49420
50012
  if (hook === void 0) return request3;
49421
50013
  let timer;
49422
50014
  try {
49423
- const timeout = new Promise((resolve22) => {
50015
+ const timeout = new Promise((resolve23) => {
49424
50016
  timer = setTimeout(() => {
49425
50017
  deps.log(
49426
50018
  `model proxy: beforeForward took over ${hookTimeoutMs}ms, sending the request as it came`
49427
50019
  );
49428
- resolve22(request3);
50020
+ resolve23(request3);
49429
50021
  }, hookTimeoutMs);
49430
50022
  });
49431
50023
  return await Promise.race([Promise.resolve(hook(request3)), timeout]);
@@ -49450,7 +50042,7 @@ function createModelProxy(deps) {
49450
50042
  const secure = target2.protocol === "https:";
49451
50043
  const sessionKey = record.recorder.sessionUuid;
49452
50044
  const startedAt = deps.now();
49453
- return new Promise((resolve22) => {
50045
+ return new Promise((resolve23) => {
49454
50046
  let done = false;
49455
50047
  let answered = false;
49456
50048
  let upstream;
@@ -49471,7 +50063,7 @@ function createModelProxy(deps) {
49471
50063
  if (done) return;
49472
50064
  done = true;
49473
50065
  release2();
49474
- resolve22(outcome);
50066
+ resolve23(outcome);
49475
50067
  };
49476
50068
  try {
49477
50069
  upstream = (secure ? httpsRequest : httpRequest2)({
@@ -50511,9 +51103,9 @@ function createModelProxyListener(options) {
50511
51103
  retryTimer.unref();
50512
51104
  }
50513
51105
  function bind() {
50514
- return new Promise((resolve22) => {
51106
+ return new Promise((resolve23) => {
50515
51107
  if (closed2) {
50516
- resolve22();
51108
+ resolve23();
50517
51109
  return;
50518
51110
  }
50519
51111
  const next = createServer4((req, res) => options.proxy.handle(req, res));
@@ -50554,7 +51146,7 @@ function createModelProxyListener(options) {
50554
51146
  scheduleRebind();
50555
51147
  if (!settledOnce) {
50556
51148
  settledOnce = true;
50557
- resolve22();
51149
+ resolve23();
50558
51150
  }
50559
51151
  });
50560
51152
  next.on("close", () => {
@@ -50573,7 +51165,7 @@ function createModelProxyListener(options) {
50573
51165
  options.log(`model proxy listening on 127.0.0.1:${boundPort}`);
50574
51166
  if (!settledOnce) {
50575
51167
  settledOnce = true;
50576
- resolve22();
51168
+ resolve23();
50577
51169
  }
50578
51170
  });
50579
51171
  });
@@ -50590,8 +51182,8 @@ function createModelProxyListener(options) {
50590
51182
  server = void 0;
50591
51183
  bound = false;
50592
51184
  if (current === void 0) return;
50593
- await new Promise((resolve22) => {
50594
- current.close(() => resolve22());
51185
+ await new Promise((resolve23) => {
51186
+ current.close(() => resolve23());
50595
51187
  current.closeAllConnections?.();
50596
51188
  });
50597
51189
  }
@@ -50617,7 +51209,7 @@ function isExportFormat(value) {
50617
51209
  return EXPORT_FORMATS.includes(value);
50618
51210
  }
50619
51211
  function readBody(req) {
50620
- return new Promise((resolve22, reject) => {
51212
+ return new Promise((resolve23, reject) => {
50621
51213
  const chunks = [];
50622
51214
  let size = 0;
50623
51215
  let overflowed = false;
@@ -50632,7 +51224,7 @@ function readBody(req) {
50632
51224
  }
50633
51225
  chunks.push(chunk2);
50634
51226
  });
50635
- req.on("end", () => resolve22(Buffer.concat(chunks).toString("utf8")));
51227
+ req.on("end", () => resolve23(Buffer.concat(chunks).toString("utf8")));
50636
51228
  req.on("error", reject);
50637
51229
  });
50638
51230
  }
@@ -50683,6 +51275,7 @@ function rememberMcpSession(sessions, id2) {
50683
51275
  function createRequestHandler(api, log, options = {}) {
50684
51276
  const mcpSessions = options.mcpSessions ?? /* @__PURE__ */ new Set();
50685
51277
  return (req, res) => {
51278
+ const arrivedAt = Date.now();
50686
51279
  void (async () => {
50687
51280
  let url;
50688
51281
  try {
@@ -50852,7 +51445,13 @@ function createRequestHandler(api, log, options = {}) {
50852
51445
  }
50853
51446
  if (path2 === "/hook" || path2 === `/hook/${api.enrollmentId}`) {
50854
51447
  const isEnvelope = req.headers["x-tacho-envelope"] === "1";
50855
- let envelope2 = { payload: parsed2 };
51448
+ let envelope2 = {
51449
+ payload: parsed2,
51450
+ answer_within_ms: Math.max(
51451
+ 0,
51452
+ HTTP_HOOK_ANSWER_MS - (Date.now() - arrivedAt)
51453
+ )
51454
+ };
50856
51455
  if (isEnvelope) {
50857
51456
  const read2 = hookEnvelopeSchema.safeParse(parsed2);
50858
51457
  if (!read2.success) {
@@ -50877,6 +51476,38 @@ function createRequestHandler(api, log, options = {}) {
50877
51476
  send2(res, 403, { error: "hook for another enrollment" });
50878
51477
  return;
50879
51478
  }
51479
+ if (path2 === "/steer-wait" || path2 === `/steer-wait/${api.enrollmentId}`) {
51480
+ if (api.waitForSteer === void 0) {
51481
+ send2(res, 404, { error: "this daemon holds no steer waiters" });
51482
+ return;
51483
+ }
51484
+ const read2 = steerWaitRequestSchema.safeParse(parsed2);
51485
+ if (!read2.success) {
51486
+ send2(res, 400, {
51487
+ error: `invalid steer wait: ${describeIssues(read2.error, "body")}`
51488
+ });
51489
+ return;
51490
+ }
51491
+ const closed2 = new AbortController();
51492
+ res.on("close", () => {
51493
+ if (!res.writableEnded) closed2.abort();
51494
+ });
51495
+ const answer = await api.waitForSteer(
51496
+ {
51497
+ sessionId: read2.data.session_id,
51498
+ ...read2.data.harness !== void 0 ? { harness: read2.data.harness } : {},
51499
+ ...read2.data.agent !== void 0 ? { agent: read2.data.agent } : {},
51500
+ ...read2.data.started_at !== void 0 ? { startedAt: read2.data.started_at } : {}
51501
+ },
51502
+ closed2.signal
51503
+ );
51504
+ if (!res.destroyed) send2(res, 200, answer);
51505
+ return;
51506
+ }
51507
+ if (path2.startsWith("/steer-wait/")) {
51508
+ send2(res, 403, { error: "steer wait for another enrollment" });
51509
+ return;
51510
+ }
50880
51511
  const mcpMatch = /^\/mcp(?:\/([^/]+))?$/.exec(path2);
50881
51512
  if (mcpMatch !== null) {
50882
51513
  if (api.mcp === void 0) {
@@ -50939,21 +51570,21 @@ async function removeStaleSocket(socketPath) {
50939
51570
  if (!statSync9(socketPath).isSocket()) {
50940
51571
  throw new Error(`collector socket path is not a socket: ${socketPath}`);
50941
51572
  }
50942
- const stale = await new Promise((resolve22, reject) => {
51573
+ const stale = await new Promise((resolve23, reject) => {
50943
51574
  const probe = createConnection(socketPath);
50944
51575
  probe.once("connect", () => {
50945
51576
  probe.destroy();
50946
- resolve22(false);
51577
+ resolve23(false);
50947
51578
  });
50948
51579
  probe.once("error", (error) => {
50949
51580
  probe.destroy();
50950
51581
  if (error.code === "ECONNREFUSED" || error.code === "ENOENT")
50951
- resolve22(true);
51582
+ resolve23(true);
50952
51583
  else reject(error);
50953
51584
  });
50954
51585
  probe.setTimeout(500, () => {
50955
51586
  probe.destroy();
50956
- resolve22(false);
51587
+ resolve23(false);
50957
51588
  });
50958
51589
  });
50959
51590
  if (!stale)
@@ -50982,8 +51613,8 @@ function createCollectorServer(api, log = () => void 0) {
50982
51613
  const close = async () => {
50983
51614
  await Promise.all(
50984
51615
  servers.map(
50985
- (server) => new Promise((resolve22) => {
50986
- server.close(() => resolve22());
51616
+ (server) => new Promise((resolve23) => {
51617
+ server.close(() => resolve23());
50987
51618
  server.closeAllConnections?.();
50988
51619
  })
50989
51620
  )
@@ -50998,11 +51629,11 @@ function createCollectorServer(api, log = () => void 0) {
50998
51629
  let boundPort = options.port;
50999
51630
  const tcp = createServer5((req, res) => handle(req, res, boundPort));
51000
51631
  servers.push(tcp);
51001
- await new Promise((resolve22, reject) => {
51632
+ await new Promise((resolve23, reject) => {
51002
51633
  tcp.once("error", reject);
51003
51634
  tcp.listen(options.port, options.host ?? "127.0.0.1", () => {
51004
51635
  tcp.off("error", reject);
51005
- resolve22();
51636
+ resolve23();
51006
51637
  });
51007
51638
  });
51008
51639
  const address = tcp.address();
@@ -51013,11 +51644,11 @@ function createCollectorServer(api, log = () => void 0) {
51013
51644
  await removeStaleSocket(options.socketPath);
51014
51645
  const unix = createServer5((req, res) => handle(req, res));
51015
51646
  servers.push(unix);
51016
- await new Promise((resolve22, reject) => {
51647
+ await new Promise((resolve23, reject) => {
51017
51648
  unix.once("error", reject);
51018
51649
  unix.listen(options.socketPath, () => {
51019
51650
  unix.off("error", reject);
51020
- resolve22();
51651
+ resolve23();
51021
51652
  });
51022
51653
  });
51023
51654
  chmodSync9(options.socketPath, 384);
@@ -51031,7 +51662,7 @@ function createCollectorServer(api, log = () => void 0) {
51031
51662
  close
51032
51663
  };
51033
51664
  }
51034
- var policyDecisionValueSchema, evaluationSchema, deliveredContextSchema, hookEnvelopeSchema, EXPORT_FORMATS, MAX_BODY_BYTES2, BodyTooLargeError, BEARER_REQUIRED, SESSION_KEY, MCP_SESSIONS_MAX;
51665
+ var HTTP_HOOK_ANSWER_MS, policyDecisionValueSchema, evaluationSchema, deliveredContextSchema, hookEnvelopeSchema, steerWaitRequestSchema, EXPORT_FORMATS, MAX_BODY_BYTES2, BodyTooLargeError, BEARER_REQUIRED, SESSION_KEY, MCP_SESSIONS_MAX;
51035
51666
  var init_server = __esm({
51036
51667
  "../../packages/tacho/src/collector/server.ts"() {
51037
51668
  "use strict";
@@ -51040,6 +51671,7 @@ var init_server = __esm({
51040
51671
  init_digest();
51041
51672
  init_wire();
51042
51673
  init_loopback_guard();
51674
+ HTTP_HOOK_ANSWER_MS = 4e3;
51043
51675
  policyDecisionValueSchema = external_exports.enum(["allow", "deny", "ask", "defer"]);
51044
51676
  evaluationSchema = external_exports.object({
51045
51677
  decision: policyDecisionValueSchema,
@@ -51073,7 +51705,14 @@ var init_server = __esm({
51073
51705
  }).optional(),
51074
51706
  harness: tachoHarnessSchema.optional(),
51075
51707
  agent: external_exports.string().min(1).optional(),
51076
- hook_id: external_exports.string().min(1).optional()
51708
+ hook_id: external_exports.string().min(1).optional(),
51709
+ answer_by: external_exports.number().int().positive().optional()
51710
+ });
51711
+ steerWaitRequestSchema = external_exports.object({
51712
+ session_id: external_exports.string().min(1).max(512),
51713
+ harness: tachoHarnessSchema.optional(),
51714
+ agent: external_exports.string().min(1).optional(),
51715
+ started_at: external_exports.number().int().positive().optional()
51077
51716
  });
51078
51717
  EXPORT_FORMATS = [
51079
51718
  "tacho",
@@ -51097,7 +51736,7 @@ var init_server = __esm({
51097
51736
 
51098
51737
  // ../../packages/tacho/src/collector/spool.ts
51099
51738
  import { existsSync as existsSync20, readFileSync as readFileSync17 } from "node:fs";
51100
- import { join as join37 } from "node:path";
51739
+ import { join as join38 } from "node:path";
51101
51740
  function sessionOwnedElsewhere(error) {
51102
51741
  return error.status === 403 && error.body.includes(SESSION_OWNED_ELSEWHERE);
51103
51742
  }
@@ -51291,7 +51930,7 @@ var init_spool = __esm({
51291
51930
  * gone for good.
51292
51931
  */
51293
51932
  stash(event, reason3, body2) {
51294
- const path2 = join37(
51933
+ const path2 = join38(
51295
51934
  this.options.quarantineDir,
51296
51935
  `${event.session_uuid}-${String(event.seq).padStart(8, "0")}.json`
51297
51936
  );
@@ -51309,7 +51948,7 @@ var init_spool = __esm({
51309
51948
  }
51310
51949
  /** Add a body to a quarantine record that was written without one. */
51311
51950
  stashBodyBeside(event, body2) {
51312
- const path2 = join37(
51951
+ const path2 = join38(
51313
51952
  this.options.quarantineDir,
51314
51953
  `${event.session_uuid}-${String(event.seq).padStart(8, "0")}.json`
51315
51954
  );
@@ -51846,7 +52485,7 @@ import {
51846
52485
  } from "node:fs";
51847
52486
  import { readdir as readdir3, readFile as readFile3, stat as stat2 } from "node:fs/promises";
51848
52487
  import { homedir as homedir7, hostname as osHostname2 } from "node:os";
51849
- import { dirname as dirname21, join as join38 } from "node:path";
52488
+ import { dirname as dirname21, join as join39 } from "node:path";
51850
52489
  import { execFile as execFile4, spawnSync as spawnSync6 } from "node:child_process";
51851
52490
  function cloudGatewayUpstreams(origin = CLOUD_GATEWAY_ORIGIN) {
51852
52491
  const base2 = new URL(origin).origin;
@@ -51902,15 +52541,20 @@ function defaultExec(command2, args) {
51902
52541
  stderr: result2.stderr ?? ""
51903
52542
  };
51904
52543
  }
51905
- function defaultExecAsync(command2, args) {
51906
- return new Promise((resolve22) => {
52544
+ function defaultExecAsync(command2, args, options) {
52545
+ return new Promise((resolve23) => {
51907
52546
  execFile4(
51908
52547
  command2,
51909
52548
  args,
51910
- { encoding: "utf8", maxBuffer: 4 * 1024 * 1024, timeout: 1e4 },
52549
+ {
52550
+ encoding: "utf8",
52551
+ maxBuffer: 4 * 1024 * 1024,
52552
+ timeout: 1e4,
52553
+ ...options?.env !== void 0 ? { env: { ...process.env, ...options.env } } : {}
52554
+ },
51911
52555
  (error, stdout, stderr) => {
51912
52556
  const code = error?.code;
51913
- resolve22({
52557
+ resolve23({
51914
52558
  status: error === null ? 0 : typeof code === "number" ? code : 1,
51915
52559
  stdout: stdout ?? "",
51916
52560
  stderr: stderr ?? ""
@@ -51929,28 +52573,28 @@ function defaultKill(pid, signal) {
51929
52573
  }
51930
52574
  function settleWithin(work, ms) {
51931
52575
  if (work === void 0) return Promise.resolve(true);
51932
- return new Promise((resolve22) => {
51933
- const timer = setTimeout(() => resolve22(false), ms);
52576
+ return new Promise((resolve23) => {
52577
+ const timer = setTimeout(() => resolve23(false), ms);
51934
52578
  timer.unref();
51935
52579
  const done = () => {
51936
52580
  clearTimeout(timer);
51937
- resolve22(true);
52581
+ resolve23(true);
51938
52582
  };
51939
52583
  work.then(done, done);
51940
52584
  });
51941
52585
  }
51942
52586
  function valueWithin(work, ms) {
51943
- return new Promise((resolve22) => {
51944
- const timer = setTimeout(() => resolve22(void 0), ms);
52587
+ return new Promise((resolve23) => {
52588
+ const timer = setTimeout(() => resolve23(void 0), ms);
51945
52589
  timer.unref();
51946
52590
  work.then(
51947
52591
  (value) => {
51948
52592
  clearTimeout(timer);
51949
- resolve22(value);
52593
+ resolve23(value);
51950
52594
  },
51951
52595
  () => {
51952
52596
  clearTimeout(timer);
51953
- resolve22(void 0);
52597
+ resolve23(void 0);
51954
52598
  }
51955
52599
  );
51956
52600
  });
@@ -51959,15 +52603,15 @@ function olderBundle(candidate, held) {
51959
52603
  return candidate.version < held.version && !(Date.parse(candidate.issued_at) > Date.parse(held.issued_at));
51960
52604
  }
51961
52605
  function abortableSleep2(ms, signal) {
51962
- return new Promise((resolve22) => {
52606
+ return new Promise((resolve23) => {
51963
52607
  if (signal.aborted) {
51964
- resolve22();
52608
+ resolve23();
51965
52609
  return;
51966
52610
  }
51967
52611
  const wake = () => {
51968
52612
  clearTimeout(timer);
51969
52613
  signal.removeEventListener("abort", wake);
51970
- resolve22();
52614
+ resolve23();
51971
52615
  };
51972
52616
  const timer = setTimeout(wake, ms);
51973
52617
  timer.unref();
@@ -52120,6 +52764,13 @@ async function initializeDaemon(options, server, port, ready) {
52120
52764
  hasGatewayKey: current.gateway_api_key !== void 0,
52121
52765
  registeredAt: current.mcp_registered_at?.["claude-code"],
52122
52766
  sessionStartedAt: session.startedAt,
52767
+ // The entry must be the one enroll wrote, local token and all, and
52768
+ // not a server that copied the enrollment id (F-2355).
52769
+ enrolled: {
52770
+ localToken: current.local_token,
52771
+ port: current.port,
52772
+ ...current.mcp_stdio_command?.[0] !== void 0 ? { shimCommand: current.mcp_stdio_command[0] } : {}
52773
+ },
52123
52774
  // A local- or project-scope `oxagen` server in this directory wins
52124
52775
  // over ours, and would refuse the reflection.
52125
52776
  ...session.cwd !== void 0 ? { cwd: session.cwd } : {},
@@ -52276,17 +52927,24 @@ async function initializeDaemon(options, server, port, ready) {
52276
52927
  let handledWritten = handledCommands.generation;
52277
52928
  const applyCommands2 = (commands, deps) => applyCommands(commands, { ...deps, handled: handledCommands });
52278
52929
  const queues = new HookQueues();
52930
+ const steerWaiters = new SteerWaiters({
52931
+ find: (key) => registry2.list().find(
52932
+ (session) => sessionMapKey(session.harnessSessionId, session) === key
52933
+ ),
52934
+ deliver: (session, alive) => deliverToWaiter(session, alive),
52935
+ log
52936
+ });
52279
52937
  const sessionExclusive = (session, apply) => queues.session(session.harnessSessionId, async () => apply());
52280
52938
  const stopping = new AbortController();
52281
- const hookExecAsync = (command2, args) => {
52939
+ const hookExecAsync = (command2, args, execOptions) => {
52282
52940
  if (stopping.signal.aborted) return Promise.resolve(STOPPED_EXEC);
52283
- return new Promise((resolve22, reject) => {
52284
- const abandon = () => resolve22(STOPPED_EXEC);
52941
+ return new Promise((resolve23, reject) => {
52942
+ const abandon = () => resolve23(STOPPED_EXEC);
52285
52943
  stopping.signal.addEventListener("abort", abandon, { once: true });
52286
- execAsync(command2, args).then(
52944
+ execAsync(command2, args, execOptions).then(
52287
52945
  (result2) => {
52288
52946
  stopping.signal.removeEventListener("abort", abandon);
52289
- resolve22(result2);
52947
+ resolve23(result2);
52290
52948
  },
52291
52949
  (error) => {
52292
52950
  stopping.signal.removeEventListener("abort", abandon);
@@ -52463,6 +53121,42 @@ async function initializeDaemon(options, server, port, ready) {
52463
53121
  mark: session.recorder.markChain()
52464
53122
  }));
52465
53123
  }
53124
+ async function deliverToWaiter(session, alive) {
53125
+ return queues.session(session.harnessSessionId, async () => {
53126
+ if (!alive() || session.sealed || session.pendingTerminal === true)
53127
+ return void 0;
53128
+ const held = [...session.control.messages];
53129
+ const owed = session.control.resumeOwed;
53130
+ if (held.length === 0 && owed === void 0) return void 0;
53131
+ const mark = session.recorder.markChain();
53132
+ const events = [];
53133
+ const acks = [];
53134
+ const texts = drainForWaiter(
53135
+ session,
53136
+ { now, acknowledge: (ack) => acks.push(ack) },
53137
+ events
53138
+ );
53139
+ try {
53140
+ if (events.length > 0) record(events);
53141
+ } catch (error) {
53142
+ session.recorder.rollbackChain(mark);
53143
+ const ids = new Set(held.map((message) => message.id));
53144
+ const arrived = session.control.messages.filter(
53145
+ (message) => !ids.has(message.id)
53146
+ );
53147
+ session.control.messages.splice(
53148
+ 0,
53149
+ session.control.messages.length,
53150
+ ...held,
53151
+ ...arrived
53152
+ );
53153
+ session.control.resumeOwed = owed;
53154
+ throw error;
53155
+ }
53156
+ pendingAcks.push(...acks);
53157
+ return texts.length > 0 ? [WAKE_LEAD, ...texts].join("\n\n") : void 0;
53158
+ });
53159
+ }
52466
53160
  async function applyCommandsRecorded(commands, deps) {
52467
53161
  let marks = markCommandChains(commands);
52468
53162
  let result2;
@@ -52535,7 +53229,7 @@ async function initializeDaemon(options, server, port, ready) {
52535
53229
  controlReachable: lastControlAt !== void 0 && now() - lastControlAt < 2 * timers.bundleRefreshMs
52536
53230
  };
52537
53231
  }
52538
- const bodyPurgeOwedPath = join38(paths.wal, "body-purge-owed");
53232
+ const bodyPurgeOwedPath = join39(paths.wal, "body-purge-owed");
52539
53233
  function markBodyPurgeOwed(retention, dropped) {
52540
53234
  try {
52541
53235
  ensureDir(paths.wal);
@@ -52806,6 +53500,7 @@ async function initializeDaemon(options, server, port, ready) {
52806
53500
  } finally {
52807
53501
  interruptModelCalls(result2.applied);
52808
53502
  }
53503
+ steerWaiters.nudge();
52809
53504
  }
52810
53505
  }
52811
53506
  const shipper = new Shipper({
@@ -53020,6 +53715,7 @@ async function initializeDaemon(options, server, port, ready) {
53020
53715
  }
53021
53716
  async function sendAcks() {
53022
53717
  if (shipper.hostRevoked) return;
53718
+ registry2.expireQueuedPrompts(now());
53023
53719
  pendingAcks.push(...registry2.takeExpiredOnSeal());
53024
53720
  const lastEnvelopeAt = Math.max(
53025
53721
  lastIngestAt ?? -Infinity,
@@ -53030,9 +53726,11 @@ async function initializeDaemon(options, server, port, ready) {
53030
53726
  }
53031
53727
  if (now() < commandPollNextAttemptAt) return;
53032
53728
  const acks = pendingAcks.splice(0, 100);
53729
+ let accepted = false;
53033
53730
  try {
53034
53731
  const { spool_oldest_at: _o, bundle_etag: _e, ...daemon } = health();
53035
53732
  const response = await client.commands(acks, daemon);
53733
+ accepted = true;
53036
53734
  lastCommandPollAt = now();
53037
53735
  await onControl(response.control);
53038
53736
  if (commandPollFailures > 0) {
@@ -53043,7 +53741,7 @@ async function initializeDaemon(options, server, port, ready) {
53043
53741
  commandPollNextAttemptAt = 0;
53044
53742
  commandPollProtocolMismatchLogged = false;
53045
53743
  } catch (error) {
53046
- pendingAcks.unshift(...acks);
53744
+ if (!accepted) pendingAcks.unshift(...acks);
53047
53745
  commandPollFailures += 1;
53048
53746
  if (error instanceof ControlError && isHostRevokedRefusal(error)) {
53049
53747
  shipper.markHostRevoked();
@@ -53306,7 +54004,7 @@ async function initializeDaemon(options, server, port, ready) {
53306
54004
  async function readSpoolFile(name) {
53307
54005
  try {
53308
54006
  const file = parseSpoolFile(
53309
- await readFile3(join38(paths.spool, name), "utf8")
54007
+ await readFile3(join39(paths.spool, name), "utf8")
53310
54008
  );
53311
54009
  spoolFacts.set(name, spoolFactsOf(file));
53312
54010
  return file;
@@ -53370,6 +54068,11 @@ async function initializeDaemon(options, server, port, ready) {
53370
54068
  acks.push(ack);
53371
54069
  },
53372
54070
  now,
54071
+ // A hook that queued behind others, or behind a slow read, can be
54072
+ // answered after the harness stopped waiting. Past this instant
54073
+ // the handler leaves the session's messages queued, rather than
54074
+ // seal a steer as delivered into an answer nobody reads.
54075
+ ...envelope2.answer_by !== void 0 ? { answerBy: envelope2.answer_by } : {},
53373
54076
  // Both reads hold this hook's session queue, and both answer no
53374
54077
  // answer once `stop` begins (`hookExecAsync`).
53375
54078
  pushCredentialBasis: (command2, cwd, harnessSessionId2) => {
@@ -53385,7 +54088,10 @@ async function initializeDaemon(options, server, port, ready) {
53385
54088
  skills,
53386
54089
  ...recallMemories !== void 0 ? { recallMemories } : {},
53387
54090
  ...noteMemoryReads !== void 0 ? { noteMemoryReads } : {},
53388
- reflectionToolRegistered
54091
+ reflectionToolRegistered,
54092
+ // The same check: the `oxagen` server Claude Code loaded for the
54093
+ // session is the one this enrollment wrote (F-2355).
54094
+ oxagenServerServes: reflectionToolRegistered
53389
54095
  },
53390
54096
  envelope2.replay,
53391
54097
  envelope2.harness,
@@ -53468,7 +54174,7 @@ async function initializeDaemon(options, server, port, ready) {
53468
54174
  function setAsideConflictingTerminal(uuid, pending, conflict) {
53469
54175
  const name = `${uuid}-terminal-conflict-${String(conflict.seq).padStart(8, "0")}.json`;
53470
54176
  writeSensitiveFileAtomic(
53471
- join38(paths.quarantine, name),
54177
+ join39(paths.quarantine, name),
53472
54178
  JSON.stringify(
53473
54179
  {
53474
54180
  reason: conflict.message,
@@ -53548,8 +54254,8 @@ async function initializeDaemon(options, server, port, ready) {
53548
54254
  function moveToFailedSpool(path2, name, reason3) {
53549
54255
  log(`spool file ${name} moved to spool/failed/: ${reason3}`);
53550
54256
  try {
53551
- ensureDir(join38(paths.spool, "failed"));
53552
- renameSync4(path2, join38(paths.spool, "failed", name));
54257
+ ensureDir(join39(paths.spool, "failed"));
54258
+ renameSync4(path2, join39(paths.spool, "failed", name));
53553
54259
  } catch (error) {
53554
54260
  log(
53555
54261
  `spool file ${name} could not be moved to spool/failed/: ${error instanceof Error ? error.message : String(error)}`
@@ -53602,7 +54308,7 @@ async function initializeDaemon(options, server, port, ready) {
53602
54308
  continue;
53603
54309
  }
53604
54310
  reads += 1;
53605
- const path2 = join38(paths.spool, name);
54311
+ const path2 = join39(paths.spool, name);
53606
54312
  let file;
53607
54313
  try {
53608
54314
  file = await readSpoolFile(name);
@@ -54191,7 +54897,16 @@ async function initializeDaemon(options, server, port, ready) {
54191
54897
  quarantineChanged();
54192
54898
  return Promise.reject(readable.error);
54193
54899
  }
54194
- return answerHook(envelope2, readable.data.session_id, {
54900
+ if (envelope2.replay === void 0 && readable.data.agent_id === void 0 && STEER_WAIT_RELEASING_EVENTS.has(readable.data.hook_event_name))
54901
+ steerWaiters.release(
54902
+ sessionMapKey(readable.data.session_id, {
54903
+ harness: envelope2.harness,
54904
+ customAgent: envelope2.agent
54905
+ }),
54906
+ now()
54907
+ );
54908
+ const timed = envelope2.answer_by === void 0 && envelope2.answer_within_ms !== void 0 ? { ...envelope2, answer_by: now() + envelope2.answer_within_ms } : envelope2;
54909
+ return answerHook(timed, readable.data.session_id, {
54195
54910
  drainSpoolFirst: true,
54196
54911
  refuseWhenStopping: true
54197
54912
  });
@@ -54220,6 +54935,20 @@ async function initializeDaemon(options, server, port, ready) {
54220
54935
  )
54221
54936
  );
54222
54937
  },
54938
+ // An `oxagen hook --await-steer` hold for a session idle at its prompt
54939
+ // (`steer-waiters.ts`). Once `stop` began it answers `wait`: the waiter
54940
+ // asks again and reaches the next daemon.
54941
+ waitForSteer: (input, signal) => {
54942
+ if (stopped2) return Promise.resolve({ wait: true });
54943
+ return steerWaiters.wait(
54944
+ sessionMapKey(input.sessionId, {
54945
+ harness: input.harness,
54946
+ customAgent: input.agent
54947
+ }),
54948
+ signal,
54949
+ input.startedAt
54950
+ );
54951
+ },
54223
54952
  health: () => ({
54224
54953
  ok: true,
54225
54954
  ...health(),
@@ -54394,7 +55123,7 @@ async function initializeDaemon(options, server, port, ready) {
54394
55123
  let removed = 0;
54395
55124
  for (const name of readdirSync12(paths.quarantine)) {
54396
55125
  if (!name.endsWith(".json")) continue;
54397
- const file = join38(paths.quarantine, name);
55126
+ const file = join39(paths.quarantine, name);
54398
55127
  try {
54399
55128
  if (at2 - statSync10(file).mtimeMs < retainMs) continue;
54400
55129
  unlinkSync12(file);
@@ -54716,7 +55445,7 @@ async function initializeDaemon(options, server, port, ready) {
54716
55445
  let memoryScan;
54717
55446
  if (options.listen ?? true) {
54718
55447
  const codexMemories = createCodexMemoryStore({
54719
- path: join38(dirname21(paths.codexHooks), CODEX_MEMORY_STORE_FILE),
55448
+ path: join39(dirname21(paths.codexHooks), CODEX_MEMORY_STORE_FILE),
54720
55449
  stat: (path2) => stat2(path2),
54721
55450
  log
54722
55451
  });
@@ -54809,6 +55538,7 @@ async function initializeDaemon(options, server, port, ready) {
54809
55538
  stop: async () => {
54810
55539
  if (stopped2) return;
54811
55540
  stopped2 = true;
55541
+ steerWaiters.releaseAll();
54812
55542
  stopping.abort();
54813
55543
  if (timer) clearInterval(timer);
54814
55544
  if (memoryTimer) clearInterval(memoryTimer);
@@ -54848,6 +55578,10 @@ async function initializeDaemon(options, server, port, ready) {
54848
55578
  log(
54849
55579
  `stop: stopped shipping after ${timers.stopDrainMs} ms; the rest of the WAL ships at the next start`
54850
55580
  );
55581
+ if (pendingAcks.length > 0 && !await settleWithin(sendAcks(), timers.stopDrainMs))
55582
+ log(
55583
+ `stop: could not send ${pendingAcks.length} command acknowledgement(s) within ${timers.stopDrainMs} ms`
55584
+ );
54851
55585
  if (!await settleWithin(localServersStopped, 0))
54852
55586
  log(
54853
55587
  "stop: a local-server reply was still posting; the cloud gateway refuses that call on its side"
@@ -54894,6 +55628,7 @@ var init_daemon = __esm({
54894
55628
  init_session_changes();
54895
55629
  init_exporters();
54896
55630
  init_hook_handler();
55631
+ init_steer_waiters();
54897
55632
  init_hook_id_journal();
54898
55633
  init_inbox();
54899
55634
  init_mcp_gateway();
@@ -55216,23 +55951,23 @@ import {
55216
55951
  realpathSync as realpathSync5,
55217
55952
  writeFileSync as writeFileSync4
55218
55953
  } from "node:fs";
55219
- import { dirname as dirname22, join as join39, resolve as resolve14 } from "node:path";
55220
- function bundlePath(root, relative10, create2 = false) {
55221
- const absolute = resolve14(root);
55954
+ import { dirname as dirname22, join as join40, resolve as resolve15 } from "node:path";
55955
+ function bundlePath(root, relative11, create2 = false) {
55956
+ const absolute = resolve15(root);
55222
55957
  if (create2) mkdirSync6(absolute, { recursive: true, mode: 448 });
55223
55958
  if (lstatSync7(absolute).isSymbolicLink() || !lstatSync7(absolute).isDirectory()) {
55224
55959
  arpFail(`The bundle root ${absolute} must be a directory, not a symlink.`);
55225
55960
  }
55226
55961
  const base2 = realpathSync5(absolute);
55227
55962
  let current = base2;
55228
- const parts = relative10.split("/");
55963
+ const parts = relative11.split("/");
55229
55964
  for (let i2 = 0; i2 < parts.length; i2++) {
55230
- current = join39(current, parts[i2]);
55965
+ current = join40(current, parts[i2]);
55231
55966
  try {
55232
55967
  const stat7 = lstatSync7(current);
55233
55968
  if (stat7.isSymbolicLink() || i2 < parts.length - 1 && !stat7.isDirectory()) {
55234
55969
  arpFail(
55235
- `The bundle path ${relative10} passes through a symlink or a file where a directory belongs.`
55970
+ `The bundle path ${relative11} passes through a symlink or a file where a directory belongs.`
55236
55971
  );
55237
55972
  }
55238
55973
  } catch (error) {
@@ -55242,35 +55977,35 @@ function bundlePath(root, relative10, create2 = false) {
55242
55977
  }
55243
55978
  }
55244
55979
  if (realpathSync5(dirname22(current)) !== dirname22(current)) {
55245
- arpFail(`The bundle directory changed while ${relative10} was read.`);
55980
+ arpFail(`The bundle directory changed while ${relative11} was read.`);
55246
55981
  }
55247
55982
  return current;
55248
55983
  }
55249
- function readBounded(root, relative10, limit = ARP_MAX_BLOB_BYTES) {
55250
- const path2 = bundlePath(root, relative10);
55984
+ function readBounded(root, relative11, limit = ARP_MAX_BLOB_BYTES) {
55985
+ const path2 = bundlePath(root, relative11);
55251
55986
  const fd2 = openSync7(path2, constants4.O_RDONLY | constants4.O_NOFOLLOW);
55252
55987
  try {
55253
55988
  const stat7 = fstatSync2(fd2);
55254
55989
  if (!stat7.isFile() || stat7.size > limit)
55255
55990
  arpFail(
55256
- `The bundle file ${relative10} is not a regular file of at most ${limit} bytes.`
55991
+ `The bundle file ${relative11} is not a regular file of at most ${limit} bytes.`
55257
55992
  );
55258
55993
  const bytes = Buffer.alloc(stat7.size);
55259
55994
  let offset = 0;
55260
55995
  while (offset < bytes.length) {
55261
55996
  const count12 = readSync4(fd2, bytes, offset, bytes.length - offset, offset);
55262
- if (!count12) arpFail(`The bundle file ${relative10} changed while it was read.`);
55997
+ if (!count12) arpFail(`The bundle file ${relative11} changed while it was read.`);
55263
55998
  offset += count12;
55264
55999
  }
55265
56000
  if (readSync4(fd2, Buffer.alloc(1), 0, 1, offset) !== 0)
55266
- arpFail(`The bundle file ${relative10} changed while it was read.`);
56001
+ arpFail(`The bundle file ${relative11} changed while it was read.`);
55267
56002
  return bytes;
55268
56003
  } finally {
55269
56004
  closeSync7(fd2);
55270
56005
  }
55271
56006
  }
55272
- function writeNew(root, relative10, bytes) {
55273
- const path2 = bundlePath(root, relative10, true);
56007
+ function writeNew(root, relative11, bytes) {
56008
+ const path2 = bundlePath(root, relative11, true);
55274
56009
  const fd2 = openSync7(
55275
56010
  path2,
55276
56011
  constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW,
@@ -56188,7 +56923,7 @@ import {
56188
56923
  rmSync as rmSync8,
56189
56924
  writeFileSync as writeFileSync5
56190
56925
  } from "node:fs";
56191
- import { dirname as dirname23, isAbsolute as isAbsolute10, join as join40, relative as relative4, resolve as resolve15, sep as sep5 } from "node:path";
56926
+ import { dirname as dirname23, isAbsolute as isAbsolute11, join as join41, relative as relative5, resolve as resolve16, sep as sep6 } from "node:path";
56192
56927
  function outsideProfile(path2) {
56193
56928
  return HARNESS_CONFIG_PATH.test(path2) || CREDENTIAL_PATH.test(path2);
56194
56929
  }
@@ -56239,12 +56974,12 @@ function rejectSecrets(label2, bytes) {
56239
56974
  }
56240
56975
  }
56241
56976
  function within2(root, path2) {
56242
- const rel = relative4(root, path2);
56243
- return rel === "" || !isAbsolute10(rel) && rel !== ".." && !rel.startsWith(`..${sep5}`);
56977
+ const rel = relative5(root, path2);
56978
+ return rel === "" || !isAbsolute11(rel) && rel !== ".." && !rel.startsWith(`..${sep6}`);
56244
56979
  }
56245
56980
  function newPath(path2) {
56246
- const full = resolve15(path2);
56247
- return join40(
56981
+ const full = resolve16(path2);
56982
+ return join41(
56248
56983
  realpathSync6(dirname23(full)),
56249
56984
  full.slice(dirname23(full).length + 1)
56250
56985
  );
@@ -56258,7 +56993,7 @@ function sourcePath(root, path2) {
56258
56993
  }
56259
56994
  let current = root;
56260
56995
  for (const part2 of path2.split("/")) {
56261
- current = join40(current, part2);
56996
+ current = join41(current, part2);
56262
56997
  if (lstatSync8(current).isSymbolicLink())
56263
56998
  arpFail(
56264
56999
  `${path2} is a symlink or passes through one. Symlinks require a resource adapter.`
@@ -56525,10 +57260,10 @@ function prepareCheckpoint(options) {
56525
57260
  });
56526
57261
  mkdirSync7(destination, { mode: 448 });
56527
57262
  try {
56528
- const restored = join40(destination, "workspace");
57263
+ const restored = join41(destination, "workspace");
56529
57264
  mkdirSync7(restored, { mode: 448 });
56530
57265
  for (const item of restore) {
56531
- const path2 = join40(restored, item.path);
57266
+ const path2 = join41(restored, item.path);
56532
57267
  if (item.kind === "directory")
56533
57268
  mkdirSync7(path2, { recursive: true, mode: 448 });
56534
57269
  else {
@@ -56539,9 +57274,9 @@ function prepareCheckpoint(options) {
56539
57274
  });
56540
57275
  }
56541
57276
  }
56542
- const promptDir = join40(restored, ".arp");
57277
+ const promptDir = join41(restored, ".arp");
56543
57278
  mkdirSync7(promptDir, { mode: 448 });
56544
- const promptFile = join40(promptDir, "handoff.json");
57279
+ const promptFile = join41(promptDir, "handoff.json");
56545
57280
  const prompt = {
56546
57281
  checkpoint_digest: checkpointDigest,
56547
57282
  task: task.data.request,
@@ -56558,7 +57293,7 @@ function prepareCheckpoint(options) {
56558
57293
  flag: "wx",
56559
57294
  mode: 384
56560
57295
  });
56561
- const reportPath = join40(destination, "report.json");
57296
+ const reportPath = join41(destination, "report.json");
56562
57297
  writeFileSync5(
56563
57298
  reportPath,
56564
57299
  jcs(
@@ -57199,7 +57934,7 @@ var init_package = __esm({
57199
57934
  "package.json"() {
57200
57935
  package_default = {
57201
57936
  name: "@oxagen/cli",
57202
- version: "2.1.4-724",
57937
+ version: "2.1.4-926",
57203
57938
  description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
57204
57939
  type: "module",
57205
57940
  main: "./dist/index.js",
@@ -57266,10 +58001,10 @@ var init_package = __esm({
57266
58001
 
57267
58002
  // src/lib/atomic-write.ts
57268
58003
  import { writeFileSync as writeFileSync6, renameSync as renameSync5, unlinkSync as unlinkSync14, existsSync as existsSync22 } from "node:fs";
57269
- import { dirname as dirname24, join as join41 } from "node:path";
58004
+ import { dirname as dirname24, join as join42 } from "node:path";
57270
58005
  function atomicWriteFileSync(path2, data, mode) {
57271
58006
  const dir = dirname24(path2);
57272
- const tmp = join41(
58007
+ const tmp = join42(
57273
58008
  dir,
57274
58009
  `.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`
57275
58010
  );
@@ -57294,7 +58029,7 @@ var init_atomic_write = __esm({
57294
58029
 
57295
58030
  // src/lib/config.ts
57296
58031
  import { homedir as homedir8 } from "os";
57297
- import { join as join42 } from "path";
58032
+ import { join as join43 } from "path";
57298
58033
  import { readFileSync as readFileSync21, mkdirSync as mkdirSync8, existsSync as existsSync23, statSync as statSync11 } from "fs";
57299
58034
  function getConfigDir() {
57300
58035
  return CONFIG_DIR;
@@ -57381,8 +58116,8 @@ var CONFIG_DIR, CONFIG_FILE, STRING_FIELDS, TELEMETRY_FIELDS, cached2;
57381
58116
  var init_config = __esm({
57382
58117
  "src/lib/config.ts"() {
57383
58118
  init_atomic_write();
57384
- CONFIG_DIR = join42(homedir8(), ".config", "oxagen");
57385
- CONFIG_FILE = join42(CONFIG_DIR, "config.json");
58119
+ CONFIG_DIR = join43(homedir8(), ".config", "oxagen");
58120
+ CONFIG_FILE = join43(CONFIG_DIR, "config.json");
57386
58121
  STRING_FIELDS = [
57387
58122
  "token",
57388
58123
  "orgSlug",
@@ -57427,16 +58162,16 @@ import {
57427
58162
  writeFile as writeFile2
57428
58163
  } from "node:fs/promises";
57429
58164
  import { homedir as homedir9 } from "node:os";
57430
- import { join as join43 } from "node:path";
58165
+ import { join as join44 } from "node:path";
57431
58166
  function isDebugEnabled() {
57432
58167
  const v = process.env[DEBUG_ENV];
57433
58168
  return v === "1" || v === "true";
57434
58169
  }
57435
58170
  function logsDir() {
57436
- return join43(homedir9(), ".oxagen", "logs");
58171
+ return join44(homedir9(), ".oxagen", "logs");
57437
58172
  }
57438
58173
  function debugLogFile() {
57439
- return join43(logsDir(), "cli.output");
58174
+ return join44(logsDir(), "cli.output");
57440
58175
  }
57441
58176
  function sanitize(value, depth = 0) {
57442
58177
  if (value === null || value === void 0) return value;
@@ -60685,7 +61420,7 @@ var init_git = __esm({
60685
61420
  signal;
60686
61421
  };
60687
61422
  ABSENT_STDERR = /not a valid object name|invalid object name|bad object|unknown revision|no such (?:object|ref)|could not get object info|does not exist in '|exists on disk, but not in '|not a git repository/i;
60688
- execGit = (args, { cwd, timeoutMs }) => new Promise((resolve22, reject) => {
61423
+ execGit = (args, { cwd, timeoutMs }) => new Promise((resolve23, reject) => {
60689
61424
  execFile5(
60690
61425
  "git",
60691
61426
  [...args],
@@ -60714,7 +61449,7 @@ var init_git = __esm({
60714
61449
  );
60715
61450
  return;
60716
61451
  }
60717
- resolve22(stdout);
61452
+ resolve23(stdout);
60718
61453
  }
60719
61454
  );
60720
61455
  });
@@ -60731,9 +61466,9 @@ var init_git = __esm({
60731
61466
 
60732
61467
  // ../../packages/steering-freshness/src/cache.ts
60733
61468
  import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
60734
- import { dirname as dirname25, join as join44 } from "node:path";
61469
+ import { dirname as dirname25, join as join45 } from "node:path";
60735
61470
  function stampPath(gitCommonDir) {
60736
- return join44(gitCommonDir, "oxagen", "steering-freshness.json");
61471
+ return join45(gitCommonDir, "oxagen", "steering-freshness.json");
60737
61472
  }
60738
61473
  async function readFetchStamp(gitCommonDir, io = defaultIo) {
60739
61474
  try {
@@ -60785,24 +61520,24 @@ var init_cache = __esm({
60785
61520
  // ../../packages/steering-freshness/src/hooks.ts
60786
61521
  import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
60787
61522
  import { homedir as homedir10 } from "node:os";
60788
- import { dirname as dirname26, join as join45 } from "node:path";
61523
+ import { dirname as dirname26, join as join46 } from "node:path";
60789
61524
  function hookCommand(harness) {
60790
61525
  return `oxagen steering gate --harness ${harness}`;
60791
61526
  }
60792
61527
  function hookConfigPath(projectRoot, harness, env = process.env, home = homedir10()) {
60793
61528
  switch (harness) {
60794
61529
  case "claude-code":
60795
- return join45(projectRoot, ".claude", "settings.json");
61530
+ return join46(projectRoot, ".claude", "settings.json");
60796
61531
  case "codex":
60797
- return join45(env["CODEX_HOME"] ?? join45(home, ".codex"), "hooks.json");
61532
+ return join46(env["CODEX_HOME"] ?? join46(home, ".codex"), "hooks.json");
60798
61533
  case "cursor":
60799
- return join45(home, ".cursor", "hooks.json");
61534
+ return join46(home, ".cursor", "hooks.json");
60800
61535
  case "stella":
60801
- return join45(env["STELLA_HOME"] ?? join45(home, ".stella"), "stella.toml");
61536
+ return join46(env["STELLA_HOME"] ?? join46(home, ".stella"), "stella.toml");
60802
61537
  }
60803
61538
  }
60804
61539
  function stellaJsonPath(env, home) {
60805
- return join45(env["STELLA_HOME"] ?? join45(home, ".stella"), "settings.json");
61540
+ return join46(env["STELLA_HOME"] ?? join46(home, ".stella"), "settings.json");
60806
61541
  }
60807
61542
  function isRecord7(v) {
60808
61543
  return v !== null && typeof v === "object" && !Array.isArray(v);
@@ -61462,7 +62197,7 @@ var init_policy = __esm({
61462
62197
  // ../../packages/steering-freshness/src/settings.ts
61463
62198
  import { readFile as readFile8 } from "node:fs/promises";
61464
62199
  import { homedir as homedir11 } from "node:os";
61465
- import { join as join46 } from "node:path";
62200
+ import { join as join47 } from "node:path";
61466
62201
  async function readLayer(scope, path2, read2) {
61467
62202
  let text5;
61468
62203
  try {
@@ -61514,14 +62249,14 @@ function parseLayer(scope, path2, text5) {
61514
62249
  }
61515
62250
  async function loadSteeringSettings({
61516
62251
  projectRoot,
61517
- userSettingsPath = join46(homedir11(), USER_SETTINGS_RELATIVE),
62252
+ userSettingsPath = join47(homedir11(), USER_SETTINGS_RELATIVE),
61518
62253
  read: read2 = readFile8,
61519
62254
  workspacePolicy = null
61520
62255
  }) {
61521
62256
  const targets = [
61522
62257
  ["user", userSettingsPath],
61523
- ["project", join46(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
61524
- ["local", join46(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
62258
+ ["project", join47(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
62259
+ ["local", join47(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
61525
62260
  ];
61526
62261
  const layers = [];
61527
62262
  const warnings = [];
@@ -61584,7 +62319,7 @@ var init_settings = __esm({
61584
62319
  "use strict";
61585
62320
  init_git();
61586
62321
  init_policy();
61587
- USER_SETTINGS_RELATIVE = join46(
62322
+ USER_SETTINGS_RELATIVE = join47(
61588
62323
  ".config",
61589
62324
  "oxagen",
61590
62325
  "settings.json"
@@ -61597,7 +62332,7 @@ var init_settings = __esm({
61597
62332
 
61598
62333
  // ../../packages/steering-freshness/src/check.ts
61599
62334
  import { lstat as lstat3 } from "node:fs/promises";
61600
- import { isAbsolute as isAbsolute11, join as join47, resolve as resolve16 } from "node:path";
62335
+ import { isAbsolute as isAbsolute12, join as join48, resolve as resolve17 } from "node:path";
61601
62336
  function publishedCommits(platform) {
61602
62337
  if (platform.headCommits && platform.headCommits.length > 0)
61603
62338
  return platform.headCommits;
@@ -61702,7 +62437,7 @@ async function checkSteeringFreshness(opts) {
61702
62437
  );
61703
62438
  }
61704
62439
  const commonDir = allowNetwork ? await gitOrNull(repoCtx, "rev-parse", "--git-common-dir") : null;
61705
- const stampDir = commonDir ? isAbsolute11(commonDir) ? commonDir : resolve16(root, commonDir) : null;
62440
+ const stampDir = commonDir ? isAbsolute12(commonDir) ? commonDir : resolve17(root, commonDir) : null;
61706
62441
  const stamp = stampDir ? await readFetchStamp(stampDir, cacheIo) : null;
61707
62442
  const remoteContactDue = allowNetwork && shouldContactRemote(stamp, policy.fetchIntervalSeconds, now());
61708
62443
  const branch = policy.branch ?? await defaultBranch(networkCtx(repoCtx), policy.remote, {
@@ -61934,7 +62669,7 @@ async function absentFromDisk(root, paths) {
61934
62669
  const flags = await Promise.all(
61935
62670
  paths.map(async (path2) => {
61936
62671
  try {
61937
- await lstat3(join47(root, path2));
62672
+ await lstat3(join48(root, path2));
61938
62673
  return false;
61939
62674
  } catch {
61940
62675
  return true;
@@ -61993,7 +62728,7 @@ var init_check = __esm({
61993
62728
  // ../../packages/steering-freshness/src/sync.ts
61994
62729
  import { mkdtemp, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
61995
62730
  import { tmpdir as tmpdir2 } from "node:os";
61996
- import { join as join48 } from "node:path";
62731
+ import { join as join49 } from "node:path";
61997
62732
  function refuse3(refusal, message) {
61998
62733
  return {
61999
62734
  applied: false,
@@ -62174,9 +62909,9 @@ async function syncSteering(opts) {
62174
62909
  };
62175
62910
  }
62176
62911
  async function commitPaths(ctx, message, paths) {
62177
- const dir = await mkdtemp(join48(tmpdir2(), "oxagen-steering-sync-"));
62912
+ const dir = await mkdtemp(join49(tmpdir2(), "oxagen-steering-sync-"));
62178
62913
  try {
62179
- const list2 = join48(dir, "pathspec");
62914
+ const list2 = join49(dir, "pathspec");
62180
62915
  await writeFile6(list2, `${paths.join("\0")}\0`, "utf8");
62181
62916
  await git3(
62182
62917
  ctx,
@@ -62704,9 +63439,9 @@ var init_paths2 = __esm({
62704
63439
 
62705
63440
  // src/commands/workspace-link.ts
62706
63441
  import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync22 } from "node:fs";
62707
- import { dirname as dirname27, join as join49 } from "node:path";
63442
+ import { dirname as dirname27, join as join50 } from "node:path";
62708
63443
  function workspaceLinkPath(cwd) {
62709
- return join49(cwd, WORKSPACE_LINK_PATH);
63444
+ return join50(cwd, WORKSPACE_LINK_PATH);
62710
63445
  }
62711
63446
  function isRecord8(value) {
62712
63447
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -62796,7 +63531,7 @@ __export(steering_exports, {
62796
63531
  });
62797
63532
  import { execFileSync } from "node:child_process";
62798
63533
  import { existsSync as existsSync25, realpathSync as realpathSync7 } from "node:fs";
62799
- import { dirname as dirname28, join as join50, normalize, parse as parsePath } from "node:path";
63534
+ import { dirname as dirname28, join as join51, normalize, parse as parsePath } from "node:path";
62800
63535
  function findProjectRoot(start) {
62801
63536
  const { root } = parsePath(start);
62802
63537
  const rawGitRoot = gitRootOr(start);
@@ -62805,7 +63540,7 @@ function findProjectRoot(start) {
62805
63540
  if (gitRoot !== null) return gitRoot;
62806
63541
  let dir = from;
62807
63542
  for (; ; ) {
62808
- if (existsSync25(join50(dir, PROJECT_DIR_NAME))) return dir;
63543
+ if (existsSync25(join51(dir, PROJECT_DIR_NAME))) return dir;
62809
63544
  if (dir === root) return from;
62810
63545
  const parent = dirname28(dir);
62811
63546
  if (parent === dir) return from;
@@ -69064,10 +69799,10 @@ var require_resolve_block_map = __commonJS({
69064
69799
  let offset = bm.offset;
69065
69800
  let commentEnd = null;
69066
69801
  for (const collItem of bm.items) {
69067
- const { start, key, sep: sep12, value } = collItem;
69802
+ const { start, key, sep: sep13, value } = collItem;
69068
69803
  const keyProps = resolveProps.resolveProps(start, {
69069
69804
  indicator: "explicit-key-ind",
69070
- next: key ?? sep12?.[0],
69805
+ next: key ?? sep13?.[0],
69071
69806
  offset,
69072
69807
  onError,
69073
69808
  parentIndent: bm.indent,
@@ -69081,7 +69816,7 @@ var require_resolve_block_map = __commonJS({
69081
69816
  else if ("indent" in key && key.indent !== bm.indent)
69082
69817
  onError(offset, "BAD_INDENT", startColMsg);
69083
69818
  }
69084
- if (!keyProps.anchor && !keyProps.tag && !sep12) {
69819
+ if (!keyProps.anchor && !keyProps.tag && !sep13) {
69085
69820
  commentEnd = keyProps.end;
69086
69821
  if (keyProps.comment) {
69087
69822
  if (map.comment)
@@ -69105,7 +69840,7 @@ var require_resolve_block_map = __commonJS({
69105
69840
  ctx.atKey = false;
69106
69841
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
69107
69842
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
69108
- const valueProps = resolveProps.resolveProps(sep12 ?? [], {
69843
+ const valueProps = resolveProps.resolveProps(sep13 ?? [], {
69109
69844
  indicator: "map-value-ind",
69110
69845
  next: value,
69111
69846
  offset: keyNode.range[2],
@@ -69121,7 +69856,7 @@ var require_resolve_block_map = __commonJS({
69121
69856
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
69122
69857
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
69123
69858
  }
69124
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep12, null, valueProps, onError);
69859
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep13, null, valueProps, onError);
69125
69860
  if (ctx.schema.compat)
69126
69861
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
69127
69862
  offset = valueNode.range[2];
@@ -69212,7 +69947,7 @@ var require_resolve_end = __commonJS({
69212
69947
  let comment = "";
69213
69948
  if (end) {
69214
69949
  let hasSpace = false;
69215
- let sep12 = "";
69950
+ let sep13 = "";
69216
69951
  for (const token of end) {
69217
69952
  const { source, type } = token;
69218
69953
  switch (type) {
@@ -69226,13 +69961,13 @@ var require_resolve_end = __commonJS({
69226
69961
  if (!comment)
69227
69962
  comment = cb;
69228
69963
  else
69229
- comment += sep12 + cb;
69230
- sep12 = "";
69964
+ comment += sep13 + cb;
69965
+ sep13 = "";
69231
69966
  break;
69232
69967
  }
69233
69968
  case "newline":
69234
69969
  if (comment)
69235
- sep12 += source;
69970
+ sep13 += source;
69236
69971
  hasSpace = true;
69237
69972
  break;
69238
69973
  default:
@@ -69275,18 +70010,18 @@ var require_resolve_flow_collection = __commonJS({
69275
70010
  let offset = fc.offset + fc.start.source.length;
69276
70011
  for (let i2 = 0; i2 < fc.items.length; ++i2) {
69277
70012
  const collItem = fc.items[i2];
69278
- const { start, key, sep: sep12, value } = collItem;
70013
+ const { start, key, sep: sep13, value } = collItem;
69279
70014
  const props = resolveProps.resolveProps(start, {
69280
70015
  flow: fcName,
69281
70016
  indicator: "explicit-key-ind",
69282
- next: key ?? sep12?.[0],
70017
+ next: key ?? sep13?.[0],
69283
70018
  offset,
69284
70019
  onError,
69285
70020
  parentIndent: fc.indent,
69286
70021
  startOnNewline: false
69287
70022
  });
69288
70023
  if (!props.found) {
69289
- if (!props.anchor && !props.tag && !sep12 && !value) {
70024
+ if (!props.anchor && !props.tag && !sep13 && !value) {
69290
70025
  if (i2 === 0 && props.comma)
69291
70026
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
69292
70027
  else if (i2 < fc.items.length - 1)
@@ -69340,8 +70075,8 @@ var require_resolve_flow_collection = __commonJS({
69340
70075
  }
69341
70076
  }
69342
70077
  }
69343
- if (!isMap3 && !sep12 && !props.found) {
69344
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep12, null, props, onError);
70078
+ if (!isMap3 && !sep13 && !props.found) {
70079
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep13, null, props, onError);
69345
70080
  coll.items.push(valueNode);
69346
70081
  offset = valueNode.range[2];
69347
70082
  if (isBlock(value))
@@ -69353,7 +70088,7 @@ var require_resolve_flow_collection = __commonJS({
69353
70088
  if (isBlock(key))
69354
70089
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
69355
70090
  ctx.atKey = false;
69356
- const valueProps = resolveProps.resolveProps(sep12 ?? [], {
70091
+ const valueProps = resolveProps.resolveProps(sep13 ?? [], {
69357
70092
  flow: fcName,
69358
70093
  indicator: "map-value-ind",
69359
70094
  next: value,
@@ -69364,8 +70099,8 @@ var require_resolve_flow_collection = __commonJS({
69364
70099
  });
69365
70100
  if (valueProps.found) {
69366
70101
  if (!isMap3 && !props.found && ctx.options.strict) {
69367
- if (sep12)
69368
- for (const st of sep12) {
70102
+ if (sep13)
70103
+ for (const st of sep13) {
69369
70104
  if (st === valueProps.found)
69370
70105
  break;
69371
70106
  if (st.type === "newline") {
@@ -69382,7 +70117,7 @@ var require_resolve_flow_collection = __commonJS({
69382
70117
  else
69383
70118
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
69384
70119
  }
69385
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep12, null, valueProps, onError) : null;
70120
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep13, null, valueProps, onError) : null;
69386
70121
  if (valueNode) {
69387
70122
  if (isBlock(value))
69388
70123
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -69562,7 +70297,7 @@ var require_resolve_block_scalar = __commonJS({
69562
70297
  chompStart = i2 + 1;
69563
70298
  }
69564
70299
  let value = "";
69565
- let sep12 = "";
70300
+ let sep13 = "";
69566
70301
  let prevMoreIndented = false;
69567
70302
  for (let i2 = 0; i2 < contentStart; ++i2)
69568
70303
  value += lines[i2][0].slice(trimIndent) + "\n";
@@ -69579,24 +70314,24 @@ var require_resolve_block_scalar = __commonJS({
69579
70314
  indent = "";
69580
70315
  }
69581
70316
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
69582
- value += sep12 + indent.slice(trimIndent) + content;
69583
- sep12 = "\n";
70317
+ value += sep13 + indent.slice(trimIndent) + content;
70318
+ sep13 = "\n";
69584
70319
  } else if (indent.length > trimIndent || content[0] === " ") {
69585
- if (sep12 === " ")
69586
- sep12 = "\n";
69587
- else if (!prevMoreIndented && sep12 === "\n")
69588
- sep12 = "\n\n";
69589
- value += sep12 + indent.slice(trimIndent) + content;
69590
- sep12 = "\n";
70320
+ if (sep13 === " ")
70321
+ sep13 = "\n";
70322
+ else if (!prevMoreIndented && sep13 === "\n")
70323
+ sep13 = "\n\n";
70324
+ value += sep13 + indent.slice(trimIndent) + content;
70325
+ sep13 = "\n";
69591
70326
  prevMoreIndented = true;
69592
70327
  } else if (content === "") {
69593
- if (sep12 === "\n")
70328
+ if (sep13 === "\n")
69594
70329
  value += "\n";
69595
70330
  else
69596
- sep12 = "\n";
70331
+ sep13 = "\n";
69597
70332
  } else {
69598
- value += sep12 + content;
69599
- sep12 = " ";
70333
+ value += sep13 + content;
70334
+ sep13 = " ";
69600
70335
  prevMoreIndented = false;
69601
70336
  }
69602
70337
  }
@@ -69779,25 +70514,25 @@ var require_resolve_flow_scalar = __commonJS({
69779
70514
  trimBoth = /^[ \t]+|[ \t]+$/g;
69780
70515
  }
69781
70516
  let res = match[1].replace(trimEnd, "");
69782
- let sep12 = " ";
70517
+ let sep13 = " ";
69783
70518
  let pos = line.lastIndex;
69784
70519
  while (match = line.exec(source)) {
69785
70520
  const lm = match[1].replace(trimBoth, "");
69786
70521
  if (lm === "") {
69787
- if (sep12 === "\n")
69788
- res += sep12;
70522
+ if (sep13 === "\n")
70523
+ res += sep13;
69789
70524
  else
69790
- sep12 = "\n";
70525
+ sep13 = "\n";
69791
70526
  } else {
69792
- res += sep12 + lm;
69793
- sep12 = " ";
70527
+ res += sep13 + lm;
70528
+ sep13 = " ";
69794
70529
  }
69795
70530
  pos = line.lastIndex;
69796
70531
  }
69797
70532
  const last = /[ \t]*(.*)/sy;
69798
70533
  last.lastIndex = pos;
69799
70534
  match = last.exec(source);
69800
- return res + sep12 + (match?.[1] ?? "");
70535
+ return res + sep13 + (match?.[1] ?? "");
69801
70536
  }
69802
70537
  function doubleQuotedValue(source, onError) {
69803
70538
  let res = "";
@@ -70607,14 +71342,14 @@ var require_cst_stringify = __commonJS({
70607
71342
  }
70608
71343
  }
70609
71344
  }
70610
- function stringifyItem({ start, key, sep: sep12, value }) {
71345
+ function stringifyItem({ start, key, sep: sep13, value }) {
70611
71346
  let res = "";
70612
71347
  for (const st of start)
70613
71348
  res += st.source;
70614
71349
  if (key)
70615
71350
  res += stringifyToken(key);
70616
- if (sep12)
70617
- for (const st of sep12)
71351
+ if (sep13)
71352
+ for (const st of sep13)
70618
71353
  res += st.source;
70619
71354
  if (value)
70620
71355
  res += stringifyToken(value);
@@ -71781,18 +72516,18 @@ var require_parser = __commonJS({
71781
72516
  if (this.type === "map-value-ind") {
71782
72517
  const prev = getPrevProps(this.peek(2));
71783
72518
  const start = getFirstKeyStartProps(prev);
71784
- let sep12;
72519
+ let sep13;
71785
72520
  if (scalar2.end) {
71786
- sep12 = scalar2.end;
71787
- sep12.push(this.sourceToken);
72521
+ sep13 = scalar2.end;
72522
+ sep13.push(this.sourceToken);
71788
72523
  delete scalar2.end;
71789
72524
  } else
71790
- sep12 = [this.sourceToken];
72525
+ sep13 = [this.sourceToken];
71791
72526
  const map = {
71792
72527
  type: "block-map",
71793
72528
  offset: scalar2.offset,
71794
72529
  indent: scalar2.indent,
71795
- items: [{ start, key: scalar2, sep: sep12 }]
72530
+ items: [{ start, key: scalar2, sep: sep13 }]
71796
72531
  };
71797
72532
  this.onKeyLine = true;
71798
72533
  this.stack[this.stack.length - 1] = map;
@@ -71945,15 +72680,15 @@ var require_parser = __commonJS({
71945
72680
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
71946
72681
  const start2 = getFirstKeyStartProps(it.start);
71947
72682
  const key = it.key;
71948
- const sep12 = it.sep;
71949
- sep12.push(this.sourceToken);
72683
+ const sep13 = it.sep;
72684
+ sep13.push(this.sourceToken);
71950
72685
  delete it.key;
71951
72686
  delete it.sep;
71952
72687
  this.stack.push({
71953
72688
  type: "block-map",
71954
72689
  offset: this.offset,
71955
72690
  indent: this.indent,
71956
- items: [{ start: start2, key, sep: sep12 }]
72691
+ items: [{ start: start2, key, sep: sep13 }]
71957
72692
  });
71958
72693
  } else if (start.length > 0) {
71959
72694
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -72147,13 +72882,13 @@ var require_parser = __commonJS({
72147
72882
  const prev = getPrevProps(parent);
72148
72883
  const start = getFirstKeyStartProps(prev);
72149
72884
  fixFlowSeqItems(fc);
72150
- const sep12 = fc.end.splice(1, fc.end.length);
72151
- sep12.push(this.sourceToken);
72885
+ const sep13 = fc.end.splice(1, fc.end.length);
72886
+ sep13.push(this.sourceToken);
72152
72887
  const map = {
72153
72888
  type: "block-map",
72154
72889
  offset: fc.offset,
72155
72890
  indent: fc.indent,
72156
- items: [{ start, key: fc, sep: sep12 }]
72891
+ items: [{ start, key: fc, sep: sep13 }]
72157
72892
  };
72158
72893
  this.onKeyLine = true;
72159
72894
  this.stack[this.stack.length - 1] = map;
@@ -75312,7 +76047,7 @@ function codegraphSettingsGroupOf(path2) {
75312
76047
  (entry2) => codegraphSettingsPath(entry2.group) === path2
75313
76048
  ) ?? null;
75314
76049
  }
75315
- var share, confidence, sourceTagSchema, codegraphSourcesSchema, CODEGRAPH_SOURCES_DEFAULTS, CODEGRAPH_FILE_SIZE_LIMIT_BYTES_DEFAULT, CODEGRAPH_SKIPPED_PATHS_DEFAULT, codegraphIndexingSchema, CODEGRAPH_INDEXING_DEFAULTS, codegraphKeySourceSchema, codegraphCallModeSchema, modelId, codegraphModelsSchema, CODEGRAPH_MODELS_DEFAULTS, codegraphEmbeddingProviderSchema, CODEGRAPH_EMBEDDING_DIMENSIONS_MAX, CODEGRAPH_OXAGEN_EMBEDDING_MODEL, CODEGRAPH_ENDPOINT_URL_PATTERN, codegraphEmbeddingsSchema, CODEGRAPH_EMBEDDINGS_DEFAULTS, codegraphLocalSchema, CODEGRAPH_LOCAL_DEFAULTS, CODEGRAPH_PROVENANCE_CONFIDENCE_DEFAULTS, codegraphConfidenceSchema, CODEGRAPH_CONFIDENCE_DEFAULTS, codegraphDomainIdSchema, written, domainName, domainDefinition, codegraphDomainChangeSchema, codegraphDomainsSchema, CODEGRAPH_DOMAINS_DEFAULTS, CODEGRAPH_BOT_AUTHORS_DEFAULT, codegraphHistorySchema, CODEGRAPH_HISTORY_DEFAULTS, codegraphDecisionsSchema, CODEGRAPH_DECISIONS_DEFAULTS, codegraphHostDefaultSchema, CODEGRAPH_HOST_DEFAULTS, codegraphScriptsSchema, CODEGRAPH_SCRIPTS_DEFAULTS, codegraphBoundariesSchema, CODEGRAPH_BOUNDARIES_DEFAULTS, codegraphBudgetsSchema, CODEGRAPH_BUDGETS_DEFAULTS, codegraphFreshnessSchema, CODEGRAPH_FRESHNESS_DEFAULTS, CODEGRAPH_SETTINGS_GROUPS;
76050
+ var share, confidence, sourceTagSchema, codegraphSourcesSchema, CODEGRAPH_SOURCES_DEFAULTS, CODEGRAPH_FILE_SIZE_LIMIT_BYTES_DEFAULT, CODEGRAPH_SKIPPED_PATHS_DEFAULT, CODEGRAPH_INVENTORY_ROLE_ARN, codegraphIndexingSchema, CODEGRAPH_INDEXING_DEFAULTS, codegraphKeySourceSchema, codegraphCallModeSchema, modelId, LINKER_ROUNDS_MAX, codegraphModelsSchema, CODEGRAPH_MODELS_DEFAULTS, codegraphEmbeddingProviderSchema, CODEGRAPH_EMBEDDING_DIMENSIONS_MAX, CODEGRAPH_OXAGEN_EMBEDDING_MODEL, CODEGRAPH_ENDPOINT_URL_PATTERN, codegraphEmbeddingsSchema, CODEGRAPH_EMBEDDINGS_DEFAULTS, codegraphLocalSchema, CODEGRAPH_LOCAL_DEFAULTS, CODEGRAPH_PROVENANCE_CONFIDENCE_DEFAULTS, codegraphConfidenceSchema, CODEGRAPH_CONFIDENCE_DEFAULTS, codegraphDomainIdSchema, written, domainName, domainDefinition, codegraphDomainChangeSchema, codegraphDomainsSchema, CODEGRAPH_DOMAINS_DEFAULTS, CODEGRAPH_BOT_AUTHORS_DEFAULT, codegraphHistorySchema, CODEGRAPH_HISTORY_DEFAULTS, codegraphDecisionsSchema, CODEGRAPH_DECISIONS_DEFAULTS, codegraphHostDefaultSchema, CODEGRAPH_HOST_DEFAULTS, codegraphScriptsSchema, CODEGRAPH_SCRIPTS_DEFAULTS, codegraphBoundariesSchema, CODEGRAPH_BOUNDARIES_DEFAULTS, codegraphBudgetsSchema, CODEGRAPH_BUDGETS_DEFAULTS, codegraphFreshnessSchema, CODEGRAPH_FRESHNESS_DEFAULTS, CODEGRAPH_SETTINGS_GROUPS;
75316
76051
  var init_codegraph_settings = __esm({
75317
76052
  "../../packages/oxagen/src/steering-repo/codegraph-settings.ts"() {
75318
76053
  "use strict";
@@ -75352,6 +76087,7 @@ var init_codegraph_settings = __esm({
75352
76087
  "**/*.key",
75353
76088
  "**/id_rsa*"
75354
76089
  ];
76090
+ CODEGRAPH_INVENTORY_ROLE_ARN = /^arn:aws(?:-[a-z]+)*:iam::\d{12}:role\/oxagen-codegraph-inventory[\w+=,.@-]{0,32}$/;
75355
76091
  codegraphIndexingSchema = external_exports.object({
75356
76092
  file_size_limit_bytes: setting(
75357
76093
  external_exports.number().int().min(1).describe("Skip a file larger than this many bytes."),
@@ -75367,6 +76103,34 @@ var init_codegraph_settings = __esm({
75367
76103
  external_exports.boolean().describe("Read the live cloud inventory as well as the code."),
75368
76104
  false
75369
76105
  ),
76106
+ cloud_accounts: uniqueArray(
76107
+ external_exports.object({
76108
+ provider: external_exports.literal("aws").describe("The cloud. AWS is the only one read so far."),
76109
+ role_arn: external_exports.string().regex(
76110
+ CODEGRAPH_INVENTORY_ROLE_ARN,
76111
+ "the role is an IAM role whose name starts with oxagen-codegraph-inventory"
76112
+ ).describe(
76113
+ "The read-only role the template in services/codegraph/worker/inventory/ creates."
76114
+ ),
76115
+ regions: uniqueArray(
76116
+ external_exports.string().regex(
76117
+ /^[a-z]{2}(?:-gov)?-[a-z]+-\d$/,
76118
+ "a region is written like us-east-1"
76119
+ ),
76120
+ "regions",
76121
+ 1
76122
+ ).describe("The regions read, such as us-east-1."),
76123
+ environment: external_exports.string().min(1).max(64).optional().describe(
76124
+ "The stage this account holds, such as production. Declared resources of another stage are not compared."
76125
+ ),
76126
+ repos: uniqueArray(repoRefSchema, "repos", 1).describe(
76127
+ "The repositories whose infrastructure code declares this account."
76128
+ )
76129
+ }).strict(),
76130
+ "cloud_accounts"
76131
+ ).optional().describe(
76132
+ "One row per cloud account live inventory reads, when live_cloud_inventory is on."
76133
+ ),
75370
76134
  repos: uniqueArray(
75371
76135
  external_exports.object({
75372
76136
  url: repoRefSchema,
@@ -75390,11 +76154,13 @@ var init_codegraph_settings = __esm({
75390
76154
  file_size_limit_bytes: CODEGRAPH_FILE_SIZE_LIMIT_BYTES_DEFAULT,
75391
76155
  skipped_paths: CODEGRAPH_SKIPPED_PATHS_DEFAULT,
75392
76156
  live_cloud_inventory: false,
76157
+ cloud_accounts: [],
75393
76158
  repos: []
75394
76159
  };
75395
76160
  codegraphKeySourceSchema = external_exports.enum(["oxagen", "organization"]);
75396
76161
  codegraphCallModeSchema = external_exports.enum(["batch", "standard"]);
75397
76162
  modelId = () => external_exports.string().min(1).max(200);
76163
+ LINKER_ROUNDS_MAX = 5;
75398
76164
  codegraphModelsSchema = external_exports.object({
75399
76165
  key_source: setting(
75400
76166
  codegraphKeySourceSchema.describe(
@@ -75447,6 +76213,12 @@ var init_codegraph_settings = __esm({
75447
76213
  ),
75448
76214
  0.4
75449
76215
  ),
76216
+ linker_rounds: setting(
76217
+ external_exports.number().int().min(0).max(LINKER_ROUNDS_MAX).describe(
76218
+ "The most model requests the linker sends for one node, across the default and the stronger model. 0 turns the linker off."
76219
+ ),
76220
+ 4
76221
+ ),
75450
76222
  spending_cap_micros_per_month: external_exports.number().int().min(0).optional().describe(
75451
76223
  "The workspace's monthly limit for code graph token calls, in millionths of a dollar. Unset: the plan's cap."
75452
76224
  )
@@ -75457,7 +76229,8 @@ var init_codegraph_settings = __esm({
75457
76229
  zero_data_retention: false,
75458
76230
  agent_reserved_share: 0.5,
75459
76231
  escalate_below: 0.6,
75460
- stronger_model_acceptance_floor: 0.4
76232
+ stronger_model_acceptance_floor: 0.4,
76233
+ linker_rounds: 4
75461
76234
  };
75462
76235
  codegraphEmbeddingProviderSchema = external_exports.enum(["oxagen", "custom"]);
75463
76236
  CODEGRAPH_EMBEDDING_DIMENSIONS_MAX = 4e3;
@@ -75830,7 +76603,7 @@ var init_codegraph_settings = __esm({
75830
76603
  group: "models",
75831
76604
  id: "codegraph-models/v1",
75832
76605
  title: "Code graph AI models and keys",
75833
- description: "codegraph/models.toml: the key source, the model for each task, call mode, providers, and escalation limits. The key itself is never stored here.",
76606
+ description: "codegraph/models.toml: the key source, the model for each task, call mode, providers, escalation limits, and linker rounds. The key itself is never stored here.",
75834
76607
  schema: codegraphModelsSchema,
75835
76608
  defaults: CODEGRAPH_MODELS_DEFAULTS,
75836
76609
  timing: "next_build"
@@ -76225,7 +76998,8 @@ var init_run_list = __esm({
76225
76998
  "run_sealed",
76226
76999
  "no_host",
76227
77000
  "host_revoked",
76228
- "host_offline"
77001
+ "host_offline",
77002
+ "daemon_chain"
76229
77003
  ];
76230
77004
  STEER_BLOCKS = ["no_prompt_carrier"];
76231
77005
  HOST_POLL_WINDOW_MS = 5 * 6e4;
@@ -76700,6 +77474,14 @@ var init_run_list = __esm({
76700
77474
  * the hostname, and a ledger run's goal.
76701
77475
  */
76702
77476
  query: external_exports.string().trim().min(1).max(200).optional(),
77477
+ /**
77478
+ * Only the runs of this agent, by its key (`org_ns.ws_ns.slug`,
77479
+ * ADR-024), matched exactly in the database. Absent lists every agent's
77480
+ * runs. A ledger run that names no agent never matches. The agent page
77481
+ * sets it, so an agent whose runs are all older than the workspace's
77482
+ * newest page still lists them (#5786).
77483
+ */
77484
+ agentKey: external_exports.string().trim().min(1).max(200).optional(),
76703
77485
  /**
76704
77486
  * The order of the list. Absent means `started` descending. Nulls sort
76705
77487
  * last in both directions.
@@ -79843,20 +80625,20 @@ import { readFile as readFile9 } from "node:fs/promises";
79843
80625
  import {
79844
80626
  basename as basename7,
79845
80627
  dirname as dirname29,
79846
- isAbsolute as isAbsolute12,
79847
- relative as relative5,
79848
- resolve as resolve17,
79849
- sep as sep6
80628
+ isAbsolute as isAbsolute13,
80629
+ relative as relative6,
80630
+ resolve as resolve18,
80631
+ sep as sep7
79850
80632
  } from "node:path";
79851
80633
  function inside(rel) {
79852
- return rel !== "" && !rel.startsWith("..") && !isAbsolute12(rel);
80634
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute13(rel);
79853
80635
  }
79854
80636
  function importFilename(path2, folder) {
79855
- let rel = relative5(process.cwd(), path2);
80637
+ let rel = relative6(process.cwd(), path2);
79856
80638
  if (!inside(rel) && folder !== void 0) {
79857
- rel = relative5(dirname29(resolve17(folder)), resolve17(path2));
80639
+ rel = relative6(dirname29(resolve18(folder)), resolve18(path2));
79858
80640
  }
79859
- const name = inside(rel) ? rel.split(sep6).join("/") : basename7(path2);
80641
+ const name = inside(rel) ? rel.split(sep7).join("/") : basename7(path2);
79860
80642
  return name.length > 256 ? basename7(path2).slice(-256) : name;
79861
80643
  }
79862
80644
  async function readImportDocuments(sources, target2, writer) {
@@ -80141,7 +80923,7 @@ __export(steering_import_exports, {
80141
80923
  });
80142
80924
  import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
80143
80925
  import { homedir as homedir12 } from "node:os";
80144
- import { basename as basename8, extname, join as join51, relative as relative6, sep as sep7 } from "node:path";
80926
+ import { basename as basename8, extname, join as join52, relative as relative7, sep as sep8 } from "node:path";
80145
80927
  function envDir2(env, key) {
80146
80928
  const value = env[key];
80147
80929
  return value === void 0 || value.trim() === "" ? null : value;
@@ -80149,34 +80931,34 @@ function envDir2(env, key) {
80149
80931
  function harnessHome(harness, env = process.env, home = homedir12()) {
80150
80932
  switch (harness) {
80151
80933
  case "claude-code": {
80152
- const config = envDir2(env, "CLAUDE_CONFIG_DIR") ?? join51(home, ".claude");
80934
+ const config = envDir2(env, "CLAUDE_CONFIG_DIR") ?? join52(home, ".claude");
80153
80935
  return {
80154
80936
  harness,
80155
80937
  folders: [
80156
80938
  {
80157
- dir: skillsRoot("claude-code", env, home) ?? join51(config, "skills"),
80939
+ dir: skillsRoot("claude-code", env, home) ?? join52(config, "skills"),
80158
80940
  mount: ".claude/skills"
80159
80941
  },
80160
- { dir: join51(config, "commands"), mount: ".claude/commands" },
80161
- { dir: join51(config, "agents"), mount: ".claude/agents" }
80942
+ { dir: join52(config, "commands"), mount: ".claude/commands" },
80943
+ { dir: join52(config, "agents"), mount: ".claude/agents" }
80162
80944
  ],
80163
80945
  instructions: [
80164
- { file: join51(config, "CLAUDE.md"), filename: ".claude/CLAUDE.md" }
80946
+ { file: join52(config, "CLAUDE.md"), filename: ".claude/CLAUDE.md" }
80165
80947
  ]
80166
80948
  };
80167
80949
  }
80168
80950
  case "codex": {
80169
- const codexHome = envDir2(env, "CODEX_HOME") ?? join51(home, ".codex");
80951
+ const codexHome = envDir2(env, "CODEX_HOME") ?? join52(home, ".codex");
80170
80952
  return {
80171
80953
  harness,
80172
80954
  folders: [
80173
80955
  {
80174
- dir: skillsRoot("codex", env, home) ?? join51(home, ".agents", "skills"),
80956
+ dir: skillsRoot("codex", env, home) ?? join52(home, ".agents", "skills"),
80175
80957
  mount: ".agents/skills"
80176
80958
  }
80177
80959
  ],
80178
80960
  instructions: ["AGENTS.override.md", "AGENTS.md"].map((name) => ({
80179
- file: join51(codexHome, name),
80961
+ file: join52(codexHome, name),
80180
80962
  filename: `.codex/${name}`
80181
80963
  }))
80182
80964
  };
@@ -80185,8 +80967,8 @@ function harnessHome(harness, env = process.env, home = homedir12()) {
80185
80967
  return {
80186
80968
  harness,
80187
80969
  folders: [
80188
- { dir: join51(home, ".cursor", "skills"), mount: ".cursor/skills" },
80189
- { dir: join51(home, ".cursor", "commands"), mount: ".cursor/commands" }
80970
+ { dir: join52(home, ".cursor", "skills"), mount: ".cursor/skills" },
80971
+ { dir: join52(home, ".cursor", "commands"), mount: ".cursor/commands" }
80190
80972
  ],
80191
80973
  instructions: []
80192
80974
  };
@@ -80196,7 +80978,7 @@ function byName(a, b3) {
80196
80978
  return a.name < b3.name ? -1 : 1;
80197
80979
  }
80198
80980
  function under(root, path2) {
80199
- return relative6(root, path2).split(sep7).join("/");
80981
+ return relative7(root, path2).split(sep8).join("/");
80200
80982
  }
80201
80983
  function isPersonal(rel) {
80202
80984
  return classifyHarnessFile(rel)?.kind === "personal";
@@ -80232,7 +81014,7 @@ async function findMarkdownFiles(paths, harness) {
80232
81014
  }
80233
81015
  const found = [];
80234
81016
  for (const entry2 of entries2.sort(byName)) {
80235
- const path2 = join51(dir, entry2.name);
81017
+ const path2 = join52(dir, entry2.name);
80236
81018
  if (entry2.isDirectory()) {
80237
81019
  if (!entry2.name.startsWith(".") && entry2.name !== "node_modules")
80238
81020
  found.push(...await filesUnder(path2, from));
@@ -80254,7 +81036,7 @@ async function findMarkdownFiles(paths, harness) {
80254
81036
  const { folder } = frame;
80255
81037
  const named = (rel) => frame.fixedNames ? { filename: rel } : {};
80256
81038
  for (const entry2 of entries2) {
80257
- const path2 = join51(dir, entry2.name);
81039
+ const path2 = join52(dir, entry2.name);
80258
81040
  const rel = frame.relOf(path2);
80259
81041
  if (entry2.isDirectory()) {
80260
81042
  if (entry2.name === "node_modules") continue;
@@ -80313,7 +81095,7 @@ async function findMarkdownFiles(paths, harness) {
80313
81095
  }
80314
81096
  if (folderGiven) {
80315
81097
  const catalogue = CATALOGUE_FOLDERS.has(basename8(path2));
80316
- const root = catalogue ? join51(path2, "..") : path2;
81098
+ const root = catalogue ? join52(path2, "..") : path2;
80317
81099
  await walk2(path2, {
80318
81100
  relOf: (p) => under(root, p),
80319
81101
  folder: path2,
@@ -80643,7 +81425,7 @@ __export(run_exports, {
80643
81425
  });
80644
81426
  import { createHash as createHash16 } from "node:crypto";
80645
81427
  import { createWriteStream, renameSync as renameSync6, rmSync as rmSync9 } from "node:fs";
80646
- import { resolve as resolve18 } from "node:path";
81428
+ import { resolve as resolve19 } from "node:path";
80647
81429
  import { Readable as Readable2 } from "node:stream";
80648
81430
  import { pipeline as pipeline2 } from "node:stream/promises";
80649
81431
  async function runExport(runId, opts = {}, writer = stdoutWriter) {
@@ -80741,7 +81523,7 @@ async function runDownload(exportId, opts = {}, writer = stdoutWriter) {
80741
81523
  return;
80742
81524
  }
80743
81525
  const url = resolveDownloadUrl(status2.download.url, getApiUrl());
80744
- const path2 = resolve18(opts.out ?? `${status2.runId}-${exportId}.zip`);
81526
+ const path2 = resolve19(opts.out ?? `${status2.runId}-${exportId}.zip`);
80745
81527
  const partial = `${path2}.${process.pid}.partial`;
80746
81528
  const hash3 = createHash16("sha256");
80747
81529
  let size = 0;
@@ -81973,10 +82755,10 @@ __export(verify_exports, {
81973
82755
  verifyBundle: () => verifyBundle3
81974
82756
  });
81975
82757
  import { existsSync as existsSync26, readFileSync as readFileSync23, statSync as statSync12 } from "node:fs";
81976
- import { join as join52 } from "node:path";
82758
+ import { join as join53 } from "node:path";
81977
82759
  function readDirectory(dir) {
81978
82760
  const read2 = (name) => {
81979
- const path2 = join52(dir, name);
82761
+ const path2 = join53(dir, name);
81980
82762
  return existsSync26(path2) ? readFileSync23(path2, "utf8") : void 0;
81981
82763
  };
81982
82764
  return assemble(read2, dir);
@@ -83105,7 +83887,7 @@ import {
83105
83887
  writeFileSync as writeFileSync7
83106
83888
  } from "node:fs";
83107
83889
  import { homedir as homedir13, hostname as osHostname3 } from "node:os";
83108
- import { join as join53, relative as relative7, resolve as resolve19, sep as sep8 } from "node:path";
83890
+ import { join as join54, relative as relative8, resolve as resolve20, sep as sep9 } from "node:path";
83109
83891
  function git4(cwd, args) {
83110
83892
  return new Promise((done) => {
83111
83893
  try {
@@ -83126,7 +83908,7 @@ function git4(cwd, args) {
83126
83908
  }
83127
83909
  async function projectRootFor(cwd) {
83128
83910
  const top = await git4(cwd, ["rev-parse", "--show-toplevel"]);
83129
- return top ? resolve19(top) : resolve19(cwd);
83911
+ return top ? resolve20(top) : resolve20(cwd);
83130
83912
  }
83131
83913
  function parseRemoteRepository(url) {
83132
83914
  const raw = url.trim();
@@ -83152,7 +83934,7 @@ function parseRemoteRepository(url) {
83152
83934
  }
83153
83935
  function oxagenPresent(root) {
83154
83936
  try {
83155
- return readdirSync13(join53(root, ".oxagen")).some(
83937
+ return readdirSync13(join54(root, ".oxagen")).some(
83156
83938
  (name) => name !== "workspace.json"
83157
83939
  );
83158
83940
  } catch {
@@ -83161,22 +83943,22 @@ function oxagenPresent(root) {
83161
83943
  }
83162
83944
  function symlinkState(root) {
83163
83945
  try {
83164
- if (!lstatSync9(join53(root, ".stella")).isDirectory()) return "none";
83946
+ if (!lstatSync9(join54(root, ".stella")).isDirectory()) return "none";
83165
83947
  } catch {
83166
83948
  return "none";
83167
83949
  }
83168
83950
  let oxagenReal;
83169
83951
  try {
83170
- oxagenReal = realpathSync8(join53(root, ".oxagen"));
83952
+ oxagenReal = realpathSync8(join54(root, ".oxagen"));
83171
83953
  } catch {
83172
83954
  return "missing";
83173
83955
  }
83174
83956
  for (const link of STELLA_LINKS) {
83175
- const at2 = join53(root, link);
83957
+ const at2 = join54(root, link);
83176
83958
  try {
83177
83959
  if (!lstatSync9(at2).isSymbolicLink()) return "missing";
83178
83960
  const target2 = realpathSync8(at2);
83179
- if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep8)) {
83961
+ if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep9)) {
83180
83962
  return "missing";
83181
83963
  }
83182
83964
  } catch {
@@ -83186,7 +83968,7 @@ function symlinkState(root) {
83186
83968
  return "linked";
83187
83969
  }
83188
83970
  function machineId(configDir = getConfigDir()) {
83189
- const file = join53(configDir, MACHINE_ID_FILE);
83971
+ const file = join54(configDir, MACHINE_ID_FILE);
83190
83972
  let secret = null;
83191
83973
  try {
83192
83974
  if (existsSync27(file)) {
@@ -83226,7 +84008,7 @@ async function probeWorkingCopy(opts) {
83226
84008
  return {
83227
84009
  machineId: machineId(opts.configDir),
83228
84010
  hostname: host.length > 0 ? host : "unknown",
83229
- directory: resolve19(root),
84011
+ directory: resolve20(root),
83230
84012
  repository: remote ? parseRemoteRepository(remote) : null,
83231
84013
  // `HEAD` is git's answer on a detached head.
83232
84014
  branch: branch && branch !== "HEAD" ? branch.slice(0, 255) : null,
@@ -83259,21 +84041,21 @@ function realpathOr2(path2) {
83259
84041
  try {
83260
84042
  return realpathSync8(path2);
83261
84043
  } catch {
83262
- return resolve19(path2);
84044
+ return resolve20(path2);
83263
84045
  }
83264
84046
  }
83265
84047
  async function ensureWorkspaceLinkIgnored(root) {
83266
84048
  const top = await git4(root, ["rev-parse", "--show-toplevel"]);
83267
84049
  if (!top) return null;
83268
- const topDir = resolve19(top);
83269
- const entry2 = relative7(
84050
+ const topDir = resolve20(top);
84051
+ const entry2 = relative8(
83270
84052
  topDir,
83271
- join53(realpathOr2(root), ".oxagen", "workspace.json")
83272
- ).split(sep8).join("/");
84053
+ join54(realpathOr2(root), ".oxagen", "workspace.json")
84054
+ ).split(sep9).join("/");
83273
84055
  if (entry2.startsWith("../")) return null;
83274
84056
  const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
83275
84057
  if (rule !== null) return null;
83276
- const gitignore = join53(resolve19(top), ".gitignore");
84058
+ const gitignore = join54(resolve20(top), ".gitignore");
83277
84059
  let existing = "";
83278
84060
  try {
83279
84061
  existing = readFileSync24(gitignore, "utf8");
@@ -83797,11 +84579,11 @@ import {
83797
84579
  } from "node:fs";
83798
84580
  import {
83799
84581
  dirname as dirname30,
83800
- isAbsolute as isAbsolute13,
83801
- join as join54,
84582
+ isAbsolute as isAbsolute14,
84583
+ join as join55,
83802
84584
  parse as parsePath2,
83803
84585
  posix as posix4,
83804
- sep as sep9
84586
+ sep as sep10
83805
84587
  } from "node:path";
83806
84588
  function isPublishedSteering(value) {
83807
84589
  if (typeof value !== "object" || value === null) return false;
@@ -83818,7 +84600,7 @@ function checkSteeringPath(path2) {
83818
84600
  if (path2.includes("\\")) {
83819
84601
  return { ok: false, reason: "contains a backslash" };
83820
84602
  }
83821
- if (posix4.isAbsolute(path2) || isAbsolute13(path2) || /^[A-Za-z]:/.test(path2)) {
84603
+ if (posix4.isAbsolute(path2) || isAbsolute14(path2) || /^[A-Za-z]:/.test(path2)) {
83822
84604
  return { ok: false, reason: "absolute path" };
83823
84605
  }
83824
84606
  const normalized = posix4.normalize(path2);
@@ -83918,7 +84700,7 @@ function findLinkedRoot(start) {
83918
84700
  }
83919
84701
  function fsReader(root) {
83920
84702
  return (path2) => {
83921
- const abs = join54(root, ...path2.split("/"));
84703
+ const abs = join55(root, ...path2.split("/"));
83922
84704
  try {
83923
84705
  const st = lstatSync10(abs);
83924
84706
  if (!st.isFile()) return Buffer.from(`\0not-a-file:${abs}`);
@@ -83929,14 +84711,14 @@ function fsReader(root) {
83929
84711
  };
83930
84712
  }
83931
84713
  function assertInsideOxagen(root, path2) {
83932
- const oxagenAbs = join54(root, OXAGEN_DIR);
84714
+ const oxagenAbs = join55(root, OXAGEN_DIR);
83933
84715
  let oxagenReal;
83934
84716
  try {
83935
84717
  oxagenReal = realpathSync9(oxagenAbs);
83936
84718
  } catch {
83937
84719
  return;
83938
84720
  }
83939
- const abs = join54(root, ...path2.split("/"));
84721
+ const abs = join55(root, ...path2.split("/"));
83940
84722
  try {
83941
84723
  if (lstatSync10(abs).isSymbolicLink()) {
83942
84724
  throw new Error(
@@ -83955,7 +84737,7 @@ function assertInsideOxagen(root, path2) {
83955
84737
  real = null;
83956
84738
  }
83957
84739
  if (real !== null) {
83958
- if (real !== oxagenReal && !real.startsWith(oxagenReal + sep9)) {
84740
+ if (real !== oxagenReal && !real.startsWith(oxagenReal + sep10)) {
83959
84741
  throw new Error(`${path2} resolves outside .oxagen/`);
83960
84742
  }
83961
84743
  return;
@@ -83966,9 +84748,9 @@ function assertInsideOxagen(root, path2) {
83966
84748
  }
83967
84749
  }
83968
84750
  function pruneEmptyDirs(root, path2) {
83969
- const stop = join54(root, OXAGEN_DIR);
83970
- let dir = dirname30(join54(root, ...path2.split("/")));
83971
- while (dir.startsWith(stop + sep9)) {
84751
+ const stop = join55(root, OXAGEN_DIR);
84752
+ let dir = dirname30(join55(root, ...path2.split("/")));
84753
+ while (dir.startsWith(stop + sep10)) {
83972
84754
  try {
83973
84755
  if (readdirSync14(dir).length > 0) return;
83974
84756
  rmdirSync7(dir);
@@ -83982,12 +84764,12 @@ function applyPlan(root, plan) {
83982
84764
  for (const w of plan.writes) assertInsideOxagen(root, w.path);
83983
84765
  for (const d of plan.deletes) assertInsideOxagen(root, d);
83984
84766
  for (const w of plan.writes) {
83985
- const abs = join54(root, ...w.path.split("/"));
84767
+ const abs = join55(root, ...w.path.split("/"));
83986
84768
  mkdirSync11(dirname30(abs), { recursive: true });
83987
84769
  atomicWriteFileSync(abs, w.content);
83988
84770
  }
83989
84771
  for (const d of plan.deletes) {
83990
- rmSync10(join54(root, ...d.split("/")), { force: true });
84772
+ rmSync10(join55(root, ...d.split("/")), { force: true });
83991
84773
  pruneEmptyDirs(root, d);
83992
84774
  }
83993
84775
  }
@@ -89994,7 +90776,7 @@ function createFileRegistry(...args) {
89994
90776
  if (seen.has(protoFileName)) {
89995
90777
  continue;
89996
90778
  }
89997
- const dep = resolve22(protoFileName);
90779
+ const dep = resolve23(protoFileName);
89998
90780
  if (!dep) {
89999
90781
  throw new Error(`Unable to resolve ${protoFileName}, imported by ${file.name}`);
90000
90782
  }
@@ -90008,7 +90790,7 @@ function createFileRegistry(...args) {
90008
90790
  return deps.concat(...deps.map(recurseDeps));
90009
90791
  };
90010
90792
  const input = args[0];
90011
- const resolve22 = args[1];
90793
+ const resolve23 = args[1];
90012
90794
  const seen = /* @__PURE__ */ new Set();
90013
90795
  for (const file of [input, ...recurseDeps(input)].reverse()) {
90014
90796
  addFile(file, registry2);
@@ -92858,7 +93640,7 @@ var require_aspromise = __commonJS({
92858
93640
  var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true;
92859
93641
  while (index < arguments.length)
92860
93642
  params[offset++] = arguments[index++];
92861
- return new Promise(function executor(resolve22, reject) {
93643
+ return new Promise(function executor(resolve23, reject) {
92862
93644
  params[offset] = function callback(err2) {
92863
93645
  if (pending) {
92864
93646
  pending = false;
@@ -92868,7 +93650,7 @@ var require_aspromise = __commonJS({
92868
93650
  var params2 = new Array(arguments.length - 1), offset2 = 0;
92869
93651
  while (offset2 < params2.length)
92870
93652
  params2[offset2++] = arguments[offset2];
92871
- resolve22.apply(null, params2);
93653
+ resolve23.apply(null, params2);
92872
93654
  }
92873
93655
  }
92874
93656
  };
@@ -95386,13 +96168,13 @@ var require_path = __commonJS({
95386
96168
  "../../node_modules/.pnpm/@protobufjs+path@1.1.2/node_modules/@protobufjs/path/index.js"(exports) {
95387
96169
  "use strict";
95388
96170
  var path2 = exports;
95389
- var isAbsolute15 = (
96171
+ var isAbsolute16 = (
95390
96172
  /**
95391
96173
  * Tests if the specified path is absolute.
95392
96174
  * @param {string} path Path to test
95393
96175
  * @returns {boolean} `true` if path is absolute
95394
96176
  */
95395
- path2.isAbsolute = function isAbsolute16(path3) {
96177
+ path2.isAbsolute = function isAbsolute17(path3) {
95396
96178
  return /^(?:\/|\w+:)/.test(path3);
95397
96179
  }
95398
96180
  );
@@ -95404,7 +96186,7 @@ var require_path = __commonJS({
95404
96186
  */
95405
96187
  path2.normalize = function normalize4(path3) {
95406
96188
  path3 = path3.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
95407
- var parts = path3.split("/"), absolute = isAbsolute15(path3), prefix = "";
96189
+ var parts = path3.split("/"), absolute = isAbsolute16(path3), prefix = "";
95408
96190
  if (absolute)
95409
96191
  prefix = parts.shift() + "/";
95410
96192
  for (var i2 = 0; i2 < parts.length; ) {
@@ -95423,10 +96205,10 @@ var require_path = __commonJS({
95423
96205
  return prefix + parts.join("/");
95424
96206
  }
95425
96207
  );
95426
- path2.resolve = function resolve22(originPath, includePath, alreadyNormalized) {
96208
+ path2.resolve = function resolve23(originPath, includePath, alreadyNormalized) {
95427
96209
  if (!alreadyNormalized)
95428
96210
  includePath = normalize3(includePath);
95429
- if (isAbsolute15(includePath))
96211
+ if (isAbsolute16(includePath))
95430
96212
  return includePath;
95431
96213
  if (!alreadyNormalized)
95432
96214
  originPath = normalize3(originPath);
@@ -95780,7 +96562,7 @@ var require_mapfield = __commonJS({
95780
96562
  keepComments ? this.comment : void 0
95781
96563
  ]);
95782
96564
  };
95783
- MapField.prototype.resolve = function resolve22() {
96565
+ MapField.prototype.resolve = function resolve23() {
95784
96566
  if (this.resolved)
95785
96567
  return this;
95786
96568
  if (types.mapKey[this.keyType] === void 0)
@@ -95857,7 +96639,7 @@ var require_method = __commonJS({
95857
96639
  this.parsedOptions
95858
96640
  ]);
95859
96641
  };
95860
- Method.prototype.resolve = function resolve22() {
96642
+ Method.prototype.resolve = function resolve23() {
95861
96643
  if (this.resolved)
95862
96644
  return this;
95863
96645
  this.resolvedRequestType = this.parent.lookupType(this.requestType);
@@ -97470,7 +98252,7 @@ var require_field = __commonJS({
97470
98252
  keepComments ? this.comment : void 0
97471
98253
  ]);
97472
98254
  };
97473
- Field.prototype.resolve = function resolve22() {
98255
+ Field.prototype.resolve = function resolve23() {
97474
98256
  if (this.resolved)
97475
98257
  return this;
97476
98258
  if ((this.typeDefault = types.defaults[this.type]) === void 0) {
@@ -97743,7 +98525,7 @@ var require_object = __commonJS({
97743
98525
  this.parent = null;
97744
98526
  this.resolved = false;
97745
98527
  };
97746
- ReflectionObject.prototype.resolve = function resolve22() {
98528
+ ReflectionObject.prototype.resolve = function resolve23() {
97747
98529
  if (this.resolved)
97748
98530
  return this;
97749
98531
  if (this.root instanceof Root)
@@ -101298,7 +102080,7 @@ function buildSet(input, notes) {
101298
102080
  for (const [name, file] of built) {
101299
102081
  const visible = visibility.of(name);
101300
102082
  for (const ref2 of file.pending)
101301
- resolve20(ref2, name, visible, everyFile, symbols);
102083
+ resolve21(ref2, name, visible, everyFile, symbols);
101302
102084
  for (const [key, text5] of file.comments) comments.set(key, text5);
101303
102085
  for (const option of file.customOptions) customOptions.add(option);
101304
102086
  }
@@ -101472,7 +102254,7 @@ function remember(built, name, file) {
101472
102254
  built.set(name, file);
101473
102255
  return file.proto;
101474
102256
  }
101475
- function resolve20(ref2, file, visible, everyFile, symbols) {
102257
+ function resolve21(ref2, file, visible, everyFile, symbols) {
101476
102258
  const found = symbols.lookup(ref2.ref, ref2.scope, visible);
101477
102259
  if (found === void 0) {
101478
102260
  const everywhere = symbols.lookup(ref2.ref, ref2.scope, everyFile);
@@ -103925,19 +104707,19 @@ function retryAfterMs(value, now) {
103925
104707
  return Number.isNaN(date) ? void 0 : Math.max(0, date - now);
103926
104708
  }
103927
104709
  function sleep(ms, signal) {
103928
- return new Promise((resolve22) => {
104710
+ return new Promise((resolve23) => {
103929
104711
  if (signal.aborted) {
103930
- resolve22(false);
104712
+ resolve23(false);
103931
104713
  return;
103932
104714
  }
103933
104715
  const onAbort = () => {
103934
104716
  clearTimeout(timer);
103935
- resolve22(false);
104717
+ resolve23(false);
103936
104718
  };
103937
104719
  const timer = setTimeout(
103938
104720
  () => {
103939
104721
  signal.removeEventListener("abort", onAbort);
103940
- resolve22(true);
104722
+ resolve23(true);
103941
104723
  },
103942
104724
  Math.min(ms, MAX_TIMER_MS)
103943
104725
  );
@@ -103991,13 +104773,13 @@ var init_retry = __esm({
103991
104773
  else signal.addEventListener("abort", this.onAbort, { once: true });
103992
104774
  }
103993
104775
  race(promise) {
103994
- return new Promise((resolve22) => {
104776
+ return new Promise((resolve23) => {
103995
104777
  let settled2 = false;
103996
104778
  const settle3 = (result2) => {
103997
104779
  if (settled2) return;
103998
104780
  settled2 = true;
103999
104781
  this.waiter = void 0;
104000
- resolve22(result2);
104782
+ resolve23(result2);
104001
104783
  };
104002
104784
  promise.then(
104003
104785
  (value) => settle3({ kind: "value", value }),
@@ -104389,8 +105171,8 @@ function sendFailure(error, sender) {
104389
105171
  };
104390
105172
  }
104391
105173
  function settle2(run3) {
104392
- return new Promise((resolve22) => {
104393
- resolve22(run3());
105174
+ return new Promise((resolve23) => {
105175
+ resolve23(run3());
104394
105176
  });
104395
105177
  }
104396
105178
  async function attemptOnce(spec, deadline) {
@@ -107790,7 +108572,7 @@ var require_call_credentials = __commonJS({
107790
108572
  if (isCurrentOauth2Client(googleCredentials)) {
107791
108573
  getHeaders = googleCredentials.getRequestHeaders(options.service_url);
107792
108574
  } else {
107793
- getHeaders = new Promise((resolve22, reject) => {
108575
+ getHeaders = new Promise((resolve23, reject) => {
107794
108576
  googleCredentials.getRequestMetadata(options.service_url, (err2, headers) => {
107795
108577
  if (err2) {
107796
108578
  reject(err2);
@@ -107800,7 +108582,7 @@ var require_call_credentials = __commonJS({
107800
108582
  reject(new Error("Headers not set by metadata plugin"));
107801
108583
  return;
107802
108584
  }
107803
- resolve22(headers);
108585
+ resolve23(headers);
107804
108586
  });
107805
108587
  });
107806
108588
  }
@@ -107853,10 +108635,10 @@ var require_call_credentials = __commonJS({
107853
108635
  this.metadataGenerator = metadataGenerator;
107854
108636
  }
107855
108637
  generateMetadata(options) {
107856
- return new Promise((resolve22, reject) => {
108638
+ return new Promise((resolve23, reject) => {
107857
108639
  this.metadataGenerator(options, (err2, metadata) => {
107858
108640
  if (metadata !== void 0) {
107859
- resolve22(metadata);
108641
+ resolve23(metadata);
107860
108642
  } else {
107861
108643
  reject(err2);
107862
108644
  }
@@ -108215,14 +108997,14 @@ var require_channel_credentials = __commonJS({
108215
108997
  }
108216
108998
  connect(socket) {
108217
108999
  const tlsConnectOptions = Object.assign({ socket }, this.connectionOptions);
108218
- return new Promise((resolve22, reject) => {
109000
+ return new Promise((resolve23, reject) => {
108219
109001
  const tlsSocket = (0, tls_1.connect)(tlsConnectOptions, () => {
108220
109002
  var _a2;
108221
109003
  if (((_a2 = this.connectionOptions.rejectUnauthorized) !== null && _a2 !== void 0 ? _a2 : true) && !tlsSocket.authorized) {
108222
109004
  reject(tlsSocket.authorizationError);
108223
109005
  return;
108224
109006
  }
108225
- resolve22({
109007
+ resolve23({
108226
109008
  socket: tlsSocket,
108227
109009
  secure: true
108228
109010
  });
@@ -108341,8 +109123,8 @@ var require_channel_credentials = __commonJS({
108341
109123
  if (this.hasReceivedUpdates()) {
108342
109124
  return Promise.resolve(this.getLatestSecureContext());
108343
109125
  } else {
108344
- return new Promise((resolve22) => {
108345
- this.secureContextWatchers.push(resolve22);
109126
+ return new Promise((resolve23) => {
109127
+ this.secureContextWatchers.push(resolve23);
108346
109128
  });
108347
109129
  }
108348
109130
  }
@@ -108375,7 +109157,7 @@ var require_channel_credentials = __commonJS({
108375
109157
  this.callCredentials = callCredentials;
108376
109158
  }
108377
109159
  connect(socket) {
108378
- return new Promise((resolve22, reject) => {
109160
+ return new Promise((resolve23, reject) => {
108379
109161
  const secureContext = this.parent.getLatestSecureContext();
108380
109162
  if (!secureContext) {
108381
109163
  reject(new Error("Failed to load credentials"));
@@ -108400,7 +109182,7 @@ var require_channel_credentials = __commonJS({
108400
109182
  reject(tlsSocket.authorizationError);
108401
109183
  return;
108402
109184
  }
108403
- resolve22({
109185
+ resolve23({
108404
109186
  socket: tlsSocket,
108405
109187
  secure: true
108406
109188
  });
@@ -115279,18 +116061,18 @@ var require_compression_filter = __commonJS({
115279
116061
  this.maxRecvMessageLength = maxRecvMessageLength;
115280
116062
  }
115281
116063
  compressMessage(message) {
115282
- return new Promise((resolve22, reject) => {
116064
+ return new Promise((resolve23, reject) => {
115283
116065
  zlib.deflate(message, (err2, output) => {
115284
116066
  if (err2) {
115285
116067
  reject(err2);
115286
116068
  } else {
115287
- resolve22(output);
116069
+ resolve23(output);
115288
116070
  }
115289
116071
  });
115290
116072
  });
115291
116073
  }
115292
116074
  decompressMessage(message) {
115293
- return new Promise((resolve22, reject) => {
116075
+ return new Promise((resolve23, reject) => {
115294
116076
  let totalLength = 0;
115295
116077
  const messageParts = [];
115296
116078
  const decompresser = zlib.createInflate();
@@ -115312,7 +116094,7 @@ var require_compression_filter = __commonJS({
115312
116094
  }
115313
116095
  });
115314
116096
  decompresser.on("end", () => {
115315
- resolve22(Buffer.concat(messageParts));
116097
+ resolve23(Buffer.concat(messageParts));
115316
116098
  });
115317
116099
  decompresser.write(message);
115318
116100
  decompresser.end();
@@ -115325,18 +116107,18 @@ var require_compression_filter = __commonJS({
115325
116107
  this.maxRecvMessageLength = maxRecvMessageLength;
115326
116108
  }
115327
116109
  compressMessage(message) {
115328
- return new Promise((resolve22, reject) => {
116110
+ return new Promise((resolve23, reject) => {
115329
116111
  zlib.gzip(message, (err2, output) => {
115330
116112
  if (err2) {
115331
116113
  reject(err2);
115332
116114
  } else {
115333
- resolve22(output);
116115
+ resolve23(output);
115334
116116
  }
115335
116117
  });
115336
116118
  });
115337
116119
  }
115338
116120
  decompressMessage(message) {
115339
- return new Promise((resolve22, reject) => {
116121
+ return new Promise((resolve23, reject) => {
115340
116122
  let totalLength = 0;
115341
116123
  const messageParts = [];
115342
116124
  const decompresser = zlib.createGunzip();
@@ -115358,7 +116140,7 @@ var require_compression_filter = __commonJS({
115358
116140
  }
115359
116141
  });
115360
116142
  decompresser.on("end", () => {
115361
- resolve22(Buffer.concat(messageParts));
116143
+ resolve23(Buffer.concat(messageParts));
115362
116144
  });
115363
116145
  decompresser.write(message);
115364
116146
  decompresser.end();
@@ -116713,7 +117495,7 @@ var require_http_proxy = __commonJS({
116713
117495
  options.headers = headers;
116714
117496
  const proxyAddressString = (0, subchannel_address_1.subchannelAddressToString)(address);
116715
117497
  trace("Using proxy " + proxyAddressString + " to connect to " + options.path);
116716
- return new Promise((resolve22, reject) => {
117498
+ return new Promise((resolve23, reject) => {
116717
117499
  const request3 = http2.request(options);
116718
117500
  request3.once("connect", (res, socket, head2) => {
116719
117501
  request3.removeAllListeners();
@@ -116724,7 +117506,7 @@ var require_http_proxy = __commonJS({
116724
117506
  socket.unshift(head2);
116725
117507
  }
116726
117508
  trace("Successfully established a plaintext connection to " + options.path + " through proxy " + proxyAddressString);
116727
- resolve22(socket);
117509
+ resolve23(socket);
116728
117510
  } else {
116729
117511
  (0, logging_1.log)(constants_1.LogVerbosity.ERROR, "Failed to connect to " + options.path + " through proxy " + proxyAddressString + " with status " + res.statusCode);
116730
117512
  reject();
@@ -117705,7 +118487,7 @@ var require_transport = __commonJS({
117705
118487
  if (secureConnectResult.socket.closed) {
117706
118488
  return Promise.reject("Connection closed before starting HTTP/2 handshake");
117707
118489
  }
117708
- return new Promise((resolve22, reject) => {
118490
+ return new Promise((resolve23, reject) => {
117709
118491
  var _a2, _b2, _c, _d, _e, _f, _g, _h;
117710
118492
  let remoteName = null;
117711
118493
  let realTarget2 = this.channelTarget;
@@ -117776,7 +118558,7 @@ var require_transport = __commonJS({
117776
118558
  session.removeAllListeners();
117777
118559
  secureConnectResult.socket.removeListener("close", closeHandler);
117778
118560
  secureConnectResult.socket.removeListener("error", errorHandler);
117779
- resolve22(new Http2Transport(session, address, options, remoteName));
118561
+ resolve23(new Http2Transport(session, address, options, remoteName));
117780
118562
  this.session = null;
117781
118563
  });
117782
118564
  session.once("close", closeHandler);
@@ -117790,7 +118572,7 @@ var require_transport = __commonJS({
117790
118572
  if (proxiedSocket) {
117791
118573
  return proxiedSocket;
117792
118574
  } else {
117793
- return new Promise((resolve22, reject) => {
118575
+ return new Promise((resolve23, reject) => {
117794
118576
  const closeCallback = () => {
117795
118577
  reject(new Error("Socket closed"));
117796
118578
  };
@@ -117800,7 +118582,7 @@ var require_transport = __commonJS({
117800
118582
  const socket = net.connect(address, () => {
117801
118583
  socket.removeListener("close", closeCallback);
117802
118584
  socket.removeListener("error", errorCallback);
117803
- resolve22(socket);
118585
+ resolve23(socket);
117804
118586
  });
117805
118587
  socket.once("close", closeCallback);
117806
118588
  socket.once("error", errorCallback);
@@ -121204,7 +121986,7 @@ var require_server_interceptors = __commonJS({
121204
121986
  } else {
121205
121987
  decompresser = zlib.createGunzip();
121206
121988
  }
121207
- return new Promise((resolve22, reject) => {
121989
+ return new Promise((resolve23, reject) => {
121208
121990
  let totalLength = 0;
121209
121991
  const messageParts = [];
121210
121992
  decompresser.on("error", (error) => {
@@ -121225,7 +122007,7 @@ var require_server_interceptors = __commonJS({
121225
122007
  }
121226
122008
  });
121227
122009
  decompresser.on("end", () => {
121228
- resolve22(Buffer.concat(messageParts));
122010
+ resolve23(Buffer.concat(messageParts));
121229
122011
  });
121230
122012
  decompresser.write(messageContents);
121231
122013
  decompresser.end();
@@ -121818,10 +122600,10 @@ var require_server = __commonJS({
121818
122600
  bindOneAddress(address, boundPortObject) {
121819
122601
  this.trace("Attempting to bind " + (0, subchannel_address_1.subchannelAddressToString)(address));
121820
122602
  const http2Server = this.createHttp2Server(boundPortObject.credentials);
121821
- return new Promise((resolve22, reject) => {
122603
+ return new Promise((resolve23, reject) => {
121822
122604
  const onError = (err2) => {
121823
122605
  this.trace("Failed to bind " + (0, subchannel_address_1.subchannelAddressToString)(address) + " with error " + err2.message);
121824
- resolve22({
122606
+ resolve23({
121825
122607
  port: "port" in address ? address.port : 1,
121826
122608
  error: err2.message
121827
122609
  });
@@ -121849,7 +122631,7 @@ var require_server = __commonJS({
121849
122631
  });
121850
122632
  boundPortObject.listeningServers.add(http2Server);
121851
122633
  this.trace("Successfully bound " + (0, subchannel_address_1.subchannelAddressToString)(boundSubchannelAddress));
121852
- resolve22({
122634
+ resolve23({
121853
122635
  port: "port" in boundSubchannelAddress ? boundSubchannelAddress.port : 1
121854
122636
  });
121855
122637
  http2Server.removeListener("error", onError);
@@ -121902,7 +122684,7 @@ var require_server = __commonJS({
121902
122684
  }
121903
122685
  }
121904
122686
  resolvePort(port) {
121905
- return new Promise((resolve22, reject) => {
122687
+ return new Promise((resolve23, reject) => {
121906
122688
  let seenResolution = false;
121907
122689
  const resolverListener = (endpointList, attributes, serviceConfig, resolutionNote) => {
121908
122690
  if (seenResolution) {
@@ -121918,7 +122700,7 @@ var require_server = __commonJS({
121918
122700
  reject(new Error(`No addresses resolved for port ${port}`));
121919
122701
  return true;
121920
122702
  }
121921
- resolve22(addressList);
122703
+ resolve23(addressList);
121922
122704
  return true;
121923
122705
  };
121924
122706
  const resolver = (0, resolver_1.createResolver)(port, resolverListener, this.options);
@@ -125925,13 +126707,13 @@ var init_env = __esm({
125925
126707
  // Row-Level Security enforcement gate. Fail-CLOSED in production:
125926
126708
  // when unset, this defaults ON in any production runtime (NODE_ENV or
125927
126709
  // VERCEL_ENV = "production") and OFF everywhere else (dev/test/preview seeding
125928
- // window). withTenantDb always sets the scope GUCs; when this resolves false
125929
- // it additionally sets app.rls_bypass='on' so the bypass-aware policies do not
125930
- // yet filter (isolation still enforced by the manual eq(orgId) predicates kept
125931
- // in every query). An operator can still force it OFF in production with an
126710
+ // window). It no longer changes what the policies filter: no policy reads
126711
+ // app.rls_bypass, and withTenantDb sets the scope GUCs either way
126712
+ // (ADR-5879). When true, assertRlsConnectionSafe refuses to start on a
126713
+ // connection role that is a superuser, has BYPASSRLS, or inherits
126714
+ // oxagen_system. An operator can still force it OFF in production with an
125932
126715
  // explicit "false", but the startup guard (assertRlsEnforcedInProduction)
125933
- // refuses to boot in that state — a production process may not run unscoped.
125934
- // Reversible via env (no migration needed).
126716
+ // refuses to boot in that state.
125935
126717
  TENANT_RLS_ENFORCEMENT_ENABLED: external_exports.union([external_exports.literal("true"), external_exports.literal("false")]).optional().transform((v) => v === void 0 ? isProductionRuntime() : v === "true"),
125936
126718
  // ── Billing / usage-meter tuning (see @oxagen/billing pricing.ts) ──
125937
126719
  // Target *blended* gross margin across all products, in (0,1). When set,
@@ -126495,7 +127277,7 @@ function withServers(entry2, outcome) {
126495
127277
  };
126496
127278
  }
126497
127279
  function nextTurn() {
126498
- return new Promise((resolve22) => setImmediate(resolve22));
127280
+ return new Promise((resolve23) => setImmediate(resolve23));
126499
127281
  }
126500
127282
  async function runChecksWithServers(input, options = {}) {
126501
127283
  const done = [];
@@ -127862,7 +128644,7 @@ import {
127862
128644
  readlinkSync as readlinkSync4,
127863
128645
  statSync as statSync13
127864
128646
  } from "node:fs";
127865
- import { dirname as dirname31, isAbsolute as isAbsolute14, join as join55, relative as relative8, resolve as resolve21, sep as sep10 } from "node:path";
128647
+ import { dirname as dirname31, isAbsolute as isAbsolute15, join as join56, relative as relative9, resolve as resolve22, sep as sep11 } from "node:path";
127866
128648
  function git5(cwd, args, input) {
127867
128649
  try {
127868
128650
  return execFileSync2("git", args, {
@@ -127894,7 +128676,7 @@ function commitOf2(root, ref2) {
127894
128676
  return sha2.length > 0 ? sha2 : null;
127895
128677
  }
127896
128678
  function readWorkingFile(root, path2) {
127897
- const abs = join55(root, ...path2.split("/"));
128679
+ const abs = join56(root, ...path2.split("/"));
127898
128680
  try {
127899
128681
  const stat7 = lstatSync11(abs);
127900
128682
  if (stat7.isSymbolicLink()) return readlinkSync4(abs, "utf8");
@@ -127986,9 +128768,9 @@ function isDir(path2) {
127986
128768
  }
127987
128769
  }
127988
128770
  function findSteeringRoot(start) {
127989
- let dir = resolve21(start);
128771
+ let dir = resolve22(start);
127990
128772
  for (; ; ) {
127991
- if (isFile(join55(dir, WORKSPACE_TOML_PATH)) || isFile(join55(dir, AGENTS_MD_PATH)) && isDir(join55(dir, STEERING_DIR))) {
128773
+ if (isFile(join56(dir, WORKSPACE_TOML_PATH)) || isFile(join56(dir, AGENTS_MD_PATH)) && isDir(join56(dir, STEERING_DIR))) {
127992
128774
  return dir;
127993
128775
  }
127994
128776
  const parent = dirname31(dir);
@@ -128002,11 +128784,11 @@ function within3(path2, scope) {
128002
128784
  function scopesFor(root, cwd, paths, trees) {
128003
128785
  const scopes = [];
128004
128786
  for (const path2 of paths) {
128005
- const rel = relative8(root, resolve21(cwd, path2));
128006
- if (rel === ".." || rel.startsWith(`..${sep10}`) || isAbsolute14(rel)) {
128787
+ const rel = relative9(root, resolve22(cwd, path2));
128788
+ if (rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute15(rel)) {
128007
128789
  return { error: `${path2} is outside the steering repo at ${root}.` };
128008
128790
  }
128009
- const scope = rel.split(sep10).join("/");
128791
+ const scope = rel.split(sep11).join("/");
128010
128792
  const known = trees.some(
128011
128793
  (tree) => tree !== null && [...tree.keys()].some((file) => within3(file, scope))
128012
128794
  );
@@ -128068,7 +128850,7 @@ function cacheFile(cacheDir, root) {
128068
128850
  key: token === void 0 ? null : createHash20("sha256").update(token).digest("hex").slice(0, 16)
128069
128851
  };
128070
128852
  const key = createHash20("sha256").update(JSON.stringify([root, identity])).digest("hex").slice(0, 32);
128071
- return join55(cacheDir, `${key}.json`);
128853
+ return join56(cacheDir, `${key}.json`);
128072
128854
  }
128073
128855
  function readCache(file, now) {
128074
128856
  let entry2;
@@ -128182,7 +128964,7 @@ function defaultDeps2() {
128182
128964
  return {
128183
128965
  fetchPublished: fetchSteeringIndex,
128184
128966
  cedar: cedarHooks,
128185
- cacheDir: join55(getConfigDir(), "cache", "steering-check"),
128967
+ cacheDir: join56(getConfigDir(), "cache", "steering-check"),
128186
128968
  now: () => Date.now()
128187
128969
  };
128188
128970
  }
@@ -129880,7 +130662,13 @@ var init_revision = __esm({
129880
130662
  /** Each repo's exact revision, by `owner/name`. */
129881
130663
  repoRevisions: external_exports.record(external_exports.string().min(1), revisionIdSchema).refine((r) => Object.keys(r).length > 0, "lists no repo revision"),
129882
130664
  /** The ID of the cross-repo link file built from those revisions. */
129883
- crossRepoFile: digestSchema2
130665
+ crossRepoFile: digestSchema2,
130666
+ /**
130667
+ * The ID of the nodes a linker recheck put back in the review queue, when
130668
+ * there are any. The specs file reads them, so a change makes a new
130669
+ * revision (ADR-371). Left out when there are none.
130670
+ */
130671
+ recheckMismatches: digestSchema2.optional()
129884
130672
  }).strict();
129885
130673
  }
129886
130674
  });
@@ -130259,10 +131047,17 @@ var init_calls = __esm({
130259
131047
  status: requirementStatusSchema,
130260
131048
  reason: external_exports.string().min(1).optional(),
130261
131049
  code: external_exports.array(graphItemSchema),
131050
+ // Each test that proves the requirement, with the result CI
131051
+ // reported for the commit of its repo's revision. `none` means no
131052
+ // report at that commit. `provenance` says whether a citation
131053
+ // (`declared`) or a linker agent (`agent`) gave the VERIFIES edge.
130262
131054
  tests: external_exports.array(
130263
131055
  testRefSchema.extend({
131056
+ repo: external_exports.string().min(1).optional(),
131057
+ provenance: provenanceKindSchema.optional(),
130264
131058
  lastResult: external_exports.enum(TEST_RESULTS),
130265
- commit: external_exports.string().min(7).optional()
131059
+ commit: external_exports.string().min(7).optional(),
131060
+ lastPassedCommit: external_exports.string().min(7).optional()
130266
131061
  }).strict()
130267
131062
  )
130268
131063
  }).strict()
@@ -132052,23 +132847,23 @@ var init_src9 = __esm({
132052
132847
 
132053
132848
  // src/commands/codegraph-upload/files.ts
132054
132849
  import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
132055
- import { join as join56, relative as relative9, sep as sep11 } from "node:path";
132850
+ import { join as join57, relative as relative10, sep as sep12 } from "node:path";
132056
132851
  function hasGlobChars(pattern) {
132057
132852
  return /[*?[\]{}]/.test(pattern);
132058
132853
  }
132059
132854
  function normalize2(path2) {
132060
132855
  const trimmed = path2.replace(/^\.\//, "");
132061
- return sep11 === "/" ? trimmed : trimmed.split(sep11).join("/");
132856
+ return sep12 === "/" ? trimmed : trimmed.split(sep12).join("/");
132062
132857
  }
132063
132858
  async function walk(root, dir, out) {
132064
132859
  const entries2 = await readdir5(dir, { withFileTypes: true });
132065
132860
  for (const entry2 of entries2) {
132066
132861
  if (entry2.isSymbolicLink()) continue;
132067
- const full = join56(dir, entry2.name);
132862
+ const full = join57(dir, entry2.name);
132068
132863
  if (entry2.isDirectory()) {
132069
132864
  if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
132070
132865
  } else if (entry2.isFile()) {
132071
- out.push(normalize2(relative9(root, full)));
132866
+ out.push(normalize2(relative10(root, full)));
132072
132867
  }
132073
132868
  }
132074
132869
  }
@@ -132076,7 +132871,7 @@ async function expandPattern(root, pattern) {
132076
132871
  const wanted = normalize2(pattern.trim());
132077
132872
  if (!hasGlobChars(wanted)) {
132078
132873
  try {
132079
- const info = await stat5(join56(root, wanted));
132874
+ const info = await stat5(join57(root, wanted));
132080
132875
  return info.isFile() ? [wanted] : [];
132081
132876
  } catch {
132082
132877
  return [];
@@ -132227,7 +133022,7 @@ var init_token = __esm({
132227
133022
  });
132228
133023
 
132229
133024
  // src/commands/codegraph-upload/run.ts
132230
- import { join as join57 } from "node:path";
133025
+ import { join as join58 } from "node:path";
132231
133026
  function addDropped(into, more) {
132232
133027
  into.sensitiveValues += more.sensitiveValues;
132233
133028
  into.secretData += more.secretData;
@@ -132245,7 +133040,7 @@ async function uploadOne(deps, config, token, group, path2, totals2) {
132245
133040
  const label2 = `${group.kind}/${group.source} ${path2}`;
132246
133041
  let bytes;
132247
133042
  try {
132248
- bytes = await deps.readFile(join57(deps.cwd, path2));
133043
+ bytes = await deps.readFile(join58(deps.cwd, path2));
132249
133044
  } catch (error) {
132250
133045
  totals2.failed += 1;
132251
133046
  deps.log(`error: ${label2}: cannot read the file: ${error.message}`);
@@ -132523,7 +133318,7 @@ Following ${file} (Ctrl-C to stop)\u2026
132523
133318
  draining = false;
132524
133319
  }
132525
133320
  };
132526
- await new Promise((resolve22) => {
133321
+ await new Promise((resolve23) => {
132527
133322
  let watcher = null;
132528
133323
  try {
132529
133324
  watcher = watch(file, { persistent: true }, () => void drain());
@@ -132532,12 +133327,12 @@ Following ${file} (Ctrl-C to stop)\u2026
132532
133327
  `Cannot follow ${file}: ${err2 instanceof Error ? err2.message : String(err2)}
132533
133328
  `
132534
133329
  );
132535
- resolve22();
133330
+ resolve23();
132536
133331
  return;
132537
133332
  }
132538
133333
  const stop = () => {
132539
133334
  watcher?.close();
132540
- resolve22();
133335
+ resolve23();
132541
133336
  };
132542
133337
  process.on("SIGINT", stop);
132543
133338
  process.on("SIGTERM", stop);
@@ -132874,7 +133669,7 @@ async function browserLogin({
132874
133669
  server.keepAliveTimeout = 1e3;
132875
133670
  server.headersTimeout = 5e3;
132876
133671
  server.requestTimeout = 15e3;
132877
- const port = await new Promise((resolve22, reject) => {
133672
+ const port = await new Promise((resolve23, reject) => {
132878
133673
  server.once("error", reject);
132879
133674
  server.listen(0, "127.0.0.1", () => {
132880
133675
  const addr = server.address();
@@ -132884,7 +133679,7 @@ async function browserLogin({
132884
133679
  );
132885
133680
  return;
132886
133681
  }
132887
- resolve22(addr.port);
133682
+ resolve23(addr.port);
132888
133683
  });
132889
133684
  });
132890
133685
  const redirectUri = `http://127.0.0.1:${port}/callback`;
@@ -132904,7 +133699,7 @@ async function browserLogin({
132904
133699
  ${authorizeUrl}`);
132905
133700
  openBrowser(authorizeUrl);
132906
133701
  return new Promise(
132907
- (resolve22, reject) => {
133702
+ (resolve23, reject) => {
132908
133703
  let settled2 = false;
132909
133704
  const exchangeAbort = new AbortController();
132910
133705
  const shutdown = () => {
@@ -133037,7 +133832,7 @@ async function browserLogin({
133037
133832
  }
133038
133833
  const data = asTokenExchangeResponse(await exchangeRes.json());
133039
133834
  await sendRedirect(cliLoginCompleteUrl(appUrl));
133040
- closeAndSettle(() => resolve22(data));
133835
+ closeAndSettle(() => resolve23(data));
133041
133836
  } catch (err2) {
133042
133837
  const msg = err2 instanceof Error ? err2.message : String(err2);
133043
133838
  try {