@guilz-dev/belay 0.9.4 → 0.10.0

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 (49) hide show
  1. package/README.md +3 -2
  2. package/dist/adapters/cursor/hook-dispatch-entry.d.ts +3 -0
  3. package/dist/adapters/cursor/hook-dispatch-entry.js +11 -0
  4. package/dist/adapters/cursor/hook-router.js +14 -7
  5. package/dist/adapters/cursor/hooks.d.ts +1 -1
  6. package/dist/adapters/cursor/hooks.js +16 -5
  7. package/dist/adapters/cursor/routing-config-trust.d.ts +1 -0
  8. package/dist/adapters/cursor/routing-config-trust.js +67 -0
  9. package/dist/adapters/cursor/runtime-entry.d.ts +2 -2
  10. package/dist/adapters/cursor/runtime-entry.js +35 -10
  11. package/dist/adapters/shared/gate-runtime.js +28 -17
  12. package/dist/bundle/claude-runtime.mjs +602 -438
  13. package/dist/bundle/codex-runtime.mjs +612 -448
  14. package/dist/bundle/cursor-dispatcher.mjs +100 -26
  15. package/dist/bundle/cursor-runtime.mjs +662 -470
  16. package/dist/cli.js +53 -4
  17. package/dist/commands/approval-token.d.ts +10 -0
  18. package/dist/commands/approval-token.js +26 -0
  19. package/dist/commands/audit.d.ts +2 -1
  20. package/dist/commands/audit.js +2 -2
  21. package/dist/commands/config.d.ts +1 -1
  22. package/dist/commands/config.js +28 -2
  23. package/dist/commands/doctor.js +10 -54
  24. package/dist/commands/dogfood-check.d.ts +3 -0
  25. package/dist/commands/dogfood-check.js +116 -0
  26. package/dist/commands/dogfood.d.ts +1 -0
  27. package/dist/commands/dogfood.js +4 -3
  28. package/dist/commands/judge.js +2 -2
  29. package/dist/commands/recovery-checkpoints.js +2 -11
  30. package/dist/config-io.d.ts +1 -0
  31. package/dist/config-io.js +8 -1
  32. package/dist/core/dogfood-environment.d.ts +8 -0
  33. package/dist/core/dogfood-environment.js +55 -0
  34. package/dist/core/effect-ir/shell-lower/decoders/belay.js +12 -0
  35. package/dist/core/egress-approval.js +0 -18
  36. package/dist/core/notify.d.ts +8 -2
  37. package/dist/core/notify.js +63 -7
  38. package/dist/core/recovery/operator-guidance.js +4 -4
  39. package/dist/core/repo-config-trust.d.ts +31 -0
  40. package/dist/core/repo-config-trust.js +152 -0
  41. package/dist/corpus/benign-probe-cores.d.ts +1 -1
  42. package/dist/corpus/benign-probe-cores.js +0 -1
  43. package/dist/defaults.js +0 -25
  44. package/dist/installer/scope-config.js +2 -2
  45. package/dist/installer.js +4 -4
  46. package/dist/types.d.ts +19 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +5 -1
@@ -3510,9 +3510,122 @@ var init_config_layers = __esm({
3510
3510
  }
3511
3511
  });
3512
3512
 
3513
- // src/config-io.ts
3513
+ // src/core/repo-config-trust.ts
3514
3514
  import { existsSync as existsSync3 } from "node:fs";
