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.
- package/dist/cli/index.js +139 -50
- 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:
|
|
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
|
|
1420
|
-
|
|
1461
|
+
if (failure.status === 1) {
|
|
1462
|
+
const first = parseDiff(failure.stdout)[0];
|
|
1463
|
+
return mk(first && first.kind === "file" ? first.hunks : []);
|
|
1421
1464
|
}
|
|
1422
|
-
|
|
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
|
-
|
|
3361
|
-
if (
|
|
3362
|
-
const
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
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
|
|
6907
|
-
if (
|
|
6908
|
-
out3.push({ t: "num", v:
|
|
6909
|
-
i +=
|
|
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
|
|
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 =
|
|
6940
|
-
const y2 =
|
|
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 =
|
|
6979
|
-
const y2 =
|
|
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
|
|
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
|
|
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
|
|
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) =>
|
|
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
|
|
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 =
|
|
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
|
|
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:" +
|
|
12100
|
+
return "sha256:" + createHash6("sha256").update(sessionId).digest("hex").slice(0, 24);
|
|
12012
12101
|
}
|
|
12013
12102
|
function eventId() {
|
|
12014
|
-
return "sha256:" +
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
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.
|
|
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",
|