tamperward 2.29.15 → 2.29.16

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 +139 -50
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1381,6 +1381,38 @@ import { execFileSync as execFileSync4 } from "node:child_process";
1381
1381
  import { writeFileSync, mkdtempSync, rmSync } from "node:fs";
1382
1382
  import { tmpdir as tmpdir2 } from "node:os";
1383
1383
  import { isAbsolute as isAbsolute4, join as join5, relative, resolve as resolve2 } from "node:path";
1384
+ function sideSize(s) {
1385
+ if (s == null) return { bytes: 0, lines: 0 };
1386
+ let lines = 1;
1387
+ for (let i = 0; i < s.length; i++) if (s.charCodeAt(i) === 10) lines++;
1388
+ return { bytes: Buffer.byteLength(s), lines };
1389
+ }
1390
+ function overReconstructCeiling(before, after) {
1391
+ const maxBytes = RECONSTRUCT_MAX_BYTES();
1392
+ const maxLines = RECONSTRUCT_MAX_LINES();
1393
+ for (const [label, side] of [["before", before], ["after", after]]) {
1394
+ const { bytes, lines } = sideSize(side);
1395
+ if (bytes > maxBytes) return `${label} is ${bytes} bytes (over the ${maxBytes}-byte reconstruction budget)`;
1396
+ if (lines > maxLines) return `${label} is ${lines} lines (over the ${maxLines}-line reconstruction budget)`;
1397
+ }
1398
+ return null;
1399
+ }
1400
+ function linearFallbackHunks(before, after) {
1401
+ const b = before == null ? [] : before.split("\n");
1402
+ const a = after == null ? [] : after.split("\n");
1403
+ let p = 0;
1404
+ while (p < b.length && p < a.length && b[p] === a[p]) p++;
1405
+ let s = 0;
1406
+ while (s < b.length - p && s < a.length - p && b[b.length - 1 - s] === a[a.length - 1 - s]) s++;
1407
+ const delContent = b.slice(p, b.length - s);
1408
+ const addContent = a.slice(p, a.length - s);
1409
+ if (delContent.length === 0 && addContent.length === 0) return [];
1410
+ const lines = [
1411
+ ...delContent.map((content, i) => ({ type: "del", content, oldLine: p + 1 + i, newLine: null })),
1412
+ ...addContent.map((content, i) => ({ type: "add", content, oldLine: null, newLine: p + 1 + i }))
1413
+ ];
1414
+ return [{ oldStart: p + 1, oldLines: delContent.length, newStart: p + 1, newLines: addContent.length, lines }];
1415
+ }
1384
1416
  function asStr(v) {
1385
1417
  return typeof v === "string" ? v : "";
1386
1418
  }