3515
- import { chmod, mkdir as mkdir2, open as open2, readFile as readFile2, rename, unlink as unlink2, writeFile } from "node:fs/promises";
3515
+ import { chmod, mkdir as mkdir2, open as open2, readFile as readFile2, rename, unlink as unlink2 } from "node:fs/promises";
3516
+ import path12 from "node:path";
3517
+ function isObjectRecord(value) {
3518
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3519
+ }
3520
+ function hasOnlyExpectedKeys(value) {
3521
+ const expected = /* @__PURE__ */ new Set([
3522
+ "schemaVersion",
3523
+ "repoRoot",
3524
+ "adapter",
3525
+ "repoConfigFingerprint",
3526
+ "trustedAt"
3527
+ ]);
3528
+ const keys = Object.keys(value);
3529
+ if (keys.length !== expected.size) {
3530
+ return false;
3531
+ }
3532
+ return keys.every((key) => expected.has(key));
3533
+ }
3534
+ function isAdapterName(value) {
3535
+ return value === "cursor" || value === "claude" || value === "codex";
3536
+ }
3537
+ function isIsoTimestamp(value) {
3538
+ return Number.isFinite(Date.parse(value));
3539
+ }
3540
+ function parseStrictTrustRecord(value) {
3541
+ if (!isObjectRecord(value) || !hasOnlyExpectedKeys(value)) {
3542
+ return null;
3543
+ }
3544
+ if (value.schemaVersion !== 1) {
3545
+ return null;
3546
+ }
3547
+ if (typeof value.repoRoot !== "string" || value.repoRoot.trim().length === 0) {
3548
+ return null;
3549
+ }
3550
+ if (!isAdapterName(value.adapter)) {
3551
+ return null;
3552
+ }
3553
+ if (typeof value.repoConfigFingerprint !== "string" || !/^[a-f0-9]{64}$/.test(value.repoConfigFingerprint)) {
3554
+ return null;
3555
+ }
3556
+ if (typeof value.trustedAt !== "string" || !isIsoTimestamp(value.trustedAt)) {
3557
+ return null;
3558
+ }
3559
+ return {
3560
+ schemaVersion: 1,
3561
+ repoRoot: value.repoRoot,
3562
+ adapter: value.adapter,
3563
+ repoConfigFingerprint: value.repoConfigFingerprint,
3564
+ trustedAt: value.trustedAt
3565
+ };
3566
+ }
3567
+ function repoConfigFingerprint(rawConfig) {
3568
+ return hashValue(canonicalStringify(rawConfig));
3569
+ }
3570
+ function repoConfigTrustPath(repoRoot, adapter) {
3571
+ const canonicalRepoRoot = canonicalPath(repoRoot);
3572
+ const identity = hashValue(`${canonicalRepoRoot}\0${adapter}`);
3573
+ return path12.join(defaultControlPlaneDir(), "config-trust", `${identity}.json`);
3574
+ }
3575
+ async function inspectRepoConfigTrust(repoRoot, adapter, rawConfig) {
3576
+ const canonicalRepoRoot = canonicalPath(repoRoot);
3577
+ const recordPath = repoConfigTrustPath(repoRoot, adapter);
3578
+ if (!existsSync3(recordPath)) {
3579
+ return { trusted: false, recordPath, reason: "missing" };
3580
+ }
3581
+ let parsed;
3582
+ try {
3583
+ parsed = JSON.parse(await readFile2(recordPath, "utf8"));
3584
+ } catch {
3585
+ return { trusted: false, recordPath, reason: "malformed" };
3586
+ }
3587
+ const record = parseStrictTrustRecord(parsed);
3588
+ if (!record) {
3589
+ return { trusted: false, recordPath, reason: "malformed" };
3590
+ }
3591
+ if (record.adapter !== adapter || canonicalPath(record.repoRoot) !== canonicalRepoRoot) {
3592
+ return { trusted: false, recordPath, reason: "identity_mismatch" };
3593
+ }
3594
+ const fingerprint = repoConfigFingerprint(rawConfig);
3595
+ if (record.repoConfigFingerprint !== fingerprint) {
3596
+ return { trusted: false, recordPath, reason: "fingerprint_mismatch" };
3597
+ }
3598
+ return { trusted: true, recordPath, fingerprint };
3599
+ }
3600
+ async function assertRepoConfigTrusted(repoRoot, adapter, rawConfig) {
3601
+ const status = await inspectRepoConfigTrust(repoRoot, adapter, rawConfig);
3602
+ if (status.trusted) {
3603
+ return;
3604
+ }
3605
+ throw new RepoConfigTrustError(status);
3606
+ }
3607
+ var TRUST_MESSAGE, RepoConfigTrustError;
3608
+ var init_repo_config_trust = __esm({
3609
+ "src/core/repo-config-trust.ts"() {
3610
+ "use strict";
3611
+ init_config();
3612
+ init_fingerprint2();
3613
+ init_path_utils();
3614
+ TRUST_MESSAGE = "Repository config is not trusted. Review it, then run `belay config trust`.";
3615
+ RepoConfigTrustError = class extends Error {
3616
+ status;
3617
+ constructor(status) {
3618
+ super(TRUST_MESSAGE);
3619
+ this.name = "RepoConfigTrustError";
3620
+ this.status = status;
3621
+ }
3622
+ };
3623
+ }
3624
+ });
3625
+
3626
+ // src/config-io.ts
3627
+ import { existsSync as existsSync4 } from "node:fs";
3628
+ import { chmod as chmod2, mkdir as mkdir3, open as open3, readFile as readFile3, rename as rename2, unlink as unlink3, writeFile } from "node:fs/promises";
3516
3629
  function resolveAdapterName(config) {
3517
3630
  if (config.adapter === "claude") {
3518
3631
  return "claude";
@@ -3523,10 +3636,10 @@ function resolveAdapterName(config) {
3523
3636
  return "cursor";
3524
3637
  }
3525
3638
  function detectAdapterName(repoRoot) {
3526
- if (existsSync3(configPathFor(repoRoot, "claude"))) {
3639
+ if (existsSync4(configPathFor(repoRoot, "claude"))) {
3527
3640
  return "claude";
3528
3641
  }
3529
- if (existsSync3(configPathFor(repoRoot, "codex"))) {
3642
+ if (existsSync4(configPathFor(repoRoot, "codex"))) {
3530
3643
  return "codex";
3531
3644
  }
3532
3645
  return "cursor";
@@ -3541,20 +3654,20 @@ async function loadLayeredConfig(repoRoot, adapter = detectAdapterName(repoRoot)
3541
3654
  const layout = getAdapterLayout(adapter);
3542
3655
  const configPath = configPathFor(repoRoot, adapter);
3543
3656
  let repoConfig = {};
3544
- if (existsSync3(configPath)) {
3545
- repoConfig = JSON.parse(await readFile2(configPath, "utf8"));
3657
+ if (existsSync4(configPath)) {
3658
+ repoConfig = JSON.parse(await readFile3(configPath, "utf8"));
3546
3659
  }
3547
3660
  let teamConfig = null;
3548
3661
  const teamPath = teamConfigPath();
3549
- if (existsSync3(teamPath)) {
3550
- teamConfig = JSON.parse(await readFile2(teamPath, "utf8"));
3662
+ if (existsSync4(teamPath)) {
3663
+ teamConfig = JSON.parse(await readFile3(teamPath, "utf8"));
3551
3664
  }
3552
3665
  return resolveLayeredConfig({
3553
3666
  repoConfig,
3554
3667
  adapterDefaults: layout.defaultConfig(repoRoot),
3555
3668
  teamConfig,
3556
3669
  teamConfigPath: teamPath,
3557
- repoConfigPath: existsSync3(configPath) ? configPath : void 0
3670
+ repoConfigPath: existsSync4(configPath) ? configPath : void 0
3558
3671
  });
3559
3672
  }
3560
3673
  async function loadConfigFile(repoRoot, adapter = detectAdapterName(repoRoot)) {
@@ -3569,6 +3682,7 @@ var init_config_io = __esm({
3569
3682
  init_approval_state_mutation();
3570
3683
  init_config();
3571
3684
  init_config_layers();
3685
+ init_repo_config_trust();
3572
3686
  }
3573
3687
  });
3574
3688
 
@@ -4230,9 +4344,9 @@ init_claude();
4230
4344
  init_approval();
4231
4345
  init_approval_replay();
4232
4346
  import { randomUUID as randomUUID6 } from "node:crypto";
4233
- import { existsSync as existsSync16 } from "node:fs";
4234
- import { mkdir as mkdir14, readFile as readFile15, writeFile as writeFile11 } from "node:fs/promises";
4235
- import path61 from "node:path";
4347
+ import { existsSync as existsSync17 } from "node:fs";
4348
+ import { mkdir as mkdir15, readFile as readFile16, writeFile as writeFile11 } from "node:fs/promises";
4349
+ import path63 from "node:path";
4236
4350
 
4237
4351
  // src/core/approval-service.ts
4238
4352
  init_config_io();
@@ -4242,47 +4356,35 @@ init_approval_replay();
4242
4356
  // src/core/approval-token.ts
4243
4357
  init_config();
4244
4358
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
4245
- import { existsSync as existsSync4 } from "node:fs";
4246
- import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
4247
- import path12 from "node:path";
4248
- function base64UrlEncode(value) {
4249
- return Buffer.from(value, "utf8").toString("base64url");
4250
- }
4359
+ import { existsSync as existsSync5 } from "node:fs";
4360
+ import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
4361
+ import path13 from "node:path";
4251
4362
  function base64UrlDecode(value) {
4252
4363
  return Buffer.from(value, "base64url").toString("utf8");
4253
4364
  }
4254
4365
  function approvalSigningKeyPath(controlPlaneDir = defaultControlPlaneDir()) {
4255
- return path12.join(controlPlaneDir, "approval-signing.key");
4366
+ return path13.join(controlPlaneDir, "approval-signing.key");
4256
4367
  }
4257
4368
  async function loadOrCreateApprovalSigningKey(controlPlaneDir = defaultControlPlaneDir()) {
4258
4369
  const keyPath = approvalSigningKeyPath(controlPlaneDir);
4259
- if (existsSync4(keyPath)) {
4260
- return readFile3(keyPath);
4370
+ if (existsSync5(keyPath)) {
4371
+ return readFile4(keyPath);
4261
4372
  }
4262
- await mkdir3(controlPlaneDir, { recursive: true });
4373
+ await mkdir4(controlPlaneDir, { recursive: true });
4263
4374
  const key = randomBytes(32);
4264
4375
  await writeFile2(keyPath, key, { mode: 384 });
4265
4376
  return key;
4266
4377
  }
4267
- function signPayload(payload, key) {
4268
- const body = base64UrlEncode(JSON.stringify(payload));
4269
- const signature = createHmac("sha256", key).update(body).digest("base64url");
4270
- return `${body}.${signature}`;
4271
- }
4272
- async function issueApprovalToken(payload, controlPlaneDir = defaultControlPlaneDir()) {
4273
- const key = await loadOrCreateApprovalSigningKey(controlPlaneDir);
4274
- return signPayload(payload, key);
4275
- }
4276
4378
  async function verifyApprovalToken(token, controlPlaneDir = defaultControlPlaneDir()) {
4277
4379
  const [body, signature] = token.split(".");
4278
4380
  if (!body || !signature) {
4279
4381
  return null;
4280
4382
  }
4281
4383
  const keyPath = approvalSigningKeyPath(controlPlaneDir);
4282
- if (!existsSync4(keyPath)) {
4384
+ if (!existsSync5(keyPath)) {
4283
4385
  return null;
4284
4386
  }
4285
- const key = await readFile3(keyPath);
4387
+ const key = await readFile4(keyPath);
4286
4388
  const expected = createHmac("sha256", key).update(body).digest("base64url");
4287
4389
  const actualBuffer = Buffer.from(signature);
4288
4390
  const expectedBuffer = Buffer.from(expected);
@@ -4489,11 +4591,11 @@ init_approval_v3();
4489
4591
 
4490
4592
  // src/core/capability/boundary-attestation-sign.ts
4491
4593
  import { createHmac as createHmac2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
4492
- import { access, readFile as readFile4 } from "node:fs/promises";
4594
+ import { access, readFile as readFile5 } from "node:fs/promises";
4493
4595
  init_fingerprint2();
4494
4596
 
4495
4597
  // src/core/capability/attestation.ts
4496
- import path13 from "node:path";
4598
+ import path14 from "node:path";
4497
4599
  var BOUNDARY_ATTESTATION_VERSION = 1;
4498
4600
  var CONTAINED_EXECUTION_ATTESTATION_VERSION = 1;
4499
4601
  var KNOWN_DRIVERS = /* @__PURE__ */ new Set([
@@ -4561,7 +4663,7 @@ function validateContainedExecutionAttestation(value) {
4561
4663
  const record = value;
4562
4664
  const dockerSubstrate = record.dockerSubstrate;
4563
4665
  const dockerConfiguration = record.dockerConfiguration;
4564
- if (record.version !== CONTAINED_EXECUTION_ATTESTATION_VERSION || typeof record.imageId !== "string" || !/^sha256:[a-f0-9]{64}$/i.test(record.imageId) || typeof record.imageReference !== "string" || !record.imageReference || /[\0\n\r]/.test(record.imageReference) || record.networkNone !== true || record.isolatesWorkspaceMirror !== true || record.readOnlyRoot !== true || record.sanitizedEnvironment !== true || !isRecord(dockerSubstrate) || typeof dockerSubstrate.binaryPath !== "string" || !path13.isAbsolute(dockerSubstrate.binaryPath) || /[\0\n\r]/.test(dockerSubstrate.binaryPath) || typeof dockerSubstrate.binarySha256 !== "string" || !/^[a-f0-9]{64}$/.test(dockerSubstrate.binarySha256) || typeof dockerSubstrate.endpoint !== "string" || !dockerSubstrate.endpoint.startsWith("unix:///") || !path13.isAbsolute(dockerSubstrate.endpoint.slice("unix://".length)) || /[\0\n\r]/.test(dockerSubstrate.endpoint) || typeof dockerSubstrate.daemonId !== "string" || !dockerSubstrate.daemonId || /[\0\n\r]/.test(dockerSubstrate.daemonId) || !isRecord(dockerConfiguration) || typeof dockerConfiguration.executable !== "string" || !path13.isAbsolute(dockerConfiguration.executable) || /[\0\n\r]/.test(dockerConfiguration.executable) || typeof dockerConfiguration.host !== "string" || !dockerConfiguration.host.startsWith("unix:///") || !path13.isAbsolute(dockerConfiguration.host.slice("unix://".length)) || /[\0\n\r]/.test(dockerConfiguration.host) || typeof record.user !== "string" || !/^\d+:\d+$/.test(record.user) || record.entrypoint !== "/bin/sh" || record.capDropAll !== true || record.noNewPrivileges !== true || record.logDriver !== "none" || record.proxyEnvironment !== "neutralized-empty" || typeof record.probedAt !== "string" || typeof record.expiresAt !== "string") {
4666
+ if (record.version !== CONTAINED_EXECUTION_ATTESTATION_VERSION || typeof record.imageId !== "string" || !/^sha256:[a-f0-9]{64}$/i.test(record.imageId) || typeof record.imageReference !== "string" || !record.imageReference || /[\0\n\r]/.test(record.imageReference) || record.networkNone !== true || record.isolatesWorkspaceMirror !== true || record.readOnlyRoot !== true || record.sanitizedEnvironment !== true || !isRecord(dockerSubstrate) || typeof dockerSubstrate.binaryPath !== "string" || !path14.isAbsolute(dockerSubstrate.binaryPath) || /[\0\n\r]/.test(dockerSubstrate.binaryPath) || typeof dockerSubstrate.binarySha256 !== "string" || !/^[a-f0-9]{64}$/.test(dockerSubstrate.binarySha256) || typeof dockerSubstrate.endpoint !== "string" || !dockerSubstrate.endpoint.startsWith("unix:///") || !path14.isAbsolute(dockerSubstrate.endpoint.slice("unix://".length)) || /[\0\n\r]/.test(dockerSubstrate.endpoint) || typeof dockerSubstrate.daemonId !== "string" || !dockerSubstrate.daemonId || /[\0\n\r]/.test(dockerSubstrate.daemonId) || !isRecord(dockerConfiguration) || typeof dockerConfiguration.executable !== "string" || !path14.isAbsolute(dockerConfiguration.executable) || /[\0\n\r]/.test(dockerConfiguration.executable) || typeof dockerConfiguration.host !== "string" || !dockerConfiguration.host.startsWith("unix:///") || !path14.isAbsolute(dockerConfiguration.host.slice("unix://".length)) || /[\0\n\r]/.test(dockerConfiguration.host) || typeof record.user !== "string" || !/^\d+:\d+$/.test(record.user) || record.entrypoint !== "/bin/sh" || record.capDropAll !== true || record.noNewPrivileges !== true || record.logDriver !== "none" || record.proxyEnvironment !== "neutralized-empty" || typeof record.probedAt !== "string" || typeof record.expiresAt !== "string") {
4565
4667
  return false;
4566
4668
  }
4567
4669
  const probedAt = Date.parse(record.probedAt);
@@ -4631,7 +4733,7 @@ async function verifySignedBoundaryAttestation(params) {
4631
4733
  return record.attestation;
4632
4734
  }
4633
4735
  async function readSignedAttestationFile(filePath) {
4634
- return JSON.parse(await readFile4(filePath, "utf8"));
4736
+ return JSON.parse(await readFile5(filePath, "utf8"));
4635
4737
  }
4636
4738
 
4637
4739
  // src/core/capability/boundary-egress.ts
@@ -4800,13 +4902,13 @@ async function runWithBoundaryRunnable(target, params) {
4800
4902
  }
4801
4903
 
4802
4904
  // src/core/capability/boundary-session.ts
4803
- import path24 from "node:path";
4905
+ import path25 from "node:path";
4804
4906
 
4805
4907
  // src/services/egress-service.ts
4806
- import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
4807
- import { mkdir as mkdir4, readFile as readFile5, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
4908
+ import { existsSync as existsSync6, readFileSync as readFileSync2 } from "node:fs";
4909
+ import { mkdir as mkdir5, readFile as readFile6, unlink as unlink4, writeFile as writeFile3 } from "node:fs/promises";
4808
4910
  import net from "node:net";
4809
- import path14 from "node:path";
4911
+ import path15 from "node:path";
4810
4912
  init_config_io();
4811
4913
  init_config();
4812
4914
 
@@ -4819,16 +4921,16 @@ function egressStatePaths(repoRoot, config) {
4819
4921
  const stateDir = belayStateDir(config, repoLocalStateDirFor(repoRoot, config));
4820
4922
  return {
4821
4923
  stateDir,
4822
- pidPath: path14.join(stateDir, "egress-proxy.pid"),
4823
- statusPath: path14.join(stateDir, "egress-proxy.json")
4924
+ pidPath: path15.join(stateDir, "egress-proxy.pid"),
4925
+ statusPath: path15.join(stateDir, "egress-proxy.json")
4824
4926
  };
4825
4927
  }
4826
4928
  async function readStatusFile(statusPath) {
4827
- if (!existsSync5(statusPath)) {
4929
+ if (!existsSync6(statusPath)) {
4828
4930
  return null;
4829
4931
  }
4830
4932
  try {
4831
- const raw = JSON.parse(await readFile5(statusPath, "utf8"));
4933
+ const raw = JSON.parse(await readFile6(statusPath, "utf8"));
4832
4934
  if (typeof raw.pid !== "number") {
4833
4935
  return null;
4834
4936
  }
@@ -4846,9 +4948,9 @@ async function readStatusFile(statusPath) {
4846
4948
  async function isPortOpen(host, port) {
4847
4949
  return new Promise((resolve) => {
4848
4950
  const socket = net.createConnection({ host, port });
4849
- const finish = (open6) => {
4951
+ const finish = (open7) => {
4850
4952
  socket.destroy();
4851
- resolve(open6);
4953
+ resolve(open7);
4852
4954
  };
4853
4955
  socket.setTimeout(300);
4854
4956
  socket.on("connect", () => finish(true));
@@ -4859,7 +4961,7 @@ async function isPortOpen(host, port) {
4859
4961
  async function resolveLiveEgressStatus(repoRoot, config) {
4860
4962
  const { statusPath } = egressStatePaths(repoRoot, config);
4861
4963
  const statusCandidates = [statusPath];
4862
- const controlPlaneStatus = path14.join(configuredControlPlaneDir(config), "egress-proxy.json");
4964
+ const controlPlaneStatus = path15.join(configuredControlPlaneDir(config), "egress-proxy.json");
4863
4965
  if (!statusCandidates.includes(controlPlaneStatus)) {
4864
4966
  statusCandidates.push(controlPlaneStatus);
4865
4967
  }
@@ -4885,7 +4987,7 @@ function isProcessAlive(pid) {
4885
4987
  }
4886
4988
  }
4887
4989
  async function egressStatus(options = {}) {
4888
- const repoRoot = path14.resolve(options.targetDir ?? process.cwd());
4990
+ const repoRoot = path15.resolve(options.targetDir ?? process.cwd());
4889
4991
  const config = await loadConfigFile(repoRoot);
4890
4992
  const { status, host, port, portOccupied } = await resolveLiveEgressStatus(repoRoot, config);
4891
4993
  const ownedRunning = Boolean(status);
@@ -4916,7 +5018,7 @@ init_config();
4916
5018
  import { createHash as createHash8, randomUUID as randomUUID2 } from "node:crypto";
4917
5019
  import { createReadStream as createReadStream2 } from "node:fs";
4918
5020
  import { access as access2, constants as constants2, lstat as lstat4, mkdtemp as mkdtemp2, realpath as realpath2, rm as rm2 } from "node:fs/promises";
4919
- import path19 from "node:path";
5021
+ import path20 from "node:path";
4920
5022
  init_fingerprint2();
4921
5023
  init_path_utils();
4922
5024
 
@@ -5095,7 +5197,7 @@ function runProcessWithBoundedOutput(file, args, options, timeoutMs, outputPolic
5095
5197
  }
5096
5198
 
5097
5199
  // src/core/contained-execution/docker-policy.ts
5098
- import path15 from "node:path";
5200
+ import path16 from "node:path";
5099
5201
 
5100
5202
  // src/core/contained-execution/policy.ts
5101
5203
  var CONTAINED_EXECUTION_APPROVAL_FALLBACK_REASONS = [
@@ -5224,7 +5326,7 @@ var PROXY_ENV_NAMES = [
5224
5326
  var IMAGE_ID_PATTERN = /^sha256:[a-f0-9]{64}$/;
5225
5327
  var SAFE_CONTAINER_NAME = /^belay-contained-[0-9a-f-]{36}$/;
5226
5328
  function assertSafeDockerPath(value, code) {
5227
- if (!path15.isAbsolute(value) || /[\0\n\r,]/.test(value)) {
5329
+ if (!path16.isAbsolute(value) || /[\0\n\r,]/.test(value)) {
5228
5330
  throw new ContainedExecutionFailureError(code);
5229
5331
  }
5230
5332
  }
@@ -5303,11 +5405,11 @@ init_path_utils();
5303
5405
  import { createHash as createHash7 } from "node:crypto";
5304
5406
  import { constants as fsConstants } from "node:fs";
5305
5407
  import {
5306
- chmod as chmod2,
5408
+ chmod as chmod3,
5307
5409
  lstat as lstat3,
5308
- mkdir as mkdir5,
5410
+ mkdir as mkdir6,
5309
5411
  mkdtemp,
5310
- open as open3,
5412
+ open as open4,
5311
5413
  opendir,
5312
5414
  readlink as readlink2,
5313
5415
  realpath,
@@ -5315,41 +5417,41 @@ import {
5315
5417
  symlink
5316
5418
  } from "node:fs/promises";
5317
5419
  import os from "node:os";
5318
- import path18 from "node:path";
5420
+ import path19 from "node:path";
5319
5421
 
5320
5422
  // src/core/transactional/file-tree.ts
5321
5423
  import { createHash as createHash6 } from "node:crypto";
5322
5424
  import { lstat as lstat2, readdir } from "node:fs/promises";
5323
- import path17 from "node:path";
5425
+ import path18 from "node:path";
5324
5426
 
5325
5427
  // src/core/transactional/file-tree-path.ts
5326
5428
  init_path_utils();
5327
- import path16 from "node:path";
5429
+ import path17 from "node:path";
5328
5430
  var FILE_CHECKPOINT_PATH_ESCAPE = "file_checkpoint_path_escape";
5329
5431
  function validateRelativePath(relativePath) {
5330
5432
  if (!relativePath || relativePath.includes("\0")) {
5331
5433
  throw new Error(FILE_CHECKPOINT_PATH_ESCAPE);
5332
5434
  }
5333
- if (path16.isAbsolute(relativePath)) {
5435
+ if (path17.isAbsolute(relativePath)) {
5334
5436
  throw new Error(FILE_CHECKPOINT_PATH_ESCAPE);
5335
5437
  }
5336
5438
  if (isPathOutsideRoot(relativePath)) {
5337
5439
  throw new Error(FILE_CHECKPOINT_PATH_ESCAPE);
5338
5440
  }
5339
- const normalized = path16.normalize(relativePath);
5340
- if (normalized === ".." || normalized.startsWith(`..${path16.sep}`)) {
5441
+ const normalized = path17.normalize(relativePath);
5442
+ if (normalized === ".." || normalized.startsWith(`..${path17.sep}`)) {
5341
5443
  throw new Error(FILE_CHECKPOINT_PATH_ESCAPE);
5342
5444
  }
5343
5445
  }
5344
5446
  function joinRelativePath(root, relativePath) {
5345
5447
  validateRelativePath(relativePath);
5346
- return path16.join(canonicalPath(root), relativePath);
5448
+ return path17.join(canonicalPath(root), relativePath);
5347
5449
  }
5348
5450
  function isRootGitMetadataPath(relativePath) {
5349
- return relativePath === ".git" || relativePath.startsWith(`.git${path16.sep}`);
5451
+ return relativePath === ".git" || relativePath.startsWith(`.git${path17.sep}`);
5350
5452
  }
5351
5453
  function isNestedGitPath(relativePath) {
5352
- const segments = relativePath.split(path16.sep).filter(Boolean);
5454
+ const segments = relativePath.split(path17.sep).filter(Boolean);
5353
5455
  if (segments.length === 0) {
5354
5456
  return false;
5355
5457
  }
@@ -5516,7 +5618,7 @@ async function readPresentNode(absolutePath, counters) {
5516
5618
  async function walkDirectory(resourceRoot, relativeDir, excludedRoots, counters, quotas, deadlineMs, entries) {
5517
5619
  assertWithinDeadline(deadlineMs);
5518
5620
  assertWithinQuotas(counters, quotas);
5519
- const absoluteDir = relativeDir ? joinRelativePath(resourceRoot, relativeDir) : path17.resolve(resourceRoot);
5621
+ const absoluteDir = relativeDir ? joinRelativePath(resourceRoot, relativeDir) : path18.resolve(resourceRoot);
5520
5622
  const dirInfo = await lstat2(absoluteDir);
5521
5623
  if (!dirInfo.isDirectory()) {
5522
5624
  throw new Error(FILE_CHECKPOINT_UNSUPPORTED_NODE);
@@ -5542,7 +5644,7 @@ async function walkDirectory(resourceRoot, relativeDir, excludedRoots, counters,
5542
5644
  const names = await readdir(absoluteDir);
5543
5645
  for (const name of names) {
5544
5646
  assertWithinDeadline(deadlineMs);
5545
- const childRelative = relativeDir ? path17.join(relativeDir, name) : name;
5647
+ const childRelative = relativeDir ? path18.join(relativeDir, name) : name;
5546
5648
  validateRelativePath(childRelative);
5547
5649
  if (isNestedGitPath(childRelative)) {
5548
5650
  throw new Error(FILE_CHECKPOINT_NESTED_REPOSITORY);
@@ -5550,7 +5652,7 @@ async function walkDirectory(resourceRoot, relativeDir, excludedRoots, counters,
5550
5652
  if (isExcludedTreePath(childRelative, excludedRoots, resourceRoot)) {
5551
5653
  continue;
5552
5654
  }
5553
- const childAbsolute = path17.join(absoluteDir, name);
5655
+ const childAbsolute = path18.join(absoluteDir, name);
5554
5656
  const childInfo = await lstat2(childAbsolute);
5555
5657
  if (childInfo.isDirectory() && !childInfo.isSymbolicLink()) {
5556
5658
  await walkDirectory(
@@ -5661,16 +5763,16 @@ function validateContainedExecutionMirrorLease(handle, expected) {
5661
5763
  );
5662
5764
  }
5663
5765
  var productionDependencies = {
5664
- makeTempRoot: () => mkdtemp(path18.join(os.tmpdir(), "belay-contained-mirror-")),
5766
+ makeTempRoot: () => mkdtemp(path19.join(os.tmpdir(), "belay-contained-mirror-")),
5665
5767
  removeRoot: (root) => rm(root, { recursive: true, force: true }),
5666
5768
  now: () => Date.now()
5667
5769
  };
5668
5770
  function isAtOrWithin(root, target) {
5669
- const relative = path18.relative(root, target);
5670
- return relative === "" || !path18.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path18.sep}`);
5771
+ const relative = path19.relative(root, target);
5772
+ return relative === "" || !path19.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path19.sep}`);
5671
5773
  }
5672
5774
  function isGitMetadataRelativePath(relativePath) {
5673
- return relativePath.split(path18.sep).some((segment) => segment.toLowerCase() === ".git");
5775
+ return relativePath.split(path19.sep).some((segment) => segment.toLowerCase() === ".git");
5674
5776
  }
5675
5777
  function identityFromStats(stats) {
5676
5778
  return {
@@ -5752,7 +5854,7 @@ async function readStableFile(absolutePath, context) {
5752
5854
  if (before.nlink > 1n) {
5753
5855
  throw new Error(FILE_CHECKPOINT_HARDLINK_UNSUPPORTED);
5754
5856
  }
5755
- const source = await open3(absolutePath, safeReadFlags());
5857
+ const source = await open4(absolutePath, safeReadFlags());
5756
5858
  try {
5757
5859
  const opened = await source.stat({ bigint: true });
5758
5860
  assertRegularSingleLinkBigInt(opened);
@@ -5807,7 +5909,7 @@ function addMetadataRoots(context, directoryPath) {
5807
5909
  }
5808
5910
  }
5809
5911
  function pathMatchesRoots(absolutePath, roots) {
5810
- const lexical = path18.resolve(absolutePath);
5912
+ const lexical = path19.resolve(absolutePath);
5811
5913
  const canonical = canonicalPath(absolutePath);
5812
5914
  for (const root of roots) {
5813
5915
  if (isAtOrWithin(root, lexical) || isAtOrWithin(root, canonical)) {
@@ -5817,7 +5919,7 @@ function pathMatchesRoots(absolutePath, roots) {
5817
5919
  return false;
5818
5920
  }
5819
5921
  function pathLexicallyMatchesRoots(absolutePath, roots) {
5820
- const lexical = path18.resolve(absolutePath);
5922
+ const lexical = path19.resolve(absolutePath);
5821
5923
  for (const root of roots) {
5822
5924
  if (isAtOrWithin(root, lexical)) {
5823
5925
  return true;
@@ -5838,11 +5940,11 @@ async function readSafeSymlink(absolutePath, context) {
5838
5940
  }
5839
5941
  const identity = identityFromStats(before);
5840
5942
  const target = await readlink2(absolutePath);
5841
- if (path18.isAbsolute(target)) {
5943
+ if (path19.isAbsolute(target)) {
5842
5944
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_UNSAFE_SYMLINK);
5843
5945
  }
5844
- const lexicalTarget = path18.resolve(path18.dirname(absolutePath), target);
5845
- if (!isAtOrWithin(context.sourceRoot, lexicalTarget) || isGitMetadataRelativePath(path18.relative(context.sourceRoot, lexicalTarget)) || pathMatchesRoots(lexicalTarget, context.protectedRoots) || pathMatchesRoots(lexicalTarget, context.metadataRoots)) {
5946
+ const lexicalTarget = path19.resolve(path19.dirname(absolutePath), target);
5947
+ if (!isAtOrWithin(context.sourceRoot, lexicalTarget) || isGitMetadataRelativePath(path19.relative(context.sourceRoot, lexicalTarget)) || pathMatchesRoots(lexicalTarget, context.protectedRoots) || pathMatchesRoots(lexicalTarget, context.metadataRoots)) {
5846
5948
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_UNSAFE_SYMLINK);
5847
5949
  }
5848
5950
  let resolvedTarget;
@@ -5878,7 +5980,7 @@ async function walkDirectory2(relativeDirectory, entries, context) {
5878
5980
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_SOURCE_CHANGED);
5879
5981
  }
5880
5982
  const directoryFlags = safeReadFlags() | (fsConstants.O_DIRECTORY ?? 0);
5881
- const directory = await open3(absoluteDirectory, directoryFlags);
5983
+ const directory = await open4(absoluteDirectory, directoryFlags);
5882
5984
  try {
5883
5985
  const opened = await directory.stat({ bigint: true });
5884
5986
  if (!opened.isDirectory() || !identitiesEqual(beforeIdentity, identityFromStats(opened))) {
@@ -5887,7 +5989,7 @@ async function walkDirectory2(relativeDirectory, entries, context) {
5887
5989
  const entriesDirectory = await opendir(absoluteDirectory, { bufferSize: 32 });
5888
5990
  for await (const directoryEntry of entriesDirectory) {
5889
5991
  assertDeadline(context.deadlineMs, context.now);
5890
- const relativePath = relativeDirectory ? path18.join(relativeDirectory, directoryEntry.name) : directoryEntry.name;
5992
+ const relativePath = relativeDirectory ? path19.join(relativeDirectory, directoryEntry.name) : directoryEntry.name;
5891
5993
  const absolutePath = joinRelativePath(context.sourceRoot, relativePath);
5892
5994
  const info = await lstat3(absolutePath);
5893
5995
  if (info.isSymbolicLink()) {
@@ -5971,7 +6073,7 @@ async function copyStableRegularFile(sourcePath, destinationPath, entry, context
5971
6073
  }
5972
6074
  assertEntryIdentity(entry, identityFromStats(before));
5973
6075
  await context.beforeCopyOpen?.(sourcePath);
5974
- const source = await open3(sourcePath, safeReadFlags());
6076
+ const source = await open4(sourcePath, safeReadFlags());
5975
6077
  let destination;
5976
6078
  try {
5977
6079
  const opened = await source.stat({ bigint: true });
@@ -5981,8 +6083,8 @@ async function copyStableRegularFile(sourcePath, destinationPath, entry, context
5981
6083
  if (entry.node.kind !== "file") {
5982
6084
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_SOURCE_CHANGED);
5983
6085
  }
5984
- await mkdir5(path18.dirname(destinationPath), { recursive: true, mode: 448 });
5985
- destination = await open3(
6086
+ await mkdir6(path19.dirname(destinationPath), { recursive: true, mode: 448 });
6087
+ destination = await open4(
5986
6088
  destinationPath,
5987
6089
  fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,
5988
6090
  safePermissionMode(opened.mode)
@@ -6024,7 +6126,7 @@ async function copyStableRegularFile(sourcePath, destinationPath, entry, context
6024
6126
  if (entry.node.kind !== "file") {
6025
6127
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_SOURCE_CHANGED);
6026
6128
  }
6027
- await chmod2(destinationPath, safePermissionMode(entry.node.mode));
6129
+ await chmod3(destinationPath, safePermissionMode(entry.node.mode));
6028
6130
  }
6029
6131
  async function materializeSnapshot(sourceRoot, destinationRoot, snapshot, context) {
6030
6132
  const directoryEntries = [];
@@ -6033,7 +6135,7 @@ async function materializeSnapshot(sourceRoot, destinationRoot, snapshot, contex
6033
6135
  const sourcePath = joinRelativePath(sourceRoot, entry.relativePath);
6034
6136
  const destinationPath = joinRelativePath(destinationRoot, entry.relativePath);
6035
6137
  if (entry.node.kind === "directory") {
6036
- await mkdir5(destinationPath, { recursive: true, mode: 448 });
6138
+ await mkdir6(destinationPath, { recursive: true, mode: 448 });
6037
6139
  directoryEntries.push(entry);
6038
6140
  continue;
6039
6141
  }
@@ -6045,7 +6147,7 @@ async function materializeSnapshot(sourceRoot, destinationRoot, snapshot, contex
6045
6147
  if (current !== entry.node.target) {
6046
6148
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_SOURCE_CHANGED);
6047
6149
  }
6048
- await mkdir5(path18.dirname(destinationPath), { recursive: true, mode: 448 });
6150
+ await mkdir6(path19.dirname(destinationPath), { recursive: true, mode: 448 });
6049
6151
  await symlink(entry.node.target, destinationPath);
6050
6152
  continue;
6051
6153
  }
@@ -6055,12 +6157,12 @@ async function materializeSnapshot(sourceRoot, destinationRoot, snapshot, contex
6055
6157
  if (entry.node.kind !== "directory") {
6056
6158
  throw new ContainedExecutionFailureError(CONTAINED_EXECUTION_SOURCE_CHANGED);
6057
6159
  }
6058
- await chmod2(
6160
+ await chmod3(
6059
6161
  joinRelativePath(destinationRoot, entry.relativePath),
6060
6162
  safePermissionMode(entry.node.mode)
6061
6163
  );
6062
6164
  }
6063
- await chmod2(destinationRoot, 448);
6165
+ await chmod3(destinationRoot, 448);
6064
6166
  }
6065
6167
  async function assertStableCopiedSnapshot(sourceRoot, destinationRoot, protectedRoots, limits, deadlineMs, now, before) {
6066
6168
  const [after, copied] = await Promise.all([
@@ -6105,7 +6207,7 @@ async function cleanupOwnedRoot(root, dependencies) {
6105
6207
  }
6106
6208
  async function prepareWithDependencies(options, dependencies) {
6107
6209
  validateOptions(options);
6108
- const guestWorkspacePath = path18.resolve(options.sourceRoot);
6210
+ const guestWorkspacePath = path19.resolve(options.sourceRoot);
6109
6211
  const sourceRoot = canonicalPath(options.sourceRoot);
6110
6212
  const protectedRoots = options.controlPlaneRoots.map((root) => canonicalPath(root));
6111
6213
  if (pathMatchesRoots(sourceRoot, protectedRoots)) {
@@ -6113,7 +6215,7 @@ async function prepareWithDependencies(options, dependencies) {
6113
6215
  }
6114
6216
  const guestRoot = await dependencies.makeTempRoot();
6115
6217
  try {
6116
- await chmod2(guestRoot, 448);
6218
+ await chmod3(guestRoot, 448);
6117
6219
  const deadlineMs = dependencies.now() + options.limits.prepareTimeoutMs;
6118
6220
  const before = await buildSafeMirrorSnapshot(
6119
6221
  sourceRoot,
@@ -6141,7 +6243,7 @@ async function prepareWithDependencies(options, dependencies) {
6141
6243
  dependencies.now,
6142
6244
  before
6143
6245
  );
6144
- await chmod2(guestRoot, 448);
6246
+ await chmod3(guestRoot, 448);
6145
6247
  const lease = {
6146
6248
  sourceRoot,
6147
6249
  hostMirrorRoot: guestRoot,
@@ -6275,14 +6377,14 @@ async function digestFile(file) {
6275
6377
  return hash.digest("hex");
6276
6378
  }
6277
6379
  async function resolveConfiguredDockerSubstrate(params) {
6278
- if (!path19.isAbsolute(params.executable) || /[\0\n\r]/.test(params.executable)) {
6380
+ if (!path20.isAbsolute(params.executable) || /[\0\n\r]/.test(params.executable)) {
6279
6381
  throw new ContainedDockerBoundaryUnavailableError("contained_execution_docker_binary_invalid");
6280
6382
  }
6281
6383
  if (!params.host.startsWith("unix:///") || /[\0\n\r]/.test(params.host)) {
6282
6384
  throw new ContainedDockerBoundaryUnavailableError("contained_execution_docker_host_invalid");
6283
6385
  }
6284
6386
  const configuredSocket = params.host.slice("unix://".length);
6285
- if (!path19.isAbsolute(configuredSocket)) {
6387
+ if (!path20.isAbsolute(configuredSocket)) {
6286
6388
  throw new ContainedDockerBoundaryUnavailableError("contained_execution_docker_host_invalid");
6287
6389
  }
6288
6390
  let binaryPath;
@@ -6543,7 +6645,7 @@ async function validatedGuestCwd(params) {
6543
6645
  const requiredExclusions = [
6544
6646
  ...new Set([params.controlPlaneDir, ...params.protectedRoots].map(canonicalPath))
6545
6647
  ];
6546
- if (params.mirror.backend !== "file_copy" || params.mirror.guestWorkspacePath !== path19.resolve(params.repoRoot) || !path19.isAbsolute(params.guestCwd) || !pathWithinRoot(params.mirror.guestWorkspacePath, params.guestCwd))
6648
+ if (params.mirror.backend !== "file_copy" || params.mirror.guestWorkspacePath !== path20.resolve(params.repoRoot) || !path20.isAbsolute(params.guestCwd) || !pathWithinRoot(params.mirror.guestWorkspacePath, params.guestCwd))
6547
6649
  throw new ContainedExecutionFailureError("contained_execution_invalid_cwd");
6548
6650
  const resolvedRoot = await realpath2(params.mirror.hostMirrorRoot);
6549
6651
  const protectedRoots = [canonicalPath(params.repoRoot), ...requiredExclusions];
@@ -6555,10 +6657,10 @@ async function validatedGuestCwd(params) {
6555
6657
  protectedRoots: requiredExclusions
6556
6658
  }))
6557
6659
  throw new ContainedExecutionFailureError("contained_execution_invalid_mirror_lease");
6558
- const relative = path19.relative(params.mirror.guestWorkspacePath, path19.resolve(params.guestCwd));
6660
+ const relative = path20.relative(params.mirror.guestWorkspacePath, path20.resolve(params.guestCwd));
6559
6661
  let resolvedCwd;
6560
6662
  try {
6561
- resolvedCwd = await realpath2(path19.join(resolvedRoot, relative));
6663
+ resolvedCwd = await realpath2(path20.join(resolvedRoot, relative));
6562
6664
  } catch {
6563
6665
  throw new ContainedExecutionFailureError("contained_execution_invalid_cwd");
6564
6666
  }
@@ -6566,7 +6668,7 @@ async function validatedGuestCwd(params) {
6566
6668
  if (!info.isDirectory() || !pathWithinRoot(resolvedRoot, resolvedCwd)) {
6567
6669
  throw new ContainedExecutionFailureError("contained_execution_invalid_cwd");
6568
6670
  }
6569
- return path19.join(params.mirror.guestWorkspacePath, path19.relative(resolvedRoot, resolvedCwd));
6671
+ return path20.join(params.mirror.guestWorkspacePath, path20.relative(resolvedRoot, resolvedCwd));
6570
6672
  }
6571
6673
  function exactKeys(value, allowed) {
6572
6674
  const names = new Set(allowed);
@@ -6793,19 +6895,19 @@ async function executeContainedDocker(params) {
6793
6895
  init_path_utils();
6794
6896
  import { spawn as spawn3 } from "node:child_process";
6795
6897
  import os3 from "node:os";
6796
- import path21 from "node:path";
6898
+ import path22 from "node:path";
6797
6899
 
6798
6900
  // src/core/transactional/apply-observed-changes.ts
6799
- import { copyFile, lstat as lstat5, mkdir as mkdir6, mkdtemp as mkdtemp3, readlink as readlink3, rm as rm3, rmdir, symlink as symlink2 } from "node:fs/promises";
6901
+ import { copyFile, lstat as lstat5, mkdir as mkdir7, mkdtemp as mkdtemp3, readlink as readlink3, rm as rm3, rmdir, symlink as symlink2 } from "node:fs/promises";
6800
6902
  import os2 from "node:os";
6801
- import path20 from "node:path";
6903
+ import path21 from "node:path";
6802
6904
  var TRANSACTIONAL_APPLY_TOCTOU = "transactional_apply_toctou";
6803
6905
  var TRANSACTIONAL_APPLY_CONFLICT = "transactional_apply_conflict";
6804
6906
  var TRANSACTIONAL_APPLY_ROLLBACK_FAILED = "transactional_apply_rollback_failed";
6805
6907
  async function chmodSafe(target, mode) {
6806
6908
  try {
6807
- const { chmod: chmod4 } = await import("node:fs/promises");
6808
- await chmod4(target, mode & 511);
6909
+ const { chmod: chmod5 } = await import("node:fs/promises");
6910
+ await chmod5(target, mode & 511);
6809
6911
  } catch {
6810
6912
  }
6811
6913
  }
@@ -6839,13 +6941,13 @@ async function copyPathPreservingType(source, target) {
6839
6941
  }
6840
6942
  }
6841
6943
  await removePathIfExists(target);
6842
- await mkdir6(path20.dirname(target), { recursive: true });
6944
+ await mkdir7(path21.dirname(target), { recursive: true });
6843
6945
  if (info.isSymbolicLink()) {
6844
6946
  await symlink2(await readlink3(source), target);
6845
6947
  return;
6846
6948
  }
6847
6949
  if (info.isDirectory() && !info.isSymbolicLink()) {
6848
- await mkdir6(target, { recursive: true, mode: info.mode & 511 });
6950
+ await mkdir7(target, { recursive: true, mode: info.mode & 511 });
6849
6951
  return;
6850
6952
  }
6851
6953
  if (!info.isFile()) {
@@ -6855,12 +6957,12 @@ async function copyPathPreservingType(source, target) {
6855
6957
  await chmodSafe(target, info.mode);
6856
6958
  }
6857
6959
  async function assertParentChainSafe(targetRoot, relativePath, plannedDirectories = /* @__PURE__ */ new Set()) {
6858
- const segments = relativePath.split(path20.sep).filter(Boolean);
6960
+ const segments = relativePath.split(path21.sep).filter(Boolean);
6859
6961
  if (segments.length <= 1) {
6860
6962
  return;
6861
6963
  }
6862
6964
  for (let index = 1; index < segments.length; index++) {
6863
- const prefix = segments.slice(0, index).join(path20.sep);
6965
+ const prefix = segments.slice(0, index).join(path21.sep);
6864
6966
  const absolute = joinRelativePath(targetRoot, prefix);
6865
6967
  let info;
6866
6968
  try {
@@ -6880,8 +6982,8 @@ async function assertParentChainSafe(targetRoot, relativePath, plannedDirectorie
6880
6982
  }
6881
6983
  }
6882
6984
  async function restorePathFromBackup(backupPath, target, rollbackRoot) {
6883
- const stagingRoot = await mkdtemp3(path20.join(rollbackRoot, "restore-"));
6884
- const staged = path20.join(stagingRoot, "node");
6985
+ const stagingRoot = await mkdtemp3(path21.join(rollbackRoot, "restore-"));
6986
+ const staged = path21.join(stagingRoot, "node");
6885
6987
  try {
6886
6988
  await copyPathPreservingType(backupPath, staged);
6887
6989
  await copyPathPreservingType(staged, target);
@@ -6965,7 +7067,7 @@ async function applySingleChange(sourceRoot, targetRoot, change) {
6965
7067
  if (change.before.kind !== "directory") {
6966
7068
  await removePathIfExists(target);
6967
7069
  }
6968
- await mkdir6(target, { recursive: true, mode: change.after.mode & 511 });
7070
+ await mkdir7(target, { recursive: true, mode: change.after.mode & 511 });
6969
7071
  await chmodSafe(target, change.after.mode);
6970
7072
  return;
6971
7073
  }
@@ -6984,7 +7086,7 @@ async function applyObservedChanges(params) {
6984
7086
  await assertParentChainSafe(targetRoot, change.relativePath, plannedDirectories);
6985
7087
  await assertTargetMatches(targetRoot, change);
6986
7088
  }
6987
- const backupRoot = await mkdtemp3(path20.join(os2.tmpdir(), "belay-tx-rollback-"));
7089
+ const backupRoot = await mkdtemp3(path21.join(os2.tmpdir(), "belay-tx-rollback-"));
6988
7090
  const rollbackActions = [];
6989
7091
  let mutationAttempted = false;
6990
7092
  let resourceIdentityChanged = false;
@@ -7003,12 +7105,12 @@ async function applyObservedChanges(params) {
7003
7105
  targetExists = false;
7004
7106
  }
7005
7107
  if (targetExists) {
7006
- const backupPath = path20.join(
7108
+ const backupPath = path21.join(
7007
7109
  backupRoot,
7008
7110
  String(rollbackActions.length),
7009
7111
  change.relativePath
7010
7112
  );
7011
- await mkdir6(path20.dirname(backupPath), { recursive: true });
7113
+ await mkdir7(path21.dirname(backupPath), { recursive: true });
7012
7114
  await copyPathPreservingType(target, backupPath);
7013
7115
  await assertParentChainSafe(targetRoot, change.relativePath);
7014
7116
  rollbackActions.push({
@@ -7107,7 +7209,7 @@ function isIgnoredDirtyPath(repoRoot, relativePath, ignoreRoots) {
7107
7209
  if (ignoreRoots.length === 0) {
7108
7210
  return false;
7109
7211
  }
7110
- const absolutePath = canonicalPath(path21.join(repoRoot, relativePath));
7212
+ const absolutePath = canonicalPath(path22.join(repoRoot, relativePath));
7111
7213
  return ignoreRoots.some(
7112
7214
  (root) => pathWithinRoot(root, absolutePath) || root === absolutePath || pathWithinRoot(absolutePath, root)
7113
7215
  );
@@ -7145,7 +7247,7 @@ async function isDirtyWorktree(repoRoot, options) {
7145
7247
  }
7146
7248
  async function createGitWorktreeSnapshot(repoRoot, _stateDir) {
7147
7249
  const { mkdtemp: mkdtemp6, rm: rm10 } = await import("node:fs/promises");
7148
- const worktreePath = await mkdtemp6(path21.join(os3.tmpdir(), "belay-tx-"));
7250
+ const worktreePath = await mkdtemp6(path22.join(os3.tmpdir(), "belay-tx-"));
7149
7251
  await execGit(repoRoot, ["worktree", "add", "--detach", worktreePath, "HEAD"]);
7150
7252
  return {
7151
7253
  worktreePath,
@@ -7164,14 +7266,14 @@ async function createGitWorktreeSnapshot(repoRoot, _stateDir) {
7164
7266
  }
7165
7267
  function resolveWorktreeCwd(repoRoot, worktreePath, cwd) {
7166
7268
  const resolvedCwd = canonicalPath(cwd);
7167
- const relative = path21.relative(canonicalPath(repoRoot), resolvedCwd);
7168
- if (isPathOutsideRoot(relative) || path21.isAbsolute(relative)) {
7269
+ const relative = path22.relative(canonicalPath(repoRoot), resolvedCwd);
7270
+ if (isPathOutsideRoot(relative) || path22.isAbsolute(relative)) {
7169
7271
  return worktreePath;
7170
7272
  }
7171
7273
  if (relative === "") {
7172
7274
  return worktreePath;
7173
7275
  }
7174
- return path21.join(worktreePath, relative);
7276
+ return path22.join(worktreePath, relative);
7175
7277
  }
7176
7278
  function runShellCommand(command, cwd, timeoutMs) {
7177
7279
  return runProcessWithBoundedOutput(command, [], { cwd, shell: true, env: process.env }, timeoutMs);
@@ -7236,7 +7338,7 @@ import { spawn as spawn4 } from "node:child_process";
7236
7338
  import { randomUUID as randomUUID3 } from "node:crypto";
7237
7339
 
7238
7340
  // src/core/capability/boundary-grant-materialize.ts
7239
- import path22 from "node:path";
7341
+ import path23 from "node:path";
7240
7342
 
7241
7343
  // src/core/glob.ts
7242
7344
  init_approval();
@@ -7396,7 +7498,7 @@ function grantMatchesRequest(grant, request) {
7396
7498
  var BOUNDARY_GRANT_TTL_MS = 15 * 6e4;
7397
7499
  var BOUNDARY_GRANT_ISSUER_CONTAINER = "boundary:container";
7398
7500
  function resolveCapabilityPath(targetPath, cwd) {
7399
- const joined = path22.isAbsolute(targetPath) ? targetPath : path22.join(cwd, targetPath);
7501
+ const joined = path23.isAbsolute(targetPath) ? targetPath : path23.join(cwd, targetPath);
7400
7502
  return canonicalPath(joined);
7401
7503
  }
7402
7504
  function isPathWithinBoundaryMount(request) {
@@ -7471,7 +7573,7 @@ function materializeContainerBoundaryGrant(request, params) {
7471
7573
 
7472
7574
  // src/core/capability/boundary-workspace-mount.ts
7473
7575
  init_path_utils();
7474
- import path23 from "node:path";
7576
+ import path24 from "node:path";
7475
7577
  var HOST_PATH_ENV_VARS = [
7476
7578
  "BELAY_EGRESS_REPO_ROOT",
7477
7579
  "BELAY_JUDGE_BROKER_REPO_ROOT",
@@ -7496,23 +7598,23 @@ function validateWorkspaceMount(mount) {
7496
7598
  if (mount.cwdRelative.includes("\0")) {
7497
7599
  throw new Error("boundary_workspace_mount_invalid_cwd");
7498
7600
  }
7499
- const normalizedRelative = path23.posix.normalize(mount.cwdRelative.replace(/\\/g, "/"));
7601
+ const normalizedRelative = path24.posix.normalize(mount.cwdRelative.replace(/\\/g, "/"));
7500
7602
  if (normalizedRelative === ".." || normalizedRelative.startsWith("../")) {
7501
7603
  throw new Error("boundary_workspace_mount_invalid_cwd");
7502
7604
  }
7503
- if (path23.posix.isAbsolute(normalizedRelative)) {
7605
+ if (path24.posix.isAbsolute(normalizedRelative)) {
7504
7606
  throw new Error("boundary_workspace_mount_invalid_cwd");
7505
7607
  }
7506
7608
  }
7507
7609
  function resolveGuestWorkdir(mount) {
7508
7610
  validateWorkspaceMount(mount);
7509
7611
  const guestTargetRoot = canonicalPath(mount.guestTargetRoot);
7510
- const normalizedRelative = path23.posix.normalize(mount.cwdRelative.replace(/\\/g, "/"));
7612
+ const normalizedRelative = path24.posix.normalize(mount.cwdRelative.replace(/\\/g, "/"));
7511
7613
  if (normalizedRelative === "." || normalizedRelative === "") {
7512
7614
  return guestTargetRoot;
7513
7615
  }
7514
7616
  const segments = normalizedRelative.split("/").filter(Boolean);
7515
- return path23.posix.join(guestTargetRoot, ...segments);
7617
+ return path24.posix.join(guestTargetRoot, ...segments);
7516
7618
  }
7517
7619
  function buildWorkspaceMountSpec(mount) {
7518
7620
  validateWorkspaceMount(mount);
@@ -7803,7 +7905,7 @@ function containedExecutionFresh(attestation, config, now = Date.now()) {
7803
7905
  }
7804
7906
  function boundaryAttestationPath(repoRoot, config) {
7805
7907
  const rel = config.capability?.attestationRelPath ?? ".belay/attestation.json";
7806
- return path24.isAbsolute(rel) ? rel : path24.join(repoRoot, rel);
7908
+ return path25.isAbsolute(rel) ? rel : path25.join(repoRoot, rel);
7807
7909
  }
7808
7910
  async function loadBoundaryAttestation(filePath, expectedRepoRoot, controlPlaneDir) {
7809
7911
  try {
@@ -7908,7 +8010,7 @@ init_capability_request_hash();
7908
8010
 
7909
8011
  // src/core/capability/gate-policy-shadow.ts
7910
8012
  init_config();
7911
- import path29 from "node:path";
8013
+ import path30 from "node:path";
7912
8014
 
7913
8015
  // src/core/verdict/judge-outbound.ts
7914
8016
  init_scrub();
@@ -7918,7 +8020,7 @@ init_path_utils();
7918
8020
 
7919
8021
  // src/core/verdict/containment.ts
7920
8022
  init_git_resource_identity();
7921
- import path25 from "node:path";
8023
+ import path26 from "node:path";
7922
8024
  init_path_utils();
7923
8025
 
7924
8026
  // src/core/verdict/persistent-paths.ts
@@ -7938,7 +8040,7 @@ function expandHome(token) {
7938
8040
  if (!home) {
7939
8041
  return token;
7940
8042
  }
7941
- return token === "~" ? home : path25.join(home, token.slice(2));
8043
+ return token === "~" ? home : path26.join(home, token.slice(2));
7942
8044
  }
7943
8045
  return token;
7944
8046
  }
@@ -7950,10 +8052,10 @@ function resolveTrustedPath(token, trustedCwd, trusted) {
7950
8052
  return null;
7951
8053
  }
7952
8054
  const expanded = expandHome(token);
7953
- if (path25.isAbsolute(expanded)) {
8055
+ if (path26.isAbsolute(expanded)) {
7954
8056
  return canonicalPath(expanded);
7955
8057
  }
7956
- return canonicalPath(path25.resolve(trustedCwd, expanded));
8058
+ return canonicalPath(path26.resolve(trustedCwd, expanded));
7957
8059
  }
7958
8060
  function isGitPath(resolvedPath, repoRoot) {
7959
8061
  if (isGitMetadataPath(resolvedPath, repoRoot)) {
@@ -8070,20 +8172,20 @@ function parseTier1Json(raw) {
8070
8172
  init_judge_runtime_config();
8071
8173
 
8072
8174
  // src/core/verdict/judge-session-kill-switch.ts
8073
- import { existsSync as existsSync6 } from "node:fs";
8074
- import { mkdir as mkdir7, readFile as readFile6, unlink as unlink4, writeFile as writeFile4 } from "node:fs/promises";
8075
- import path26 from "node:path";
8175
+ import { existsSync as existsSync7 } from "node:fs";
8176
+ import { mkdir as mkdir8, readFile as readFile7, unlink as unlink5, writeFile as writeFile4 } from "node:fs/promises";
8177
+ import path27 from "node:path";
8076
8178
  var JUDGE_SESSION_KILL_FILE = "judge-session-kill.json";
8077
8179
  function judgeSessionKillSwitchPath(stateDir) {
8078
- return path26.join(stateDir, JUDGE_SESSION_KILL_FILE);
8180
+ return path27.join(stateDir, JUDGE_SESSION_KILL_FILE);
8079
8181
  }
8080
8182
  async function readJudgeSessionKillSwitch(stateDir) {
8081
8183
  const filePath = judgeSessionKillSwitchPath(stateDir);
8082
- if (!existsSync6(filePath)) {
8184
+ if (!existsSync7(filePath)) {
8083
8185
  return null;
8084
8186
  }
8085
8187
  try {
8086
- const raw = JSON.parse(await readFile6(filePath, "utf8"));
8188
+ const raw = JSON.parse(await readFile7(filePath, "utf8"));
8087
8189
  return raw.triggered === true ? raw : null;
8088
8190
  } catch {
8089
8191
  return null;
@@ -8094,7 +8196,7 @@ async function isJudgeSessionKillSwitchPersisted(stateDir) {
8094
8196
  return record?.triggered === true;
8095
8197
  }
8096
8198
  async function persistJudgeSessionKillSwitch(stateDir, reason = "shadow_mismatch") {
8097
- await mkdir7(stateDir, { recursive: true, mode: 448 });
8199
+ await mkdir8(stateDir, { recursive: true, mode: 448 });
8098
8200
  const record = {
8099
8201
  triggered: true,
8100
8202
  at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -8255,10 +8357,10 @@ function recordJudgeLatency(phase, latencyMs, at = Date.now()) {
8255
8357
 
8256
8358
  // src/core/verdict/judge-broker-service.ts
8257
8359
  import { spawn as spawn6 } from "node:child_process";
8258
- import { existsSync as existsSync7 } from "node:fs";
8259
- import { unlink as unlink5 } from "node:fs/promises";
8360
+ import { existsSync as existsSync8 } from "node:fs";
8361
+ import { unlink as unlink6 } from "node:fs/promises";
8260
8362
  import net2 from "node:net";
8261
- import path27 from "node:path";
8363
+ import path28 from "node:path";
8262
8364
  import { fileURLToPath } from "node:url";
8263
8365
 
8264
8366
  // src/core/verdict/judge-cli.ts
@@ -8804,10 +8906,10 @@ var JUDGE_BROKER_SESSION = "judge-broker-session.json";
8804
8906
  function judgeBrokerPaths(stateDir) {
8805
8907
  return {
8806
8908
  stateDir,
8807
- socketPath: path27.join(stateDir, JUDGE_BROKER_SOCKET),
8808
- statusPath: path27.join(stateDir, JUDGE_BROKER_STATUS),
8809
- pidPath: path27.join(stateDir, JUDGE_BROKER_PID),
8810
- sessionConfigPath: path27.join(stateDir, JUDGE_BROKER_SESSION)
8909
+ socketPath: path28.join(stateDir, JUDGE_BROKER_SOCKET),
8910
+ statusPath: path28.join(stateDir, JUDGE_BROKER_STATUS),
8911
+ pidPath: path28.join(stateDir, JUDGE_BROKER_PID),
8912
+ sessionConfigPath: path28.join(stateDir, JUDGE_BROKER_SESSION)
8811
8913
  };
8812
8914
  }
8813
8915
  function daemonScriptPath() {
@@ -8825,12 +8927,12 @@ function useInProcessBroker(env = process.env) {
8825
8927
  return Boolean(env.VITEST || env.VITEST_WORKER_ID || env.BELAY_JUDGE_BROKER_IN_PROCESS === "1");
8826
8928
  }
8827
8929
  async function readBrokerStatus(statusPath) {
8828
- if (!existsSync7(statusPath)) {
8930
+ if (!existsSync8(statusPath)) {
8829
8931
  return null;
8830
8932
  }
8831
8933
  try {
8832
- const { readFile: readFile16 } = await import("node:fs/promises");
8833
- const raw = JSON.parse(await readFile16(statusPath, "utf8"));
8934
+ const { readFile: readFile17 } = await import("node:fs/promises");
8935
+ const raw = JSON.parse(await readFile17(statusPath, "utf8"));
8834
8936
  if (typeof raw.pid !== "number" || typeof raw.socketPath !== "string") {
8835
8937
  return null;
8836
8938
  }
@@ -8840,13 +8942,13 @@ async function readBrokerStatus(statusPath) {
8840
8942
  }
8841
8943
  }
8842
8944
  async function readBrokerSessionConfig(sessionConfigPath) {
8843
- if (!existsSync7(sessionConfigPath)) {
8945
+ if (!existsSync8(sessionConfigPath)) {
8844
8946
  return null;
8845
8947
  }
8846
8948
  try {
8847
- const { readFile: readFile16 } = await import("node:fs/promises");
8949
+ const { readFile: readFile17 } = await import("node:fs/promises");
8848
8950
  const raw = JSON.parse(
8849
- await readFile16(sessionConfigPath, "utf8")
8951
+ await readFile17(sessionConfigPath, "utf8")
8850
8952
  );
8851
8953
  return normalizeJudgeSessionConfig({ ...raw, enabled: true });
8852
8954
  } catch {
@@ -8937,7 +9039,7 @@ async function ensureJudgeBrokerDaemon(stateDir, repoRoot, sessionConfig) {
8937
9039
  const existingConfig = await readBrokerSessionConfig(paths.sessionConfigPath);
8938
9040
  const configChanged = existingConfig !== null && brokerSessionConfigPayload(existingConfig) !== nextConfigPayload;
8939
9041
  const status = await readBrokerStatus(paths.statusPath);
8940
- if (status && isProcessAlive2(status.pid) && existsSync7(paths.socketPath) && !configChanged) {
9042
+ if (status && isProcessAlive2(status.pid) && existsSync8(paths.socketPath) && !configChanged) {
8941
9043
  await writeBrokerSessionConfig(paths, brokerSessionConfig);
8942
9044
  return paths;
8943
9045
  }
@@ -8959,7 +9061,7 @@ async function ensureJudgeBrokerDaemon(stateDir, repoRoot, sessionConfig) {
8959
9061
  child.unref();
8960
9062
  const deadline = Date.now() + sessionConfig.connectTimeoutMs;
8961
9063
  while (Date.now() < deadline) {
8962
- if (existsSync7(paths.socketPath)) {
9064
+ if (existsSync8(paths.socketPath)) {
8963
9065
  const live = await readBrokerStatus(paths.statusPath);
8964
9066
  if (live && isProcessAlive2(live.pid)) {
8965
9067
  return paths;
@@ -8976,8 +9078,8 @@ async function cleanupJudgeBrokerArtifacts(paths) {
8976
9078
  paths.pidPath,
8977
9079
  paths.sessionConfigPath
8978
9080
  ]) {
8979
- if (existsSync7(artifact)) {
8980
- await unlink5(artifact).catch(() => void 0);
9081
+ if (existsSync8(artifact)) {
9082
+ await unlink6(artifact).catch(() => void 0);
8981
9083
  }
8982
9084
  }
8983
9085
  }
@@ -9473,9 +9575,9 @@ async function evaluateWithJudgeTransport(request, options = {}) {
9473
9575
  }
9474
9576
 
9475
9577
  // src/core/capability/gate-shadow-ratchet.ts
9476
- import { existsSync as existsSync8 } from "node:fs";
9477
- import { mkdir as mkdir8, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
9478
- import path28 from "node:path";
9578
+ import { existsSync as existsSync9 } from "node:fs";
9579
+ import { mkdir as mkdir9, readFile as readFile8, writeFile as writeFile5 } from "node:fs/promises";
9580
+ import path29 from "node:path";
9479
9581
  var DEFAULT_STATE = {
9480
9582
  version: 1,
9481
9583
  policyJudgeComparisons: 0,
@@ -9484,15 +9586,15 @@ var DEFAULT_STATE = {
9484
9586
  updatedAt: (/* @__PURE__ */ new Date(0)).toISOString()
9485
9587
  };
9486
9588
  function ratchetPath(stateDir) {
9487
- return path28.join(stateDir, "gate-shadow-ratchet.json");
9589
+ return path29.join(stateDir, "gate-shadow-ratchet.json");
9488
9590
  }
9489
9591
  async function loadState(stateDir) {
9490
9592
  const filePath = ratchetPath(stateDir);
9491
- if (!existsSync8(filePath)) {
9593
+ if (!existsSync9(filePath)) {
9492
9594
  return { ...DEFAULT_STATE, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
9493
9595
  }
9494
9596
  try {
9495
- const raw = JSON.parse(await readFile7(filePath, "utf8"));
9597
+ const raw = JSON.parse(await readFile8(filePath, "utf8"));
9496
9598
  return {
9497
9599
  ...DEFAULT_STATE,
9498
9600
  ...raw,
@@ -9503,7 +9605,7 @@ async function loadState(stateDir) {
9503
9605
  }
9504
9606
  }
9505
9607
  async function saveState(stateDir, state) {
9506
- await mkdir8(stateDir, { recursive: true, mode: 448 });
9608
+ await mkdir9(stateDir, { recursive: true, mode: 448 });
9507
9609
  await writeFile5(
9508
9610
  ratchetPath(stateDir),
9509
9611
  `${JSON.stringify({ ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)}
@@ -9626,7 +9728,7 @@ function scheduleGateShadowAudit(params) {
9626
9728
  async function runGatePolicyShadowComparison(params) {
9627
9729
  const judge = params.config.judge;
9628
9730
  const runtime = normalizeJudgeRuntimeConfig(judge.runtime);
9629
- const stateDir = params.stateDir ?? belayStateDir(params.config, path29.join(params.repoRoot, ".belay"));
9731
+ const stateDir = params.stateDir ?? belayStateDir(params.config, path30.join(params.repoRoot, ".belay"));
9630
9732
  const transport = await evaluateWithJudgeTransport(
9631
9733
  {
9632
9734
  prompt: buildTier1Prompt(params.command),
@@ -9916,15 +10018,15 @@ async function loadClassifierAuthorization(params) {
9916
10018
  }
9917
10019
 
9918
10020
  // src/core/capability/allowlist.ts
9919
- import { existsSync as existsSync9, readFileSync as readFileSync3 } from "node:fs";
10021
+ import { existsSync as existsSync10, readFileSync as readFileSync3 } from "node:fs";
9920
10022
  init_config();
9921
10023
  init_path_utils();
9922
- import path30 from "node:path";
10024
+ import path31 from "node:path";
9923
10025
  function fsScopeAllowlistPath(config, repoLocalStateDir) {
9924
- return path30.join(belayStateDir(config, repoLocalStateDir), "fs-scope-allowlist.json");
10026
+ return path31.join(belayStateDir(config, repoLocalStateDir), "fs-scope-allowlist.json");
9925
10027
  }
9926
10028
  function loadFsScopeAllowlistSync(filePath) {
9927
- if (!existsSync9(filePath)) {
10029
+ if (!existsSync10(filePath)) {
9928
10030
  return { version: 1, paths: [] };
9929
10031
  }
9930
10032
  const raw = JSON.parse(readFileSync3(filePath, "utf8"));
@@ -10016,7 +10118,7 @@ function checkGatedActionLimits(action) {
10016
10118
  // src/core/capability/paths.ts
10017
10119
  init_path_utils();
10018
10120
  init_shell_tokenizer();
10019
- import path31 from "node:path";
10121
+ import path32 from "node:path";
10020
10122
  function applyPatchTargets(patch) {
10021
10123
  const targets = [];
10022
10124
  for (const line of patch.split("\n")) {
@@ -10081,7 +10183,7 @@ function collectOutsideRepoPathsFromToolPayload(payload, cwd, repoRoot, trustedW
10081
10183
  const paths = /* @__PURE__ */ new Set();
10082
10184
  const filePath = extractToolFilePath(payload);
10083
10185
  if (filePath) {
10084
- const resolved = path31.isAbsolute(filePath) ? filePath : path31.resolve(cwd, filePath);
10186
+ const resolved = path32.isAbsolute(filePath) ? filePath : path32.resolve(cwd, filePath);
10085
10187
  if (resolveWorkspaceRootMatch(repoRoot, trustedWorkspaceRoots, resolved) === null) {
10086
10188
  paths.add(resolved);
10087
10189
  }
@@ -10091,7 +10193,7 @@ function collectOutsideRepoPathsFromToolPayload(payload, cwd, repoRoot, trustedW
10091
10193
  const patch = extractToolPatch(payload);
10092
10194
  if (patch) {
10093
10195
  for (const target of applyPatchTargets(patch)) {
10094
- const resolved = path31.isAbsolute(target) ? target : path31.resolve(cwd, target);
10196
+ const resolved = path32.isAbsolute(target) ? target : path32.resolve(cwd, target);
10095
10197
  if (resolveWorkspaceRootMatch(repoRoot, trustedWorkspaceRoots, resolved) === null) {
10096
10198
  paths.add(resolved);
10097
10199
  }
@@ -10145,7 +10247,7 @@ function policyReasonToLegacyReason(decision) {
10145
10247
  // src/core/capability/policy-engine.ts
10146
10248
  init_git_resource_identity();
10147
10249
  import { createHash as createHash10 } from "node:crypto";
10148
- import path32 from "node:path";
10250
+ import path33 from "node:path";
10149
10251
  init_path_utils();
10150
10252
  init_shell_tokenizer();
10151
10253
  init_grant();
@@ -10437,7 +10539,7 @@ function hashSession(value) {
10437
10539
  return createHash10("sha256").update(value).digest("hex").slice(0, 16);
10438
10540
  }
10439
10541
  function resolveCapabilityPath2(targetPath, cwd) {
10440
- const joined = path32.isAbsolute(targetPath) ? targetPath : path32.join(cwd, targetPath);
10542
+ const joined = path33.isAbsolute(targetPath) ? targetPath : path33.join(cwd, targetPath);
10441
10543
  return canonicalPath(joined);
10442
10544
  }
10443
10545
  function actionForFileMutation(analysis) {
@@ -10516,7 +10618,7 @@ function isRepoLocalPackageExec(request) {
10516
10618
  return false;
10517
10619
  }
10518
10620
  const commandPath = canonicalPath(request.resource.command);
10519
- return path32.isAbsolute(commandPath) && pathWithinRoot(request.principal.repoRoot, commandPath);
10621
+ return path33.isAbsolute(commandPath) && pathWithinRoot(request.principal.repoRoot, commandPath);
10520
10622
  }
10521
10623
  function isRepoLocalRoutineWrite(request, sensitivePaths) {
10522
10624
  if (!isRepoLocalShellLocation(request)) {
@@ -10780,15 +10882,15 @@ function shouldSkipBrokerApprovedRecord(brokerActive, approvalReason) {
10780
10882
  }
10781
10883
 
10782
10884
  // src/core/capability/trusted-workspace-roots.ts
10783
- import { existsSync as existsSync10, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
10885
+ import { existsSync as existsSync11, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
10784
10886
  init_config();
10785
10887
  init_path_utils();
10786
- import path33 from "node:path";
10888
+ import path34 from "node:path";
10787
10889
  function trustedWorkspaceRootsPath(config, repoLocalStateDir) {
10788
- return path33.join(belayStateDir(config, repoLocalStateDir), "trusted-workspace-roots.json");
10890
+ return path34.join(belayStateDir(config, repoLocalStateDir), "trusted-workspace-roots.json");
10789
10891
  }
10790
10892
  function loadTrustedWorkspaceRootsSync(filePath) {
10791
- if (!existsSync10(filePath)) {
10893
+ if (!existsSync11(filePath)) {
10792
10894
  return { version: 1, roots: [] };
10793
10895
  }
10794
10896
  const raw = JSON.parse(readFileSync4(filePath, "utf8"));
@@ -10814,7 +10916,7 @@ function sanitizeTrustedWorkspaceRootEntries(input) {
10814
10916
  const source = record.source === "approval" ? "approval" : void 0;
10815
10917
  return [
10816
10918
  {
10817
- path: path33.resolve(record.path),
10919
+ path: path34.resolve(record.path),
10818
10920
  approvedAt,
10819
10921
  approvalId,
10820
10922
  ...source ? { source } : {}
@@ -10843,7 +10945,7 @@ function isDirectoryPath(targetPath) {
10843
10945
  function isBroadTrustedWorkspaceRoot(targetPath) {
10844
10946
  const home = process.env.HOME ?? process.env.USERPROFILE;
10845
10947
  const root = normalizeTrustedWorkspaceRootPath(targetPath);
10846
- if (root === normalizeTrustedWorkspaceRootPath(path33.parse(root).root)) {
10948
+ if (root === normalizeTrustedWorkspaceRootPath(path34.parse(root).root)) {
10847
10949
  return true;
10848
10950
  }
10849
10951
  if (home && normalizeTrustedWorkspaceRootPath(home) === root) {
@@ -10867,7 +10969,7 @@ function isHighStakesTrustedWorkspaceRoot(targetPath) {
10867
10969
  return false;
10868
10970
  }
10869
10971
  return HOME_HIGH_STAKES_SEGMENTS.some(
10870
- (segment) => pathWithinRoot(path33.join(homeRoot, segment), normalized)
10972
+ (segment) => pathWithinRoot(path34.join(homeRoot, segment), normalized)
10871
10973
  );
10872
10974
  }
10873
10975
  function validateTrustedWorkspaceRootCandidate(params) {
@@ -10904,7 +11006,7 @@ function validateTrustedWorkspaceRootCandidate(params) {
10904
11006
  init_config_layers();
10905
11007
 
10906
11008
  // src/core/contained-execution/eligibility.ts
10907
- import path34 from "node:path";
11009
+ import path35 from "node:path";
10908
11010
  init_path_utils();
10909
11011
  var FORBIDDEN_SIGNALS = /* @__PURE__ */ new Set([
10910
11012
  "command_substitution",
@@ -10921,7 +11023,7 @@ var FORBIDDEN_SIGNALS = /* @__PURE__ */ new Set([
10921
11023
  ]);
10922
11024
  function isContainedUnknownExecutionEligible(config, action, result) {
10923
11025
  const contained = config.sandbox.containedExecution;
10924
- if (!contained?.enabled || !config.sandbox.enabled || config.sandbox.runtime !== "container" || action.kind !== "shell" || !path34.isAbsolute(action.repoRoot) || !hasResolvedRepoIdentity(action.repoRoot) || !config.gates.shell || result.reason !== "unknown_local_effect" || result.axes?.location !== "repo_local" || result.assessment.external) {
11026
+ if (!contained?.enabled || !config.sandbox.enabled || config.sandbox.runtime !== "container" || action.kind !== "shell" || !path35.isAbsolute(action.repoRoot) || !hasResolvedRepoIdentity(action.repoRoot) || !config.gates.shell || result.reason !== "unknown_local_effect" || result.axes?.location !== "repo_local" || result.assessment.external) {
10925
11027
  return false;
10926
11028
  }
10927
11029
  const plan = result.effectPlan;
@@ -11152,7 +11254,7 @@ function classifySubagent(payload, repoRoot, options = {}, config) {
11152
11254
  }
11153
11255
 
11154
11256
  // src/core/classify-tool.ts
11155
- import path49 from "node:path";
11257
+ import path50 from "node:path";
11156
11258
  init_fingerprint2();
11157
11259
  init_path_utils();
11158
11260
  init_scrub();
@@ -11272,13 +11374,13 @@ function worstEffectDecision(decisions) {
11272
11374
 
11273
11375
  // src/core/effect-ir/shell-lower.ts
11274
11376
  init_shell_tokenizer();
11275
- import path48 from "node:path";
11377
+ import path49 from "node:path";
11276
11378
 
11277
11379
  // src/core/verdict/docker-compose-run.ts
11278
- import path36 from "node:path";
11380
+ import path37 from "node:path";
11279
11381
 
11280
11382
  // src/core/verdict/recursive-invocation.ts
11281
- import path35 from "node:path";
11383
+ import path36 from "node:path";
11282
11384
  var SHELL_INTERPRETERS = /* @__PURE__ */ new Set(["bash", "sh", "zsh", "dash", "fish"]);
11283
11385
  var PYTHON_INTERPRETERS = /* @__PURE__ */ new Set(["python", "python3"]);
11284
11386
  var SHELL_SHORT_OPTIONS = /* @__PURE__ */ new Set(["c", "l", "e", "x", "u"]);
@@ -11340,7 +11442,7 @@ var OSASCRIPT_PROFILE = {
11340
11442
  attachedValuePrefixes: []
11341
11443
  };
11342
11444
  function normalizeInterpreter(value) {
11343
- return path35.basename(value);
11445
+ return path36.basename(value);
11344
11446
  }
11345
11447
  function scriptResult(interpreter, token) {
11346
11448
  if (!token) {
@@ -11570,7 +11672,7 @@ function parseOptions(words, start, options) {
11570
11672
  function decodeDockerComposeRun(tokens) {
11571
11673
  if (tokens.some((token) => token.kind === "operator")) return { kind: "none" };
11572
11674
  const words = tokens.filter((token) => token.kind === "word");
11573
- const head = path36.basename(words[0]?.value ?? "");
11675
+ const head = path37.basename(words[0]?.value ?? "");
11574
11676
  let index;
11575
11677
  if (head === "docker-compose") {
11576
11678
  index = 1;
@@ -11611,7 +11713,7 @@ function decodeDockerComposeRun(tokens) {
11611
11713
  }
11612
11714
 
11613
11715
  // src/core/verdict/egress-classify.ts
11614
- import path37 from "node:path";
11716
+ import path38 from "node:path";
11615
11717
  var EGRESS_TOOL_HEADS = /* @__PURE__ */ new Set([
11616
11718
  "aws",
11617
11719
  "curl",
@@ -11660,7 +11762,7 @@ function isEgressToolHead(head) {
11660
11762
  return EGRESS_TOOL_HEADS.has(head);
11661
11763
  }
11662
11764
  function decodeEgressEffects(params) {
11663
- const head = path37.basename(params.tokens[0] ?? "");
11765
+ const head = path38.basename(params.tokens[0] ?? "");
11664
11766
  if (head !== "curl" && head !== "wget" && head !== "gh") {
11665
11767
  return null;
11666
11768
  }
@@ -11668,7 +11770,7 @@ function decodeEgressEffects(params) {
11668
11770
  const provenance = { segment: params.segment };
11669
11771
  const requirements = [];
11670
11772
  for (const file of decoded.files) {
11671
- const resolved = path37.resolve(params.cwd, expandHome2(file));
11773
+ const resolved = path38.resolve(params.cwd, expandHome2(file));
11672
11774
  requirements.push(
11673
11775
  requirement("fs.read", "fs.read", { kind: "path", path: resolved }, params.segment, [
11674
11776
  "egress.explicit_file_read"
@@ -11690,7 +11792,7 @@ function decodeEgressEffects(params) {
11690
11792
  if (file === "-") {
11691
11793
  continue;
11692
11794
  }
11693
- const resolved = path37.resolve(params.cwd, expandHome2(file));
11795
+ const resolved = path38.resolve(params.cwd, expandHome2(file));
11694
11796
  if (resolved === "/dev/null") {
11695
11797
  continue;
11696
11798
  }
@@ -12168,13 +12270,13 @@ function decodeSingleCurlWgetGrammar(head, tokens) {
12168
12270
  if (head === "wget" && !explicitOutput) {
12169
12271
  outputFiles.push(
12170
12272
  ...endpointOutputNames.map(
12171
- (name) => outputDirectory ? path37.join(outputDirectory, name) : name
12273
+ (name) => outputDirectory ? path38.join(outputDirectory, name) : name
12172
12274
  )
12173
12275
  );
12174
12276
  } else if (head === "curl" && remoteNameOutput) {
12175
12277
  outputFiles.push(
12176
12278
  ...endpointOutputNames.map(
12177
- (name) => outputDirectory ? path37.join(outputDirectory, name) : name
12279
+ (name) => outputDirectory ? path38.join(outputDirectory, name) : name
12178
12280
  )
12179
12281
  );
12180
12282
  }
@@ -12188,7 +12290,7 @@ function decodeSingleCurlWgetGrammar(head, tokens) {
12188
12290
  outputFiles: [
12189
12291
  ...new Set(
12190
12292
  outputFiles.map(
12191
- (file) => outputDirectory && directoryEligibleOutputs.has(file) && !path37.isAbsolute(file) ? path37.join(outputDirectory, file) : file
12293
+ (file) => outputDirectory && directoryEligibleOutputs.has(file) && !path38.isAbsolute(file) ? path38.join(outputDirectory, file) : file
12192
12294
  )
12193
12295
  )
12194
12296
  ],
@@ -12203,7 +12305,7 @@ function remoteOutputName(spec) {
12203
12305
  } catch {
12204
12306
  pathname = spec.split(/[?#]/, 1)[0] ?? "";
12205
12307
  }
12206
- const name = path37.posix.basename(pathname);
12308
+ const name = path38.posix.basename(pathname);
12207
12309
  return name && name !== "/" ? name : "index.html";
12208
12310
  }
12209
12311
  function decodeGhGrammar(tokens) {
@@ -12368,7 +12470,7 @@ function expandHome2(value) {
12368
12470
  return process.env.HOME ?? value;
12369
12471
  }
12370
12472
  if (value.startsWith("~/")) {
12371
- return path37.join(process.env.HOME ?? "~", value.slice(2));
12473
+ return path38.join(process.env.HOME ?? "~", value.slice(2));
12372
12474
  }
12373
12475
  return value;
12374
12476
  }
@@ -12387,7 +12489,7 @@ function requirement(tag, action, resource, segment, signals) {
12387
12489
  }
12388
12490
 
12389
12491
  // src/core/verdict/git-classifier.ts
12390
- import path38 from "node:path";
12492
+ import path39 from "node:path";
12391
12493
  init_shell_tokenizer();
12392
12494
  var GIT_BRANCH_MUTATION_FLAGS = /* @__PURE__ */ new Set([
12393
12495
  "--copy",
@@ -12483,7 +12585,7 @@ var FILE_OPERAND_SUBCOMMANDS = /* @__PURE__ */ new Set([
12483
12585
  var COMPOUND_SUBCOMMAND_HEADS = /* @__PURE__ */ new Set(["worktree", "stash", "tag"]);
12484
12586
  var REF_ONLY_WITHOUT_TERMINATOR = /* @__PURE__ */ new Set(["checkout", "show", "log"]);
12485
12587
  function isGitExecutable(token) {
12486
- return path38.basename(token) === "git";
12588
+ return path39.basename(token) === "git";
12487
12589
  }
12488
12590
  function takesValue(flag) {
12489
12591
  return flag === "-C" || flag === "-c" || flag === "--git-dir" || flag === "--work-tree" || flag === "--exec-path" || flag === "--paginate" || flag === "--config-env" || flag.startsWith("-C") || flag.startsWith("-c") || flag.startsWith("--git-dir=") || flag.startsWith("--work-tree=");
@@ -12511,7 +12613,7 @@ function peelGlobalOptions(tokens, baseCwd) {
12511
12613
  if (token === "-C" || token === "--work-tree" || token === "--git-dir" || token === "-c") {
12512
12614
  const value = tokens[index + 1];
12513
12615
  if (token === "-C" && value) {
12514
- effectiveCwd = path38.resolve(baseCwd, value);
12616
+ effectiveCwd = path39.resolve(baseCwd, value);
12515
12617
  } else if (token === "--work-tree" && value) {
12516
12618
  workTree = value;
12517
12619
  } else if (token === "--git-dir" && value) {
@@ -12521,7 +12623,7 @@ function peelGlobalOptions(tokens, baseCwd) {
12521
12623
  continue;
12522
12624
  }
12523
12625
  if (token.startsWith("-C") && token.length > 2) {
12524
- effectiveCwd = path38.resolve(baseCwd, token.slice(2));
12626
+ effectiveCwd = path39.resolve(baseCwd, token.slice(2));
12525
12627
  index += 1;
12526
12628
  continue;
12527
12629
  }
@@ -12664,7 +12766,7 @@ function looksLikeDiffPathOperand(token) {
12664
12766
  if (!looksLikeFileOperand(token)) {
12665
12767
  return false;
12666
12768
  }
12667
- if (token.startsWith(".") || path38.isAbsolute(token)) {
12769
+ if (token.startsWith(".") || path39.isAbsolute(token)) {
12668
12770
  return true;
12669
12771
  }
12670
12772
  return token.includes(".");
@@ -12672,12 +12774,12 @@ function looksLikeDiffPathOperand(token) {
12672
12774
  function resolveGitWorkTree(baseCwd, effectiveCwd, workTree, gitDir) {
12673
12775
  const resolveBase = effectiveCwd ?? baseCwd;
12674
12776
  if (workTree) {
12675
- return path38.resolve(resolveBase, workTree);
12777
+ return path39.resolve(resolveBase, workTree);
12676
12778
  }
12677
12779
  if (gitDir) {
12678
- const resolvedGitDir = path38.resolve(resolveBase, gitDir);
12679
- if (path38.basename(resolvedGitDir) === ".git") {
12680
- return path38.dirname(resolvedGitDir);
12780
+ const resolvedGitDir = path39.resolve(resolveBase, gitDir);
12781
+ if (path39.basename(resolvedGitDir) === ".git") {
12782
+ return path39.dirname(resolvedGitDir);
12681
12783
  }
12682
12784
  }
12683
12785
  return void 0;
@@ -12758,7 +12860,7 @@ function classifyGitCommand(tokens, baseCwd) {
12758
12860
  const { subcommand, args, effectiveCwd, gitDir, workTree } = normalized;
12759
12861
  const normalizedKey = `git ${subcommand}`;
12760
12862
  const gitWorkTree = resolveGitWorkTree(baseCwd, effectiveCwd, workTree, gitDir);
12761
- const effectiveGitDir = gitDir ? path38.resolve(effectiveCwd ?? baseCwd, gitDir) : void 0;
12863
+ const effectiveGitDir = gitDir ? path39.resolve(effectiveCwd ?? baseCwd, gitDir) : void 0;
12762
12864
  const scopeTargets = [effectiveCwd, gitWorkTree, effectiveGitDir].filter(
12763
12865
  (target, index, targets) => Boolean(target) && targets.indexOf(target) === index
12764
12866
  );
@@ -12910,9 +13012,9 @@ function decodeGitEffects(params) {
12910
13012
  ...subcommand === "push" ? ["tier0_external"] : []
12911
13013
  ];
12912
13014
  const effectiveCwd = normalized.effectiveCwd ?? params.cwd;
12913
- const workTreeRoot = normalized.workTree ? path38.resolve(normalized.effectiveCwd ?? params.cwd, normalized.workTree) : normalized.effectiveCwd ?? params.repoRoot;
12914
- const gitRefRoot = normalized.gitDir ? path38.resolve(effectiveCwd, normalized.gitDir) : workTreeRoot;
12915
- const gitControlRoot = normalized.gitDir ? gitRefRoot : path38.join(gitRefRoot, ".git");
13015
+ const workTreeRoot = normalized.workTree ? path39.resolve(normalized.effectiveCwd ?? params.cwd, normalized.workTree) : normalized.effectiveCwd ?? params.repoRoot;
13016
+ const gitRefRoot = normalized.gitDir ? path39.resolve(effectiveCwd, normalized.gitDir) : workTreeRoot;
13017
+ const gitControlRoot = normalized.gitDir ? gitRefRoot : path39.join(gitRefRoot, ".git");
12916
13018
  const requirements = [];
12917
13019
  if (subcommand === "fetch" || subcommand === "pull") {
12918
13020
  const positionals = gitRemotePositionals(args);
@@ -13071,7 +13173,7 @@ function decodeGitEffects(params) {
13071
13173
  gitRequirement(
13072
13174
  "control_plane.write",
13073
13175
  "control_plane.write",
13074
- { kind: "path", path: path38.join(gitControlRoot, "logs") },
13176
+ { kind: "path", path: path39.join(gitControlRoot, "logs") },
13075
13177
  params.segment,
13076
13178
  [...signals, "git_history_destructive", "git.reflog.mutate"]
13077
13179
  )
@@ -13129,7 +13231,7 @@ function decodeGitEffects(params) {
13129
13231
  gitRequirement(
13130
13232
  "fs.read",
13131
13233
  "fs.read",
13132
- { kind: "path", path: path38.resolve(workTreeRoot, operand) },
13234
+ { kind: "path", path: path39.resolve(workTreeRoot, operand) },
13133
13235
  params.segment,
13134
13236
  [...signals, "git.path.read"]
13135
13237
  )
@@ -13164,7 +13266,7 @@ function decodeGitEffects(params) {
13164
13266
  gitRequirement(
13165
13267
  "fs.write",
13166
13268
  "fs.write",
13167
- { kind: "path", path: path38.resolve(workTreeRoot, operand) },
13269
+ { kind: "path", path: path39.resolve(workTreeRoot, operand) },
13168
13270
  params.segment,
13169
13271
  [...signals, "git.path.write"]
13170
13272
  )
@@ -13348,8 +13450,8 @@ function gitRequirement(tag, action, resource, segment, signals) {
13348
13450
  }
13349
13451
 
13350
13452
  // src/core/verdict/launcher-resolve.ts
13351
- import { existsSync as existsSync11, readFileSync as readFileSync5 } from "node:fs";
13352
- import path39 from "node:path";
13453
+ import { existsSync as existsSync12, readFileSync as readFileSync5 } from "node:fs";
13454
+ import path40 from "node:path";
13353
13455
 
13354
13456
  // src/core/verdict/makefile-expand.ts
13355
13457
  var MAX_EXPAND_DEPTH = 16;
@@ -13522,8 +13624,8 @@ var PNPM_BUILTIN_COMMANDS = /* @__PURE__ */ new Set([
13522
13624
  "why"
13523
13625
  ]);
13524
13626
  function readPackageJson(dir) {
13525
- const packagePath = path39.join(dir, "package.json");
13526
- if (!existsSync11(packagePath)) {
13627
+ const packagePath = path40.join(dir, "package.json");
13628
+ if (!existsSync12(packagePath)) {
13527
13629
  return null;
13528
13630
  }
13529
13631
  try {
@@ -13533,17 +13635,17 @@ function readPackageJson(dir) {
13533
13635
  }
13534
13636
  }
13535
13637
  function findPackageJson(startDir, stopDir) {
13536
- let current = path39.resolve(startDir);
13537
- const stop = path39.resolve(stopDir);
13638
+ let current = path40.resolve(startDir);
13639
+ const stop = path40.resolve(stopDir);
13538
13640
  while (true) {
13539
- const packagePath = path39.join(current, "package.json");
13540
- if (existsSync11(packagePath)) {
13641
+ const packagePath = path40.join(current, "package.json");
13642
+ if (existsSync12(packagePath)) {
13541
13643
  return packagePath;
13542
13644
  }
13543
- if (current === stop || current === path39.dirname(current)) {
13544
- return existsSync11(packagePath) ? packagePath : null;
13645
+ if (current === stop || current === path40.dirname(current)) {
13646
+ return existsSync12(packagePath) ? packagePath : null;
13545
13647
  }
13546
- const parent = path39.dirname(current);
13648
+ const parent = path40.dirname(current);
13547
13649
  if (!parent.startsWith(stop) && parent !== current) {
13548
13650
  }
13549
13651
  if (parent === current) {
@@ -13600,7 +13702,7 @@ function resolveNpmRecipe(cwd, repoRoot, scriptName, extraArgs) {
13600
13702
  }
13601
13703
  return { recipes: [], opaque: true, reason: "package_json_missing" };
13602
13704
  }
13603
- const pkg = readPackageJson(path39.dirname(packagePath));
13705
+ const pkg = readPackageJson(path40.dirname(packagePath));
13604
13706
  const scripts = pkg?.scripts;
13605
13707
  if (!scripts || typeof scripts !== "object") {
13606
13708
  return { recipes: [], opaque: true, reason: "package_scripts_missing" };
@@ -13691,20 +13793,20 @@ function parseMakefileRecipeContent(content) {
13691
13793
  function resolveMakeRecipe(cwd, repoRoot, target, cliVars = {}) {
13692
13794
  const candidates = ["Makefile", "makefile", "GNUmakefile"];
13693
13795
  let makefilePath = null;
13694
- let searchDir = path39.resolve(cwd);
13695
- const stop = path39.resolve(repoRoot);
13796
+ let searchDir = path40.resolve(cwd);
13797
+ const stop = path40.resolve(repoRoot);
13696
13798
  while (true) {
13697
13799
  for (const name of candidates) {
13698
- const candidate = path39.join(searchDir, name);
13699
- if (existsSync11(candidate)) {
13800
+ const candidate = path40.join(searchDir, name);
13801
+ if (existsSync12(candidate)) {
13700
13802
  makefilePath = candidate;
13701
13803
  break;
13702
13804
  }
13703
13805
  }
13704
- if (makefilePath || searchDir === stop || searchDir === path39.dirname(searchDir)) {
13806
+ if (makefilePath || searchDir === stop || searchDir === path40.dirname(searchDir)) {
13705
13807
  break;
13706
13808
  }
13707
- searchDir = path39.dirname(searchDir);
13809
+ searchDir = path40.dirname(searchDir);
13708
13810
  }
13709
13811
  if (!makefilePath) {
13710
13812
  return { recipes: [], opaque: true, reason: "unknown_local_effect" };
@@ -13731,7 +13833,7 @@ function resolveMakeRecipe(cwd, repoRoot, target, cliVars = {}) {
13731
13833
  }
13732
13834
  const entry = targets.get(name);
13733
13835
  if (!entry) {
13734
- if (!existsSync11(path39.resolve(path39.dirname(makefilePath), name))) {
13836
+ if (!existsSync12(path40.resolve(path40.dirname(makefilePath), name))) {
13735
13837
  hasUndefinedPrerequisite = true;
13736
13838
  }
13737
13839
  return;
@@ -13830,7 +13932,7 @@ function resolveLauncherRecipe(params) {
13830
13932
  }
13831
13933
 
13832
13934
  // src/core/verdict/parser.ts
13833
- import path40 from "node:path";
13935
+ import path41 from "node:path";
13834
13936
 
13835
13937
  // src/core/shell-substitution.ts
13836
13938
  function findStructuralCommandSubstitutions(command) {
@@ -14070,7 +14172,7 @@ var INTERPRETER_SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([
14070
14172
  ".sh"
14071
14173
  ]);
14072
14174
  function normalizeHead(token) {
14073
- const base = path40.basename(token);
14175
+ const base = path41.basename(token);
14074
14176
  if (base && base !== "." && base !== "..") {
14075
14177
  return base;
14076
14178
  }
@@ -14380,7 +14482,7 @@ function isBareInterpreter(tokens) {
14380
14482
  return false;
14381
14483
  }
14382
14484
  const scriptArg = args.find((token) => !token.startsWith("-"));
14383
- if (scriptArg && INTERPRETER_SCRIPT_EXTENSIONS.has(path40.extname(scriptArg))) {
14485
+ if (scriptArg && INTERPRETER_SCRIPT_EXTENSIONS.has(path41.extname(scriptArg))) {
14384
14486
  return false;
14385
14487
  }
14386
14488
  if (scriptArg) {
@@ -14620,7 +14722,7 @@ function mergeNodes(nodes) {
14620
14722
  }
14621
14723
 
14622
14724
  // src/core/effect-ir/shell-lower/argv-delegate-gate.ts
14623
- import path41 from "node:path";
14725
+ import path42 from "node:path";
14624
14726
  var ARGV_DELEGATE_INNER_BLOCKLIST = /* @__PURE__ */ new Set([
14625
14727
  "sudo",
14626
14728
  "env",
@@ -14641,7 +14743,7 @@ function shouldApplyArgvDelegate(head, innerTokens, depth) {
14641
14743
  if (ARGV_DELEGATE_INNER_BLOCKLIST.has(head)) {
14642
14744
  return false;
14643
14745
  }
14644
- const innerHead = path41.basename(innerTokens[0] ?? "");
14746
+ const innerHead = path42.basename(innerTokens[0] ?? "");
14645
14747
  if (ARGV_DELEGATE_INNER_BLOCKLIST.has(innerHead)) {
14646
14748
  return false;
14647
14749
  }
@@ -14748,7 +14850,7 @@ function withInnerProvenance(requirementValue, innerCommand, launcher, outerSegm
14748
14850
 
14749
14851
  // src/core/effect-ir/shell-lower/tokens.ts
14750
14852
  init_shell_tokenizer();
14751
- import path42 from "node:path";
14853
+ import path43 from "node:path";
14752
14854
  var ENV_PREFIX_PATTERN2 = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/;
14753
14855
  var LOOPBACK_HOSTS2 = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1", "0:0:0:0:0:0:0:1"]);
14754
14856
  var METADATA_ONLY_FLAGS = /* @__PURE__ */ new Set(["--version", "-v", "-V", "--help", "-h"]);
@@ -14892,9 +14994,9 @@ function resolvePathOperand(operand, cwd) {
14892
14994
  return process.env.HOME ?? operand;
14893
14995
  }
14894
14996
  if (operand.startsWith("~/")) {
14895
- return path42.join(process.env.HOME ?? "~", operand.slice(2));
14997
+ return path43.join(process.env.HOME ?? "~", operand.slice(2));
14896
14998
  }
14897
- return path42.resolve(cwd, operand);
14999
+ return path43.resolve(cwd, operand);
14898
15000
  }
14899
15001
  function isOptionToken(value) {
14900
15002
  return value.startsWith("-") || value.startsWith("+");
@@ -14906,7 +15008,7 @@ function pipeToShell(command) {
14906
15008
  return /(?:^|[|;&]\s*)(?:bash|sh|zsh|dash|fish)(?:\s|$)/.test(command) && /\|/.test(command);
14907
15009
  }
14908
15010
  function executableBaseName(head) {
14909
- return path42.basename(head);
15011
+ return path43.basename(head);
14910
15012
  }
14911
15013
  function isMetadataOnlyArgv(argv) {
14912
15014
  return argv.length > 0 && argv.every((token) => METADATA_ONLY_FLAGS.has(token));
@@ -15025,15 +15127,22 @@ function effectChangingEnvironmentSignals(head, env, changedNames) {
15025
15127
  }
15026
15128
 
15027
15129
  // src/core/effect-ir/shell-lower/decode-process.ts
15028
- import path46 from "node:path";
15130
+ import path47 from "node:path";
15029
15131
 
15030
15132
  // src/core/effect-ir/shell-lower/decoders/belay.ts
15031
- import path43 from "node:path";
15133
+ import path44 from "node:path";
15032
15134
  function decodeBelay(args, repoRoot, segment) {
15033
15135
  const [section, operation, key] = args;
15034
15136
  const judgeCommand = section === "judge" && operation !== void 0 && ["consent", "list", "status", "test", "use"].includes(operation);
15035
15137
  const configRead = section === "config" && (operation === void 0 || operation === "list" || operation === "get" && key?.startsWith("judge."));
15036
15138
  const configJudgeMutation = section === "config" && (["set", "unset"].includes(operation ?? "") && key?.startsWith("judge.") || operation === "credential" && key === "mode");
15139
+ const approvalAuthorityCommand = [
15140
+ "approval-token",
15141
+ "approve",
15142
+ "revoke",
15143
+ "standing-allow"
15144
+ ].includes(section ?? "");
15145
+ const configTrustMutation = section === "config" && operation === "trust";
15037
15146
  if (judgeCommand || configRead || configJudgeMutation) {
15038
15147
  return [
15039
15148
  processRequirement("belay", "inspect", segment, [
@@ -15042,12 +15151,23 @@ function decodeBelay(args, repoRoot, segment) {
15042
15151
  ])
15043
15152
  ];
15044
15153
  }
15154
+ if (approvalAuthorityCommand || configTrustMutation) {
15155
+ return [
15156
+ requirement2(
15157
+ "control_plane.write",
15158
+ "control_plane.write",
15159
+ { kind: "path", path: path44.join(repoRoot, ".belay-control-plane") },
15160
+ segment,
15161
+ [approvalAuthorityCommand ? "belay.approval_authority" : "belay.config_trust"]
15162
+ )
15163
+ ];
15164
+ }
15045
15165
  if (section === "config" && ["set", "unset", "credential"].includes(operation ?? "")) {
15046
15166
  return [
15047
15167
  requirement2(
15048
15168
  "control_plane.write",
15049
15169
  "control_plane.write",
15050
- { kind: "path", path: path43.join(repoRoot, ".belay-control-plane") },
15170
+ { kind: "path", path: path44.join(repoRoot, ".belay-control-plane") },
15051
15171
  segment,
15052
15172
  ["belay.config_non_judge_mutation"]
15053
15173
  )
@@ -15288,7 +15408,7 @@ function validDockerInfo(args) {
15288
15408
  // src/core/effect-ir/shell-lower/decoders/filesystem.ts
15289
15409
  init_git_resource_identity();
15290
15410
  import { lstatSync as lstatSync2, realpathSync as realpathSync4 } from "node:fs";
15291
- import path44 from "node:path";
15411
+ import path45 from "node:path";
15292
15412
  function decodeCopyMove(head, args, cwd, segment) {
15293
15413
  const requirements = [processRequirement(head, "spawn", segment, ["process.filesystem_mutation"])];
15294
15414
  const operands = [];
@@ -15416,11 +15536,11 @@ function decodeRm(args, cwd, repoRoot, segment) {
15416
15536
  function canonicalRmOperand(targetPath, finalOperandIsSymlink) {
15417
15537
  try {
15418
15538
  if (finalOperandIsSymlink) {
15419
- return path44.join(realpathSync4.native(path44.dirname(targetPath)), path44.basename(targetPath));
15539
+ return path45.join(realpathSync4.native(path45.dirname(targetPath)), path45.basename(targetPath));
15420
15540
  }
15421
15541
  return realpathSync4.native(targetPath);
15422
15542
  } catch {
15423
- return path44.resolve(targetPath);
15543
+ return path45.resolve(targetPath);
15424
15544
  }
15425
15545
  }
15426
15546
  function isSymbolicLink(targetPath) {
@@ -15431,8 +15551,8 @@ function isSymbolicLink(targetPath) {
15431
15551
  }
15432
15552
  }
15433
15553
  function pathContains(ancestor, candidate) {
15434
- const relative = path44.relative(path44.resolve(ancestor), path44.resolve(candidate));
15435
- return relative === "" || !relative.startsWith("..") && !path44.isAbsolute(relative);
15554
+ const relative = path45.relative(path45.resolve(ancestor), path45.resolve(candidate));
15555
+ return relative === "" || !relative.startsWith("..") && !path45.isAbsolute(relative);
15436
15556
  }
15437
15557
  function filesystemReadOperands(head, args) {
15438
15558
  switch (head) {
@@ -15572,7 +15692,7 @@ function decodePrisma(args, env, repoRoot, segment) {
15572
15692
 
15573
15693
  // src/core/effect-ir/shell-lower/decoders/ruby.ts
15574
15694
  init_path_utils();
15575
- import path45 from "node:path";
15695
+ import path46 from "node:path";
15576
15696
  var RAILS_READ_ONLY_SUBCOMMANDS = /* @__PURE__ */ new Set(["routes", "middleware", "stats", "about", "version"]);
15577
15697
  function railsReadOnlySubcommand(args) {
15578
15698
  const subcommand = args[0];
@@ -15582,7 +15702,7 @@ function railsReadOnlySubcommand(args) {
15582
15702
  return RAILS_READ_ONLY_SUBCOMMANDS.has(subcommand);
15583
15703
  }
15584
15704
  function isRubyTestScript(scriptPath) {
15585
- const base = path45.basename(scriptPath);
15705
+ const base = path46.basename(scriptPath);
15586
15706
  return base.endsWith("_test.rb") || base.endsWith("_spec.rb");
15587
15707
  }
15588
15708
  function parseRubyTestInvocation(args) {
@@ -15996,7 +16116,7 @@ function decodeProcessOrFilesystem(params) {
15996
16116
  requirement2(
15997
16117
  "fs.read",
15998
16118
  "fs.read",
15999
- { kind: "path", path: path46.resolve(cwd, syntax) },
16119
+ { kind: "path", path: path47.resolve(cwd, syntax) },
16000
16120
  segment,
16001
16121
  ["shell.syntax_source_read"]
16002
16122
  )
@@ -16202,7 +16322,7 @@ function packageExecInnerIsMetadata(peel) {
16202
16322
 
16203
16323
  // src/core/effect-ir/shell-lower/segment.ts
16204
16324
  init_shell_tokenizer();
16205
- import path47 from "node:path";
16325
+ import path48 from "node:path";
16206
16326
  var DYNAMIC_SHELL_VALUE_PATTERN = /(?:\$\(|`|\$(?:\d+|[@*#?$!-]|\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*))/;
16207
16327
  var SHELL_GLOB_PATTERN = /[*?[]/;
16208
16328
  function requiresKnownCwd(requirementValue) {
@@ -16217,11 +16337,11 @@ function joinNestedOpacity(outer, nested) {
16217
16337
  }
16218
16338
  function startsLocalPostgresService(command) {
16219
16339
  const tokens = tokenizeShell(command);
16220
- return path47.basename(tokens[0] ?? "") === "docker" && tokens[1] === "compose" && ["up", "start", "restart"].includes(tokens[2] ?? "") && tokens.includes("postgres");
16340
+ return path48.basename(tokens[0] ?? "") === "docker" && tokens[1] === "compose" && ["up", "start", "restart"].includes(tokens[2] ?? "") && tokens.includes("postgres");
16221
16341
  }
16222
16342
  function resolveCdTransition(command, currentCwd) {
16223
16343
  const tokens = tokenizeShell(command);
16224
- if (path47.basename(tokens[0] ?? "") !== "cd") {
16344
+ if (path48.basename(tokens[0] ?? "") !== "cd") {
16225
16345
  return null;
16226
16346
  }
16227
16347
  const target = tokens[1] ?? "~";
@@ -16384,7 +16504,7 @@ function lowerSegment(command, context) {
16384
16504
  stripStructuredRedirects(lexed.tokens),
16385
16505
  stripRedirects(parsedTokens)
16386
16506
  );
16387
- const head = path48.basename(tokens[0] ?? parsed.head);
16507
+ const head = path49.basename(tokens[0] ?? parsed.head);
16388
16508
  let opacity = segmentOpacity(command);
16389
16509
  const signals = /* @__PURE__ */ new Set();
16390
16510
  const requirements = [];
@@ -17236,7 +17356,7 @@ async function classifyToolUse(payload, repoRoot, cwd, config, options = {}) {
17236
17356
  };
17237
17357
  }
17238
17358
  const signals = [];
17239
- const resolvedPath = path49.isAbsolute(filePath) ? filePath : path49.resolve(cwd, filePath);
17359
+ const resolvedPath = path50.isAbsolute(filePath) ? filePath : path50.resolve(cwd, filePath);
17240
17360
  const hitsProtectedRoot = protectedRoots.some((root) => pathWithinRoot(root, resolvedPath));
17241
17361
  if (hitsProtectedRoot) {
17242
17362
  signals.push("control_plane_path");
@@ -17822,7 +17942,7 @@ function hashDecisionConfig(config) {
17822
17942
  init_fingerprint2();
17823
17943
 
17824
17944
  // src/version.ts
17825
- var PACKAGE_VERSION = "0.9.4";
17945
+ var PACKAGE_VERSION = "0.10.0";
17826
17946
 
17827
17947
  // src/runtime-provenance.ts
17828
17948
  function resolveRuntimeArtifactHash(artifactHash) {
@@ -17895,56 +18015,56 @@ function capabilityRequestsBlockRecovery(requests) {
17895
18015
  init_fingerprint2();
17896
18016
  init_path_utils();
17897
18017
  import { randomUUID as randomUUID5 } from "node:crypto";
17898
- import { existsSync as existsSync15 } from "node:fs";
17899
- import { mkdir as mkdir11, readdir as readdir3, readFile as readFile12, rename as rename3, rm as rm6 } from "node:fs/promises";
17900
- import path54 from "node:path";
18018
+ import { existsSync as existsSync16 } from "node:fs";
18019
+ import { mkdir as mkdir12, readdir as readdir3, readFile as readFile13, rename as rename4, rm as rm6 } from "node:fs/promises";
18020
+ import path55 from "node:path";
17901
18021
 
17902
18022
  // src/core/recovery/artifact-store.ts
17903
18023
  init_fingerprint2();
17904
18024
  init_path_utils();
17905
18025
  import { randomUUID as randomUUID4 } from "node:crypto";
17906
- import { existsSync as existsSync13 } from "node:fs";
17907
- import { lstat as lstat7, mkdir as mkdir10, open as open5, readdir as readdir2, readFile as readFile9, rename as rename2, rm as rm5, writeFile as writeFile7 } from "node:fs/promises";
17908
- import path51 from "node:path";
18026
+ import { existsSync as existsSync14 } from "node:fs";
18027
+ import { lstat as lstat7, mkdir as mkdir11, open as open6, readdir as readdir2, readFile as readFile10, rename as rename3, rm as rm5, writeFile as writeFile7 } from "node:fs/promises";
18028
+ import path52 from "node:path";
17909
18029
 
17910
18030
  // src/core/recovery/snapshot-node.ts
17911
18031
  init_fingerprint2();
17912
18032
  init_path_utils();
17913
18033
  import { createHash as createHash12 } from "node:crypto";
17914
- import { existsSync as existsSync12 } from "node:fs";
18034
+ import { existsSync as existsSync13 } from "node:fs";
17915
18035
  import {
17916
- chmod as chmod3,
18036
+ chmod as chmod4,
17917
18037
  copyFile as copyFile2,
17918
18038
  lstat as lstat6,
17919
- mkdir as mkdir9,
17920
- open as open4,
17921
- readFile as readFile8,
18039
+ mkdir as mkdir10,
18040
+ open as open5,
18041
+ readFile as readFile9,
17922
18042
  readlink as readlink4,
17923
18043
  rm as rm4,
17924
18044
  rmdir as rmdir2,
17925
18045
  symlink as symlink3,
17926
18046
  writeFile as writeFile6
17927
18047
  } from "node:fs/promises";
17928
- import path50 from "node:path";
18048
+ import path51 from "node:path";
17929
18049
  var RECOVERY_UNSUPPORTED_FILE_KIND = "recovery_unsupported_file_kind";
17930
18050
  function validRecoveryRelativePath(relativePath) {
17931
- if (!relativePath || relativePath.includes("\0") || path50.isAbsolute(relativePath)) return false;
17932
- const normalized = path50.normalize(relativePath);
17933
- return normalized !== "." && normalized !== ".." && !normalized.startsWith(`..${path50.sep}`);
18051
+ if (!relativePath || relativePath.includes("\0") || path51.isAbsolute(relativePath)) return false;
18052
+ const normalized = path51.normalize(relativePath);
18053
+ return normalized !== "." && normalized !== ".." && !normalized.startsWith(`..${path51.sep}`);
17934
18054
  }
17935
18055
  async function assertRecoverySafeTarget(resourceRoot, relativePath) {
17936
18056
  if (!validRecoveryRelativePath(relativePath)) throw new Error("recovery_path_escape");
17937
18057
  const root = canonicalPath(resourceRoot);
17938
- const target = path50.resolve(root, relativePath);
17939
- const relative = path50.relative(root, target);
17940
- if (relative === ".." || relative.startsWith(`..${path50.sep}`) || path50.isAbsolute(relative)) {
18058
+ const target = path51.resolve(root, relativePath);
18059
+ const relative = path51.relative(root, target);
18060
+ if (relative === ".." || relative.startsWith(`..${path51.sep}`) || path51.isAbsolute(relative)) {
17941
18061
  throw new Error("recovery_path_escape");
17942
18062
  }
17943
18063
  let current = root;
17944
- const parentParts = path50.relative(root, path50.dirname(target)).split(path50.sep).filter(Boolean);
18064
+ const parentParts = path51.relative(root, path51.dirname(target)).split(path51.sep).filter(Boolean);
17945
18065
  for (const part of parentParts) {
17946
- current = path50.join(current, part);
17947
- if (!existsSync12(current)) break;
18066
+ current = path51.join(current, part);
18067
+ if (!existsSync13(current)) break;
17948
18068
  const info = await lstat6(current);
17949
18069
  if (info.isSymbolicLink()) throw new Error("recovery_symlink_escape");
17950
18070
  if (!info.isDirectory()) break;
@@ -17952,7 +18072,7 @@ async function assertRecoverySafeTarget(resourceRoot, relativePath) {
17952
18072
  return target;
17953
18073
  }
17954
18074
  async function fsyncPath(filePath) {
17955
- const handle = await open4(filePath, "r");
18075
+ const handle = await open5(filePath, "r");
17956
18076
  try {
17957
18077
  await handle.sync();
17958
18078
  } finally {
@@ -17994,13 +18114,13 @@ async function captureRecoverySnapshot(filePath, options) {
17994
18114
  return { kind: "directory", mode, hash: recoveryDirectoryHash(mode) };
17995
18115
  }
17996
18116
  if (!info.isFile()) throw new Error(RECOVERY_UNSUPPORTED_FILE_KIND);
17997
- const content = await readFile8(filePath);
18117
+ const content = await readFile9(filePath);
17998
18118
  const hash = createHash12("sha256").update(content).digest("hex");
17999
18119
  let blob;
18000
18120
  if (options?.blobDir) {
18001
- await mkdir9(options.blobDir, { recursive: true, mode: 448 });
18002
- const blobPath = path50.join(options.blobDir, hash);
18003
- if (!existsSync12(blobPath)) {
18121
+ await mkdir10(options.blobDir, { recursive: true, mode: 448 });
18122
+ const blobPath = path51.join(options.blobDir, hash);
18123
+ if (!existsSync13(blobPath)) {
18004
18124
  await writeFile6(blobPath, content, { mode: 384 });
18005
18125
  await fsyncPath(blobPath);
18006
18126
  }
@@ -18054,7 +18174,7 @@ async function validateRecoverySnapshot(params) {
18054
18174
  if (record.blob !== `blobs/${record.hash}`) throw new Error(params.corruptReason);
18055
18175
  let content;
18056
18176
  try {
18057
- content = await readFile8(path50.join(params.artifactDir, record.blob));
18177
+ content = await readFile9(path51.join(params.artifactDir, record.blob));
18058
18178
  } catch {
18059
18179
  throw new Error(params.corruptReason);
18060
18180
  }
@@ -18082,16 +18202,16 @@ var RECOVERY_STATES = /* @__PURE__ */ new Set([
18082
18202
  ]);
18083
18203
  var STAGING_STALE_MS = 5 * 6e4;
18084
18204
  function checkpointsRoot(stateDir) {
18085
- return path51.join(stateDir, "recovery", "checkpoints");
18205
+ return path52.join(stateDir, "recovery", "checkpoints");
18086
18206
  }
18087
18207
  function checkpointDir(stateDir, checkpointId) {
18088
18208
  if (!/^cp_[a-f0-9]{24}$/.test(checkpointId)) {
18089
18209
  throw new Error("invalid_recovery_checkpoint_id");
18090
18210
  }
18091
- return path51.join(checkpointsRoot(stateDir), checkpointId);
18211
+ return path52.join(checkpointsRoot(stateDir), checkpointId);
18092
18212
  }
18093
18213
  async function fsyncPath2(filePath) {
18094
- const handle = await open5(filePath, "r");
18214
+ const handle = await open6(filePath, "r");
18095
18215
  try {
18096
18216
  await handle.sync();
18097
18217
  } finally {
@@ -18099,13 +18219,13 @@ async function fsyncPath2(filePath) {
18099
18219
  }
18100
18220
  }
18101
18221
  async function atomicWriteJson(filePath, value) {
18102
- await mkdir10(path51.dirname(filePath), { recursive: true, mode: 448 });
18222
+ await mkdir11(path52.dirname(filePath), { recursive: true, mode: 448 });
18103
18223
  const temporary = `${filePath}.tmp-${randomUUID4()}`;
18104
18224
  await writeFile7(temporary, `${JSON.stringify(value, null, 2)}
18105
18225
  `, { mode: 384 });
18106
18226
  await fsyncPath2(temporary);
18107
- await rename2(temporary, filePath);
18108
- await fsyncPath2(path51.dirname(filePath));
18227
+ await rename3(temporary, filePath);
18228
+ await fsyncPath2(path52.dirname(filePath));
18109
18229
  }
18110
18230
  async function writeRecoveryState(artifactDir, state, manifestHash, detail) {
18111
18231
  const value = {
@@ -18115,13 +18235,13 @@ async function writeRecoveryState(artifactDir, state, manifestHash, detail) {
18115
18235
  manifestHash,
18116
18236
  ...detail ? { detail } : {}
18117
18237
  };
18118
- await atomicWriteJson(path51.join(artifactDir, "state.json"), value);
18238
+ await atomicWriteJson(path52.join(artifactDir, "state.json"), value);
18119
18239
  }
18120
18240
  async function directorySize(root) {
18121
- if (!existsSync13(root)) return 0;
18241
+ if (!existsSync14(root)) return 0;
18122
18242
  let total = 0;
18123
18243
  for (const entry of await readdir2(root, { withFileTypes: true })) {
18124
- const entryPath = path51.join(root, entry.name);
18244
+ const entryPath = path52.join(root, entry.name);
18125
18245
  if (entry.isDirectory()) total += await directorySize(entryPath);
18126
18246
  else total += (await lstat7(entryPath)).size;
18127
18247
  }
@@ -18166,9 +18286,9 @@ async function readRecoveryArtifact(stateDir, checkpointId) {
18166
18286
  let rawManifest;
18167
18287
  let state;
18168
18288
  try {
18169
- rawManifest = JSON.parse(await readFile9(path51.join(artifactDir, "manifest.json"), "utf8"));
18289
+ rawManifest = JSON.parse(await readFile10(path52.join(artifactDir, "manifest.json"), "utf8"));
18170
18290
  state = JSON.parse(
18171
- await readFile9(path51.join(artifactDir, "state.json"), "utf8")
18291
+ await readFile10(path52.join(artifactDir, "state.json"), "utf8")
18172
18292
  );
18173
18293
  } catch {
18174
18294
  throw new Error(RECOVERY_CHECKPOINT_CORRUPT);
@@ -18184,10 +18304,10 @@ async function readRecoveryArtifact(stateDir, checkpointId) {
18184
18304
  }
18185
18305
  const entryPaths = /* @__PURE__ */ new Set();
18186
18306
  for (const entry of manifest.entries) {
18187
- if (!entry || typeof entry !== "object" || Array.isArray(entry) || Object.keys(entry).length !== 3 || !Object.keys(entry).every((key) => ["path", "before", "after"].includes(key)) || typeof entry.path !== "string" || !("before" in entry) || !("after" in entry) || !validRecoveryRelativePath(entry.path) || entryPaths.has(path51.normalize(entry.path))) {
18307
+ if (!entry || typeof entry !== "object" || Array.isArray(entry) || Object.keys(entry).length !== 3 || !Object.keys(entry).every((key) => ["path", "before", "after"].includes(key)) || typeof entry.path !== "string" || !("before" in entry) || !("after" in entry) || !validRecoveryRelativePath(entry.path) || entryPaths.has(path52.normalize(entry.path))) {
18188
18308
  throw new Error(RECOVERY_CHECKPOINT_CORRUPT);
18189
18309
  }
18190
- entryPaths.add(path51.normalize(entry.path));
18310
+ entryPaths.add(path52.normalize(entry.path));
18191
18311
  for (const [side, snapshot] of [
18192
18312
  ["before", entry.before],
18193
18313
  ["after", entry.after]
@@ -18201,9 +18321,9 @@ async function readRecoveryArtifact(stateDir, checkpointId) {
18201
18321
  });
18202
18322
  }
18203
18323
  }
18204
- const receiptPath = path51.join(artifactDir, "receipt.json");
18324
+ const receiptPath = path52.join(artifactDir, "receipt.json");
18205
18325
  let receipt;
18206
- if (["applied", "restoring", "restored", "conflict"].includes(state.state) || existsSync13(receiptPath)) {
18326
+ if (["applied", "restoring", "restored", "conflict"].includes(state.state) || existsSync14(receiptPath)) {
18207
18327
  receipt = await readAndValidateRecoveryReceipt(artifactDir, manifest, manifestHash);
18208
18328
  }
18209
18329
  return { artifactDir, manifest, state, manifestHash, ...receipt ? { receipt } : {} };
@@ -18211,7 +18331,7 @@ async function readRecoveryArtifact(stateDir, checkpointId) {
18211
18331
  async function readAndValidateRecoveryReceipt(artifactDir, manifest, manifestHash) {
18212
18332
  let rawReceipt;
18213
18333
  try {
18214
- rawReceipt = JSON.parse(await readFile9(path51.join(artifactDir, "receipt.json"), "utf8"));
18334
+ rawReceipt = JSON.parse(await readFile10(path52.join(artifactDir, "receipt.json"), "utf8"));
18215
18335
  } catch {
18216
18336
  throw new Error(RECOVERY_CHECKPOINT_CORRUPT);
18217
18337
  }
@@ -18234,8 +18354,8 @@ async function readAndValidateRecoveryReceipt(artifactDir, manifest, manifestHas
18234
18354
  return receipt;
18235
18355
  }
18236
18356
  async function ensureRecoveryReceipt(artifactDir, manifest, manifestHash) {
18237
- const receiptPath = path51.join(artifactDir, "receipt.json");
18238
- if (existsSync13(receiptPath)) {
18357
+ const receiptPath = path52.join(artifactDir, "receipt.json");
18358
+ if (existsSync14(receiptPath)) {
18239
18359
  return readAndValidateRecoveryReceipt(artifactDir, manifest, manifestHash);
18240
18360
  }
18241
18361
  const receipt = {
@@ -18252,14 +18372,14 @@ async function ensureRecoveryReceipt(artifactDir, manifest, manifestHash) {
18252
18372
  }
18253
18373
  async function checkpointIds(stateDir) {
18254
18374
  const root = checkpointsRoot(stateDir);
18255
- if (!existsSync13(root)) return [];
18375
+ if (!existsSync14(root)) return [];
18256
18376
  return (await readdir2(root, { withFileTypes: true })).filter((entry) => entry.isDirectory() && /^cp_[a-f0-9]{24}$/.test(entry.name)).map((entry) => entry.name);
18257
18377
  }
18258
18378
  async function artifactRepoRoot(stateDir, checkpointId) {
18259
18379
  const artifactDir = checkpointDir(stateDir, checkpointId);
18260
18380
  try {
18261
18381
  const manifest = JSON.parse(
18262
- await readFile9(path51.join(artifactDir, "manifest.json"), "utf8")
18382
+ await readFile10(path52.join(artifactDir, "manifest.json"), "utf8")
18263
18383
  );
18264
18384
  if (typeof manifest.repoRoot === "string" && manifest.repoRoot) {
18265
18385
  return canonicalPath(manifest.repoRoot);
@@ -18267,7 +18387,7 @@ async function artifactRepoRoot(stateDir, checkpointId) {
18267
18387
  } catch {
18268
18388
  }
18269
18389
  try {
18270
- const owner = JSON.parse(await readFile9(path51.join(artifactDir, "owner.json"), "utf8"));
18390
+ const owner = JSON.parse(await readFile10(path52.join(artifactDir, "owner.json"), "utf8"));
18271
18391
  return typeof owner.repoRoot === "string" && owner.repoRoot ? canonicalPath(owner.repoRoot) : null;
18272
18392
  } catch {
18273
18393
  return null;
@@ -18283,14 +18403,14 @@ async function checkpointIdsForRepo(stateDir, repoRoot) {
18283
18403
  }
18284
18404
  async function cleanupOrphanedStaging(stateDir) {
18285
18405
  const root = checkpointsRoot(stateDir);
18286
- if (!existsSync13(root)) return;
18406
+ if (!existsSync14(root)) return;
18287
18407
  const now = Date.now();
18288
18408
  for (const entry of await readdir2(root, { withFileTypes: true })) {
18289
18409
  if (!entry.isDirectory() || !/^\.tmp-cp_[a-f0-9]{24}$/.test(entry.name)) continue;
18290
- const stagingPath = path51.join(root, entry.name);
18410
+ const stagingPath = path52.join(root, entry.name);
18291
18411
  let stale = false;
18292
18412
  try {
18293
- const owner = JSON.parse(await readFile9(path51.join(stagingPath, "owner.json"), "utf8"));
18413
+ const owner = JSON.parse(await readFile10(path52.join(stagingPath, "owner.json"), "utf8"));
18294
18414
  const pid = typeof owner.pid === "number" ? owner.pid : Number.NaN;
18295
18415
  const createdAt = typeof owner.createdAt === "string" ? Date.parse(owner.createdAt) : NaN;
18296
18416
  let alive = false;
@@ -18330,9 +18450,9 @@ async function markRecoveryCheckpointApplied(stateDir, checkpoint) {
18330
18450
 
18331
18451
  // src/core/recovery/reconcile.ts
18332
18452
  init_fingerprint2();
18333
- import { existsSync as existsSync14 } from "node:fs";
18334
- import { readFile as readFile10 } from "node:fs/promises";
18335
- import path52 from "node:path";
18453
+ import { existsSync as existsSync15 } from "node:fs";
18454
+ import { readFile as readFile11 } from "node:fs/promises";
18455
+ import path53 from "node:path";
18336
18456
  async function matchRecoverySide(resourceRoot, entries, side) {
18337
18457
  for (const entry of entries) {
18338
18458
  const target = await assertRecoverySafeTarget(resourceRoot, entry.path);
@@ -18346,9 +18466,9 @@ async function reconcileRecoveryCheckpoint(stateDir, checkpointId) {
18346
18466
  loaded = await readRecoveryArtifact(stateDir, checkpointId);
18347
18467
  } catch {
18348
18468
  const artifactDir = checkpointDir(stateDir, checkpointId);
18349
- if (existsSync14(artifactDir)) {
18350
- const manifestPath = path52.join(artifactDir, "manifest.json");
18351
- const hash = existsSync14(manifestPath) ? hashValue(await readFile10(manifestPath, "utf8")) : "unavailable";
18469
+ if (existsSync15(artifactDir)) {
18470
+ const manifestPath = path53.join(artifactDir, "manifest.json");
18471
+ const hash = existsSync15(manifestPath) ? hashValue(await readFile11(manifestPath, "utf8")) : "unavailable";
18352
18472
  await writeRecoveryState(artifactDir, "corrupt", hash, RECOVERY_CHECKPOINT_CORRUPT);
18353
18473
  }
18354
18474
  return "corrupt";
@@ -18383,8 +18503,8 @@ async function reconcileRecoveryCheckpoint(stateDir, checkpointId) {
18383
18503
 
18384
18504
  // src/core/recovery/resource-identity.ts
18385
18505
  init_fingerprint2();
18386
- import { lstat as lstat8, readFile as readFile11, realpath as realpath3 } from "node:fs/promises";
18387
- import path53 from "node:path";
18506
+ import { lstat as lstat8, readFile as readFile12, realpath as realpath3 } from "node:fs/promises";
18507
+ import path54 from "node:path";
18388
18508
  async function currentRecoveryResourceIdentity(resourceRoot, resourceKind) {
18389
18509
  const resolvedRoot = await realpath3(resourceRoot);
18390
18510
  if (resourceKind === "directory") {
@@ -18392,13 +18512,13 @@ async function currentRecoveryResourceIdentity(resourceRoot, resourceKind) {
18392
18512
  if (!rootInfo.isDirectory()) throw new Error("recovery_repo_identity_unavailable");
18393
18513
  return hashValue(`${resolvedRoot}\0${rootInfo.dev}:${rootInfo.ino}:${rootInfo.birthtimeMs}`);
18394
18514
  }
18395
- const dotGit = path53.join(resolvedRoot, ".git");
18515
+ const dotGit = path54.join(resolvedRoot, ".git");
18396
18516
  const gitInfo = await lstat8(dotGit);
18397
18517
  let gitMetadataPath = dotGit;
18398
18518
  if (gitInfo.isFile()) {
18399
- const marker = (await readFile11(dotGit, "utf8")).trim();
18519
+ const marker = (await readFile12(dotGit, "utf8")).trim();
18400
18520
  if (!marker.startsWith("gitdir:")) throw new Error("recovery_repo_identity_unavailable");
18401
- gitMetadataPath = path53.resolve(resolvedRoot, marker.slice("gitdir:".length).trim());
18521
+ gitMetadataPath = path54.resolve(resolvedRoot, marker.slice("gitdir:".length).trim());
18402
18522
  } else if (!gitInfo.isDirectory()) {
18403
18523
  throw new Error("recovery_repo_identity_unavailable");
18404
18524
  }
@@ -18463,7 +18583,7 @@ async function garbageCollect(stateDir, config, repoRoot) {
18463
18583
  async function prepareRecoveryCheckpoint(params) {
18464
18584
  const backend = params.backend ?? "git_worktree";
18465
18585
  const resourceKind = await resolveRecoveryResourceKind(backend, params.repoRoot);
18466
- await mkdir11(checkpointsRoot(params.stateDir), { recursive: true, mode: 448 });
18586
+ await mkdir12(checkpointsRoot(params.stateDir), { recursive: true, mode: 448 });
18467
18587
  await cleanupOrphanedStaging(params.stateDir);
18468
18588
  await garbageCollect(params.stateDir, params.config, params.repoRoot);
18469
18589
  const existing = await checkpointIdsForRepo(params.stateDir, params.repoRoot);
@@ -18471,16 +18591,16 @@ async function prepareRecoveryCheckpoint(params) {
18471
18591
  throw new Error(RECOVERY_CHECKPOINT_QUOTA);
18472
18592
  }
18473
18593
  const checkpointId = `cp_${randomUUID5().replaceAll("-", "").slice(0, 24)}`;
18474
- const temporary = path54.join(checkpointsRoot(params.stateDir), `.tmp-${checkpointId}`);
18594
+ const temporary = path55.join(checkpointsRoot(params.stateDir), `.tmp-${checkpointId}`);
18475
18595
  const finalDir = checkpointDir(params.stateDir, checkpointId);
18476
- await mkdir11(temporary, { recursive: true, mode: 448 });
18477
- await atomicWriteJson(path54.join(temporary, "owner.json"), {
18596
+ await mkdir12(temporary, { recursive: true, mode: 448 });
18597
+ await atomicWriteJson(path55.join(temporary, "owner.json"), {
18478
18598
  version: 1,
18479
18599
  pid: process.pid,
18480
18600
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
18481
18601
  repoRoot: canonicalPath(params.repoRoot)
18482
18602
  });
18483
- await mkdir11(path54.join(temporary, "blobs"), { recursive: true, mode: 448 });
18603
+ await mkdir12(path55.join(temporary, "blobs"), { recursive: true, mode: 448 });
18484
18604
  try {
18485
18605
  const entries = [];
18486
18606
  const protectedRoots = (params.protectedRoots ?? []).map(canonicalPath);
@@ -18489,8 +18609,8 @@ async function prepareRecoveryCheckpoint(params) {
18489
18609
  )) {
18490
18610
  const target = await assertRecoverySafeTarget(params.repoRoot, change.relativePath);
18491
18611
  if (protectedRoots.some((root) => {
18492
- const relative = path54.relative(root, target);
18493
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path54.sep}`) && !path54.isAbsolute(relative);
18612
+ const relative = path55.relative(root, target);
18613
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path55.sep}`) && !path55.isAbsolute(relative);
18494
18614
  })) {
18495
18615
  throw new Error("recovery_protected_path");
18496
18616
  }
@@ -18502,7 +18622,7 @@ async function prepareRecoveryCheckpoint(params) {
18502
18622
  entries.push({
18503
18623
  path: change.relativePath,
18504
18624
  before: await captureRecoverySnapshot(baseline, {
18505
- blobDir: path54.join(temporary, "blobs")
18625
+ blobDir: path55.join(temporary, "blobs")
18506
18626
  }),
18507
18627
  after: withoutRecoveryBlob(await captureRecoverySnapshot(source))
18508
18628
  });
@@ -18539,12 +18659,12 @@ async function prepareRecoveryCheckpoint(params) {
18539
18659
  entries
18540
18660
  };
18541
18661
  const manifestHash = hashValue(canonicalStringify(manifest));
18542
- await atomicWriteJson(path54.join(temporary, "manifest.json"), manifest);
18662
+ await atomicWriteJson(path55.join(temporary, "manifest.json"), manifest);
18543
18663
  await writeRecoveryState(temporary, "prepared", manifestHash);
18544
18664
  await fsyncPath2(temporary);
18545
18665
  const projectedBytes = await recoveryCheckpointStorageBytes(params.stateDir, params.repoRoot);
18546
18666
  if (projectedBytes > params.config.maxBytes) throw new Error(RECOVERY_CHECKPOINT_QUOTA);
18547
- await rename3(temporary, finalDir);
18667
+ await rename4(temporary, finalDir);
18548
18668
  await fsyncPath2(checkpointsRoot(params.stateDir));
18549
18669
  return {
18550
18670
  checkpointId,
@@ -18582,7 +18702,7 @@ async function listRecoveryCheckpoints(stateDir, repoRoot) {
18582
18702
  } catch {
18583
18703
  try {
18584
18704
  const raw = JSON.parse(
18585
- await readFile12(path54.join(checkpointDir(stateDir, id), "manifest.json"), "utf8")
18705
+ await readFile13(path55.join(checkpointDir(stateDir, id), "manifest.json"), "utf8")
18586
18706
  );
18587
18707
  rootFromArtifact = typeof raw.repoRoot === "string" && raw.repoRoot ? raw.repoRoot : void 0;
18588
18708
  } catch {
@@ -18616,7 +18736,7 @@ async function listRecoveryCheckpoints(stateDir, repoRoot) {
18616
18736
  } catch {
18617
18737
  try {
18618
18738
  const manifest = JSON.parse(
18619
- await readFile12(path54.join(checkpointDir(stateDir, id), "manifest.json"), "utf8")
18739
+ await readFile13(path55.join(checkpointDir(stateDir, id), "manifest.json"), "utf8")
18620
18740
  );
18621
18741
  if (manifest.checkpointId !== id || ![1, 2].includes(manifest.version)) continue;
18622
18742
  if (repoRoot && canonicalPath(manifest.repoRoot) !== canonicalPath(repoRoot)) continue;
@@ -18641,12 +18761,12 @@ async function listRecoveryCheckpoints(stateDir, repoRoot) {
18641
18761
  async function recoveryCheckpointStorageBytes(stateDir, repoRoot) {
18642
18762
  const root = checkpointsRoot(stateDir);
18643
18763
  if (!repoRoot) return directorySize(root);
18644
- if (!existsSync15(root)) return 0;
18764
+ if (!existsSync16(root)) return 0;
18645
18765
  const expected = canonicalPath(repoRoot);
18646
18766
  let total = 0;
18647
18767
  for (const entry of await readdir3(root, { withFileTypes: true })) {
18648
18768
  if (!entry.isDirectory()) continue;
18649
- const entryPath = path54.join(root, entry.name);
18769
+ const entryPath = path55.join(root, entry.name);
18650
18770
  if (/^cp_[a-f0-9]{24}$/.test(entry.name)) {
18651
18771
  if (await artifactRepoRoot(stateDir, entry.name) === expected) {
18652
18772
  total += await directorySize(entryPath);
@@ -18655,7 +18775,7 @@ async function recoveryCheckpointStorageBytes(stateDir, repoRoot) {
18655
18775
  }
18656
18776
  if (/^\.tmp-cp_[a-f0-9]{24}$/.test(entry.name)) {
18657
18777
  try {
18658
- const owner = JSON.parse(await readFile12(path54.join(entryPath, "owner.json"), "utf8"));
18778
+ const owner = JSON.parse(await readFile13(path55.join(entryPath, "owner.json"), "utf8"));
18659
18779
  if (typeof owner.repoRoot === "string" && canonicalPath(owner.repoRoot) === expected) {
18660
18780
  total += await directorySize(entryPath);
18661
18781
  }
@@ -18697,16 +18817,16 @@ function recoveryFailClosedResult(predicted, reason, signals = []) {
18697
18817
  init_scrub();
18698
18818
 
18699
18819
  // src/core/transactional/file-checkpoint-backend.ts
18700
- import { cp, lstat as lstat11, mkdir as mkdir13, mkdtemp as mkdtemp5, readdir as readdir6, rm as rm9, writeFile as writeFile10 } from "node:fs/promises";
18820
+ import { cp, lstat as lstat11, mkdir as mkdir14, mkdtemp as mkdtemp5, readdir as readdir6, rm as rm9, writeFile as writeFile10 } from "node:fs/promises";
18701
18821
  import os5 from "node:os";
18702
- import path58 from "node:path";
18822
+ import path59 from "node:path";
18703
18823
 
18704
18824
  // src/core/transactional/file-checkpoint-git.ts
18705
18825
  init_path_utils();
18706
18826
  import { spawn as spawn8 } from "node:child_process";
18707
18827
  import { createHash as createHash13 } from "node:crypto";
18708
- import { copyFile as copyFile3, lstat as lstat9, readdir as readdir4, readFile as readFile13 } from "node:fs/promises";
18709
- import path55 from "node:path";
18828
+ import { copyFile as copyFile3, lstat as lstat9, readdir as readdir4, readFile as readFile14 } from "node:fs/promises";
18829
+ import path56 from "node:path";
18710
18830
  var FILE_CHECKPOINT_GIT_METADATA_CHANGED = "file_checkpoint_git_metadata_changed";
18711
18831
  var FILE_CHECKPOINT_SOURCE_CHANGED = "file_checkpoint_source_changed";
18712
18832
  var FILE_CHECKPOINT_CWD_OUTSIDE_ROOT = "file_checkpoint_cwd_outside_root";
@@ -18740,7 +18860,7 @@ function rethrowStableFileCheckpointError(error) {
18740
18860
  }
18741
18861
  async function rootGitMetadataPresent(repoRoot) {
18742
18862
  try {
18743
- await lstat9(path55.join(repoRoot, ".git"));
18863
+ await lstat9(path56.join(repoRoot, ".git"));
18744
18864
  return true;
18745
18865
  } catch {
18746
18866
  return false;
@@ -18789,10 +18909,10 @@ function execGit2(repoRoot, args) {
18789
18909
  }
18790
18910
  async function resolveGitPath(repoRoot, gitPath) {
18791
18911
  const trimmed = gitPath.trim();
18792
- if (path55.isAbsolute(trimmed)) {
18912
+ if (path56.isAbsolute(trimmed)) {
18793
18913
  return trimmed;
18794
18914
  }
18795
- return path55.join(repoRoot, trimmed);
18915
+ return path56.join(repoRoot, trimmed);
18796
18916
  }
18797
18917
  async function cloneBareWorktreeCopy(sourceRoot, destinationRoot) {
18798
18918
  await execGit2(sourceRoot, [
@@ -18834,7 +18954,7 @@ async function copyGitIndexState(sourceRoot, destinationRoot) {
18834
18954
  destinationRoot,
18835
18955
  await execGit2(destinationRoot, ["rev-parse", "--git-dir"])
18836
18956
  );
18837
- const destinationShared = path55.join(destinationGitDir, path55.basename(sourceShared));
18957
+ const destinationShared = path56.join(destinationGitDir, path56.basename(sourceShared));
18838
18958
  try {
18839
18959
  await copyFile3(sourceShared, destinationShared);
18840
18960
  } catch (error) {
@@ -18843,14 +18963,14 @@ async function copyGitIndexState(sourceRoot, destinationRoot) {
18843
18963
  }
18844
18964
  async function readGitFile(gitDir, relativePath) {
18845
18965
  try {
18846
- return await readFile13(path55.join(gitDir, relativePath));
18966
+ return await readFile14(path56.join(gitDir, relativePath));
18847
18967
  } catch {
18848
18968
  return null;
18849
18969
  }
18850
18970
  }
18851
18971
  async function readAbsoluteGitFile(absolutePath) {
18852
18972
  try {
18853
- return await readFile13(absolutePath);
18973
+ return await readFile14(absolutePath);
18854
18974
  } catch {
18855
18975
  return null;
18856
18976
  }
@@ -18867,8 +18987,8 @@ async function hashResolvedGitPath(repoRoot, gitDir, gitPath, hash) {
18867
18987
  repoRoot,
18868
18988
  await execGit2(repoRoot, ["rev-parse", "--git-path", gitPath])
18869
18989
  );
18870
- const relative = path55.resolve(resolved).startsWith(path55.resolve(gitDir)) ? path55.relative(gitDir, resolved) : resolved;
18871
- const content = typeof relative === "string" && !relative.startsWith("..") && !path55.isAbsolute(relative) ? await readGitFile(gitDir, relative) : await readAbsoluteGitFile(resolved);
18990
+ const relative = path56.resolve(resolved).startsWith(path56.resolve(gitDir)) ? path56.relative(gitDir, resolved) : resolved;
18991
+ const content = typeof relative === "string" && !relative.startsWith("..") && !path56.isAbsolute(relative) ? await readGitFile(gitDir, relative) : await readAbsoluteGitFile(resolved);
18872
18992
  if (content !== null) {
18873
18993
  hashGitFileContent(hash, gitPath, content);
18874
18994
  }
@@ -18878,13 +18998,13 @@ async function hashResolvedGitPath(repoRoot, gitDir, gitPath, hash) {
18878
18998
  async function hashGitTree(gitDir, relativeDir, hash) {
18879
18999
  let names;
18880
19000
  try {
18881
- names = await readdir4(path55.join(gitDir, relativeDir));
19001
+ names = await readdir4(path56.join(gitDir, relativeDir));
18882
19002
  } catch {
18883
19003
  return;
18884
19004
  }
18885
19005
  for (const name of names.sort()) {
18886
- const relativePath = relativeDir ? path55.join(relativeDir, name) : name;
18887
- const absolutePath = path55.join(gitDir, relativePath);
19006
+ const relativePath = relativeDir ? path56.join(relativeDir, name) : name;
19007
+ const absolutePath = path56.join(gitDir, relativePath);
18888
19008
  let childNames = null;
18889
19009
  try {
18890
19010
  childNames = await readdir4(absolutePath);
@@ -18906,7 +19026,7 @@ async function hashGitTree(gitDir, relativeDir, hash) {
18906
19026
  }
18907
19027
  async function computeGitMetadataFingerprint(repoRoot) {
18908
19028
  const gitDirRel = (await execGit2(repoRoot, ["rev-parse", "--git-dir"])).trim();
18909
- const gitDir = path55.isAbsolute(gitDirRel) ? gitDirRel : path55.join(repoRoot, gitDirRel);
19029
+ const gitDir = path56.isAbsolute(gitDirRel) ? gitDirRel : path56.join(repoRoot, gitDirRel);
18910
19030
  const hash = createHash13("sha256");
18911
19031
  for (const file of [
18912
19032
  "HEAD",
@@ -18929,8 +19049,8 @@ async function computeGitMetadataFingerprint(repoRoot) {
18929
19049
  const sharedIndex = (await execGit2(repoRoot, ["rev-parse", "--shared-index-path"])).trim();
18930
19050
  if (sharedIndex) {
18931
19051
  const resolved = await resolveGitPath(repoRoot, sharedIndex);
18932
- const relative = path55.relative(gitDir, resolved);
18933
- const content = relative && !relative.startsWith("..") && !path55.isAbsolute(relative) ? await readGitFile(gitDir, relative) : await readAbsoluteGitFile(resolved);
19052
+ const relative = path56.relative(gitDir, resolved);
19053
+ const content = relative && !relative.startsWith("..") && !path56.isAbsolute(relative) ? await readGitFile(gitDir, relative) : await readAbsoluteGitFile(resolved);
18934
19054
  if (content !== null) {
18935
19055
  hashGitFileContent(hash, "shared-index", content);
18936
19056
  }
@@ -18941,7 +19061,7 @@ async function computeGitMetadataFingerprint(repoRoot) {
18941
19061
  await hashResolvedGitPath(repoRoot, gitDir, gitPath, hash);
18942
19062
  }
18943
19063
  try {
18944
- const rootGitPath = path55.join(repoRoot, ".git");
19064
+ const rootGitPath = path56.join(repoRoot, ".git");
18945
19065
  const rootGitInfo = await lstat9(rootGitPath);
18946
19066
  if (rootGitInfo.isFile()) {
18947
19067
  const content = await readAbsoluteGitFile(rootGitPath);
@@ -18957,14 +19077,14 @@ async function computeGitMetadataFingerprint(repoRoot) {
18957
19077
  function resolveExecutionCwdRelative(resourceRoot, cwd) {
18958
19078
  const resolvedCwd = canonicalPath(cwd);
18959
19079
  const resourceCanonical = canonicalPath(resourceRoot);
18960
- const relative = path55.relative(resourceCanonical, resolvedCwd);
19080
+ const relative = path56.relative(resourceCanonical, resolvedCwd);
18961
19081
  if (relative === "" || relative === ".") {
18962
19082
  return "";
18963
19083
  }
18964
- if (relative.startsWith("..") || path55.isAbsolute(relative)) {
19084
+ if (relative.startsWith("..") || path56.isAbsolute(relative)) {
18965
19085
  throw new Error(FILE_CHECKPOINT_CWD_OUTSIDE_ROOT);
18966
19086
  }
18967
- return relative.split(path55.sep).join("/");
19087
+ return relative.split(path56.sep).join("/");
18968
19088
  }
18969
19089
 
18970
19090
  // src/core/transactional/file-checkpoint-isolation.ts
@@ -18985,8 +19105,8 @@ function fileCheckpointIsolationReason(context) {
18985
19105
  }
18986
19106
 
18987
19107
  // src/core/transactional/file-checkpoint-staging.ts
18988
- import { readdir as readdir5, readFile as readFile14, rm as rm7, writeFile as writeFile8 } from "node:fs/promises";
18989
- import path56 from "node:path";
19108
+ import { readdir as readdir5, readFile as readFile15, rm as rm7, writeFile as writeFile8 } from "node:fs/promises";
19109
+ import path57 from "node:path";
18990
19110
  function isOwnerProcessAlive(pid) {
18991
19111
  try {
18992
19112
  process.kill(pid, 0);
@@ -18996,12 +19116,12 @@ function isOwnerProcessAlive(pid) {
18996
19116
  }
18997
19117
  }
18998
19118
  async function writeOwnerMarker(stagingRoot, marker) {
18999
- await writeFile8(path56.join(stagingRoot, "owner.json"), `${JSON.stringify(marker)}
19119
+ await writeFile8(path57.join(stagingRoot, "owner.json"), `${JSON.stringify(marker)}
19000
19120
  `, "utf8");
19001
19121
  }
19002
19122
  async function readOwnerMarker(stagingRoot) {
19003
19123
  try {
19004
- const raw = await readFile14(path56.join(stagingRoot, "owner.json"), "utf8");
19124
+ const raw = await readFile15(path57.join(stagingRoot, "owner.json"), "utf8");
19005
19125
  return JSON.parse(raw.trim());
19006
19126
  } catch {
19007
19127
  return null;
@@ -19019,7 +19139,7 @@ async function collectDeadOwnerStaging(parentDir) {
19019
19139
  if (!name.startsWith("belay-file-checkpoint-")) {
19020
19140
  continue;
19021
19141
  }
19022
- const stagingRoot = path56.join(parentDir, name);
19142
+ const stagingRoot = path57.join(parentDir, name);
19023
19143
  const marker = await readOwnerMarker(stagingRoot);
19024
19144
  if (!marker) {
19025
19145
  dead.push(stagingRoot);
@@ -19042,7 +19162,7 @@ import { constants as fsConstants2 } from "node:fs";
19042
19162
  import {
19043
19163
  copyFile as copyFile4,
19044
19164
  lstat as lstat10,
19045
- mkdir as mkdir12,
19165
+ mkdir as mkdir13,
19046
19166
  mkdtemp as mkdtemp4,
19047
19167
  readlink as readlink5,
19048
19168
  rm as rm8,
@@ -19051,17 +19171,17 @@ import {
19051
19171
  writeFile as writeFile9
19052
19172
  } from "node:fs/promises";
19053
19173
  import os4 from "node:os";
19054
- import path57 from "node:path";
19174
+ import path58 from "node:path";
19055
19175
  var FILE_CHECKPOINT_COPY_FAILED = "file_checkpoint_copy_failed";
19056
19176
  async function chmodSafe2(target, mode) {
19057
19177
  try {
19058
- const { chmod: chmod4 } = await import("node:fs/promises");
19059
- await chmod4(target, mode & 511);
19178
+ const { chmod: chmod5 } = await import("node:fs/promises");
19179
+ await chmod5(target, mode & 511);
19060
19180
  } catch {
19061
19181
  }
19062
19182
  }
19063
19183
  async function copyRegularFile(sourcePath, destinationPath, mode, strategy) {
19064
- await mkdir12(path57.dirname(destinationPath), { recursive: true });
19184
+ await mkdir13(path58.dirname(destinationPath), { recursive: true });
19065
19185
  if (strategy === "clonefile" && fsConstants2.COPYFILE_FICLONE !== void 0) {
19066
19186
  try {
19067
19187
  await copyFile4(sourcePath, destinationPath, fsConstants2.COPYFILE_FICLONE);
@@ -19083,11 +19203,11 @@ async function copyNode(sourceRoot, destinationRoot, relativePath, strategy) {
19083
19203
  const info = await lstat10(sourcePath);
19084
19204
  await rm8(destinationPath, { force: true, recursive: false });
19085
19205
  if (info.isDirectory() && !info.isSymbolicLink()) {
19086
- await mkdir12(destinationPath, { recursive: true, mode: info.mode & 511 });
19206
+ await mkdir13(destinationPath, { recursive: true, mode: info.mode & 511 });
19087
19207
  return strategy;
19088
19208
  }
19089
19209
  if (info.isSymbolicLink()) {
19090
- await mkdir12(path57.dirname(destinationPath), { recursive: true });
19210
+ await mkdir13(path58.dirname(destinationPath), { recursive: true });
19091
19211
  await symlink4(await readlink5(sourcePath), destinationPath);
19092
19212
  return strategy;
19093
19213
  }
@@ -19143,9 +19263,9 @@ async function mapWithConcurrency(items, concurrency, worker) {
19143
19263
  async function probeFileCloneStrategy() {
19144
19264
  let tempDir = null;
19145
19265
  try {
19146
- tempDir = await mkdtemp4(path57.join(os4.tmpdir(), "belay-clone-probe-"));
19147
- const source = path57.join(tempDir, "source.txt");
19148
- const destination = path57.join(tempDir, "dest.txt");
19266
+ tempDir = await mkdtemp4(path58.join(os4.tmpdir(), "belay-clone-probe-"));
19267
+ const source = path58.join(tempDir, "source.txt");
19268
+ const destination = path58.join(tempDir, "dest.txt");
19149
19269
  await writeFile9(source, "probe\n");
19150
19270
  if (fsConstants2.COPYFILE_FICLONE_FORCE !== void 0) {
19151
19271
  try {
@@ -19298,11 +19418,11 @@ async function protectedRootState(root) {
19298
19418
  return `directory:${node.hash}:${index.treeHash}`;
19299
19419
  }
19300
19420
  function executionProtectedRoot(resourceRoot, executionRoot, protectedRoot) {
19301
- const relative = path58.relative(path58.resolve(resourceRoot), path58.resolve(protectedRoot));
19302
- if (relative === "" || relative.startsWith("..") || path58.isAbsolute(relative)) {
19421
+ const relative = path59.relative(path59.resolve(resourceRoot), path59.resolve(protectedRoot));
19422
+ if (relative === "" || relative.startsWith("..") || path59.isAbsolute(relative)) {
19303
19423
  return null;
19304
19424
  }
19305
- return path58.join(executionRoot, relative);
19425
+ return path59.join(executionRoot, relative);
19306
19426
  }
19307
19427
  async function captureProtectedRootStates(resourceRoot, executionRoot, protectedRoots) {
19308
19428
  const states = /* @__PURE__ */ new Map();
@@ -19327,15 +19447,15 @@ async function directoryByteSize(root, deadlineMs) {
19327
19447
  }
19328
19448
  let total = 0;
19329
19449
  for (const name of await readdir6(root)) {
19330
- total += await directoryByteSize(path58.join(root, name), deadlineMs);
19450
+ total += await directoryByteSize(path59.join(root, name), deadlineMs);
19331
19451
  }
19332
19452
  return total;
19333
19453
  }
19334
19454
  async function copyGitMetadataDirectory(sourceRoot, destinationRoot) {
19335
19455
  const gitDirRel = (await execGit2(sourceRoot, ["rev-parse", "--git-dir"])).trim();
19336
- const sourceGitDir = path58.isAbsolute(gitDirRel) ? gitDirRel : path58.join(sourceRoot, gitDirRel);
19337
- const relativeGitDir = path58.relative(path58.resolve(sourceRoot), path58.resolve(sourceGitDir));
19338
- const destinationGitDir = relativeGitDir && !relativeGitDir.startsWith("..") ? path58.join(destinationRoot, relativeGitDir) : path58.join(destinationRoot, ".git");
19456
+ const sourceGitDir = path59.isAbsolute(gitDirRel) ? gitDirRel : path59.join(sourceRoot, gitDirRel);
19457
+ const relativeGitDir = path59.relative(path59.resolve(sourceRoot), path59.resolve(sourceGitDir));
19458
+ const destinationGitDir = relativeGitDir && !relativeGitDir.startsWith("..") ? path59.join(destinationRoot, relativeGitDir) : path59.join(destinationRoot, ".git");
19339
19459
  await cp(sourceGitDir, destinationGitDir, { recursive: true, force: true });
19340
19460
  }
19341
19461
  async function prepareDirtyGitSnapshot(context) {
@@ -19344,7 +19464,7 @@ async function prepareDirtyGitSnapshot(context) {
19344
19464
  const quotas = context.fileCheckpoint;
19345
19465
  const deadlineMs = Date.now() + quotas.prepareTimeoutMs;
19346
19466
  await removeDeadOwnerStaging(os5.tmpdir());
19347
- const stagingRoot = await mkdtemp5(path58.join(os5.tmpdir(), "belay-file-checkpoint-"));
19467
+ const stagingRoot = await mkdtemp5(path59.join(os5.tmpdir(), "belay-file-checkpoint-"));
19348
19468
  await writeOwnerMarker(stagingRoot, {
19349
19469
  version: 1,
19350
19470
  pid: process.pid,
@@ -19352,8 +19472,8 @@ async function prepareDirtyGitSnapshot(context) {
19352
19472
  resourceRoot: context.repoRoot,
19353
19473
  backend: "file_checkpoint"
19354
19474
  });
19355
- const baselineRoot = path58.join(stagingRoot, "baseline");
19356
- const executionRoot = path58.join(stagingRoot, "execution");
19475
+ const baselineRoot = path59.join(stagingRoot, "baseline");
19476
+ const executionRoot = path59.join(stagingRoot, "execution");
19357
19477
  try {
19358
19478
  resolveExecutionCwdRelative(context.repoRoot, context.cwd);
19359
19479
  const sourceGitMetadataFingerprint = await computeGitMetadataFingerprint(context.repoRoot);
@@ -19387,7 +19507,7 @@ async function prepareDirtyGitSnapshot(context) {
19387
19507
  throw new Error(FILE_CHECKPOINT_SOURCE_CHANGED);
19388
19508
  }
19389
19509
  await writeFile10(
19390
- path58.join(stagingRoot, "baseline-index.json"),
19510
+ path59.join(stagingRoot, "baseline-index.json"),
19391
19511
  `${JSON.stringify(baselineIndex)}
19392
19512
  `,
19393
19513
  "utf8"
@@ -19437,7 +19557,7 @@ async function prepareNonGitSnapshot(context) {
19437
19557
  const quotas = context.fileCheckpoint;
19438
19558
  const deadlineMs = Date.now() + quotas.prepareTimeoutMs;
19439
19559
  await removeDeadOwnerStaging(os5.tmpdir());
19440
- const stagingRoot = await mkdtemp5(path58.join(os5.tmpdir(), "belay-file-checkpoint-"));
19560
+ const stagingRoot = await mkdtemp5(path59.join(os5.tmpdir(), "belay-file-checkpoint-"));
19441
19561
  await writeOwnerMarker(stagingRoot, {
19442
19562
  version: 1,
19443
19563
  pid: process.pid,
@@ -19445,8 +19565,8 @@ async function prepareNonGitSnapshot(context) {
19445
19565
  resourceRoot: context.repoRoot,
19446
19566
  backend: "file_checkpoint"
19447
19567
  });
19448
- const baselineRoot = path58.join(stagingRoot, "baseline");
19449
- const executionRoot = path58.join(stagingRoot, "execution");
19568
+ const baselineRoot = path59.join(stagingRoot, "baseline");
19569
+ const executionRoot = path59.join(stagingRoot, "execution");
19450
19570
  try {
19451
19571
  resolveExecutionCwdRelative(context.repoRoot, context.cwd);
19452
19572
  const resourceIdentity = await currentRecoveryResourceIdentity(context.repoRoot, "directory");
@@ -19455,7 +19575,7 @@ async function prepareNonGitSnapshot(context) {
19455
19575
  quotas,
19456
19576
  deadlineMs
19457
19577
  });
19458
- await mkdir13(baselineRoot, { recursive: true });
19578
+ await mkdir14(baselineRoot, { recursive: true });
19459
19579
  const baselineIndex = await buildFileTreeIndex({
19460
19580
  resourceRoot: baselineRoot,
19461
19581
  excludedRoots,
@@ -19475,7 +19595,7 @@ async function prepareNonGitSnapshot(context) {
19475
19595
  throw new Error(FILE_CHECKPOINT_SOURCE_CHANGED);
19476
19596
  }
19477
19597
  await writeFile10(
19478
- path58.join(stagingRoot, "baseline-index.json"),
19598
+ path59.join(stagingRoot, "baseline-index.json"),
19479
19599
  `${JSON.stringify(baselineIndex)}
19480
19600
  `,
19481
19601
  "utf8"
@@ -19485,7 +19605,7 @@ async function prepareNonGitSnapshot(context) {
19485
19605
  quotas,
19486
19606
  deadlineMs
19487
19607
  });
19488
- await mkdir13(executionRoot, { recursive: true });
19608
+ await mkdir14(executionRoot, { recursive: true });
19489
19609
  const finalSourceIndex = await buildFileTreeIndex({
19490
19610
  resourceRoot: context.repoRoot,
19491
19611
  excludedRoots,
@@ -19828,10 +19948,10 @@ async function selectTransactionalBackend(context) {
19828
19948
  }
19829
19949
 
19830
19950
  // src/core/transactional/diff-evaluator.ts
19831
- import path59 from "node:path";
19951
+ import path60 from "node:path";
19832
19952
  init_path_utils();
19833
19953
  function categorizeChange(change, ctx) {
19834
- const absolutePath = canonicalPath(path59.join(ctx.repoRoot, change.relativePath));
19954
+ const absolutePath = canonicalPath(path60.join(ctx.repoRoot, change.relativePath));
19835
19955
  if (!pathWithinRoot(ctx.repoRoot, absolutePath)) {
19836
19956
  return "repo_outside";
19837
19957
  }
@@ -20381,17 +20501,55 @@ function formatJudgeInfrastructureDenyMessage(params) {
20381
20501
  }
20382
20502
 
20383
20503
  // src/core/notify.ts
20504
+ init_path_utils();
20384
20505
  import { execFile } from "node:child_process";
20506
+ import path61 from "node:path";
20385
20507
  import { promisify } from "node:util";
20386
20508
  var execFileAsync = promisify(execFile);
20387
- async function notifyDeny(config, event) {
20388
- const payload = JSON.stringify(event);
20389
- if (config.webhookUrl) {
20509
+ var LOOPBACK_WEBHOOK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
20510
+ function webhookConfigIssue(url) {
20511
+ let parsed;
20512
+ try {
20513
+ parsed = new URL(url);
20514
+ } catch {
20515
+ return `notifications.webhookUrl is invalid: ${url}`;
20516
+ }
20517
+ if (parsed.protocol === "https:") {
20518
+ return null;
20519
+ }
20520
+ const normalizedHostname = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, "");
20521
+ if (parsed.protocol === "http:" && LOOPBACK_WEBHOOK_HOSTS.has(normalizedHostname)) {
20522
+ return null;
20523
+ }
20524
+ return `notifications.webhookUrl must use https (http is allowed only for localhost, 127.0.0.1, or ::1): ${url}`;
20525
+ }
20526
+ function commandHookConfigIssue(commandHook, repoRoot) {
20527
+ if (!path61.isAbsolute(commandHook)) {
20528
+ return `notifications.commandHook must be an absolute path: ${commandHook}`;
20529
+ }
20530
+ if (pathWithinRoot(canonicalPath(repoRoot), canonicalPath(commandHook))) {
20531
+ return `notifications.commandHook must not be inside the repository: ${commandHook}`;
20532
+ }
20533
+ return null;
20534
+ }
20535
+ async function notifyDeny(config, event, deps = {
20536
+ fetch: globalThis.fetch.bind(globalThis),
20537
+ execFile: (file, args, options) => execFileAsync(file, [...args], options)
20538
+ }) {
20539
+ const payload = JSON.stringify({
20540
+ approvalId: event.approvalId,
20541
+ reason: event.reason,
20542
+ summary: event.summary,
20543
+ repoRoot: event.repoRoot,
20544
+ fingerprint: event.fingerprint
20545
+ });
20546
+ const webhookIssue = config.webhookUrl ? webhookConfigIssue(config.webhookUrl) : null;
20547
+ if (config.webhookUrl && !webhookIssue) {
20390
20548
  try {
20391
20549
  const controller = new AbortController();
20392
20550
  const timeout = setTimeout(() => controller.abort(), 5e3);
20393
20551
  try {
20394
- await fetch(config.webhookUrl, {
20552
+ await deps.fetch(config.webhookUrl, {
20395
20553
  method: "POST",
20396
20554
  headers: { "content-type": "application/json" },
20397
20555
  body: payload,
@@ -20403,17 +20561,16 @@ async function notifyDeny(config, event) {
20403
20561
  } catch {
20404
20562
  }
20405
20563
  }
20406
- if (config.commandHook) {
20564
+ const commandHookIssue = config.commandHook ? commandHookConfigIssue(config.commandHook, event.repoRoot) : null;
20565
+ if (config.commandHook && !commandHookIssue) {
20407
20566
  try {
20408
- await execFileAsync(config.commandHook, [], {
20567
+ await deps.execFile(config.commandHook, [], {
20409
20568
  env: {
20410
- ...process.env,
20411
20569
  BELAY_APPROVAL_ID: event.approvalId,
20412
20570
  BELAY_REASON: event.reason,
20413
20571
  BELAY_SUMMARY: event.summary,
20414
20572
  BELAY_REPO_ROOT: event.repoRoot,
20415
- BELAY_FINGERPRINT: event.fingerprint,
20416
- BELAY_APPROVAL_TOKEN: event.approvalToken ?? ""
20573
+ BELAY_FINGERPRINT: event.fingerprint
20417
20574
  }
20418
20575
  });
20419
20576
  } catch {
@@ -20423,9 +20580,10 @@ async function notifyDeny(config, event) {
20423
20580
 
20424
20581
  // src/adapters/shared/gate-runtime.ts
20425
20582
  init_path_utils();
20583
+ init_repo_config_trust();
20426
20584
 
20427
20585
  // src/adapters/layouts/protected-paths.ts
20428
- import path60 from "node:path";
20586
+ import path62 from "node:path";
20429
20587
  function protectedArtifactRoots(layout, repoRoot, controlPlaneDir) {
20430
20588
  const roots = [
20431
20589
  layout.configPath(repoRoot),
@@ -20437,7 +20595,7 @@ function protectedArtifactRoots(layout, repoRoot, controlPlaneDir) {
20437
20595
  if (controlPlaneDir) {
20438
20596
  roots.push(controlPlaneDir);
20439
20597
  }
20440
- return roots.map((entry) => path60.resolve(entry));
20598
+ return roots.map((entry) => path62.resolve(entry));
20441
20599
  }
20442
20600
 
20443
20601
  // src/adapters/shared/gate-runtime.ts
@@ -20478,7 +20636,7 @@ async function appendReplayAuditSafely(ctx, deps, event) {
20478
20636
  }
20479
20637
  async function loadJsonFile(filePath, fallback) {
20480
20638
  try {
20481
- const raw = await readFile15(filePath, "utf8");
20639
+ const raw = await readFile16(filePath, "utf8");
20482
20640
  return JSON.parse(raw);
20483
20641
  } catch {
20484
20642
  return fallback;
@@ -20487,11 +20645,18 @@ async function loadJsonFile(filePath, fallback) {
20487
20645
  function createDefaultGateRuntimeDeps() {
20488
20646
  return {
20489
20647
  async readConfig(configPath) {
20490
- return loadJsonFile(configPath, {});
20648
+ try {
20649
+ return JSON.parse(await readFile16(configPath, "utf8"));
20650
+ } catch (error) {
20651
+ if (error.code === "ENOENT") {
20652
+ return {};
20653
+ }
20654
+ throw error;
20655
+ }
20491
20656
  },
20492
20657
  async appendAudit(ctx, event) {
20493
- const auditPath = path61.join(ctx.repoRoot, ctx.config.audit.logPath);
20494
- await mkdir14(path61.dirname(auditPath), { recursive: true });
20658
+ const auditPath = path63.join(ctx.repoRoot, ctx.config.audit.logPath);
20659
+ await mkdir15(path63.dirname(auditPath), { recursive: true });
20495
20660
  const provenance = auditProvenance(ctx.config);
20496
20661
  const record = {
20497
20662
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20524,7 +20689,7 @@ function createDefaultGateRuntimeDeps() {
20524
20689
  };
20525
20690
  },
20526
20691
  async writeApprovals(filePath, state) {
20527
- await mkdir14(path61.dirname(filePath), { recursive: true });
20692
+ await mkdir15(path63.dirname(filePath), { recursive: true });
20528
20693
  await writeFile11(filePath, `${JSON.stringify(compactApprovals(state), null, 2)}
20529
20694
  `, "utf8");
20530
20695
  },
@@ -20545,10 +20710,11 @@ function createDefaultGateRuntimeDeps() {
20545
20710
  }
20546
20711
  async function resolveGateConfig(ctx, deps) {
20547
20712
  const loaded = await deps.readConfig(ctx.configPath);
20713
+ await assertRepoConfigTrusted(ctx.repoRoot, ctx.layout.name, loaded);
20548
20714
  let teamConfig = null;
20549
20715
  const teamPath = teamConfigPath();
20550
- if (existsSync16(teamPath)) {
20551
- teamConfig = JSON.parse(await readFile15(teamPath, "utf8"));
20716
+ if (existsSync17(teamPath)) {
20717
+ teamConfig = JSON.parse(await readFile16(teamPath, "utf8"));
20552
20718
  }
20553
20719
  return resolveLayeredConfig({
20554
20720
  repoConfig: loaded,
@@ -20686,7 +20852,7 @@ function deriveWorkspaceRootScopeHint(params) {
20686
20852
  if (!targetPath) {
20687
20853
  return void 0;
20688
20854
  }
20689
- const candidateRoot = canonicalPath(path61.dirname(targetPath));
20855
+ const candidateRoot = canonicalPath(path63.dirname(targetPath));
20690
20856
  const validation = validateTrustedWorkspaceRootCandidate({
20691
20857
  candidatePath: candidateRoot,
20692
20858
  repoRoot: action.repoRoot,
@@ -21077,7 +21243,21 @@ async function evaluateGatedAction(ctx, deps, params) {
21077
21243
  ...authorization,
21078
21244
  egressProxyActive
21079
21245
  };
21080
- const predicted = await classifyGatedActionAsync(action, ctx.config, enrichedClassifierOptions);
21246
+ let predicted = await classifyGatedActionAsync(action, ctx.config, enrichedClassifierOptions);
21247
+ if (action.kind === "tool" && predicted.reason === "unclassified_tool" && (ctx.config.policy.codexUnmappedTool ?? "deny") === "deny") {
21248
+ predicted = {
21249
+ ...predicted,
21250
+ verdict: "deny_pending_approval",
21251
+ reason: "unmapped_tool",
21252
+ assessment: {
21253
+ reversibility: "irreversible",
21254
+ external: false,
21255
+ blastRadius: "unknown tool action",
21256
+ confidence: 0.5,
21257
+ signals: ["unmapped_tool"]
21258
+ }
21259
+ };
21260
+ }
21081
21261
  if (action.kind === "shell" && action.command && isContainedUnknownExecutionEligible(ctx.config, action, predicted)) {
21082
21262
  const mediated = await mediateContainedUnknownExecution({
21083
21263
  ctx,
@@ -21262,7 +21442,7 @@ async function gateDecisionToVerdict(ctx, deps, kind, result, auditExtras = {})
21262
21442
  event: auditEvent,
21263
21443
  sourceEvent,
21264
21444
  kind,
21265
- repoLabel: path61.basename(ctx.repoRoot),
21445
+ repoLabel: path63.basename(ctx.repoRoot),
21266
21446
  ...auditExtras.toolInvocationCorrelationId ? { toolInvocationCorrelationId: auditExtras.toolInvocationCorrelationId } : {},
21267
21447
  fingerprint: result.fingerprint,
21268
21448
  summary: result.normalizedCommand ?? result.summary ?? "",
@@ -21294,21 +21474,6 @@ async function gateDecisionToVerdict(ctx, deps, kind, result, auditExtras = {})
21294
21474
  if (created) {
21295
21475
  await recordGateApprovalAsk(stateDir, result.reason, false);
21296
21476
  }
21297
- let approvalToken;
21298
- try {
21299
- approvalToken = await issueApprovalToken(
21300
- {
21301
- approvalId: approval.approvalId,
21302
- fingerprint: approval.fingerprint,
21303
- repoRoot: approval.repoRoot,
21304
- issuedAt: approval.createdAt,
21305
- expiresAt: approval.expiresAt
21306
- },
21307
- configuredControlPlaneDir(ctx.config)
21308
- );
21309
- } catch {
21310
- approvalToken = void 0;
21311
- }
21312
21477
  const denialReason = failure?.reason ?? result.reason;
21313
21478
  if (ctx.config.notifications.webhookUrl || ctx.config.notifications.commandHook) {
21314
21479
  await notifyDeny(ctx.config.notifications, {
@@ -21316,8 +21481,7 @@ async function gateDecisionToVerdict(ctx, deps, kind, result, auditExtras = {})
21316
21481
  reason: denialReason,
21317
21482
  summary: result.normalizedCommand ?? result.summary ?? "",
21318
21483
  repoRoot: ctx.repoRoot,
21319
- fingerprint: result.fingerprint,
21320
- approvalToken
21484
+ fingerprint: result.fingerprint
21321
21485
  });
21322
21486
  }
21323
21487
  const failureAuditFields = typeof failure?.auditFields === "function" ? failure.auditFields(approval) : failure?.auditFields;
@@ -21728,38 +21892,38 @@ async function appendObservedAudit(ctx, deps, eventName, payload) {
21728
21892
  }
21729
21893
 
21730
21894
  // src/adapters/shared/repo-root.ts
21731
- import { existsSync as existsSync17 } from "node:fs";
21732
- import path62 from "node:path";
21895
+ import { existsSync as existsSync18 } from "node:fs";
21896
+ import path64 from "node:path";
21733
21897
  function belayConfigPath(current, adapterName) {
21734
21898
  if (adapterName === "cursor") {
21735
- return path62.join(current, ".cursor", "belay.config.json");
21899
+ return path64.join(current, ".cursor", "belay.config.json");
21736
21900
  }
21737
21901
  if (adapterName === "claude") {
21738
- return path62.join(current, ".claude", "belay.config.json");
21902
+ return path64.join(current, ".claude", "belay.config.json");
21739
21903
  }
21740
- return path62.join(current, ".codex", "belay.config.json");
21904
+ return path64.join(current, ".codex", "belay.config.json");
21741
21905
  }
21742
21906
  function markerMatches(current, marker, layout) {
21743
- const markerPath = path62.join(current, marker);
21744
- if (!existsSync17(markerPath)) {
21907
+ const markerPath = path64.join(current, marker);
21908
+ if (!existsSync18(markerPath)) {
21745
21909
  return false;
21746
21910
  }
21747
21911
  if (marker === ".cursor" || marker === ".claude" || marker === ".codex") {
21748
- return existsSync17(belayConfigPath(current, layout.name));
21912
+ return existsSync18(belayConfigPath(current, layout.name));
21749
21913
  }
21750
21914
  return true;
21751
21915
  }
21752
21916
  function findRepoRoot(startPath, layout) {
21753
- let current = path62.resolve(startPath);
21917
+ let current = path64.resolve(startPath);
21754
21918
  while (true) {
21755
21919
  for (const marker of layout.repoRootMarkers) {
21756
21920
  if (markerMatches(current, marker, layout)) {
21757
21921
  return current;
21758
21922
  }
21759
21923
  }
21760
- const parent = path62.dirname(current);
21924
+ const parent = path64.dirname(current);
21761
21925
  if (parent === current) {
21762
- return path62.resolve(startPath);
21926
+ return path64.resolve(startPath);
21763
21927
  }
21764
21928
  current = parent;
21765
21929
  }