tamperward 2.39.9 → 2.39.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli/index.js +266 -215
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -671,7 +671,7 @@ var init_policy = __esm({
671
671
  });
672
672
 
673
673
  // src/disk.ts
674
- import { closeSync, constants, fstatSync, lstatSync as lstatSync2, openSync, readSync, readlinkSync, realpathSync as realpathSync2 } from "node:fs";
674
+ import { closeSync, constants, fstatSync, lstatSync as lstatSync2, openSync, readSync, readlinkSync, realpathSync as realpathSync2, writeSync } from "node:fs";
675
675
  import { join as join3 } from "node:path";
676
676
  function errText(e) {
677
677
  return e instanceof Error ? e.message : String(e);
@@ -769,6 +769,58 @@ function inspectResolved(abs) {
769
769
  function textOf2(e) {
770
770
  return e.content == null ? null : e.content.toString("utf8");
771
771
  }
772
+ function notARegularFile(e) {
773
+ switch (e.kind) {
774
+ case "symlink":
775
+ return `is a symbolic link to ${escapeControl(e.detail)}`;
776
+ case "directory":
777
+ return "is a directory";
778
+ case "irregular":
779
+ return `is a ${e.detail}`;
780
+ case "oversize":
781
+ return `is ${e.detail}, above the ${READ_CAP / (1024 * 1024)} MiB the gate reads`;
782
+ default:
783
+ return `cannot be read (${e.detail})`;
784
+ }
785
+ }
786
+ function readStateFile(abs) {
787
+ const e = inspectPath(abs);
788
+ if (e.kind === "absent") return null;
789
+ if (e.kind === "file") return textOf2(e) ?? "";
790
+ throw new StateFileError(
791
+ `${abs} ${notARegularFile(e)}; the gate reads its session state only as a regular file \u2014 remove what stands there so the state can be re-established`
792
+ );
793
+ }
794
+ function multiplyLinked(st) {
795
+ return st.nlink === 1 ? null : `has ${st.nlink} names \u2014 a hard link is the same file under another name, the session marker's or the policy's, say`;
796
+ }
797
+ function appendRegular(abs, text, mode = 438) {
798
+ const st = lstatSync2(abs, { throwIfNoEntry: false });
799
+ if (st !== void 0 && !st.isFile()) throw new StateFileError(`${abs} ${notARegularFile(classify(abs, st))}${APPEND_REFUSED}`);
800
+ const linked = st === void 0 ? null : multiplyLinked(st);
801
+ if (linked !== null) throw new StateFileError(`${abs} ${linked}${APPEND_REFUSED}`);
802
+ let fd;
803
+ try {
804
+ fd = openSync(abs, O_APPEND_REGULAR, mode);
805
+ } catch (e) {
806
+ const code2 = errCode(e);
807
+ if (code2 === "ELOOP" || code2 === "ENXIO" || code2 === "EISDIR") {
808
+ throw new StateFileError(`${abs} changed shape while it was being opened (${errText(e)})${APPEND_REFUSED}`);
809
+ }
810
+ throw e;
811
+ }
812
+ try {
813
+ const now = fstatSync(fd);
814
+ if (!now.isFile()) throw new StateFileError(`${abs} is a ${irregularName(now)}${APPEND_REFUSED}`);
815
+ const opened = multiplyLinked(now);
816
+ if (opened !== null) throw new StateFileError(`${abs} ${opened}${APPEND_REFUSED}`);
817
+ const buf = Buffer.from(text, "utf8");
818
+ let off2 = 0;
819
+ while (off2 < buf.length) off2 += writeSync(fd, buf, off2, buf.length - off2);
820
+ } finally {
821
+ closeSync(fd);
822
+ }
823
+ }
772
824
  function describe(e, shown) {
773
825
  switch (e.kind) {
774
826
  case "symlink":
@@ -809,7 +861,7 @@ function unjudgeableProtected(cwd, policy, changes) {
809
861
  }
810
862
  return out3;
811
863
  }
812
- var READ_CAP, NO_META, O_READ;
864
+ var READ_CAP, NO_META, O_READ, StateFileError, O_APPEND_REGULAR, APPEND_REFUSED;
813
865
  var init_disk = __esm({
814
866
  "src/disk.ts"() {
815
867
  "use strict";
@@ -818,6 +870,10 @@ var init_disk = __esm({
818
870
  READ_CAP = 64 * 1024 * 1024;
819
871
  NO_META = { mode: 0, size: 0, mtimeMs: 0 };
820
872
  O_READ = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
873
+ StateFileError = class extends Error {
874
+ };
875
+ O_APPEND_REGULAR = constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
876
+ APPEND_REFUSED = "; the gate appends its records only to a regular file with one name \u2014 remove what stands there so the record can be kept";
821
877
  }
822
878
  });
823
879
 
@@ -10868,20 +10924,6 @@ function parseOrThrow(src, where) {
10868
10924
  }
10869
10925
  return parsePolicy(raw, where);
10870
10926
  }
10871
- function notARegularFile(e) {
10872
- switch (e.kind) {
10873
- case "symlink":
10874
- return `is a symbolic link to ${escapeControl(e.detail)}`;
10875
- case "directory":
10876
- return "is a directory";
10877
- case "irregular":
10878
- return `is a ${e.detail}`;
10879
- case "oversize":
10880
- return `is ${e.detail}, above the ${READ_CAP / (1024 * 1024)} MiB the gate reads`;
10881
- default:
10882
- return `cannot be read (${e.detail})`;
10883
- }
10884
- }
10885
10927
  function loadPolicy(cwd = process.cwd()) {
10886
10928
  const entry = inspectPath(join8(repoRoot(cwd), POLICY_FILE));
10887
10929
  if (entry.kind === "absent") return defaultPolicy();
@@ -11553,7 +11595,7 @@ var init_deny = __esm({
11553
11595
  });
11554
11596
 
11555
11597
  // src/session.ts
11556
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
11598
+ import { mkdirSync as mkdirSync2, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
11557
11599
  import { dirname as dirname3, join as join10 } from "node:path";
11558
11600
  function writeBaseline(p, sha3) {
11559
11601
  mkdirSync2(dirname3(p), { recursive: true });
@@ -11578,13 +11620,8 @@ function turnBaseline(cwd, sessionId) {
11578
11620
  if (!sessionId) return null;
11579
11621
  const p = baselinePath(cwd, sessionId);
11580
11622
  if (!p) return null;
11581
- try {
11582
- if (existsSync5(p)) {
11583
- const v = readFileSync6(p, "utf8").trim();
11584
- if (SHA.test(v)) return v;
11585
- }
11586
- } catch {
11587
- }
11623
+ const v = readStateFile(p)?.trim();
11624
+ if (v !== void 0 && SHA.test(v)) return v;
11588
11625
  const head = headSha(cwd);
11589
11626
  if (!head) return null;
11590
11627
  try {
@@ -11608,6 +11645,7 @@ var UNSAFE, SHA, BaselineWriteError;
11608
11645
  var init_session = __esm({
11609
11646
  "src/session.ts"() {
11610
11647
  "use strict";
11648
+ init_disk();
11611
11649
  init_build();
11612
11650
  UNSAFE = /[^A-Za-z0-9_-]/g;
11613
11651
  SHA = /^[0-9a-f]{40}$/;
@@ -11623,7 +11661,7 @@ var init_session = __esm({
11623
11661
 
11624
11662
  // src/effect.ts
11625
11663
  import { createHash as createHash4 } from "node:crypto";
11626
- import { existsSync as existsSync6, lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync7, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
11664
+ import { lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
11627
11665
  import { join as join11 } from "node:path";
11628
11666
  function ptreeFrom(value) {
11629
11667
  if (!isRecord(value)) return null;
@@ -11715,9 +11753,11 @@ function driftBetween(expected, current) {
11715
11753
  return { changed, deleted, added };
11716
11754
  }
11717
11755
  function loadTree(p) {
11718
- if (!p || !existsSync6(p)) return null;
11756
+ if (!p) return null;
11757
+ const text = readStateFile(p);
11758
+ if (text === null) return null;
11719
11759
  try {
11720
- return ptreeFrom(JSON.parse(readFileSync7(p, "utf8")));
11760
+ return ptreeFrom(JSON.parse(text));
11721
11761
  } catch {
11722
11762
  return null;
11723
11763
  }
@@ -11769,8 +11809,53 @@ var init_effect = __esm({
11769
11809
  }
11770
11810
  });
11771
11811
 
11812
+ // src/safe-write.ts
11813
+ import { randomBytes } from "node:crypto";
11814
+ import { lstatSync as lstatSync5, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "node:fs";
11815
+ function writeTargetKind(path) {
11816
+ let st;
11817
+ try {
11818
+ st = lstatSync5(path, { throwIfNoEntry: false });
11819
+ } catch (e) {
11820
+ if (errnoCode(e) === "ENOTDIR") return "absent";
11821
+ throw e;
11822
+ }
11823
+ if (!st) return "absent";
11824
+ if (st.isSymbolicLink()) return "symlink";
11825
+ return st.isFile() ? "file" : "irregular";
11826
+ }
11827
+ function refuseNonRegular(path) {
11828
+ switch (writeTargetKind(path)) {
11829
+ case "symlink":
11830
+ return "refusing: symlink \u2014 the target would be written instead of this path; replace the link with a regular file, then re-run";
11831
+ case "irregular":
11832
+ return "refusing: not a regular file \u2014 a directory or special file stands where a file is expected; remove it, then re-run";
11833
+ default:
11834
+ return null;
11835
+ }
11836
+ }
11837
+ function existingMode(path, fallback) {
11838
+ if (writeTargetKind(path) !== "file") return fallback;
11839
+ return lstatSync5(path).mode & 511;
11840
+ }
11841
+ function atomicReplaceFile(path, content, mode) {
11842
+ const tmp = `${path}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
11843
+ try {
11844
+ writeFileSync4(tmp, content, { encoding: "utf8", flag: "wx", mode });
11845
+ renameSync3(tmp, path);
11846
+ } finally {
11847
+ rmSync4(tmp, { force: true });
11848
+ }
11849
+ }
11850
+ var init_safe_write = __esm({
11851
+ "src/safe-write.ts"() {
11852
+ "use strict";
11853
+ init_narrow();
11854
+ }
11855
+ });
11856
+
11772
11857
  // src/cli/watch.ts
11773
- import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync2, watch, writeFileSync as writeFileSync4 } from "node:fs";
11858
+ import { lstatSync as lstatSync6, mkdirSync as mkdirSync4, readdirSync as readdirSync2, watch } from "node:fs";
11774
11859
  import { join as join12 } from "node:path";
11775
11860
  import { createHash as createHash5 } from "node:crypto";
11776
11861
  function snap(abs) {
@@ -11788,8 +11873,10 @@ function watcherHealthPath(log) {
11788
11873
  return `${log}.health.json`;
11789
11874
  }
11790
11875
  function readWatcherHealth(log) {
11876
+ const text = readStateFile(watcherHealthPath(log));
11877
+ if (text === null) return null;
11791
11878
  try {
11792
- const value = JSON.parse(readFileSync8(watcherHealthPath(log), "utf8"));
11879
+ const value = JSON.parse(text);
11793
11880
  if (!isRecord(value)) return null;
11794
11881
  const { state, backend, pid, started_at } = value;
11795
11882
  if (value.version !== 1 || typeof pid !== "number" || typeof started_at !== "string") return null;
@@ -11823,7 +11910,13 @@ function pidAlive(pid) {
11823
11910
  }
11824
11911
  }
11825
11912
  function watcherTelemetry(log) {
11826
- const health = readWatcherHealth(log);
11913
+ let health;
11914
+ try {
11915
+ health = readWatcherHealth(log);
11916
+ } catch (e) {
11917
+ if (!(e instanceof StateFileError)) throw e;
11918
+ return { state: "unavailable", health: null, reason: e.message };
11919
+ }
11827
11920
  if (!health) return { state: "unavailable", health: null, reason: "no health record" };
11828
11921
  if (health.state === "stopped")
11829
11922
  return { state: "unavailable", health, reason: "observer stopped" };
@@ -11873,7 +11966,7 @@ function watchTree(dir, cb, onState, onError, watchFn = watch) {
11873
11966
  const child = rel ? `${rel}/${String(fname)}` : String(fname);
11874
11967
  cb(kind, child);
11875
11968
  try {
11876
- if (lstatSync5(join12(dir, child)).isDirectory()) addDir(child);
11969
+ if (lstatSync6(join12(dir, child)).isDirectory()) addDir(child);
11877
11970
  } catch {
11878
11971
  }
11879
11972
  });
@@ -11909,7 +12002,7 @@ function watchTree(dir, cb, onState, onError, watchFn = watch) {
11909
12002
  const child = rel ? `${rel}/${name}` : name;
11910
12003
  if (SKIP2.test(child + "/")) continue;
11911
12004
  try {
11912
- if (lstatSync5(join12(dir, child)).isDirectory()) walk2(child);
12005
+ if (lstatSync6(join12(dir, child)).isDirectory()) walk2(child);
11913
12006
  } catch {
11914
12007
  }
11915
12008
  }
@@ -11948,7 +12041,7 @@ function startWatcher(dir, log, policy, watchFn = watch) {
11948
12041
  let healthWriteWarningEmitted = false;
11949
12042
  const persistHealth = () => {
11950
12043
  try {
11951
- writeFileSync4(healthPath, JSON.stringify(health) + "\n", { mode: 384 });
12044
+ atomicReplaceFile(healthPath, JSON.stringify(health) + "\n", 384);
11952
12045
  healthWriteWarningEmitted = false;
11953
12046
  } catch (e) {
11954
12047
  if (!healthWriteWarningEmitted) {
@@ -11988,7 +12081,7 @@ function startWatcher(dir, log, policy, watchFn = watch) {
11988
12081
  ...s
11989
12082
  };
11990
12083
  try {
11991
- appendFileSync3(log, JSON.stringify(ev) + "\n");
12084
+ appendRegular(log, JSON.stringify(ev) + "\n");
11992
12085
  health.event_count++;
11993
12086
  health.last_append_at = (/* @__PURE__ */ new Date()).toISOString();
11994
12087
  persistHealth();
@@ -12051,6 +12144,7 @@ var init_watch = __esm({
12051
12144
  "src/cli/watch.ts"() {
12052
12145
  "use strict";
12053
12146
  init_disk();
12147
+ init_safe_write();
12054
12148
  init_policy_load();
12055
12149
  init_policy();
12056
12150
  init_build();
@@ -12316,15 +12410,15 @@ var init_fs_events = __esm({
12316
12410
  });
12317
12411
 
12318
12412
  // src/cli/audit.ts
12319
- import { createHash as createHash6, randomBytes } from "node:crypto";
12320
- import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync as openSync4, readSync as readSync3 } from "node:fs";
12413
+ import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
12414
+ import { closeSync as closeSync4, existsSync as existsSync5, mkdirSync as mkdirSync5, openSync as openSync4, readSync as readSync3 } from "node:fs";
12321
12415
  import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
12322
12416
  function sessionHash(sessionId) {
12323
12417
  if (!sessionId) return void 0;
12324
12418
  return "sha256:" + createHash6("sha256").update(sessionId).digest("hex").slice(0, 24);
12325
12419
  }
12326
12420
  function eventId() {
12327
- return "sha256:" + createHash6("sha256").update(randomBytes(32)).digest("hex").slice(0, 32);
12421
+ return "sha256:" + createHash6("sha256").update(randomBytes2(32)).digest("hex").slice(0, 32);
12328
12422
  }
12329
12423
  function configuredAuditPath(cwd, env = process.env) {
12330
12424
  const value = env[AUDIT_LOG_ENV];
@@ -12362,7 +12456,7 @@ function recordAuditFindings(findings, context) {
12362
12456
  };
12363
12457
  return JSON.stringify(event);
12364
12458
  });
12365
- appendFileSync4(path, lines.join("\n") + "\n");
12459
+ appendRegular(path, lines.join("\n") + "\n");
12366
12460
  } catch {
12367
12461
  }
12368
12462
  }
@@ -12576,7 +12670,7 @@ function runStats(opts = {}) {
12576
12670
  const file = opts.file ? isAbsolute8(opts.file) ? opts.file : resolve4(cwd, opts.file) : configured && configured !== "auto" ? isAbsolute8(configured) ? configured : resolve4(cwd, configured) : defaultAuditPath(cwd);
12577
12671
  const cutoff = opts.since ? parseSince(opts.since) : null;
12578
12672
  if (!file) throw new Error("stats needs --file outside a Git repository");
12579
- if (!existsSync7(file)) {
12673
+ if (!existsSync5(file)) {
12580
12674
  if (explicitFile) throw new Error(`audit file not found: ${file}`);
12581
12675
  const empty2 = summarizeAudit([]);
12582
12676
  process.stdout.write(opts.json ? JSON.stringify(empty2) + "\n" : renderAuditStats(empty2));
@@ -12597,6 +12691,7 @@ var init_audit = __esm({
12597
12691
  "src/cli/audit.ts"() {
12598
12692
  "use strict";
12599
12693
  init_repo_context();
12694
+ init_disk();
12600
12695
  AUDIT_SCHEMA_VERSION = 1;
12601
12696
  AUDIT_LOG_ENV = "TAMPERWARD_AUDIT_LOG";
12602
12697
  MAX_AUDIT_LINE_BYTES = 16 * 1024;
@@ -12615,14 +12710,14 @@ var init_audit = __esm({
12615
12710
  });
12616
12711
 
12617
12712
  // src/cli/hook.ts
12618
- import { readFileSync as readFileSync9, appendFileSync as appendFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync8 } from "node:fs";
12713
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6 } from "node:fs";
12619
12714
  import { createHash as createHash7 } from "node:crypto";
12620
12715
  function setSnapshotCache(cache3) {
12621
12716
  snapshotCache = cache3;
12622
12717
  }
12623
12718
  function readStdin() {
12624
12719
  try {
12625
- return readFileSync9(0, "utf8");
12720
+ return readFileSync6(0, "utf8");
12626
12721
  } catch (e) {
12627
12722
  throw new HookInputError(`cannot read the hook payload on stdin: ${e instanceof Error ? e.message : String(e)}`);
12628
12723
  }
@@ -12650,7 +12745,7 @@ function recordDenylog(blocks2) {
12650
12745
  const log = process.env.TAMPERWARD_DENYLOG;
12651
12746
  if (!log) return;
12652
12747
  try {
12653
- appendFileSync5(log, blocks2.map((b) => b.rule).join(",") + "\n");
12748
+ appendRegular(log, blocks2.map((b) => b.rule).join(",") + "\n");
12654
12749
  } catch {
12655
12750
  }
12656
12751
  }
@@ -12912,10 +13007,11 @@ function turnTransientBlocks(cwd, sessionId, policy, changes) {
12912
13007
  recordObserverHealth(cwd, sessionId, telemetry.state, telemetry.reason);
12913
13008
  }
12914
13009
  const cp = cursorPath(cwd, sessionId);
12915
- if (!existsSync8(log)) return none;
13010
+ if (!existsSync6(log)) return none;
12916
13011
  let offset = 0;
12917
- if (cp && existsSync8(cp)) {
12918
- const n2 = Number(readFileSync9(cp, "utf8"));
13012
+ const cursorText = cp ? readStateFile(cp) : null;
13013
+ if (cursorText !== null) {
13014
+ const n2 = Number(cursorText);
12919
13015
  offset = Number.isFinite(n2) ? n2 : 0;
12920
13016
  }
12921
13017
  const drained = drainEvents(log, offset);
@@ -12968,7 +13064,7 @@ function recordWarns(cwd, sessionId, warns) {
12968
13064
  const log = process.env.TAMPERWARD_DENYLOG;
12969
13065
  if (!log) return;
12970
13066
  try {
12971
- appendFileSync5(log, warns.map((w) => `warn:${w.rule}:${w.file ?? ""}`).join("\n") + "\n");
13067
+ appendRegular(log, warns.map((w) => `warn:${w.rule}:${w.file ?? ""}`).join("\n") + "\n");
12972
13068
  } catch {
12973
13069
  }
12974
13070
  }
@@ -12978,7 +13074,7 @@ function recordObserverHealth(cwd, sessionId, state, reason) {
12978
13074
  if (!log) return;
12979
13075
  const detail = (reason ?? "").replace(/[\r\n]+/g, " ").trim();
12980
13076
  try {
12981
- appendFileSync5(
13077
+ appendRegular(
12982
13078
  log,
12983
13079
  `warn:transient-observer:${state}${detail ? ":" + detail : ""}
12984
13080
  `
@@ -13095,7 +13191,7 @@ var init_hook = __esm({
13095
13191
  });
13096
13192
 
13097
13193
  // src/ptree-cache.ts
13098
- import { lstatSync as lstatSync6 } from "node:fs";
13194
+ import { lstatSync as lstatSync7 } from "node:fs";
13099
13195
  import { join as join14 } from "node:path";
13100
13196
  function keyOf(st) {
13101
13197
  return `${st.dev}:${st.ino}:${st.size}:${st.mode}:${st.mtimeNs}:${st.ctimeNs}`;
@@ -13149,7 +13245,7 @@ var init_ptree_cache = __esm({
13149
13245
  const abs = join14(cwd, rel);
13150
13246
  let st;
13151
13247
  try {
13152
- st = lstatSync6(abs, { bigint: true });
13248
+ st = lstatSync7(abs, { bigint: true });
13153
13249
  } catch {
13154
13250
  this.map.delete(abs);
13155
13251
  this.stats.misses++;
@@ -13171,7 +13267,7 @@ var init_ptree_cache = __esm({
13171
13267
  const entry = compute();
13172
13268
  let after;
13173
13269
  try {
13174
- after = lstatSync6(abs, { bigint: true });
13270
+ after = lstatSync7(abs, { bigint: true });
13175
13271
  } catch {
13176
13272
  this.map.delete(abs);
13177
13273
  return entry;
@@ -13189,13 +13285,13 @@ var init_ptree_cache = __esm({
13189
13285
  });
13190
13286
 
13191
13287
  // src/cli/hook-service.ts
13192
- import { chmodSync, existsSync as existsSync9, lstatSync as lstatSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
13288
+ import { chmodSync, existsSync as existsSync7, lstatSync as lstatSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "node:fs";
13193
13289
  import { createConnection as createConnection2, createServer } from "node:net";
13194
13290
  import { realpathSync as realpathSync4 } from "node:fs";
13195
13291
  import { sep } from "node:path";
13196
13292
  function readServiceState(paths) {
13197
13293
  try {
13198
- const v = JSON.parse(readFileSync10(paths.state, "utf8"));
13294
+ const v = JSON.parse(readFileSync7(paths.state, "utf8"));
13199
13295
  if (!isRecord(v)) return null;
13200
13296
  const { pid, version, root, started_at } = v;
13201
13297
  if (typeof pid !== "number" || typeof version !== "string" || typeof root !== "string" || typeof started_at !== "string") return null;
@@ -13272,13 +13368,13 @@ function withEnv(env, fn) {
13272
13368
  }
13273
13369
  function removeQuietly(p) {
13274
13370
  try {
13275
- rmSync4(p, { force: true });
13371
+ rmSync5(p, { force: true });
13276
13372
  } catch {
13277
13373
  }
13278
13374
  }
13279
13375
  function ensurePrivateDir(dir, uid) {
13280
- if (!existsSync9(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
13281
- const st = lstatSync7(dir);
13376
+ if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
13377
+ const st = lstatSync8(dir);
13282
13378
  if (!st.isDirectory()) throw new Error(`${dir} is not a directory`);
13283
13379
  if (st.uid !== uid) throw new Error(`${dir} is owned by uid ${st.uid}, not ${uid}; refusing to serve from it`);
13284
13380
  if ((st.mode & 63) !== 0) chmodSync(dir, 448);
@@ -13474,7 +13570,7 @@ async function stopHookService(paths, expectedRoot) {
13474
13570
  process.kill(st.pid, "SIGTERM");
13475
13571
  } catch {
13476
13572
  }
13477
- const gone = () => !pidAlive2(st.pid) || !existsSync9(paths.socket);
13573
+ const gone = () => !pidAlive2(st.pid) || !existsSync7(paths.socket);
13478
13574
  const until = Date.now() + STOP_WAIT_MS;
13479
13575
  while (!gone() && Date.now() < until) sleepSync(50);
13480
13576
  if (!gone()) throw new Error(`hook service pid ${st.pid} did not exit within ${STOP_WAIT_MS / 1e3}s`);
@@ -13708,55 +13804,10 @@ var init_verifier_limits = __esm({
13708
13804
  }
13709
13805
  });
13710
13806
 
13711
- // src/safe-write.ts
13712
- import { randomBytes as randomBytes2 } from "node:crypto";
13713
- import { lstatSync as lstatSync8, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
13714
- function writeTargetKind(path) {
13715
- let st;
13716
- try {
13717
- st = lstatSync8(path, { throwIfNoEntry: false });
13718
- } catch (e) {
13719
- if (errnoCode(e) === "ENOTDIR") return "absent";
13720
- throw e;
13721
- }
13722
- if (!st) return "absent";
13723
- if (st.isSymbolicLink()) return "symlink";
13724
- return st.isFile() ? "file" : "irregular";
13725
- }
13726
- function refuseNonRegular(path) {
13727
- switch (writeTargetKind(path)) {
13728
- case "symlink":
13729
- return "refusing: symlink \u2014 the target would be written instead of this path; replace the link with a regular file, then re-run";
13730
- case "irregular":
13731
- return "refusing: not a regular file \u2014 a directory or special file stands where a file is expected; remove it, then re-run";
13732
- default:
13733
- return null;
13734
- }
13735
- }
13736
- function existingMode(path, fallback) {
13737
- if (writeTargetKind(path) !== "file") return fallback;
13738
- return lstatSync8(path).mode & 511;
13739
- }
13740
- function atomicReplaceFile(path, content, mode) {
13741
- const tmp = `${path}.${process.pid}.${randomBytes2(8).toString("hex")}.tmp`;
13742
- try {
13743
- writeFileSync7(tmp, content, { encoding: "utf8", flag: "wx", mode });
13744
- renameSync3(tmp, path);
13745
- } finally {
13746
- rmSync5(tmp, { force: true });
13747
- }
13748
- }
13749
- var init_safe_write = __esm({
13750
- "src/safe-write.ts"() {
13751
- "use strict";
13752
- init_narrow();
13753
- }
13754
- });
13755
-
13756
13807
  // src/cli/init.ts
13757
13808
  import { execFileSync as execFileSync6 } from "node:child_process";
13758
13809
  import { createHash as createHash8 } from "node:crypto";
13759
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync11, realpathSync as realpathSync5 } from "node:fs";
13810
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "node:fs";
13760
13811
  import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, relative as relative4, resolve as resolve6 } from "node:path";
13761
13812
  function gitConfig(cwd, key2) {
13762
13813
  try {
@@ -13850,34 +13901,34 @@ function verifierCandidates(cwd) {
13850
13901
  if (!candidates.includes(command)) candidates.push(command);
13851
13902
  };
13852
13903
  try {
13853
- const pkg = JSON.parse(readFileSync11(join15(cwd, "package.json"), "utf8"));
13904
+ const pkg = JSON.parse(readFileSync8(join15(cwd, "package.json"), "utf8"));
13854
13905
  const test = isRecord(pkg) && isRecord(pkg.scripts) ? pkg.scripts.test : void 0;
13855
13906
  if (typeof test === "string" && test.trim() !== "" && !/error:\s*no test specified/i.test(test)) add("npm test");
13856
13907
  } catch {
13857
13908
  }
13858
13909
  try {
13859
- const pyproject = readFileSync11(join15(cwd, "pyproject.toml"), "utf8");
13910
+ const pyproject = readFileSync8(join15(cwd, "pyproject.toml"), "utf8");
13860
13911
  if (/^\s*\[tool\.pytest(?:\.ini_options)?\]\s*$/m.test(pyproject)) add("pytest");
13861
13912
  } catch {
13862
13913
  }
13863
- if (existsSync10(join15(cwd, "pytest.ini"))) add("pytest");
13914
+ if (existsSync8(join15(cwd, "pytest.ini"))) add("pytest");
13864
13915
  try {
13865
- const setupCfg = readFileSync11(join15(cwd, "setup.cfg"), "utf8");
13916
+ const setupCfg = readFileSync8(join15(cwd, "setup.cfg"), "utf8");
13866
13917
  if (/^\s*\[tool:pytest\]\s*$/m.test(setupCfg)) add("pytest");
13867
13918
  } catch {
13868
13919
  }
13869
13920
  try {
13870
- const tox = readFileSync11(join15(cwd, "tox.ini"), "utf8");
13921
+ const tox = readFileSync8(join15(cwd, "tox.ini"), "utf8");
13871
13922
  if (/^\s*\[tox\]\s*$/m.test(tox)) add("tox");
13872
13923
  } catch {
13873
13924
  }
13874
13925
  try {
13875
- const cargo = readFileSync11(join15(cwd, "Cargo.toml"), "utf8");
13926
+ const cargo = readFileSync8(join15(cwd, "Cargo.toml"), "utf8");
13876
13927
  if (/^\s*\[(?:package|workspace)\]\s*(?:#.*)?$/m.test(cargo)) add("cargo test");
13877
13928
  } catch {
13878
13929
  }
13879
13930
  try {
13880
- const goMod = readFileSync11(join15(cwd, "go.mod"), "utf8");
13931
+ const goMod = readFileSync8(join15(cwd, "go.mod"), "utf8");
13881
13932
  if (/^\s*module\s+\S+\s*(?:\/\/.*)?$/m.test(goMod)) add("go test ./...");
13882
13933
  } catch {
13883
13934
  }
@@ -13920,7 +13971,7 @@ function planPolicy(cwd) {
13920
13971
  const path = join15(cwd, POLICY_FILE);
13921
13972
  const refused = refuseNonRegular(path);
13922
13973
  if (refused) return { item: "policy", path: POLICY_FILE, status: "error", detail: refused };
13923
- if (existsSync10(path)) {
13974
+ if (existsSync8(path)) {
13924
13975
  try {
13925
13976
  loadPolicy(cwd);
13926
13977
  } catch (e) {
@@ -13939,7 +13990,7 @@ function planPolicy(cwd) {
13939
13990
  function planGitignore(cwd) {
13940
13991
  const rel = ".gitignore";
13941
13992
  const path = join15(cwd, rel);
13942
- if (!existsSync10(join15(cwd, "node_modules"))) return null;
13993
+ if (!existsSync8(join15(cwd, "node_modules"))) return null;
13943
13994
  let existing = "";
13944
13995
  let kind;
13945
13996
  try {
@@ -13949,7 +14000,7 @@ function planGitignore(cwd) {
13949
14000
  }
13950
14001
  const refused = refuseNonRegular(path);
13951
14002
  if (refused) return { item: "gitignore", path: rel, status: "error", detail: refused };
13952
- if (kind === "file") existing = readFileSync11(path, "utf8");
14003
+ if (kind === "file") existing = readFileSync8(path, "utf8");
13953
14004
  try {
13954
14005
  const tracked = execFileSync6("git", ["ls-files", "--cached", "--", "node_modules"], {
13955
14006
  cwd,
@@ -14004,10 +14055,10 @@ function planClaudeHooks(cwd) {
14004
14055
  const refused = refuseNonRegular(path);
14005
14056
  if (refused) return { item: "agent", path: rel, status: "error", detail: refused };
14006
14057
  let settings = {};
14007
- if (existsSync10(path)) {
14058
+ if (existsSync8(path)) {
14008
14059
  let parsed;
14009
14060
  try {
14010
- parsed = JSON.parse(readFileSync11(path, "utf8"));
14061
+ parsed = JSON.parse(readFileSync8(path, "utf8"));
14011
14062
  } catch {
14012
14063
  return {
14013
14064
  item: "agent",
@@ -14056,7 +14107,7 @@ function planClaudeHooks(cwd) {
14056
14107
  return {
14057
14108
  item: "agent",
14058
14109
  path: rel,
14059
- status: existsSync10(path) ? "update" : "create",
14110
+ status: existsSync8(path) ? "update" : "create",
14060
14111
  detail: [
14061
14112
  needPre && "wire PreToolUse deny",
14062
14113
  needStop && "wire Stop sweep",
@@ -14100,7 +14151,7 @@ function hooksDir(cwd) {
14100
14151
  if (out3) return resolve6(cwd, out3);
14101
14152
  } catch {
14102
14153
  }
14103
- return existsSync10(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
14154
+ return existsSync8(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
14104
14155
  }
14105
14156
  function display(cwd, path) {
14106
14157
  const rel = relative4(cwd, path);
@@ -14127,11 +14178,11 @@ function planPreCommit(cwd) {
14127
14178
  const skip = (detail) => ({ item: "pre-commit", path: "(none)", status: "skip", detail });
14128
14179
  let path;
14129
14180
  let note;
14130
- if (existsSync10(join15(cwd, ".husky"))) {
14181
+ if (existsSync8(join15(cwd, ".husky"))) {
14131
14182
  path = join15(cwd, ".husky", "pre-commit");
14132
14183
  note = "husky";
14133
14184
  } else {
14134
- const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync10(join15(cwd, c))));
14185
+ const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync8(join15(cwd, c))));
14135
14186
  if (managed) {
14136
14187
  return skip(`${managed.name} manages this repository's hooks and regenerates them on install, so a line in the hooks directory would not last \u2014 ${managed.hint}`);
14137
14188
  }
@@ -14149,7 +14200,7 @@ function planPreCommit(cwd) {
14149
14200
  const rel = display(cwd, path);
14150
14201
  const refused = refuseNonRegular(path);
14151
14202
  if (refused) return { item: "pre-commit", path: rel, status: "error", detail: refused };
14152
- const existing = existsSync10(path) ? readFileSync11(path, "utf8") : null;
14203
+ const existing = existsSync8(path) ? readFileSync8(path, "utf8") : null;
14153
14204
  const hookMode = () => existingMode(path, 493) | 73;
14154
14205
  if (existing === null) {
14155
14206
  return {
@@ -14240,7 +14291,7 @@ function planCodeowners(cwd) {
14240
14291
  const path = join15(cwd, existingRel ?? rel);
14241
14292
  const refused = refuseNonRegular(path);
14242
14293
  if (refused) return { item: "codeowners", path: existingRel ?? rel, status: "error", detail: refused };
14243
- const existing = existingRel ? readFileSync11(path, "utf8") : null;
14294
+ const existing = existingRel ? readFileSync8(path, "utf8") : null;
14244
14295
  const missing = CODEOWNERS_PATHS.filter((p) => existing === null || !coveredBy(existing, p));
14245
14296
  if (existingRel !== void 0 && missing.length === 0) {
14246
14297
  return { item: "codeowners", path: existingRel, status: "ok", detail: "gate paths already have code owners" };
@@ -14280,7 +14331,7 @@ function planWorkflow(cwd, force) {
14280
14331
  };
14281
14332
  const refused = refuseNonRegular(path);
14282
14333
  if (refused) return { item: "ci", path: rel, status: "error", detail: refused };
14283
- if (!existsSync10(path)) {
14334
+ if (!existsSync8(path)) {
14284
14335
  return {
14285
14336
  item: "ci",
14286
14337
  path: rel,
@@ -14291,7 +14342,7 @@ function planWorkflow(cwd, force) {
14291
14342
  }
14292
14343
  let src;
14293
14344
  try {
14294
- src = readFileSync11(path, "utf8");
14345
+ src = readFileSync8(path, "utf8");
14295
14346
  } catch {
14296
14347
  return { item: "ci", path: rel, status: "error", detail: "exists but cannot be read \u2014 refusing to overwrite" };
14297
14348
  }
@@ -14638,10 +14689,10 @@ var init_fingerprint = __esm({
14638
14689
  // src/dependency-env.ts
14639
14690
  import { createHash as createHash10 } from "node:crypto";
14640
14691
  import {
14641
- existsSync as existsSync11,
14692
+ existsSync as existsSync9,
14642
14693
  lstatSync as lstatSync9,
14643
14694
  readdirSync as readdirSync3,
14644
- readFileSync as readFileSync12,
14695
+ readFileSync as readFileSync9,
14645
14696
  readlinkSync as readlinkSync2,
14646
14697
  realpathSync as realpathSync6,
14647
14698
  statSync as statSync3
@@ -14699,7 +14750,7 @@ function fingerprintRoot(root, cwd, h) {
14699
14750
  st = statSync3(path);
14700
14751
  if (!st.isFile()) throw new Error("not a regular file");
14701
14752
  h.update(label + "\0external-file\0" + path + "\0" + String(st.mode) + "\0");
14702
- h.update(readFileSync12(path));
14753
+ h.update(readFileSync9(path));
14703
14754
  h.update("\0");
14704
14755
  } catch (e) {
14705
14756
  throw new Unattestable(
@@ -14733,7 +14784,7 @@ function fingerprintRoot(root, cwd, h) {
14733
14784
  h.update(rel + "\0" + ident.kind + "\0" + String(ident.mode) + "\0");
14734
14785
  if (ident.kind === "file") {
14735
14786
  try {
14736
- h.update(readFileSync12(path));
14787
+ h.update(readFileSync9(path));
14737
14788
  h.update("\0");
14738
14789
  } catch (e) {
14739
14790
  throw new Unattestable(
@@ -14792,7 +14843,7 @@ function snapshot(roots, probes, cwd) {
14792
14843
  const h = createHash10("sha256");
14793
14844
  for (const probe of probes) {
14794
14845
  h.update(
14795
- "probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync11(probe.path) ? "present" : "absent") + "\0"
14846
+ "probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync9(probe.path) ? "present" : "absent") + "\0"
14796
14847
  );
14797
14848
  }
14798
14849
  for (const root of roots) fingerprintRoot(root, cwd, h);
@@ -14851,7 +14902,7 @@ function resolveExecutable(token, cwd, env) {
14851
14902
  if (token.includes("/") || token.includes("\\")) {
14852
14903
  const path = isAbsolute10(token) ? token : resolve7(cwd, token);
14853
14904
  try {
14854
- return existsSync11(path) ? realpathSync6(path) : null;
14905
+ return existsSync9(path) ? realpathSync6(path) : null;
14855
14906
  } catch {
14856
14907
  return null;
14857
14908
  }
@@ -14859,7 +14910,7 @@ function resolveExecutable(token, cwd, env) {
14859
14910
  for (const entry of (env.PATH ?? "").split(delimiter).filter(Boolean)) {
14860
14911
  const candidate = resolve7(entry, token);
14861
14912
  try {
14862
- if (existsSync11(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
14913
+ if (existsSync9(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
14863
14914
  } catch {
14864
14915
  }
14865
14916
  }
@@ -14882,7 +14933,7 @@ function inferredVenvFromToken(token, cwd) {
14882
14933
  const parentName = basename4(parent).toLowerCase();
14883
14934
  if (parentName !== "bin" && parentName !== "scripts") return null;
14884
14935
  const root = dirname6(parent);
14885
- return existsSync11(join16(root, "pyvenv.cfg")) ? root : null;
14936
+ return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
14886
14937
  }
14887
14938
  function unsupportedEcosystem(command, token) {
14888
14939
  const name = token ? basename4(token).toLowerCase() : "";
@@ -14898,13 +14949,13 @@ function inferredVenv(executable) {
14898
14949
  const parentName = basename4(parent).toLowerCase();
14899
14950
  if (parentName !== "bin" && parentName !== "scripts") return null;
14900
14951
  const root = dirname6(parent);
14901
- return existsSync11(join16(root, "pyvenv.cfg")) ? root : null;
14952
+ return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
14902
14953
  }
14903
14954
  function venvProblem(root) {
14904
14955
  const cfg = join16(root, "pyvenv.cfg");
14905
- if (!existsSync11(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
14956
+ if (!existsSync9(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
14906
14957
  try {
14907
- const body = readFileSync12(cfg, "utf8");
14958
+ const body = readFileSync9(cfg, "utf8");
14908
14959
  if (/^\s*include-system-site-packages\s*=\s*true\s*$/im.test(body)) {
14909
14960
  return "Python environment " + JSON.stringify(root) + " enables system site-packages; those external package roots are not bounded";
14910
14961
  }
@@ -14929,7 +14980,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
14929
14980
  };
14930
14981
  try {
14931
14982
  const nodeModules = join16(cwd, "node_modules");
14932
- if (existsSync11(nodeModules)) addRoot("node_modules", nodeModules);
14983
+ if (existsSync9(nodeModules)) addRoot("node_modules", nodeModules);
14933
14984
  else probes.push({ kind: "node_modules", path: nodeModules });
14934
14985
  const token = firstExecutable(command);
14935
14986
  const executable = resolveExecutable(token, cwd, env);
@@ -14941,7 +14992,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
14941
14992
  venv = resolve7(env.VIRTUAL_ENV);
14942
14993
  } else {
14943
14994
  venv = inferredVenv(executable) ?? inferredVenvFromToken(token, cwd);
14944
- if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync11(join16(cwd, ".venv", "pyvenv.cfg"))) {
14995
+ if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync9(join16(cwd, ".venv", "pyvenv.cfg"))) {
14945
14996
  venv = join16(cwd, ".venv");
14946
14997
  }
14947
14998
  }
@@ -15046,7 +15097,7 @@ var init_dependency_env = __esm({
15046
15097
 
15047
15098
  // src/suite-diagnostics.ts
15048
15099
  import { spawnSync } from "node:child_process";
15049
- import { mkdtempSync as mkdtempSync2, rmSync as rmSync6, writeFileSync as writeFileSync8 } from "node:fs";
15100
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "node:fs";
15050
15101
  import { tmpdir as tmpdir3 } from "node:os";
15051
15102
  import { join as join17 } from "node:path";
15052
15103
  function emptySuiteDiagnostics() {
@@ -15132,7 +15183,7 @@ function runCapturedProcessSync(executable, args, opts) {
15132
15183
  const configFile = join17(stateDir2, "config.json");
15133
15184
  const backstop = opts.backstopMs ?? 3e4;
15134
15185
  try {
15135
- writeFileSync8(
15186
+ writeFileSync7(
15136
15187
  configFile,
15137
15188
  JSON.stringify({
15138
15189
  executable,
@@ -15420,7 +15471,7 @@ if (child) {
15420
15471
  // src/verifier-backend.ts
15421
15472
  import { createHash as createHash11, randomUUID } from "node:crypto";
15422
15473
  import { spawnSync as spawnSync2 } from "node:child_process";
15423
- import { accessSync as accessSync2, constants as constants4, readFileSync as readFileSync13, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
15474
+ import { accessSync as accessSync2, constants as constants4, readFileSync as readFileSync10, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
15424
15475
  import { delimiter as delimiter2, dirname as dirname7, join as join18, resolve as resolve8 } from "node:path";
15425
15476
  function identity() {
15426
15477
  const uid = typeof process.getuid === "function" ? process.getuid() : null;
@@ -15465,7 +15516,7 @@ function findExecutable(name) {
15465
15516
  return null;
15466
15517
  }
15467
15518
  function fileSha256(path) {
15468
- return createHash11("sha256").update(readFileSync13(path)).digest("hex");
15519
+ return createHash11("sha256").update(readFileSync10(path)).digest("hex");
15469
15520
  }
15470
15521
  function engineClientEnv() {
15471
15522
  return {
@@ -15899,7 +15950,7 @@ var init_verifier_backend = __esm({
15899
15950
  // src/verification-state.ts
15900
15951
  import { execFileSync as execFileSync8 } from "node:child_process";
15901
15952
  import { createHash as createHash12 } from "node:crypto";
15902
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync14, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "node:fs";
15953
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync11, rmSync as rmSync7, writeFileSync as writeFileSync8 } from "node:fs";
15903
15954
  import { dirname as dirname8, join as join19 } from "node:path";
15904
15955
  function git2(args, cwd) {
15905
15956
  return execFileSync8("git", args, {
@@ -15958,7 +16009,7 @@ function interventionWiring(cwd) {
15958
16009
  return sources.map(([source, path]) => {
15959
16010
  let parsed;
15960
16011
  try {
15961
- parsed = JSON.parse(readFileSync14(path, "utf8"));
16012
+ parsed = JSON.parse(readFileSync11(path, "utf8"));
15962
16013
  } catch {
15963
16014
  return { source, present: false };
15964
16015
  }
@@ -16043,7 +16094,7 @@ function recordVerification(cwd, inputs, treeFingerprintValue) {
16043
16094
  binding
16044
16095
  };
16045
16096
  mkdirSync8(dirname8(path), { recursive: true });
16046
- writeFileSync9(path, JSON.stringify(record) + "\n");
16097
+ writeFileSync8(path, JSON.stringify(record) + "\n");
16047
16098
  return true;
16048
16099
  }
16049
16100
  function invalidateVerificationRecordIfCurrent(cwd) {
@@ -16111,7 +16162,7 @@ function readVerificationRecord(cwd) {
16111
16162
  if (!path) return null;
16112
16163
  let raw;
16113
16164
  try {
16114
- raw = readFileSync14(path, "utf8");
16165
+ raw = readFileSync11(path, "utf8");
16115
16166
  } catch {
16116
16167
  return null;
16117
16168
  }
@@ -16141,7 +16192,7 @@ function beginVerifying(cwd) {
16141
16192
  started_at: (/* @__PURE__ */ new Date()).toISOString()
16142
16193
  };
16143
16194
  mkdirSync8(dirname8(path), { recursive: true });
16144
- writeFileSync9(path, JSON.stringify(marker) + "\n");
16195
+ writeFileSync8(path, JSON.stringify(marker) + "\n");
16145
16196
  return true;
16146
16197
  } catch {
16147
16198
  return false;
@@ -16160,7 +16211,7 @@ function readVerifyingMarker(cwd) {
16160
16211
  if (!path) return null;
16161
16212
  let parsed;
16162
16213
  try {
16163
- parsed = JSON.parse(readFileSync14(path, "utf8"));
16214
+ parsed = JSON.parse(readFileSync11(path, "utf8"));
16164
16215
  } catch {
16165
16216
  return null;
16166
16217
  }
@@ -16294,7 +16345,7 @@ var init_verification_state = __esm({
16294
16345
 
16295
16346
  // src/verification-receipt.ts
16296
16347
  import { createHash as createHash13 } from "node:crypto";
16297
- import { mkdirSync as mkdirSync9, rmSync as rmSync8, writeFileSync as writeFileSync10 } from "node:fs";
16348
+ import { mkdirSync as mkdirSync9, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "node:fs";
16298
16349
  import { dirname as dirname9, join as join20 } from "node:path";
16299
16350
  function isRecord5(v) {
16300
16351
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -16341,7 +16392,7 @@ function storeReceipt(cwd, receipt) {
16341
16392
  if (!path) return false;
16342
16393
  try {
16343
16394
  mkdirSync9(dirname9(path), { recursive: true });
16344
- writeFileSync10(path, JSON.stringify(receipt) + "\n");
16395
+ writeFileSync9(path, JSON.stringify(receipt) + "\n");
16345
16396
  return true;
16346
16397
  } catch {
16347
16398
  return false;
@@ -16524,7 +16575,7 @@ var init_verification_receipt = __esm({
16524
16575
  // src/cli/verify.ts
16525
16576
  import { execFileSync as execFileSync9, spawnSync as spawnSync3 } from "node:child_process";
16526
16577
  import { createHash as createHash14 } from "node:crypto";
16527
- import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as readFileSync15, readlinkSync as readlinkSync3, rmSync as rmSync9, symlinkSync, writeFileSync as writeFileSync11, existsSync as existsSync12 } from "node:fs";
16578
+ import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as readFileSync12, readlinkSync as readlinkSync3, rmSync as rmSync9, symlinkSync, writeFileSync as writeFileSync10, existsSync as existsSync10 } from "node:fs";
16528
16579
  import { tmpdir as tmpdir4 } from "node:os";
16529
16580
  import { dirname as dirname10, isAbsolute as isAbsolute11, join as join21, relative as relative6, resolve as resolve9, sep as sep4 } from "node:path";
16530
16581
  function oracleAssuranceReport() {
@@ -16719,8 +16770,8 @@ function probeFilesystemCaseSensitivity(dir) {
16719
16770
  const upper = join21(dir, ".tw-case-probe-A");
16720
16771
  const lower = join21(dir, ".tw-case-probe-a");
16721
16772
  try {
16722
- writeFileSync11(upper, "", { flag: "wx" });
16723
- return !existsSync12(lower);
16773
+ writeFileSync10(upper, "", { flag: "wx" });
16774
+ return !existsSync10(lower);
16724
16775
  } finally {
16725
16776
  rmSync9(upper, { force: true });
16726
16777
  }
@@ -16784,7 +16835,7 @@ function overlayDigest(dest, paths) {
16784
16835
  try {
16785
16836
  const st = lstatSync10(p);
16786
16837
  h.update(String(st.mode));
16787
- h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync15(p));
16838
+ h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync12(p));
16788
16839
  } catch {
16789
16840
  h.update("<gone>");
16790
16841
  }
@@ -16822,7 +16873,7 @@ function overlayPristine(cwd, base, dest, policy, cmd, dependencyRoot, caseSensi
16822
16873
  safeSymlink(target, out3, dest, `the base's ${e.path}`);
16823
16874
  restoredLinks.push({ path: e.path, out: out3, target });
16824
16875
  } else {
16825
- writeFileSync11(out3, content);
16876
+ writeFileSync10(out3, content);
16826
16877
  chmodSync2(out3, parseInt(e.mode.slice(-4), 8) & 511);
16827
16878
  }
16828
16879
  restored.push(e.path);
@@ -16847,7 +16898,7 @@ function suiteEnv(scratch) {
16847
16898
  }
16848
16899
  const userRc = join21(scratch, "npmrc-user");
16849
16900
  const globalRc = join21(scratch, "npmrc-global");
16850
- for (const f of [userRc, globalRc]) writeFileSync11(f, "", { mode: 292 });
16901
+ for (const f of [userRc, globalRc]) writeFileSync10(f, "", { mode: 292 });
16851
16902
  env.npm_config_userconfig = userRc;
16852
16903
  env.npm_config_globalconfig = globalRc;
16853
16904
  env.npm_config_node_options = " ";
@@ -17598,7 +17649,7 @@ var init_verify = __esm({
17598
17649
  // src/cli/run.ts
17599
17650
  import { execFileSync as execFileSync10, spawn, spawnSync as spawnSync4 } from "node:child_process";
17600
17651
  import { randomBytes as randomBytes3 } from "node:crypto";
17601
- import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync16, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as rmSync10, statSync as statSync5, writeFileSync as writeFileSync12 } from "node:fs";
17652
+ import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync13, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as rmSync10, statSync as statSync5, writeFileSync as writeFileSync11 } from "node:fs";
17602
17653
  import { tmpdir as tmpdir5 } from "node:os";
17603
17654
  import { dirname as dirname11, join as join22, resolve as resolve10 } from "node:path";
17604
17655
  function authoritativeRunLifecyclePlatform(platform = process.platform) {
@@ -17695,7 +17746,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
17695
17746
  failure: trustedPython.reason ?? "trusted Linux python3 interpreter is unavailable"
17696
17747
  };
17697
17748
  }
17698
- writeFileSync12(agentEnvFile, JSON.stringify(process.env), { mode: 384 });
17749
+ writeFileSync11(agentEnvFile, JSON.stringify(process.env), { mode: 384 });
17699
17750
  executable = trustedPython.path;
17700
17751
  args = [
17701
17752
  "-I",
@@ -17752,7 +17803,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
17752
17803
  }
17753
17804
  let state = {};
17754
17805
  try {
17755
- state = JSON.parse(readFileSync16(resultFile, "utf8"));
17806
+ state = JSON.parse(readFileSync13(resultFile, "utf8"));
17756
17807
  } catch {
17757
17808
  return {
17758
17809
  exit: 1,
@@ -17796,7 +17847,7 @@ function observerExited(pid) {
17796
17847
  if (!pidAlive4(pid)) return true;
17797
17848
  if (process.platform !== "linux") return false;
17798
17849
  try {
17799
- const stat = readFileSync16(`/proc/${pid}/stat`, "utf8");
17850
+ const stat = readFileSync13(`/proc/${pid}/stat`, "utf8");
17800
17851
  const state = stat.slice(stat.lastIndexOf(")") + 2).split(" ")[0];
17801
17852
  return state === "Z" || state === "X";
17802
17853
  } catch (e) {
@@ -17918,7 +17969,7 @@ function git4(args, cwd) {
17918
17969
  }
17919
17970
  function nowTicks() {
17920
17971
  try {
17921
- return Math.floor(parseFloat(readFileSync16("/proc/uptime", "utf8").split(" ")[0]) * 100);
17972
+ return Math.floor(parseFloat(readFileSync13("/proc/uptime", "utf8").split(" ")[0]) * 100);
17922
17973
  } catch {
17923
17974
  return Number.POSITIVE_INFINITY;
17924
17975
  }
@@ -17941,7 +17992,7 @@ function survivorsHoldingTree(cwd, spawnedAfterTicks) {
17941
17992
  const n2 = Number(pid);
17942
17993
  if (n2 === process.pid) continue;
17943
17994
  try {
17944
- const stat = readFileSync16(`/proc/${pid}/stat`, "utf8");
17995
+ const stat = readFileSync13(`/proc/${pid}/stat`, "utf8");
17945
17996
  const startTicks = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19]);
17946
17997
  if (!Number.isFinite(startTicks) || startTicks < spawnedAfterTicks) continue;
17947
17998
  } catch {
@@ -18514,7 +18565,7 @@ raise SystemExit(0)
18514
18565
 
18515
18566
  // src/cli/doctor.ts
18516
18567
  import { execFileSync as execFileSync11 } from "node:child_process";
18517
- import { existsSync as existsSync13, readFileSync as readFileSync17, readdirSync as readdirSync5 } from "node:fs";
18568
+ import { existsSync as existsSync11, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "node:fs";
18518
18569
  import { join as join23, resolve as resolve11 } from "node:path";
18519
18570
  function lifecyclePlatformCheck(platform = process.platform, linuxPython = platform === "linux" ? trustedLinuxPython() : null) {
18520
18571
  if (platform === "linux") {
@@ -18570,10 +18621,10 @@ function wiringState(status, authority) {
18570
18621
  return authority ? "BROKEN" : "WARN";
18571
18622
  }
18572
18623
  function pinsInFile(path) {
18573
- if (!existsSync13(path)) return [];
18624
+ if (!existsSync11(path)) return [];
18574
18625
  let src = "";
18575
18626
  try {
18576
- src = readFileSync17(path, "utf8");
18627
+ src = readFileSync14(path, "utf8");
18577
18628
  } catch {
18578
18629
  return [];
18579
18630
  }
@@ -18594,13 +18645,13 @@ function workflowPermissionCheck(cwd, workflowRels = [".github/workflows/tamperw
18594
18645
  const warnings = [];
18595
18646
  for (const rel of workflowRels) {
18596
18647
  const path = resolve11(cwd, rel);
18597
- if (!existsSync13(path)) {
18648
+ if (!existsSync11(path)) {
18598
18649
  broken.push(`${rel} is missing`);
18599
18650
  continue;
18600
18651
  }
18601
18652
  let doc;
18602
18653
  try {
18603
- doc = yaml.parse(readFileSync17(path, "utf8"));
18654
+ doc = yaml.parse(readFileSync14(path, "utf8"));
18604
18655
  } catch (e) {
18605
18656
  broken.push(`${rel} is not valid YAML (${e instanceof Error ? e.message : String(e)})`);
18606
18657
  continue;
@@ -18999,7 +19050,7 @@ function diagnose(opts = {}) {
18999
19050
  } else {
19000
19051
  const workflowDirRel = ".github/workflows";
19001
19052
  const workflowDir = resolve11(cwd, workflowDirRel);
19002
- if (!existsSync13(workflowDir)) {
19053
+ if (!existsSync11(workflowDir)) {
19003
19054
  return fail("ci-verifier", `${workflowDirRel}: workflow directory does not exist`);
19004
19055
  }
19005
19056
  let entries;
@@ -19019,12 +19070,12 @@ function diagnose(opts = {}) {
19019
19070
  const authorityWorkflows = [];
19020
19071
  for (const workflowRel of workflowRels) {
19021
19072
  const workflowPath = resolve11(cwd, workflowRel);
19022
- if (!existsSync13(workflowPath)) {
19073
+ if (!existsSync11(workflowPath)) {
19023
19074
  return fail("ci-verifier", `${workflowRel}: workflow does not exist`);
19024
19075
  }
19025
19076
  let doc;
19026
19077
  try {
19027
- doc = yaml.parse(readFileSync17(workflowPath, "utf8"));
19078
+ doc = yaml.parse(readFileSync14(workflowPath, "utf8"));
19028
19079
  } catch (e) {
19029
19080
  return fail(
19030
19081
  "ci-verifier",
@@ -19335,9 +19386,9 @@ var init_status2 = __esm({
19335
19386
  // src/cli/trace-verify.ts
19336
19387
  import { execFileSync as execFileSync12, spawnSync as spawnSync5 } from "node:child_process";
19337
19388
  import {
19338
- existsSync as existsSync14,
19389
+ existsSync as existsSync12,
19339
19390
  mkdtempSync as mkdtempSync5,
19340
- readFileSync as readFileSync18,
19391
+ readFileSync as readFileSync15,
19341
19392
  readdirSync as readdirSync6,
19342
19393
  realpathSync as realpathSync9,
19343
19394
  rmSync as rmSync11,
@@ -19594,7 +19645,7 @@ function materializeBase(base, cwd, dest) {
19594
19645
  }
19595
19646
  const hostModules = join24(cwd, "node_modules");
19596
19647
  const tracedModules = join24(dest, "node_modules");
19597
- if (existsSync14(hostModules) && !existsSync14(tracedModules)) {
19648
+ if (existsSync12(hostModules) && !existsSync12(tracedModules)) {
19598
19649
  symlinkSync2(resolve12(hostModules), tracedModules, "dir");
19599
19650
  }
19600
19651
  }
@@ -19651,7 +19702,7 @@ function straceOnce(root, command, budget) {
19651
19702
  }
19652
19703
  );
19653
19704
  const logs = traced.error ? [] : traceFiles(prefix);
19654
- const accesses = logs.flatMap((path) => parseStraceFileAccess(readFileSync18(path, "utf8"), TRACE_ROOT));
19705
+ const accesses = logs.flatMap((path) => parseStraceFileAccess(readFileSync15(path, "utf8"), TRACE_ROOT));
19655
19706
  const raw = {
19656
19707
  spawnError: traced.error ? traced.error.message : null,
19657
19708
  status: traced.status,
@@ -19906,7 +19957,7 @@ var init_immutable = __esm({
19906
19957
  });
19907
19958
 
19908
19959
  // src/runtimes.ts
19909
- import { existsSync as existsSync15, readFileSync as readFileSync19 } from "node:fs";
19960
+ import { existsSync as existsSync13, readFileSync as readFileSync16 } from "node:fs";
19910
19961
  import { join as join25 } from "node:path";
19911
19962
  function isRecord6(x) {
19912
19963
  return typeof x === "object" && x !== null && !Array.isArray(x);
@@ -19936,8 +19987,8 @@ function claudeSettingsBeyondTamperward(cwd) {
19936
19987
  const path = join25(cwd, ".claude", "settings.json");
19937
19988
  let raw;
19938
19989
  try {
19939
- if (!existsSync15(path)) return false;
19940
- raw = readFileSync19(path, "utf8");
19990
+ if (!existsSync13(path)) return false;
19991
+ raw = readFileSync16(path, "utf8");
19941
19992
  } catch {
19942
19993
  return false;
19943
19994
  }
@@ -19963,7 +20014,7 @@ function detectRuntimes(cwd) {
19963
20014
  for (const rt of KNOWN_RUNTIMES) {
19964
20015
  const marker = rt.markers.find((m) => {
19965
20016
  try {
19966
- return existsSync15(join25(cwd, m));
20017
+ return existsSync13(join25(cwd, m));
19967
20018
  } catch {
19968
20019
  return false;
19969
20020
  }
@@ -20988,7 +21039,7 @@ var init_adapter3 = __esm({
20988
21039
 
20989
21040
  // src/adapters/copilot-sdk/changes.ts
20990
21041
  import { execFileSync as execFileSync13 } from "node:child_process";
20991
- import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as readFileSync20, rmSync as rmSync12, existsSync as existsSync16, realpathSync as realpathSync10 } from "node:fs";
21042
+ import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync17, rmSync as rmSync12, existsSync as existsSync14, realpathSync as realpathSync10 } from "node:fs";
20992
21043
  import { tmpdir as tmpdir7 } from "node:os";
20993
21044
  import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute16, relative as relative11, resolve as resolve15, join as join26 } from "node:path";
20994
21045
  function asStr4(v) {
@@ -21007,7 +21058,7 @@ function canonicalContainedTarget(abs, root) {
21007
21058
  }
21008
21059
  let dir = abs;
21009
21060
  const tail = [];
21010
- while (!existsSync16(dir)) {
21061
+ while (!existsSync14(dir)) {
21011
21062
  const parent = dirname12(dir);
21012
21063
  if (parent === dir) break;
21013
21064
  tail.unshift(basename5(dir));
@@ -21065,9 +21116,9 @@ function reconstructAfterViaGit(rawDiff, display2, before, isCreate) {
21065
21116
  const dir = mkdtempSync6(join26(tmpdir7(), "hf-sdk-apply-"));
21066
21117
  try {
21067
21118
  const targetPath = join26(dir, TARGET);
21068
- if (op !== "create") writeFileSync13(targetPath, before ?? "");
21119
+ if (op !== "create") writeFileSync12(targetPath, before ?? "");
21069
21120
  const patchPath = join26(dir, "change.patch");
21070
- writeFileSync13(patchPath, patch);
21121
+ writeFileSync12(patchPath, patch);
21071
21122
  const git8 = (extra) => execFileSync13("git", ["apply", ...extra, patchPath], {
21072
21123
  cwd: dir,
21073
21124
  encoding: "utf8",
@@ -21082,7 +21133,7 @@ function reconstructAfterViaGit(rawDiff, display2, before, isCreate) {
21082
21133
  if (statPath !== TARGET) throw new Error(`write diff reconstructs a different file (${statPath}) than the bound target`);
21083
21134
  git8(["--check"]);
21084
21135
  git8([]);
21085
- return op === "delete" ? null : readFileSync20(targetPath, "utf8");
21136
+ return op === "delete" ? null : readFileSync17(targetPath, "utf8");
21086
21137
  } catch (e) {
21087
21138
  throw new Error(`could not reconstruct the write to ${display2} from its diff via git apply: ${e instanceof Error ? e.message : String(e)}`);
21088
21139
  } finally {
@@ -21835,7 +21886,7 @@ var init_runtime_qualification = __esm({
21835
21886
 
21836
21887
  // src/cli/runtime.ts
21837
21888
  import { execFileSync as execFileSync14 } from "node:child_process";
21838
- import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync14 } from "node:fs";
21889
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync13 } from "node:fs";
21839
21890
  import { join as join27, dirname as dirname13 } from "node:path";
21840
21891
  function storePath(cwd) {
21841
21892
  const dir = gitDir(cwd);
@@ -21843,9 +21894,9 @@ function storePath(cwd) {
21843
21894
  }
21844
21895
  function readStore(cwd) {
21845
21896
  const path = storePath(cwd);
21846
- if (!path || !existsSync17(path)) return null;
21897
+ if (!path || !existsSync15(path)) return null;
21847
21898
  try {
21848
- const parsed = JSON.parse(readFileSync21(path, "utf8"));
21899
+ const parsed = JSON.parse(readFileSync18(path, "utf8"));
21849
21900
  if (parsed && typeof parsed === "object" && parsed.records && typeof parsed.records === "object") return parsed;
21850
21901
  } catch {
21851
21902
  return null;
@@ -21976,7 +22027,7 @@ function writeRecord(cwd, id, report2) {
21976
22027
  store.updated_at = report2.timestamp;
21977
22028
  try {
21978
22029
  mkdirSync11(dirname13(path), { recursive: true });
21979
- writeFileSync14(path, JSON.stringify(store, null, 2) + "\n", { mode: 384 });
22030
+ writeFileSync13(path, JSON.stringify(store, null, 2) + "\n", { mode: 384 });
21980
22031
  return true;
21981
22032
  } catch {
21982
22033
  return false;
@@ -22014,9 +22065,9 @@ function resolveHookConfigHash(canonicalId, cwd) {
22014
22065
  "github-copilot-cli": join27(cwd, ".github", "hooks", "tamperward.json")
22015
22066
  };
22016
22067
  const file = files[canonicalId];
22017
- if (!file || !existsSync17(file)) return null;
22068
+ if (!file || !existsSync15(file)) return null;
22018
22069
  try {
22019
- const raw = readFileSync21(file, "utf8");
22070
+ const raw = readFileSync18(file, "utf8");
22020
22071
  let hooks = raw;
22021
22072
  try {
22022
22073
  const parsed = JSON.parse(raw);
@@ -22295,7 +22346,7 @@ var init_runtime = __esm({
22295
22346
 
22296
22347
  // src/cli/onboard.ts
22297
22348
  import { execFileSync as execFileSync15 } from "node:child_process";
22298
- import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as readFileSync22, realpathSync as realpathSync11, rmSync as rmSync13 } from "node:fs";
22349
+ import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as readFileSync19, realpathSync as realpathSync11, rmSync as rmSync13 } from "node:fs";
22299
22350
  import { tmpdir as tmpdir8 } from "node:os";
22300
22351
  import { join as join28, relative as relative12, resolve as resolve16, sep as sep6 } from "node:path";
22301
22352
  import { createInterface } from "node:readline";
@@ -22368,7 +22419,7 @@ function writeVerifyCommand(cwd, command) {
22368
22419
  return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
22369
22420
  }
22370
22421
  const mode = existingMode(path, 420);
22371
- const original = kind === "file" ? readFileSync22(path, "utf8") : null;
22422
+ const original = kind === "file" ? readFileSync19(path, "utf8") : null;
22372
22423
  let next;
22373
22424
  try {
22374
22425
  const doc = parseDocument(original && original.trim() ? original : "version: 1\n");
@@ -23023,7 +23074,7 @@ var init_capture = __esm({
23023
23074
 
23024
23075
  // src/research/manifest.ts
23025
23076
  import { createHash as createHash16 } from "node:crypto";
23026
- import { readFileSync as readFileSync23 } from "node:fs";
23077
+ import { readFileSync as readFileSync20 } from "node:fs";
23027
23078
  import { dirname as dirname14, resolve as resolve18 } from "node:path";
23028
23079
  function taskFrom(raw, index, manifestDir) {
23029
23080
  const where = `task #${index + 1}`;
@@ -23057,7 +23108,7 @@ function readManifest(path) {
23057
23108
  const abs = resolve18(path);
23058
23109
  let bytes;
23059
23110
  try {
23060
- bytes = readFileSync23(abs);
23111
+ bytes = readFileSync20(abs);
23061
23112
  } catch (e) {
23062
23113
  throw new ResearchError(`cannot read task manifest ${abs}: ${e instanceof Error ? e.message : String(e)}`);
23063
23114
  }
@@ -23476,7 +23527,7 @@ var init_record = __esm({
23476
23527
  // src/research/run.ts
23477
23528
  import { randomUUID as randomUUID2 } from "node:crypto";
23478
23529
  import { execFileSync as execFileSync16 } from "node:child_process";
23479
- import { closeSync as closeSync5, existsSync as existsSync18, linkSync, mkdirSync as mkdirSync12, openSync as openSync5, readFileSync as readFileSync24, renameSync as renameSync4, rmSync as rmSync14, unlinkSync, writeFileSync as writeFileSync15, writeSync } from "node:fs";
23530
+ import { closeSync as closeSync5, existsSync as existsSync16, linkSync, mkdirSync as mkdirSync12, openSync as openSync5, readFileSync as readFileSync21, renameSync as renameSync4, rmSync as rmSync14, unlinkSync, writeFileSync as writeFileSync14, writeSync as writeSync2 } from "node:fs";
23480
23531
  import { hostname } from "node:os";
23481
23532
  import { join as join29, resolve as resolve19 } from "node:path";
23482
23533
  function git7(args, cwd) {
@@ -23490,7 +23541,7 @@ function researchLockPath(ledger) {
23490
23541
  }
23491
23542
  function readLockOwner(path) {
23492
23543
  try {
23493
- const parsed = JSON.parse(readFileSync24(path, "utf8"));
23544
+ const parsed = JSON.parse(readFileSync21(path, "utf8"));
23494
23545
  if (!isRecord(parsed) || typeof parsed.pid !== "number" || !Number.isInteger(parsed.pid) || parsed.pid <= 0) return null;
23495
23546
  if (typeof parsed.host !== "string" || typeof parsed.started_at !== "string" || typeof parsed.token !== "string") return null;
23496
23547
  return { pid: parsed.pid, host: parsed.host, started_at: parsed.started_at, token: parsed.token };
@@ -23513,7 +23564,7 @@ function lockHolder(path) {
23513
23564
  function acquireResearchLock(ledger, breakStaleLock = false) {
23514
23565
  mkdirSync12(ledger, { recursive: true });
23515
23566
  const path = researchLockPath(ledger);
23516
- if (breakStaleLock && existsSync18(path)) {
23567
+ if (breakStaleLock && existsSync16(path)) {
23517
23568
  const owner2 = readLockOwner(path);
23518
23569
  if (!owner2) {
23519
23570
  throw new ResearchError(`research output ${ledger} has an unreadable lock at ${path}; verify no run is active, then remove it deliberately`);
@@ -23557,7 +23608,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
23557
23608
  let fd = -1;
23558
23609
  try {
23559
23610
  fd = openSync5(path, "wx", 384);
23560
- writeSync(fd, text);
23611
+ writeSync2(fd, text);
23561
23612
  closeSync5(fd);
23562
23613
  fd = -1;
23563
23614
  } catch (e) {
@@ -23575,7 +23626,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
23575
23626
  if (released) return;
23576
23627
  released = true;
23577
23628
  try {
23578
- if (readFileSync24(path, "utf8") === text) unlinkSync(path);
23629
+ if (readFileSync21(path, "utf8") === text) unlinkSync(path);
23579
23630
  } catch {
23580
23631
  }
23581
23632
  }
@@ -23584,7 +23635,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
23584
23635
  function resumableRecord(path, expected) {
23585
23636
  let raw;
23586
23637
  try {
23587
- raw = JSON.parse(readFileSync24(path, "utf8"));
23638
+ raw = JSON.parse(readFileSync21(path, "utf8"));
23588
23639
  } catch (e) {
23589
23640
  throw new ResearchError(`ledger record ${path} is malformed (${errorMessage(e).split("\n")[0]}); remove it to regenerate the pair, or use a new --out`);
23590
23641
  }
@@ -23621,7 +23672,7 @@ function resumableRecord(path, expected) {
23621
23672
  }
23622
23673
  function writeRecordAtomically(path, text) {
23623
23674
  const tmp = `${path}.${process.pid}.tmp`;
23624
- writeFileSync15(tmp, text);
23675
+ writeFileSync14(tmp, text);
23625
23676
  renameSync4(tmp, path);
23626
23677
  }
23627
23678
  function cloneArgs(repo, ws3) {
@@ -23886,7 +23937,7 @@ function runResearch(opts) {
23886
23937
  try {
23887
23938
  for (let pair = 1; pair <= pairs; pair++) {
23888
23939
  const path = pairRecordPath(ledger, task.id, pair);
23889
- if (!existsSync18(path)) continue;
23940
+ if (!existsSync16(path)) continue;
23890
23941
  const existing = resumableRecord(path, {
23891
23942
  task: task.id,
23892
23943
  pair,
@@ -24006,7 +24057,7 @@ var init_run2 = __esm({
24006
24057
  });
24007
24058
 
24008
24059
  // src/research/ledger-files.ts
24009
- import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as readFileSync25, readdirSync as readdirSync7, realpathSync as realpathSync12 } from "node:fs";
24060
+ import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as readFileSync22, readdirSync as readdirSync7, realpathSync as realpathSync12 } from "node:fs";
24010
24061
  import { join as join30, resolve as resolve20 } from "node:path";
24011
24062
  function lstatOrNull(path) {
24012
24063
  try {
@@ -24049,7 +24100,7 @@ function readRegularFile(path, realPairsDir, name) {
24049
24100
  if (!opened.isFile() || !sameInode || opened.nlink !== 1) {
24050
24101
  throw new ResearchError(`ledger record ${path} changed between listing and reading; refusing to read it`);
24051
24102
  }
24052
- return readFileSync25(fd);
24103
+ return readFileSync22(fd);
24053
24104
  } finally {
24054
24105
  closeSync6(fd);
24055
24106
  }
@@ -24222,7 +24273,7 @@ var init_summarize = __esm({
24222
24273
 
24223
24274
  // src/research/init.ts
24224
24275
  import { createHash as createHash17 } from "node:crypto";
24225
- import { existsSync as existsSync19, mkdirSync as mkdirSync13, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "node:fs";
24276
+ import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
24226
24277
  import { basename as basename6, dirname as dirname15, resolve as resolve21 } from "node:path";
24227
24278
  function idFrom(repo) {
24228
24279
  const clean = repo.replace(/[\\/]$/, "").split(/[\\/]/).pop() || "task";
@@ -24234,7 +24285,7 @@ function createResearchManifest(opts) {
24234
24285
  if (!opts.prompt) throw new ResearchError("research init requires --prompt");
24235
24286
  if (!opts.verifyCommand) throw new ResearchError("research init requires --verify-command");
24236
24287
  const out3 = resolve21(opts.out);
24237
- if (existsSync19(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
24288
+ if (existsSync17(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
24238
24289
  const id = opts.id ?? idFrom(opts.repo);
24239
24290
  if (!/^[A-Za-z0-9._-]+$/.test(id)) throw new ResearchError(`research init id must match [A-Za-z0-9._-] (got "${id}")`);
24240
24291
  if (opts.verifyBudget !== void 0 && (!Number.isFinite(opts.verifyBudget) || opts.verifyBudget <= 0)) {
@@ -24252,7 +24303,7 @@ function createResearchManifest(opts) {
24252
24303
  };
24253
24304
  const text = JSON.stringify(doc, null, 2) + "\n";
24254
24305
  mkdirSync13(dirname15(out3), { recursive: true });
24255
- writeFileSync16(out3, text, { flag: "wx", mode: 384 });
24306
+ writeFileSync15(out3, text, { flag: "wx", mode: 384 });
24256
24307
  const parsed = readManifest(out3);
24257
24308
  if (parsed.tasks.length !== 1 || parsed.tasks[0].id !== id) throw new ResearchError(`research init wrote an invalid manifest ${out3}`);
24258
24309
  return out3;
@@ -24274,7 +24325,7 @@ function runResearchInit(opts) {
24274
24325
  }
24275
24326
  }
24276
24327
  function requireHash(path) {
24277
- return createHash17("sha256").update(readFileSync26(path)).digest("hex");
24328
+ return createHash17("sha256").update(readFileSync23(path)).digest("hex");
24278
24329
  }
24279
24330
  var init_init2 = __esm({
24280
24331
  "src/research/init.ts"() {
@@ -24342,7 +24393,7 @@ var init_report2 = __esm({
24342
24393
  import { createHash as createHash18 } from "node:crypto";
24343
24394
  import { isDeepStrictEqual } from "node:util";
24344
24395
  import { gzipSync, gunzipSync } from "node:zlib";
24345
- import { mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync17 } from "node:fs";
24396
+ import { mkdirSync as mkdirSync14, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
24346
24397
  import { dirname as dirname16, resolve as resolve22 } from "node:path";
24347
24398
  function octal(value, width) {
24348
24399
  return value.toString(8).padStart(width - 1, "0") + "\0";
@@ -24448,7 +24499,7 @@ function jsonBytes(value) {
24448
24499
  function validateResearchBundle(path) {
24449
24500
  let files;
24450
24501
  try {
24451
- files = parseTar(gunzipSync(readFileSync27(resolve22(path))));
24502
+ files = parseTar(gunzipSync(readFileSync24(resolve22(path))));
24452
24503
  } catch (e) {
24453
24504
  throw new ResearchError(`cannot read research bundle ${path}: ${e instanceof Error ? e.message : String(e)}`);
24454
24505
  }
@@ -24518,7 +24569,7 @@ function createResearchBundle(opts) {
24518
24569
  const { records, entries } = packagedRecords(ledger);
24519
24570
  const summary = summarizeRecords(records);
24520
24571
  if (opts.manifest) {
24521
- const manifest = readFileSync27(resolve22(opts.manifest));
24572
+ const manifest = readFileSync24(resolve22(opts.manifest));
24522
24573
  const sha3 = createHash18("sha256").update(manifest).digest("hex");
24523
24574
  if (sha3 !== summary.manifest_sha256) throw new ResearchError(`manifest sha256 ${sha3} does not match ledger ${summary.manifest_sha256}`);
24524
24575
  entries.push({ name: "manifest.json", bytes: manifest });
@@ -24542,7 +24593,7 @@ function createResearchBundle(opts) {
24542
24593
  entries.push({ name: "provenance.json", bytes: jsonBytes(provenance) });
24543
24594
  const out3 = resolve22(opts.out);
24544
24595
  mkdirSync14(dirname16(out3), { recursive: true });
24545
- writeFileSync17(out3, gzipSync(makeTar(entries)), { flag: "wx", mode: 384 });
24596
+ writeFileSync16(out3, gzipSync(makeTar(entries)), { flag: "wx", mode: 384 });
24546
24597
  return out3;
24547
24598
  }
24548
24599
  function runResearchBundle(opts) {
@@ -24689,7 +24740,7 @@ var init_research = __esm({
24689
24740
  });
24690
24741
 
24691
24742
  // src/cli/receipt.ts
24692
- import { appendFileSync as appendFileSync6, readFileSync as readFileSync28, writeFileSync as writeFileSync18 } from "node:fs";
24743
+ import { appendFileSync as appendFileSync3, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
24693
24744
  function parseReceipt(args) {
24694
24745
  const [sub, ...rest] = args;
24695
24746
  const exportOpts = {};
@@ -24791,7 +24842,7 @@ function runReceiptExport(opts = {}) {
24791
24842
  const serialized = JSON.stringify(receipt) + "\n";
24792
24843
  if (opts.out) {
24793
24844
  try {
24794
- writeFileSync18(opts.out, serialized);
24845
+ writeFileSync17(opts.out, serialized);
24795
24846
  } catch (e) {
24796
24847
  process.stderr.write(`tamperward: could not write receipt to ${opts.out} (${e instanceof Error ? e.message : String(e)})
24797
24848
  `);
@@ -24816,7 +24867,7 @@ function ciAdjudicate(cwd, opts) {
24816
24867
  if (opts.ciResult !== void 0) {
24817
24868
  let doc;
24818
24869
  try {
24819
- doc = JSON.parse(readFileSync28(opts.ciResult, "utf8"));
24870
+ doc = JSON.parse(readFileSync25(opts.ciResult, "utf8"));
24820
24871
  } catch (e) {
24821
24872
  return {
24822
24873
  ci: { verdict: "CANNOT_VERIFY", binding, binding_error: `unreadable CI verify result: ${e instanceof Error ? e.message : String(e)}` },
@@ -24962,7 +25013,7 @@ function loadClaimedReceipt(path) {
24962
25013
  }
24963
25014
  let raw;
24964
25015
  try {
24965
- raw = readFileSync28(path, "utf8");
25016
+ raw = readFileSync25(path, "utf8");
24966
25017
  } catch (e) {
24967
25018
  return { disposition: "MALFORMED", detail: `receipt file could not be read (${e instanceof Error ? e.message : String(e)})` };
24968
25019
  }
@@ -25013,7 +25064,7 @@ function writeJobSummary(r, receipt, ciBinding, adjudicatedTree) {
25013
25064
  for (const d of r.divergence) md.push(`- ${d}`);
25014
25065
  md.push("");
25015
25066
  try {
25016
- appendFileSync6(path, md.join("\n") + "\n");
25067
+ appendFileSync3(path, md.join("\n") + "\n");
25017
25068
  } catch {
25018
25069
  }
25019
25070
  }
@@ -25823,7 +25874,7 @@ var init_main = __esm({
25823
25874
  // src/cli/index.ts
25824
25875
  init_hook_client();
25825
25876
  init_exit();
25826
- import { readFileSync as readFileSync29 } from "node:fs";
25877
+ import { readFileSync as readFileSync26 } from "node:fs";
25827
25878
  function loadMain() {
25828
25879
  return Promise.resolve().then(() => (init_main(), main_exports));
25829
25880
  }
@@ -25836,7 +25887,7 @@ async function launch(argv) {
25836
25887
  if (kind && hookServiceEnabled()) {
25837
25888
  let raw = null;
25838
25889
  try {
25839
- raw = readFileSync29(0, "utf8");
25890
+ raw = readFileSync26(0, "utf8");
25840
25891
  } catch {
25841
25892
  raw = null;
25842
25893
  }