@@ -1402,31 +1434,39 @@ function synthFileChange(displayPath, before, after) {
1402
1434
  if (before === null) op = "add";
1403
1435
  else if (after === null) op = "delete";
1404
1436
  else op = "modify";
1437
+ const over = overReconstructCeiling(before, after);
1438
+ if (over) {
1439
+ throw new Error(`cannot safely reconstruct the incoming edit to ${displayPath} within the hook budget: ${over}`);
1440
+ }
1441
+ const mk = (hunks) => [
1442
+ { kind: "file", path: displayPath, oldPath: null, op, before, after, binary: false, hunks }
1443
+ ];
1405
1444
  const dir = mkdtempSync(join5(tmpdir2(), "hf-"));
1406
- let raw = "";
1407
1445
  try {
1408
1446
  const a = join5(dir, "a");
1409
1447
  const b = join5(dir, "b");
1410
1448
  writeFileSync(a, before ?? "");
1411
1449
  writeFileSync(b, after ?? "");
1412
1450
  try {
1413
- raw = execFileSync4("git", ["diff", "--no-index", "--no-color", "--text", a, b], {
1451
+ const raw = execFileSync4("git", ["diff", "--no-index", "--no-color", "--text", a, b], {
1414
1452
  encoding: "utf8",
1415
- maxBuffer: 256 * 1024 * 1024
1453
+ maxBuffer: RECONSTRUCT_MAXBUFFER(),
1454
+ timeout: RECONSTRUCT_TIMEOUT_MS(),
1455
+ killSignal: "SIGKILL"
1416
1456
  });
1457
+ const first = parseDiff(raw)[0];
1458
+ return mk(first && first.kind === "file" ? first.hunks : []);
1417
1459
  } catch (e) {
1418
1460
  const failure = execFailure(e);
1419
- if (failure.status !== 1) {
1420
- throw new Error(`cannot diff the incoming edit to ${displayPath}: ${failure.code ?? failure.message}`);
1461
+ if (failure.status === 1) {
1462
+ const first = parseDiff(failure.stdout)[0];
1463
+ return mk(first && first.kind === "file" ? first.hunks : []);
1421
1464
  }
1422
- raw = failure.stdout;
1465
+ return mk(linearFallbackHunks(before, after));
1423
1466
  }
1424
1467
  } finally {
1425
1468
  rmSync(dir, { recursive: true, force: true });
1426
1469
  }
1427
- const first = parseDiff(raw)[0];
1428
- const hunks = first && first.kind === "file" ? first.hunks : [];
1429
- return [{ kind: "file", path: displayPath, oldPath: null, op, before, after, binary: false, hunks }];
1430
1470
  }
1431
1471
  function changesFromClaudeHook(input, cwd, base = cwd) {
1432
1472
  const ti = input.tool_input ?? {};
@@ -1471,12 +1511,22 @@ function changesFromClaudeHook(input, cwd, base = cwd) {
1471
1511
  return [];
1472
1512
  }
1473
1513
  }
1514
+ var num, RECONSTRUCT_TIMEOUT_MS, RECONSTRUCT_MAXBUFFER, RECONSTRUCT_MAX_BYTES, RECONSTRUCT_MAX_LINES;
1474
1515
  var init_changes = __esm({
1475
1516
  "src/adapters/claude/changes.ts"() {
1476
1517
  "use strict";
1477
1518
  init_parse();
1478
1519
  init_disk();
1479
1520
  init_narrow();
1521
+ num = (name, fallback) => {
1522
+ const raw = process.env[name];
1523
+ const n = raw === void 0 ? NaN : Number(raw);
1524
+ return Number.isFinite(n) && n > 0 ? n : fallback;
1525
+ };
1526
+ RECONSTRUCT_TIMEOUT_MS = () => num("TAMPERWARD_RECONSTRUCT_TIMEOUT_MS", 5e3);
1527
+ RECONSTRUCT_MAXBUFFER = () => num("TAMPERWARD_RECONSTRUCT_MAXBUFFER", 32 * 1024 * 1024);
1528
+ RECONSTRUCT_MAX_BYTES = () => num("TAMPERWARD_RECONSTRUCT_MAX_BYTES", 384 * 1024);
1529
+ RECONSTRUCT_MAX_LINES = () => num("TAMPERWARD_RECONSTRUCT_MAX_LINES", 4e3);
1480
1530
  }
1481
1531
  });
1482
1532
 
@@ -3337,6 +3387,7 @@ var init_no_verify = __esm({
3337
3387
 
3338
3388
  // src/ts-lazy.ts
3339
3389
  import { createRequire as createRequire2 } from "node:module";
3390
+ import { createHash as createHash2 } from "node:crypto";
3340
3391
  function loadTs() {
3341
3392
  if (loaded === null) {
3342
3393
  const required = createRequire2(import.meta.url)("typescript");
@@ -3357,17 +3408,37 @@ function nestsWithinCeiling(src) {
3357
3408
  return true;
3358
3409
  }
3359
3410
  function parseSource(fileName, src, kind) {
3360
- if (Buffer.byteLength(src) > MAX_PARSE_BYTES) return null;
3361
- if (!nestsWithinCeiling(src)) return null;
3362
- const t = loadTs();
3363
- try {
3364
- return t.createSourceFile(fileName, src, t.ScriptTarget.Latest, true, kind ?? t.ScriptKind.TS);
3365
- } catch (e) {
3366
- if (e instanceof RangeError) return null;
3367
- throw e;
3411
+ const bytes = Buffer.byteLength(src);
3412
+ if (bytes > MAX_PARSE_BYTES) return null;
3413
+ const key2 = `${kind ?? ""}\0${fileName}\0${createHash2("sha256").update(src).digest("hex")}`;
3414
+ const at = parseCache.findIndex((e) => e.key === key2);
3415
+ if (at !== -1) {
3416
+ const [entry] = parseCache.splice(at, 1);
3417
+ parseCache.push(entry);
3418
+ return entry.sf;
3368
3419
  }
3420
+ let sf;
3421
+ if (!nestsWithinCeiling(src)) {
3422
+ sf = null;
3423
+ } else {
3424
+ const t = loadTs();
3425
+ try {
3426
+ sf = t.createSourceFile(fileName, src, t.ScriptTarget.Latest, true, kind ?? t.ScriptKind.TS);
3427
+ } catch (e) {
3428
+ if (e instanceof RangeError) sf = null;
3429
+ else throw e;
3430
+ }
3431
+ }
3432
+ parseCache.push({ key: key2, sf, bytes });
3433
+ parseCacheBytes += bytes;
3434
+ while (parseCache.length > PARSE_CACHE_MAX_ENTRIES || parseCacheBytes > PARSE_CACHE_MAX_BYTES) {
3435
+ const evicted = parseCache.shift();
3436
+ if (!evicted) break;
3437
+ parseCacheBytes -= evicted.bytes;
3438
+ }
3439
+ return sf;
3369
3440
  }
3370
- var loaded, handler, ts, MAX_PARSE_BYTES, MAX_PARSE_DEPTH;
3441
+ var loaded, handler, ts, MAX_PARSE_BYTES, MAX_PARSE_DEPTH, PARSE_CACHE_MAX_ENTRIES, PARSE_CACHE_MAX_BYTES, parseCache, parseCacheBytes;
3371
3442
  var init_ts_lazy = __esm({
3372
3443
  "src/ts-lazy.ts"() {
3373
3444
  "use strict";
@@ -3390,6 +3461,10 @@ var init_ts_lazy = __esm({
3390
3461
  ts = new Proxy(/* @__PURE__ */ Object.create(null), handler);
3391
3462
  MAX_PARSE_BYTES = 4 * 1024 * 1024;
3392
3463
  MAX_PARSE_DEPTH = 256;
3464
+ PARSE_CACHE_MAX_ENTRIES = 32;
3465
+ PARSE_CACHE_MAX_BYTES = 24 * 1024 * 1024;
3466
+ parseCache = [];
3467
+ parseCacheBytes = 0;
3393
3468
  }
3394
3469
  });
3395
3470
 
@@ -6903,10 +6978,10 @@ function lex(src) {
6903
6978
  i = j + 1;
6904
6979
  continue;
6905
6980
  }
6906
- const num = src.slice(i).match(/^-?\d+(?:\.\d+)?/);
6907
- if (num) {
6908
- out3.push({ t: "num", v: num[0] });
6909
- i += num[0].length;
6981
+ const num2 = src.slice(i).match(/^-?\d+(?:\.\d+)?/);
6982
+ if (num2) {
6983
+ out3.push({ t: "num", v: num2[0] });
6984
+ i += num2[0].length;
6910
6985
  continue;
6911
6986
  }
6912
6987
  const op = src.slice(i).match(/^(?:==|!=|&&|\|\||<=|>=|[!()<>,[\]])/);
@@ -6931,13 +7006,13 @@ function foldConst(src) {
6931
7006
  let p = 0;
6932
7007
  const peek = () => toks[p];
6933
7008
  const eat = (v2) => toks[p]?.t === "op" && toks[p].v === v2 ? (p++, true) : false;
6934
- const num = (v2) => v2 === TRUTHY ? NaN : typeof v2 === "number" ? v2 : typeof v2 === "boolean" ? v2 ? 1 : 0 : v2 === null ? 0 : v2.trim() === "" ? 0 : Number(v2);
7009
+ const num2 = (v2) => v2 === TRUTHY ? NaN : typeof v2 === "number" ? v2 : typeof v2 === "boolean" ? v2 ? 1 : 0 : v2 === null ? 0 : v2.trim() === "" ? 0 : Number(v2);
6935
7010
  const eq = (a, b) => {
6936
7011
  if (a === TRUTHY || b === TRUTHY) return void 0;
6937
7012
  if (typeof a === "string" && typeof b === "string") return a.toLowerCase() === b.toLowerCase();
6938
7013
  if (a === null && b === null) return true;
6939
- const x = num(a);
6940
- const y2 = num(b);
7014
+ const x = num2(a);
7015
+ const y2 = num2(b);
6941
7016
  return !Number.isNaN(x) && x === y2;
6942
7017
  };
6943
7018
  const or = () => {
@@ -6975,8 +7050,8 @@ function foldConst(src) {
6975
7050
  const e = eq(l, r);
6976
7051
  l = e === void 0 ? void 0 : t.v === "==" ? e : !e;
6977
7052
  } else {
6978
- const x = num(l);
6979
- const y2 = num(r);
7053
+ const x = num2(l);
7054
+ const y2 = num2(r);
6980
7055
  if (Number.isNaN(x) || Number.isNaN(y2)) l = void 0;
6981
7056
  else l = t.v === "<" ? x < y2 : t.v === ">" ? x > y2 : t.v === "<=" ? x <= y2 : x >= y2;
6982
7057
  }
@@ -9914,6 +9989,14 @@ var init_test_content_removal = __esm({
9914
9989
  KeptPool = class {
9915
9990
  text = "";
9916
9991
  inLiteral = [];
9992
+ // O(1) fast path (#517): the ws-text of each kept significant line whose retained
9993
+ // text BEGINS at a code position (inLiteral 0). A removed line whose ws-text equals
9994
+ // one of these is kept — necessarily the SAME answer `indexOf` gives, since that exact
9995
+ // text then occurs in `text` at a code position — but in O(1) instead of scanning the
9996
+ // whole concatenated pool per removed line (a 20k-line high-churn spec was O(n²) here,
9997
+ // ~13s, #517). The substring scan below is unchanged and still covers rewrapped/joined
9998
+ // lines and moved fixtures, so `keeps` returns exactly what it did before.
9999
+ wholeCodeLines = /* @__PURE__ */ new Set();
9917
10000
  addLive(src, path) {
9918
10001
  const p = partition(src, path);
9919
10002
  const lang = langOf(path);
@@ -9922,11 +10005,16 @@ var init_test_content_removal = __esm({
9922
10005
  if (i < p.live.length && p.live[i] !== "\n") continue;
9923
10006
  const line = p.live.slice(lineStart, i);
9924
10007
  if (isSignificantLine(line.trim(), lang)) {
10008
+ let lineWs = "";
10009
+ let startsAtCode = false;
9925
10010
  for (let j = lineStart; j < i; j++) {
9926
10011
  if (/\s/.test(p.live[j])) continue;
10012
+ if (lineWs.length === 0) startsAtCode = p.inLiteral[j] === 0;
9927
10013
  this.text += p.live[j];
9928
10014
  this.inLiteral.push(p.inLiteral[j]);
10015
+ lineWs += p.live[j];
9929
10016
  }
10017
+ if (lineWs.length > 0 && startsAtCode) this.wholeCodeLines.add(lineWs);
9930
10018
  }
9931
10019
  lineStart = i + 1;
9932
10020
  }
@@ -9938,6 +10026,7 @@ var init_test_content_removal = __esm({
9938
10026
  }
9939
10027
  keeps(wsLine) {
9940
10028
  if (wsLine.length === 0) return true;
10029
+ if (this.wholeCodeLines.has(wsLine)) return true;
9941
10030
  let at = this.text.indexOf(wsLine);
9942
10031
  while (at !== -1) {
9943
10032
  if (this.inLiteral[at] === 0) return true;
@@ -10763,7 +10852,7 @@ var init_policy_load = __esm({
10763
10852
  });
10764
10853
 
10765
10854
  // src/signoff.ts
10766
- import { createHash as createHash2 } from "node:crypto";
10855
+ import { createHash as createHash3 } from "node:crypto";
10767
10856
  import { appendFileSync, mkdirSync, readFileSync as readFileSync6, existsSync as existsSync6 } from "node:fs";
10768
10857
  import { dirname as dirname2, join as join9 } from "node:path";
10769
10858
  function ledgerEntryFrom(value) {
@@ -10775,7 +10864,7 @@ function ledgerEntryFrom(value) {
10775
10864
  return { rule, ...file !== void 0 ? { file } : {}, fingerprint: fingerprint2, reason, recordedAt, expiresAt };
10776
10865
  }
10777
10866
  function fingerprint(rule, file, evidence) {
10778
- return createHash2("sha256").update(`${rule}\0${file ?? ""}\0${evidence}`).digest("hex").slice(0, 16);
10867
+ return createHash3("sha256").update(`${rule}\0${file ?? ""}\0${evidence}`).digest("hex").slice(0, 16);
10779
10868
  }
10780
10869
  function ledgerPath(cwd, policy) {
10781
10870
  const rel = policy.signoff?.ledger ?? ".tamperward/ledger.jsonl";
@@ -11335,7 +11424,7 @@ var init_session = __esm({
11335
11424
  });
11336
11425
 
11337
11426
  // src/effect.ts
11338
- import { createHash as createHash3 } from "node:crypto";
11427
+ import { createHash as createHash4 } from "node:crypto";
11339
11428
  import { existsSync as existsSync8, lstatSync as lstatSync3, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync8, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
11340
11429
  import { join as join11 } from "node:path";
11341
11430
  function ptreeFrom(value) {
@@ -11478,19 +11567,19 @@ var init_effect = __esm({
11478
11567
  init_narrow();
11479
11568
  UNSAFE2 = /[^A-Za-z0-9._-]/g;
11480
11569
  SKIP_DIRS2 = /* @__PURE__ */ new Set([".git", "node_modules", ".hg", ".svn"]);
11481
- sha = (buf) => createHash3("sha256").update(buf).digest("hex").slice(0, 16);
11570
+ sha = (buf) => createHash4("sha256").update(buf).digest("hex").slice(0, 16);
11482
11571
  }
11483
11572
  });
11484
11573
 
11485
11574
  // src/cli/watch.ts
11486
11575
  import { appendFileSync as appendFileSync3, lstatSync as lstatSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync9, readdirSync as readdirSync2, watch, writeFileSync as writeFileSync4 } from "node:fs";
11487
11576
  import { join as join12 } from "node:path";
11488
- import { createHash as createHash4 } from "node:crypto";
11577
+ import { createHash as createHash5 } from "node:crypto";
11489
11578
  function snap(abs) {
11490
11579
  const e = inspectPath(abs);
11491
11580
  if (e.kind === "absent" || e.kind === "unreadable") return { mode: null, size: null, hash: null };
11492
11581
  if (e.kind !== "file" || e.content == null) return { mode: e.mode, size: null, hash: null };
11493
- const hash = createHash4("sha256").update(e.content).digest("hex").slice(0, 16);
11582
+ const hash = createHash5("sha256").update(e.content).digest("hex").slice(0, 16);
11494
11583
  return { mode: e.mode, size: e.size, hash };
11495
11584
  }
11496
11585
  function defaultEventLog(cwd) {
@@ -12003,15 +12092,15 @@ var init_fs_events = __esm({
12003
12092
  });
12004
12093
 
12005
12094
  // src/cli/audit.ts
12006
- import { createHash as createHash5, randomBytes } from "node:crypto";
12095
+ import { createHash as createHash6, randomBytes } from "node:crypto";
12007
12096
  import { appendFileSync as appendFileSync4, existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync10 } from "node:fs";
12008
12097
  import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
12009
12098
  function sessionHash(sessionId) {
12010
12099
  if (!sessionId) return void 0;
12011
- return "sha256:" + createHash5("sha256").update(sessionId).digest("hex").slice(0, 24);
12100
+ return "sha256:" + createHash6("sha256").update(sessionId).digest("hex").slice(0, 24);
12012
12101
  }
12013
12102
  function eventId() {
12014
- return "sha256:" + createHash5("sha256").update(randomBytes(32)).digest("hex").slice(0, 32);
12103
+ return "sha256:" + createHash6("sha256").update(randomBytes(32)).digest("hex").slice(0, 32);
12015
12104
  }
12016
12105
  function configuredAuditPath(cwd, env = process.env) {
12017
12106
  const value = env[AUDIT_LOG_ENV];
@@ -12240,7 +12329,7 @@ var init_audit = __esm({
12240
12329
 
12241
12330
  // src/cli/hook.ts
12242
12331
  import { readFileSync as readFileSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync10 } from "node:fs";
12243
- import { createHash as createHash6 } from "node:crypto";
12332
+ import { createHash as createHash7 } from "node:crypto";
12244
12333
  function setSnapshotCache(cache3) {
12245
12334
  snapshotCache = cache3;
12246
12335
  }
@@ -12478,7 +12567,7 @@ function sanctionPredictedWrites(cwd, sessionId, policy, changes) {
12478
12567
  let dirty = false;
12479
12568
  for (const c of changes) {
12480
12569
  if (c.kind !== "file" || c.after == null || !isProtected(c.path, policy)) continue;
12481
- const hash = createHash6("sha256").update(c.after).digest("hex").slice(0, 16);
12570
+ const hash = createHash7("sha256").update(c.after).digest("hex").slice(0, 16);
12482
12571
  const prev = tree[c.path];
12483
12572
  tree[c.path] = {
12484
12573
  hash,
@@ -13325,7 +13414,7 @@ var init_safe_write = __esm({
13325
13414
 
13326
13415
  // src/cli/init.ts
13327
13416
  import { execFileSync as execFileSync6 } from "node:child_process";
13328
- import { createHash as createHash7 } from "node:crypto";
13417
+ import { createHash as createHash8 } from "node:crypto";
13329
13418
  import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync13, realpathSync as realpathSync5 } from "node:fs";
13330
13419
  import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, relative as relative3, resolve as resolve5 } from "node:path";
13331
13420
  function gitConfig(cwd, key2) {
@@ -13375,7 +13464,7 @@ function stalePin(command) {
13375
13464
  return pin !== null && (pin !== TW_VERSION || !OURS.test(command));
13376
13465
  }
13377
13466
  function bodyHash(body) {
13378
- return createHash7("sha256").update(body).digest("hex").slice(0, 16);
13467
+ return createHash8("sha256").update(body).digest("hex").slice(0, 16);
13379
13468
  }
13380
13469
  function workflowFile(body) {
13381
13470
  return `${WORKFLOW_MARK} v${TW_VERSION} sha256:${bodyHash(body)}
@@ -14120,7 +14209,7 @@ jobs:
14120
14209
 
14121
14210
  // src/fingerprint.ts
14122
14211
  import { execFileSync as execFileSync7 } from "node:child_process";
14123
- import { createHash as createHash8 } from "node:crypto";
14212
+ import { createHash as createHash9 } from "node:crypto";
14124
14213
  function treeFingerprint(cwd, keepIgnored) {
14125
14214
  const listed = execFileSync7("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
14126
14215
  cwd,
@@ -14129,7 +14218,7 @@ function treeFingerprint(cwd, keepIgnored) {
14129
14218
  env: trustedGitEnv()
14130
14219
  }).split("\0").filter(Boolean);
14131
14220
  const files = [.../* @__PURE__ */ new Set([...listed, ...keepIgnored ? ignoredPaths({ cwd }, keepIgnored) : []])].sort();
14132
- const h = createHash8("sha256");
14221
+ const h = createHash9("sha256");
14133
14222
  for (const rel of files) {
14134
14223
  h.update(rel);
14135
14224
  h.update("\0");
@@ -14153,7 +14242,7 @@ var init_fingerprint = __esm({
14153
14242
  });
14154
14243
 
14155
14244
  // src/dependency-env.ts
14156
- import { createHash as createHash9 } from "node:crypto";
14245
+ import { createHash as createHash10 } from "node:crypto";
14157
14246
  import {
14158
14247
  existsSync as existsSync13,
14159
14248
  lstatSync as lstatSync8,
@@ -14306,7 +14395,7 @@ function fingerprintRoot(root, cwd, h) {
14306
14395
  walk2(root.realPath, "");
14307
14396
  }
14308
14397
  function snapshot(roots, probes, cwd) {
14309
- const h = createHash9("sha256");
14398
+ const h = createHash10("sha256");
14310
14399
  for (const probe of probes) {
14311
14400
  h.update(
14312
14401
  "probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync13(probe.path) ? "present" : "absent") + "\0"
@@ -14891,7 +14980,7 @@ if (child) {
14891
14980
  });
14892
14981
 
14893
14982
  // src/verifier-backend.ts
14894
- import { createHash as createHash10, randomUUID } from "node:crypto";
14983
+ import { createHash as createHash11, randomUUID } from "node:crypto";
14895
14984
  import { spawnSync as spawnSync2 } from "node:child_process";
14896
14985
  import { accessSync as accessSync2, constants as constants3, readFileSync as readFileSync16, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
14897
14986
  import { delimiter as delimiter2, dirname as dirname7, join as join18, resolve as resolve7 } from "node:path";
@@ -14938,7 +15027,7 @@ function findExecutable(name) {
14938
15027
  return null;
14939
15028
  }
14940
15029
  function fileSha256(path) {
14941
- return createHash10("sha256").update(readFileSync16(path)).digest("hex");
15030
+ return createHash11("sha256").update(readFileSync16(path)).digest("hex");
14942
15031
  }
14943
15032
  function engineClientEnv() {
14944
15033
  return {
@@ -15371,7 +15460,7 @@ var init_verifier_backend = __esm({
15371
15460
 
15372
15461
  // src/cli/verify.ts
15373
15462
  import { execFileSync as execFileSync8, spawnSync as spawnSync3 } from "node:child_process";
15374
- import { createHash as createHash11 } from "node:crypto";
15463
+ import { createHash as createHash12 } from "node:crypto";
15375
15464
  import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync9, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync3, readFileSync as readFileSync17, readlinkSync as readlinkSync3, rmSync as rmSync7, symlinkSync, writeFileSync as writeFileSync9, existsSync as existsSync14 } from "node:fs";
15376
15465
  import { tmpdir as tmpdir4 } from "node:os";
15377
15466
  import { dirname as dirname8, isAbsolute as isAbsolute11, join as join19, relative as relative5, resolve as resolve8, sep as sep3 } from "node:path";
@@ -15585,7 +15674,7 @@ function baseEntries(base, cwd) {
15585
15674
  });
15586
15675
  }
15587
15676
  function overlayDigest(dest, paths) {
15588
- const h = createHash11("sha256");
15677
+ const h = createHash12("sha256");
15589
15678
  for (const rel of [...paths].sort()) {
15590
15679
  h.update(rel);
15591
15680
  h.update("\0");
@@ -19147,7 +19236,7 @@ var init_capture = __esm({
19147
19236
  });
19148
19237
 
19149
19238
  // src/research/manifest.ts
19150
- import { createHash as createHash13 } from "node:crypto";
19239
+ import { createHash as createHash14 } from "node:crypto";
19151
19240
  import { readFileSync as readFileSync23 } from "node:fs";
19152
19241
  import { dirname as dirname10, resolve as resolve14 } from "node:path";
19153
19242
  function taskFrom(raw, index, manifestDir) {
@@ -19205,7 +19294,7 @@ function readManifest(path) {
19205
19294
  if (seen.has(t.id)) throw new ResearchError(`task manifest ${abs}: duplicate task id "${t.id}"`);
19206
19295
  seen.add(t.id);
19207
19296
  }
19208
- return { path: abs, sha256: createHash13("sha256").update(bytes).digest("hex"), tasks };
19297
+ return { path: abs, sha256: createHash14("sha256").update(bytes).digest("hex"), tasks };
19209
19298
  }
19210
19299
  var MANIFEST_VERSION;
19211
19300
  var init_manifest = __esm({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.29.15",
3
+ "version": "2.29.16",
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",