tamperward 2.39.10 → 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 +128 -94
  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);
@@ -791,6 +791,36 @@ function readStateFile(abs) {
791
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
792
  );
793
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
+ }
794
824
  function describe(e, shown) {
795
825
  switch (e.kind) {
796
826
  case "symlink":
@@ -831,7 +861,7 @@ function unjudgeableProtected(cwd, policy, changes) {
831
861
  }
832
862
  return out3;
833
863
  }
834
- var READ_CAP, NO_META, O_READ, StateFileError;
864
+ var READ_CAP, NO_META, O_READ, StateFileError, O_APPEND_REGULAR, APPEND_REFUSED;
835
865
  var init_disk = __esm({
836
866
  "src/disk.ts"() {
837
867
  "use strict";
@@ -842,6 +872,8 @@ var init_disk = __esm({
842
872
  O_READ = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
843
873
  StateFileError = class extends Error {
844
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";
845
877
  }
846
878
  });
847
879
 
@@ -11777,8 +11809,53 @@ var init_effect = __esm({
11777
11809
  }
11778
11810
  });
11779
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
+
11780
11857
  // src/cli/watch.ts
11781
- import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, 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";
11782
11859
  import { join as join12 } from "node:path";
11783
11860
  import { createHash as createHash5 } from "node:crypto";
11784
11861
  function snap(abs) {
@@ -11889,7 +11966,7 @@ function watchTree(dir, cb, onState, onError, watchFn = watch) {
11889
11966
  const child = rel ? `${rel}/${String(fname)}` : String(fname);
11890
11967
  cb(kind, child);
11891
11968
  try {
11892
- if (lstatSync5(join12(dir, child)).isDirectory()) addDir(child);
11969
+ if (lstatSync6(join12(dir, child)).isDirectory()) addDir(child);
11893
11970
  } catch {
11894
11971
  }
11895
11972
  });
@@ -11925,7 +12002,7 @@ function watchTree(dir, cb, onState, onError, watchFn = watch) {
11925
12002
  const child = rel ? `${rel}/${name}` : name;
11926
12003
  if (SKIP2.test(child + "/")) continue;
11927
12004
  try {
11928
- if (lstatSync5(join12(dir, child)).isDirectory()) walk2(child);
12005
+ if (lstatSync6(join12(dir, child)).isDirectory()) walk2(child);
11929
12006
  } catch {
11930
12007
  }
11931
12008
  }
@@ -11964,7 +12041,7 @@ function startWatcher(dir, log, policy, watchFn = watch) {
11964
12041
  let healthWriteWarningEmitted = false;
11965
12042
  const persistHealth = () => {
11966
12043
  try {
11967
- writeFileSync4(healthPath, JSON.stringify(health) + "\n", { mode: 384 });
12044
+ atomicReplaceFile(healthPath, JSON.stringify(health) + "\n", 384);
11968
12045
  healthWriteWarningEmitted = false;
11969
12046
  } catch (e) {
11970
12047
  if (!healthWriteWarningEmitted) {
@@ -12004,7 +12081,7 @@ function startWatcher(dir, log, policy, watchFn = watch) {
12004
12081
  ...s
12005
12082
  };
12006
12083
  try {
12007
- appendFileSync3(log, JSON.stringify(ev) + "\n");
12084
+ appendRegular(log, JSON.stringify(ev) + "\n");
12008
12085
  health.event_count++;
12009
12086
  health.last_append_at = (/* @__PURE__ */ new Date()).toISOString();
12010
12087
  persistHealth();
@@ -12067,6 +12144,7 @@ var init_watch = __esm({
12067
12144
  "src/cli/watch.ts"() {
12068
12145
  "use strict";
12069
12146
  init_disk();
12147
+ init_safe_write();
12070
12148
  init_policy_load();
12071
12149
  init_policy();
12072
12150
  init_build();
@@ -12332,15 +12410,15 @@ var init_fs_events = __esm({
12332
12410
  });
12333
12411
 
12334
12412
  // src/cli/audit.ts
12335
- import { createHash as createHash6, randomBytes } from "node:crypto";
12336
- import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as existsSync5, 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";
12337
12415
  import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
12338
12416
  function sessionHash(sessionId) {
12339
12417
  if (!sessionId) return void 0;
12340
12418
  return "sha256:" + createHash6("sha256").update(sessionId).digest("hex").slice(0, 24);
12341
12419
  }
12342
12420
  function eventId() {
12343
- 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);
12344
12422
  }
12345
12423
  function configuredAuditPath(cwd, env = process.env) {
12346
12424
  const value = env[AUDIT_LOG_ENV];
@@ -12378,7 +12456,7 @@ function recordAuditFindings(findings, context) {
12378
12456
  };
12379
12457
  return JSON.stringify(event);
12380
12458
  });
12381
- appendFileSync4(path, lines.join("\n") + "\n");
12459
+ appendRegular(path, lines.join("\n") + "\n");
12382
12460
  } catch {
12383
12461
  }
12384
12462
  }
@@ -12613,6 +12691,7 @@ var init_audit = __esm({
12613
12691
  "src/cli/audit.ts"() {
12614
12692
  "use strict";
12615
12693
  init_repo_context();
12694
+ init_disk();
12616
12695
  AUDIT_SCHEMA_VERSION = 1;
12617
12696
  AUDIT_LOG_ENV = "TAMPERWARD_AUDIT_LOG";
12618
12697
  MAX_AUDIT_LINE_BYTES = 16 * 1024;
@@ -12631,7 +12710,7 @@ var init_audit = __esm({
12631
12710
  });
12632
12711
 
12633
12712
  // src/cli/hook.ts
12634
- import { readFileSync as readFileSync6, appendFileSync as appendFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync6 } from "node:fs";
12713
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6 } from "node:fs";
12635
12714
  import { createHash as createHash7 } from "node:crypto";
12636
12715
  function setSnapshotCache(cache3) {
12637
12716
  snapshotCache = cache3;
@@ -12666,7 +12745,7 @@ function recordDenylog(blocks2) {
12666
12745
  const log = process.env.TAMPERWARD_DENYLOG;
12667
12746
  if (!log) return;
12668
12747
  try {
12669
- appendFileSync5(log, blocks2.map((b) => b.rule).join(",") + "\n");
12748
+ appendRegular(log, blocks2.map((b) => b.rule).join(",") + "\n");
12670
12749
  } catch {
12671
12750
  }
12672
12751
  }
@@ -12985,7 +13064,7 @@ function recordWarns(cwd, sessionId, warns) {
12985
13064
  const log = process.env.TAMPERWARD_DENYLOG;
12986
13065
  if (!log) return;
12987
13066
  try {
12988
- 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");
12989
13068
  } catch {
12990
13069
  }
12991
13070
  }
@@ -12995,7 +13074,7 @@ function recordObserverHealth(cwd, sessionId, state, reason) {
12995
13074
  if (!log) return;
12996
13075
  const detail = (reason ?? "").replace(/[\r\n]+/g, " ").trim();
12997
13076
  try {
12998
- appendFileSync5(
13077
+ appendRegular(
12999
13078
  log,
13000
13079
  `warn:transient-observer:${state}${detail ? ":" + detail : ""}
13001
13080
  `
@@ -13112,7 +13191,7 @@ var init_hook = __esm({
13112
13191
  });
13113
13192
 
13114
13193
  // src/ptree-cache.ts
13115
- import { lstatSync as lstatSync6 } from "node:fs";
13194
+ import { lstatSync as lstatSync7 } from "node:fs";
13116
13195
  import { join as join14 } from "node:path";
13117
13196
  function keyOf(st) {
13118
13197
  return `${st.dev}:${st.ino}:${st.size}:${st.mode}:${st.mtimeNs}:${st.ctimeNs}`;
@@ -13166,7 +13245,7 @@ var init_ptree_cache = __esm({
13166
13245
  const abs = join14(cwd, rel);
13167
13246
  let st;
13168
13247
  try {
13169
- st = lstatSync6(abs, { bigint: true });
13248
+ st = lstatSync7(abs, { bigint: true });
13170
13249
  } catch {
13171
13250
  this.map.delete(abs);
13172
13251
  this.stats.misses++;
@@ -13188,7 +13267,7 @@ var init_ptree_cache = __esm({
13188
13267
  const entry = compute();
13189
13268
  let after;
13190
13269
  try {
13191
- after = lstatSync6(abs, { bigint: true });
13270
+ after = lstatSync7(abs, { bigint: true });
13192
13271
  } catch {
13193
13272
  this.map.delete(abs);
13194
13273
  return entry;
@@ -13206,7 +13285,7 @@ var init_ptree_cache = __esm({
13206
13285
  });
13207
13286
 
13208
13287
  // src/cli/hook-service.ts
13209
- import { chmodSync, existsSync as existsSync7, lstatSync as lstatSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync7, 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";
13210
13289
  import { createConnection as createConnection2, createServer } from "node:net";
13211
13290
  import { realpathSync as realpathSync4 } from "node:fs";
13212
13291
  import { sep } from "node:path";
@@ -13289,13 +13368,13 @@ function withEnv(env, fn) {
13289
13368
  }
13290
13369
  function removeQuietly(p) {
13291
13370
  try {
13292
- rmSync4(p, { force: true });
13371
+ rmSync5(p, { force: true });
13293
13372
  } catch {
13294
13373
  }
13295
13374
  }
13296
13375
  function ensurePrivateDir(dir, uid) {
13297
13376
  if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
13298
- const st = lstatSync7(dir);
13377
+ const st = lstatSync8(dir);
13299
13378
  if (!st.isDirectory()) throw new Error(`${dir} is not a directory`);
13300
13379
  if (st.uid !== uid) throw new Error(`${dir} is owned by uid ${st.uid}, not ${uid}; refusing to serve from it`);
13301
13380
  if ((st.mode & 63) !== 0) chmodSync(dir, 448);
@@ -13725,51 +13804,6 @@ var init_verifier_limits = __esm({
13725
13804
  }
13726
13805
  });
13727
13806
 
13728
- // src/safe-write.ts
13729
- import { randomBytes as randomBytes2 } from "node:crypto";
13730
- import { lstatSync as lstatSync8, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
13731
- function writeTargetKind(path) {
13732
- let st;
13733
- try {
13734
- st = lstatSync8(path, { throwIfNoEntry: false });
13735
- } catch (e) {
13736
- if (errnoCode(e) === "ENOTDIR") return "absent";
13737
- throw e;
13738
- }
13739
- if (!st) return "absent";
13740
- if (st.isSymbolicLink()) return "symlink";
13741
- return st.isFile() ? "file" : "irregular";
13742
- }
13743
- function refuseNonRegular(path) {
13744
- switch (writeTargetKind(path)) {
13745
- case "symlink":
13746
- return "refusing: symlink \u2014 the target would be written instead of this path; replace the link with a regular file, then re-run";
13747
- case "irregular":
13748
- return "refusing: not a regular file \u2014 a directory or special file stands where a file is expected; remove it, then re-run";
13749
- default:
13750
- return null;
13751
- }
13752
- }
13753
- function existingMode(path, fallback) {
13754
- if (writeTargetKind(path) !== "file") return fallback;
13755
- return lstatSync8(path).mode & 511;
13756
- }
13757
- function atomicReplaceFile(path, content, mode) {
13758
- const tmp = `${path}.${process.pid}.${randomBytes2(8).toString("hex")}.tmp`;
13759
- try {
13760
- writeFileSync7(tmp, content, { encoding: "utf8", flag: "wx", mode });
13761
- renameSync3(tmp, path);
13762
- } finally {
13763
- rmSync5(tmp, { force: true });
13764
- }
13765
- }
13766
- var init_safe_write = __esm({
13767
- "src/safe-write.ts"() {
13768
- "use strict";
13769
- init_narrow();
13770
- }
13771
- });
13772
-
13773
13807
  // src/cli/init.ts
13774
13808
  import { execFileSync as execFileSync6 } from "node:child_process";
13775
13809
  import { createHash as createHash8 } from "node:crypto";
@@ -15063,7 +15097,7 @@ var init_dependency_env = __esm({
15063
15097
 
15064
15098
  // src/suite-diagnostics.ts
15065
15099
  import { spawnSync } from "node:child_process";
15066
- 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";
15067
15101
  import { tmpdir as tmpdir3 } from "node:os";
15068
15102
  import { join as join17 } from "node:path";
15069
15103
  function emptySuiteDiagnostics() {
@@ -15149,7 +15183,7 @@ function runCapturedProcessSync(executable, args, opts) {
15149
15183
  const configFile = join17(stateDir2, "config.json");
15150
15184
  const backstop = opts.backstopMs ?? 3e4;
15151
15185
  try {
15152
- writeFileSync8(
15186
+ writeFileSync7(
15153
15187
  configFile,
15154
15188
  JSON.stringify({
15155
15189
  executable,
@@ -15916,7 +15950,7 @@ var init_verifier_backend = __esm({
15916
15950
  // src/verification-state.ts
15917
15951
  import { execFileSync as execFileSync8 } from "node:child_process";
15918
15952
  import { createHash as createHash12 } from "node:crypto";
15919
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync11, 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";
15920
15954
  import { dirname as dirname8, join as join19 } from "node:path";
15921
15955
  function git2(args, cwd) {
15922
15956
  return execFileSync8("git", args, {
@@ -16060,7 +16094,7 @@ function recordVerification(cwd, inputs, treeFingerprintValue) {
16060
16094
  binding
16061
16095
  };
16062
16096
  mkdirSync8(dirname8(path), { recursive: true });
16063
- writeFileSync9(path, JSON.stringify(record) + "\n");
16097
+ writeFileSync8(path, JSON.stringify(record) + "\n");
16064
16098
  return true;
16065
16099
  }
16066
16100
  function invalidateVerificationRecordIfCurrent(cwd) {
@@ -16158,7 +16192,7 @@ function beginVerifying(cwd) {
16158
16192
  started_at: (/* @__PURE__ */ new Date()).toISOString()
16159
16193
  };
16160
16194
  mkdirSync8(dirname8(path), { recursive: true });
16161
- writeFileSync9(path, JSON.stringify(marker) + "\n");
16195
+ writeFileSync8(path, JSON.stringify(marker) + "\n");
16162
16196
  return true;
16163
16197
  } catch {
16164
16198
  return false;
@@ -16311,7 +16345,7 @@ var init_verification_state = __esm({
16311
16345
 
16312
16346
  // src/verification-receipt.ts
16313
16347
  import { createHash as createHash13 } from "node:crypto";
16314
- 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";
16315
16349
  import { dirname as dirname9, join as join20 } from "node:path";
16316
16350
  function isRecord5(v) {
16317
16351
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -16358,7 +16392,7 @@ function storeReceipt(cwd, receipt) {
16358
16392
  if (!path) return false;
16359
16393
  try {
16360
16394
  mkdirSync9(dirname9(path), { recursive: true });
16361
- writeFileSync10(path, JSON.stringify(receipt) + "\n");
16395
+ writeFileSync9(path, JSON.stringify(receipt) + "\n");
16362
16396
  return true;
16363
16397
  } catch {
16364
16398
  return false;
@@ -16541,7 +16575,7 @@ var init_verification_receipt = __esm({
16541
16575
  // src/cli/verify.ts
16542
16576
  import { execFileSync as execFileSync9, spawnSync as spawnSync3 } from "node:child_process";
16543
16577
  import { createHash as createHash14 } from "node:crypto";
16544
- 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 writeFileSync11, existsSync as existsSync10 } 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";
16545
16579
  import { tmpdir as tmpdir4 } from "node:os";
16546
16580
  import { dirname as dirname10, isAbsolute as isAbsolute11, join as join21, relative as relative6, resolve as resolve9, sep as sep4 } from "node:path";
16547
16581
  function oracleAssuranceReport() {
@@ -16736,7 +16770,7 @@ function probeFilesystemCaseSensitivity(dir) {
16736
16770
  const upper = join21(dir, ".tw-case-probe-A");
16737
16771
  const lower = join21(dir, ".tw-case-probe-a");
16738
16772
  try {
16739
- writeFileSync11(upper, "", { flag: "wx" });
16773
+ writeFileSync10(upper, "", { flag: "wx" });
16740
16774
  return !existsSync10(lower);
16741
16775
  } finally {
16742
16776
  rmSync9(upper, { force: true });
@@ -16839,7 +16873,7 @@ function overlayPristine(cwd, base, dest, policy, cmd, dependencyRoot, caseSensi
16839
16873
  safeSymlink(target, out3, dest, `the base's ${e.path}`);
16840
16874
  restoredLinks.push({ path: e.path, out: out3, target });
16841
16875
  } else {
16842
- writeFileSync11(out3, content);
16876
+ writeFileSync10(out3, content);
16843
16877
  chmodSync2(out3, parseInt(e.mode.slice(-4), 8) & 511);
16844
16878
  }
16845
16879
  restored.push(e.path);
@@ -16864,7 +16898,7 @@ function suiteEnv(scratch) {
16864
16898
  }
16865
16899
  const userRc = join21(scratch, "npmrc-user");
16866
16900
  const globalRc = join21(scratch, "npmrc-global");
16867
- for (const f of [userRc, globalRc]) writeFileSync11(f, "", { mode: 292 });
16901
+ for (const f of [userRc, globalRc]) writeFileSync10(f, "", { mode: 292 });
16868
16902
  env.npm_config_userconfig = userRc;
16869
16903
  env.npm_config_globalconfig = globalRc;
16870
16904
  env.npm_config_node_options = " ";
@@ -17615,7 +17649,7 @@ var init_verify = __esm({
17615
17649
  // src/cli/run.ts
17616
17650
  import { execFileSync as execFileSync10, spawn, spawnSync as spawnSync4 } from "node:child_process";
17617
17651
  import { randomBytes as randomBytes3 } from "node:crypto";
17618
- 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 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";
17619
17653
  import { tmpdir as tmpdir5 } from "node:os";
17620
17654
  import { dirname as dirname11, join as join22, resolve as resolve10 } from "node:path";
17621
17655
  function authoritativeRunLifecyclePlatform(platform = process.platform) {
@@ -17712,7 +17746,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
17712
17746
  failure: trustedPython.reason ?? "trusted Linux python3 interpreter is unavailable"
17713
17747
  };
17714
17748
  }
17715
- writeFileSync12(agentEnvFile, JSON.stringify(process.env), { mode: 384 });
17749
+ writeFileSync11(agentEnvFile, JSON.stringify(process.env), { mode: 384 });
17716
17750
  executable = trustedPython.path;
17717
17751
  args = [
17718
17752
  "-I",
@@ -21005,7 +21039,7 @@ var init_adapter3 = __esm({
21005
21039
 
21006
21040
  // src/adapters/copilot-sdk/changes.ts
21007
21041
  import { execFileSync as execFileSync13 } from "node:child_process";
21008
- import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as readFileSync17, rmSync as rmSync12, existsSync as existsSync14, 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";
21009
21043
  import { tmpdir as tmpdir7 } from "node:os";
21010
21044
  import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute16, relative as relative11, resolve as resolve15, join as join26 } from "node:path";
21011
21045
  function asStr4(v) {
@@ -21082,9 +21116,9 @@ function reconstructAfterViaGit(rawDiff, display2, before, isCreate) {
21082
21116
  const dir = mkdtempSync6(join26(tmpdir7(), "hf-sdk-apply-"));
21083
21117
  try {
21084
21118
  const targetPath = join26(dir, TARGET);
21085
- if (op !== "create") writeFileSync13(targetPath, before ?? "");
21119
+ if (op !== "create") writeFileSync12(targetPath, before ?? "");
21086
21120
  const patchPath = join26(dir, "change.patch");
21087
- writeFileSync13(patchPath, patch);
21121
+ writeFileSync12(patchPath, patch);
21088
21122
  const git8 = (extra) => execFileSync13("git", ["apply", ...extra, patchPath], {
21089
21123
  cwd: dir,
21090
21124
  encoding: "utf8",
@@ -21852,7 +21886,7 @@ var init_runtime_qualification = __esm({
21852
21886
 
21853
21887
  // src/cli/runtime.ts
21854
21888
  import { execFileSync as execFileSync14 } from "node:child_process";
21855
- import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
21889
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync13 } from "node:fs";
21856
21890
  import { join as join27, dirname as dirname13 } from "node:path";
21857
21891
  function storePath(cwd) {
21858
21892
  const dir = gitDir(cwd);
@@ -21993,7 +22027,7 @@ function writeRecord(cwd, id, report2) {
21993
22027
  store.updated_at = report2.timestamp;
21994
22028
  try {
21995
22029
  mkdirSync11(dirname13(path), { recursive: true });
21996
- writeFileSync14(path, JSON.stringify(store, null, 2) + "\n", { mode: 384 });
22030
+ writeFileSync13(path, JSON.stringify(store, null, 2) + "\n", { mode: 384 });
21997
22031
  return true;
21998
22032
  } catch {
21999
22033
  return false;
@@ -23493,7 +23527,7 @@ var init_record = __esm({
23493
23527
  // src/research/run.ts
23494
23528
  import { randomUUID as randomUUID2 } from "node:crypto";
23495
23529
  import { execFileSync as execFileSync16 } from "node:child_process";
23496
- 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 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";
23497
23531
  import { hostname } from "node:os";
23498
23532
  import { join as join29, resolve as resolve19 } from "node:path";
23499
23533
  function git7(args, cwd) {
@@ -23574,7 +23608,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
23574
23608
  let fd = -1;
23575
23609
  try {
23576
23610
  fd = openSync5(path, "wx", 384);
23577
- writeSync(fd, text);
23611
+ writeSync2(fd, text);
23578
23612
  closeSync5(fd);
23579
23613
  fd = -1;
23580
23614
  } catch (e) {
@@ -23638,7 +23672,7 @@ function resumableRecord(path, expected) {
23638
23672
  }
23639
23673
  function writeRecordAtomically(path, text) {
23640
23674
  const tmp = `${path}.${process.pid}.tmp`;
23641
- writeFileSync15(tmp, text);
23675
+ writeFileSync14(tmp, text);
23642
23676
  renameSync4(tmp, path);
23643
23677
  }
23644
23678
  function cloneArgs(repo, ws3) {
@@ -24239,7 +24273,7 @@ var init_summarize = __esm({
24239
24273
 
24240
24274
  // src/research/init.ts
24241
24275
  import { createHash as createHash17 } from "node:crypto";
24242
- import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
24276
+ import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
24243
24277
  import { basename as basename6, dirname as dirname15, resolve as resolve21 } from "node:path";
24244
24278
  function idFrom(repo) {
24245
24279
  const clean = repo.replace(/[\\/]$/, "").split(/[\\/]/).pop() || "task";
@@ -24269,7 +24303,7 @@ function createResearchManifest(opts) {
24269
24303
  };
24270
24304
  const text = JSON.stringify(doc, null, 2) + "\n";
24271
24305
  mkdirSync13(dirname15(out3), { recursive: true });
24272
- writeFileSync16(out3, text, { flag: "wx", mode: 384 });
24306
+ writeFileSync15(out3, text, { flag: "wx", mode: 384 });
24273
24307
  const parsed = readManifest(out3);
24274
24308
  if (parsed.tasks.length !== 1 || parsed.tasks[0].id !== id) throw new ResearchError(`research init wrote an invalid manifest ${out3}`);
24275
24309
  return out3;
@@ -24359,7 +24393,7 @@ var init_report2 = __esm({
24359
24393
  import { createHash as createHash18 } from "node:crypto";
24360
24394
  import { isDeepStrictEqual } from "node:util";
24361
24395
  import { gzipSync, gunzipSync } from "node:zlib";
24362
- import { mkdirSync as mkdirSync14, readFileSync as readFileSync24, writeFileSync as writeFileSync17 } from "node:fs";
24396
+ import { mkdirSync as mkdirSync14, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
24363
24397
  import { dirname as dirname16, resolve as resolve22 } from "node:path";
24364
24398
  function octal(value, width) {
24365
24399
  return value.toString(8).padStart(width - 1, "0") + "\0";
@@ -24559,7 +24593,7 @@ function createResearchBundle(opts) {
24559
24593
  entries.push({ name: "provenance.json", bytes: jsonBytes(provenance) });
24560
24594
  const out3 = resolve22(opts.out);
24561
24595
  mkdirSync14(dirname16(out3), { recursive: true });
24562
- writeFileSync17(out3, gzipSync(makeTar(entries)), { flag: "wx", mode: 384 });
24596
+ writeFileSync16(out3, gzipSync(makeTar(entries)), { flag: "wx", mode: 384 });
24563
24597
  return out3;
24564
24598
  }
24565
24599
  function runResearchBundle(opts) {
@@ -24706,7 +24740,7 @@ var init_research = __esm({
24706
24740
  });
24707
24741
 
24708
24742
  // src/cli/receipt.ts
24709
- import { appendFileSync as appendFileSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync18 } from "node:fs";
24743
+ import { appendFileSync as appendFileSync3, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
24710
24744
  function parseReceipt(args) {
24711
24745
  const [sub, ...rest] = args;
24712
24746
  const exportOpts = {};
@@ -24808,7 +24842,7 @@ function runReceiptExport(opts = {}) {
24808
24842
  const serialized = JSON.stringify(receipt) + "\n";
24809
24843
  if (opts.out) {
24810
24844
  try {
24811
- writeFileSync18(opts.out, serialized);
24845
+ writeFileSync17(opts.out, serialized);
24812
24846
  } catch (e) {
24813
24847
  process.stderr.write(`tamperward: could not write receipt to ${opts.out} (${e instanceof Error ? e.message : String(e)})
24814
24848
  `);
@@ -25030,7 +25064,7 @@ function writeJobSummary(r, receipt, ciBinding, adjudicatedTree) {
25030
25064
  for (const d of r.divergence) md.push(`- ${d}`);
25031
25065
  md.push("");
25032
25066
  try {
25033
- appendFileSync6(path, md.join("\n") + "\n");
25067
+ appendFileSync3(path, md.join("\n") + "\n");
25034
25068
  } catch {
25035
25069
  }
25036
25070
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.39.10",
3
+ "version": "2.39.11",
4
4
  "description": "The deterministic agent-integrity gate. One ruleset, evaluated on the actual diff/commands as a verdict, enforced everywhere a change can be made.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "hexrift",