tamperward 2.30.2 → 2.30.4
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 +121 -88
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -866,10 +866,10 @@ function headerPaths(line) {
|
|
|
866
866
|
first = rest.slice(0, mid);
|
|
867
867
|
rest = rest.slice(mid + 1);
|
|
868
868
|
} else {
|
|
869
|
-
const
|
|
870
|
-
if (
|
|
871
|
-
first =
|
|
872
|
-
rest =
|
|
869
|
+
const at = rest.lastIndexOf(" b/");
|
|
870
|
+
if (at < 0) return [null, null];
|
|
871
|
+
first = rest.slice(0, at);
|
|
872
|
+
rest = rest.slice(at + 1);
|
|
873
873
|
}
|
|
874
874
|
}
|
|
875
875
|
}
|
|
@@ -2874,7 +2874,6 @@ function expandShellPath(t, env = process.env) {
|
|
|
2874
2874
|
function hookTests(policy, ctx) {
|
|
2875
2875
|
const cwd = ctx?.cwd;
|
|
2876
2876
|
const diskCwd = cwd !== void 0 && existsSync3(cwd) ? cwd : void 0;
|
|
2877
|
-
const onDisk = diskCwd !== void 0;
|
|
2878
2877
|
const root = diskCwd !== void 0 ? canonicalPath(diskCwd) : cwd;
|
|
2879
2878
|
const memo = /* @__PURE__ */ new Map();
|
|
2880
2879
|
const rel = (t) => {
|
|
@@ -2938,7 +2937,7 @@ function shellHookTarget(seg, toks, policy, ctx) {
|
|
|
2938
2937
|
return null;
|
|
2939
2938
|
}
|
|
2940
2939
|
function shellWritesHook(seg, toks, policy, ctx) {
|
|
2941
|
-
const {
|
|
2940
|
+
const { hook, whole, holds, hookish } = hookTests(policy, ctx);
|
|
2942
2941
|
for (const m of seg.matchAll(REDIRECT_TARGET)) {
|
|
2943
2942
|
if (hook(m[1])) return "a redirect empties or rewrites a protected hook";
|
|
2944
2943
|
}
|
|
@@ -2947,7 +2946,6 @@ function shellWritesHook(seg, toks, policy, ctx) {
|
|
|
2947
2946
|
const cmd = (toks[at] ?? "").replace(/^.*\//, "");
|
|
2948
2947
|
const args = toks.slice(at + 1);
|
|
2949
2948
|
const positional = args.filter((a) => a !== "--" && !a.startsWith("-"));
|
|
2950
|
-
const last = positional[positional.length - 1] ?? "";
|
|
2951
2949
|
const anyHook = args.some(hook);
|
|
2952
2950
|
const inPlace = args.some((a) => /^-[A-Za-z]*i|^--in-place/.test(a));
|
|
2953
2951
|
const scripts = args.filter((_, i) => i > 0 && INLINE_FLAG.test(args[i - 1]));
|
|
@@ -11157,7 +11155,7 @@ function annotations(findings) {
|
|
|
11157
11155
|
});
|
|
11158
11156
|
}
|
|
11159
11157
|
function cell(s) {
|
|
11160
|
-
return stripControl(s).replace(/\s+/g, " ").replace(/\|/g, "\\|").trim();
|
|
11158
|
+
return stripControl(s).replace(/\s+/g, " ").replace(/\\/g, "\\\\").replace(/\|/g, "\\|").trim();
|
|
11161
11159
|
}
|
|
11162
11160
|
function mdCode(s) {
|
|
11163
11161
|
return s.replace(/`/g, "'").replace(/[\r\n]/g, " ");
|
|
@@ -14525,7 +14523,7 @@ function freezeRoot(kind, path) {
|
|
|
14525
14523
|
}
|
|
14526
14524
|
}
|
|
14527
14525
|
function shellTokens(command) {
|
|
14528
|
-
const matches = command.match(/(?:[^\s"'\\]
|
|
14526
|
+
const matches = command.match(/(?:[^\s"'\\]|"[^"\\]*(?:\\.[^"\\]*)*"|'[^']*')+/g) ?? [];
|
|
14529
14527
|
return matches.map((token) => {
|
|
14530
14528
|
if (token.startsWith("'") && token.endsWith("'") || token.startsWith('"') && token.endsWith('"')) return token.slice(1, -1);
|
|
14531
14529
|
return token;
|
|
@@ -14884,7 +14882,7 @@ function runCapturedProcessSync(executable, args, opts) {
|
|
|
14884
14882
|
rmSync6(stateDir, { recursive: true, force: true });
|
|
14885
14883
|
}
|
|
14886
14884
|
}
|
|
14887
|
-
var DIAGNOSTIC_TAIL_BYTES, EMPTY_STREAM, CAPTURE_SUPERVISOR;
|
|
14885
|
+
var DIAGNOSTIC_TAIL_BYTES, EMPTY_STREAM, CLEANUP_HELPERS_SRC, CAPTURE_SUPERVISOR;
|
|
14888
14886
|
var init_suite_diagnostics = __esm({
|
|
14889
14887
|
"src/suite-diagnostics.ts"() {
|
|
14890
14888
|
"use strict";
|
|
@@ -14896,40 +14894,32 @@ var init_suite_diagnostics = __esm({
|
|
|
14896
14894
|
truncated: false,
|
|
14897
14895
|
tail: ""
|
|
14898
14896
|
};
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
const
|
|
14904
|
-
const
|
|
14905
|
-
const
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
// Linux ordinary-exit hardening (#371): process-group ownership alone misses a
|
|
14912
|
-
// descendant that calls setsid(). Track the real descendant tree while the
|
|
14913
|
-
// suite is alive so a reparented session escape is still known when the main
|
|
14914
|
-
// child exits. This supplements, rather than replaces, group termination.
|
|
14915
|
-
const trackedDescendants = new Set();
|
|
14897
|
+
CLEANUP_HELPERS_SRC = String.raw`
|
|
14898
|
+
function readStat(pid) {
|
|
14899
|
+
try {
|
|
14900
|
+
const stat = fs.readFileSync('/proc/' + pid + '/stat', 'utf8');
|
|
14901
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
|
|
14902
|
+
const ppid = Number(fields[1]);
|
|
14903
|
+
const starttime = fields[19];
|
|
14904
|
+
if (!Number.isFinite(ppid) || starttime === undefined) return null;
|
|
14905
|
+
return { ppid: ppid, starttime: starttime };
|
|
14906
|
+
} catch (e) { return null; }
|
|
14907
|
+
}
|
|
14916
14908
|
|
|
14917
14909
|
function linuxDescendants(rootPid) {
|
|
14918
14910
|
if (process.platform !== 'linux' || !rootPid) return [];
|
|
14919
14911
|
const byParent = new Map();
|
|
14912
|
+
const startById = new Map();
|
|
14920
14913
|
let names = [];
|
|
14921
|
-
try { names = fs.readdirSync('/proc').filter((x) => /^\d+$/.test(x)); } catch { return []; }
|
|
14914
|
+
try { names = fs.readdirSync('/proc').filter((x) => /^\d+$/.test(x)); } catch (e) { return []; }
|
|
14922
14915
|
for (const name of names) {
|
|
14923
14916
|
const pid = Number(name);
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
kids.push(pid);
|
|
14931
|
-
byParent.set(ppid, kids);
|
|
14932
|
-
} catch {}
|
|
14917
|
+
const st = readStat(pid);
|
|
14918
|
+
if (!st) continue;
|
|
14919
|
+
startById.set(pid, st.starttime);
|
|
14920
|
+
const kids = byParent.get(st.ppid) || [];
|
|
14921
|
+
kids.push(pid);
|
|
14922
|
+
byParent.set(st.ppid, kids);
|
|
14933
14923
|
}
|
|
14934
14924
|
const out = [];
|
|
14935
14925
|
const seen = new Set([rootPid]);
|
|
@@ -14939,16 +14929,56 @@ function linuxDescendants(rootPid) {
|
|
|
14939
14929
|
for (const pid of (byParent.get(parent) || [])) {
|
|
14940
14930
|
if (seen.has(pid)) continue;
|
|
14941
14931
|
seen.add(pid);
|
|
14942
|
-
out.push(pid);
|
|
14932
|
+
out.push({ pid: pid, starttime: startById.get(pid) });
|
|
14943
14933
|
stack.push(pid);
|
|
14944
14934
|
}
|
|
14945
14935
|
}
|
|
14946
14936
|
return out;
|
|
14947
14937
|
}
|
|
14948
14938
|
|
|
14939
|
+
function killableDescendants(tracked) {
|
|
14940
|
+
const out = [];
|
|
14941
|
+
for (const entry of tracked) {
|
|
14942
|
+
const pid = entry[0];
|
|
14943
|
+
const starttime = entry[1];
|
|
14944
|
+
const st = readStat(pid);
|
|
14945
|
+
if (st && st.starttime === starttime) out.push(pid);
|
|
14946
|
+
}
|
|
14947
|
+
return out;
|
|
14948
|
+
}
|
|
14949
|
+
|
|
14950
|
+
function cleanupPlan(child, cfg, platform, killable) {
|
|
14951
|
+
const live = !!child && child.exitCode === null && child.signalCode === null;
|
|
14952
|
+
return {
|
|
14953
|
+
signalGroup: !!(live && cfg.detached && platform !== 'win32'),
|
|
14954
|
+
signalMainChild: live,
|
|
14955
|
+
descendants: platform === 'linux' ? killable() : [],
|
|
14956
|
+
};
|
|
14957
|
+
}
|
|
14958
|
+
`;
|
|
14959
|
+
CAPTURE_SUPERVISOR = String.raw`
|
|
14960
|
+
const cp = require('node:child_process');
|
|
14961
|
+
const fs = require('node:fs');
|
|
14962
|
+
|
|
14963
|
+
const [configFile] = process.argv.slice(1);
|
|
14964
|
+
const cfg = JSON.parse(fs.readFileSync(configFile, 'utf8'));
|
|
14965
|
+
const CAP = Number(cfg.captureBytes);
|
|
14966
|
+
|
|
14967
|
+
const fresh = () => ({ total: 0, tail: Buffer.alloc(0) });
|
|
14968
|
+
const stdout = fresh();
|
|
14969
|
+
const stderr = fresh();
|
|
14970
|
+
|
|
14971
|
+
// Linux ordinary-exit hardening (#371): process-group ownership alone misses a
|
|
14972
|
+
// descendant that calls setsid(). Track the real descendant tree while the
|
|
14973
|
+
// suite is alive so a reparented session escape is still known when the main
|
|
14974
|
+
// child exits. This supplements, rather than replaces, group termination.
|
|
14975
|
+
// pid -> the /proc start-time observed for that pid, so cleanup can re-check
|
|
14976
|
+
// identity before signalling (a bare pid alone can be reused — #545).
|
|
14977
|
+
const trackedDescendants = new Map();
|
|
14978
|
+
${CLEANUP_HELPERS_SRC}
|
|
14949
14979
|
function trackDescendants() {
|
|
14950
14980
|
if (!child || !child.pid || process.platform !== 'linux') return;
|
|
14951
|
-
for (const
|
|
14981
|
+
for (const d of linuxDescendants(child.pid)) trackedDescendants.set(d.pid, d.starttime);
|
|
14952
14982
|
}
|
|
14953
14983
|
|
|
14954
14984
|
function append(state, chunk) {
|
|
@@ -14983,17 +15013,17 @@ let drainTimer = null;
|
|
|
14983
15013
|
function killOwned() {
|
|
14984
15014
|
if (!child || !child.pid) return;
|
|
14985
15015
|
trackDescendants();
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
}
|
|
15016
|
+
// The main child and its detached group are signalled only while the child is
|
|
15017
|
+
// still reported live: after its exit event the pid can be reused, and both
|
|
15018
|
+
// child.kill() and kill(-pid) resolve the current bearer of that number (#545).
|
|
15019
|
+
// Descendants are the independently identity-checked set (deepest-first, which
|
|
15020
|
+
// is friendlier to short-lived process trees).
|
|
15021
|
+
const plan = cleanupPlan(child, cfg, process.platform, function () {
|
|
15022
|
+
return killableDescendants(Array.from(trackedDescendants).reverse());
|
|
15023
|
+
});
|
|
15024
|
+
if (plan.signalGroup) { try { process.kill(-child.pid, 'SIGKILL'); } catch {} }
|
|
15025
|
+
if (plan.signalMainChild) { try { child.kill('SIGKILL'); } catch {} }
|
|
15026
|
+
for (const pid of plan.descendants) { try { process.kill(pid, 'SIGKILL'); } catch {} }
|
|
14997
15027
|
}
|
|
14998
15028
|
|
|
14999
15029
|
function finish(extra) {
|
|
@@ -15092,7 +15122,7 @@ if (child) {
|
|
|
15092
15122
|
// src/verifier-backend.ts
|
|
15093
15123
|
import { createHash as createHash11, randomUUID } from "node:crypto";
|
|
15094
15124
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
15095
|
-
import { accessSync as accessSync2, constants as constants3, readFileSync as
|
|
15125
|
+
import { accessSync as accessSync2, constants as constants3, readFileSync as readFileSync15, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
|
|
15096
15126
|
import { delimiter as delimiter2, dirname as dirname7, join as join18, resolve as resolve7 } from "node:path";
|
|
15097
15127
|
function identity() {
|
|
15098
15128
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -15137,7 +15167,7 @@ function findExecutable(name) {
|
|
|
15137
15167
|
return null;
|
|
15138
15168
|
}
|
|
15139
15169
|
function fileSha256(path) {
|
|
15140
|
-
return createHash11("sha256").update(
|
|
15170
|
+
return createHash11("sha256").update(readFileSync15(path)).digest("hex");
|
|
15141
15171
|
}
|
|
15142
15172
|
function engineClientEnv() {
|
|
15143
15173
|
return {
|
|
@@ -15571,7 +15601,7 @@ var init_verifier_backend = __esm({
|
|
|
15571
15601
|
// src/cli/verify.ts
|
|
15572
15602
|
import { execFileSync as execFileSync8, spawnSync as spawnSync3 } from "node:child_process";
|
|
15573
15603
|
import { createHash as createHash12 } from "node:crypto";
|
|
15574
|
-
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync9, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync3, readFileSync as
|
|
15604
|
+
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync9, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, readlinkSync as readlinkSync3, rmSync as rmSync7, symlinkSync, writeFileSync as writeFileSync9, existsSync as existsSync14 } from "node:fs";
|
|
15575
15605
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
15576
15606
|
import { dirname as dirname8, isAbsolute as isAbsolute11, join as join19, relative as relative5, resolve as resolve8, sep as sep3 } from "node:path";
|
|
15577
15607
|
function oracleAssuranceReport() {
|
|
@@ -15792,7 +15822,7 @@ function overlayDigest(dest, paths) {
|
|
|
15792
15822
|
try {
|
|
15793
15823
|
const st = lstatSync9(p);
|
|
15794
15824
|
h.update(String(st.mode));
|
|
15795
|
-
h.update(st.isSymbolicLink() ? readlinkSync3(p) :
|
|
15825
|
+
h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync16(p));
|
|
15796
15826
|
} catch {
|
|
15797
15827
|
h.update("<gone>");
|
|
15798
15828
|
}
|
|
@@ -16506,7 +16536,7 @@ var init_verify = __esm({
|
|
|
16506
16536
|
// src/cli/run.ts
|
|
16507
16537
|
import { execFileSync as execFileSync9, spawn, spawnSync as spawnSync4 } from "node:child_process";
|
|
16508
16538
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
16509
|
-
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as
|
|
16539
|
+
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync17, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as rmSync8, statSync as statSync5, writeFileSync as writeFileSync10 } from "node:fs";
|
|
16510
16540
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
16511
16541
|
import { dirname as dirname9, join as join20, resolve as resolve9 } from "node:path";
|
|
16512
16542
|
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
@@ -16561,7 +16591,7 @@ function trustedLinuxPython(candidates = DEFAULT_TRUSTED_PYTHON_CANDIDATES) {
|
|
|
16561
16591
|
}
|
|
16562
16592
|
for (const candidate of candidates) {
|
|
16563
16593
|
try {
|
|
16564
|
-
const real =
|
|
16594
|
+
const real = realpathSync8(candidate);
|
|
16565
16595
|
const st = statSync5(real);
|
|
16566
16596
|
if (!st.isFile() || writableByCaller2(real)) continue;
|
|
16567
16597
|
const probe = spawnSync4(
|
|
@@ -16660,7 +16690,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
|
|
|
16660
16690
|
}
|
|
16661
16691
|
let state = {};
|
|
16662
16692
|
try {
|
|
16663
|
-
state = JSON.parse(
|
|
16693
|
+
state = JSON.parse(readFileSync17(resultFile, "utf8"));
|
|
16664
16694
|
} catch {
|
|
16665
16695
|
return {
|
|
16666
16696
|
exit: 1,
|
|
@@ -16704,7 +16734,7 @@ function observerExited(pid) {
|
|
|
16704
16734
|
if (!pidAlive3(pid)) return true;
|
|
16705
16735
|
if (process.platform !== "linux") return false;
|
|
16706
16736
|
try {
|
|
16707
|
-
const stat =
|
|
16737
|
+
const stat = readFileSync17(`/proc/${pid}/stat`, "utf8");
|
|
16708
16738
|
const state = stat.slice(stat.lastIndexOf(")") + 2).split(" ")[0];
|
|
16709
16739
|
return state === "Z" || state === "X";
|
|
16710
16740
|
} catch (e) {
|
|
@@ -16826,7 +16856,7 @@ function git3(args, cwd) {
|
|
|
16826
16856
|
}
|
|
16827
16857
|
function nowTicks() {
|
|
16828
16858
|
try {
|
|
16829
|
-
return Math.floor(parseFloat(
|
|
16859
|
+
return Math.floor(parseFloat(readFileSync17("/proc/uptime", "utf8").split(" ")[0]) * 100);
|
|
16830
16860
|
} catch {
|
|
16831
16861
|
return Number.POSITIVE_INFINITY;
|
|
16832
16862
|
}
|
|
@@ -16835,7 +16865,7 @@ function survivorsHoldingTree(cwd, spawnedAfterTicks) {
|
|
|
16835
16865
|
const out3 = [];
|
|
16836
16866
|
let real;
|
|
16837
16867
|
try {
|
|
16838
|
-
real =
|
|
16868
|
+
real = realpathSync8(cwd);
|
|
16839
16869
|
} catch {
|
|
16840
16870
|
return out3;
|
|
16841
16871
|
}
|
|
@@ -16849,7 +16879,7 @@ function survivorsHoldingTree(cwd, spawnedAfterTicks) {
|
|
|
16849
16879
|
const n = Number(pid);
|
|
16850
16880
|
if (n === process.pid) continue;
|
|
16851
16881
|
try {
|
|
16852
|
-
const stat =
|
|
16882
|
+
const stat = readFileSync17(`/proc/${pid}/stat`, "utf8");
|
|
16853
16883
|
const startTicks = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19]);
|
|
16854
16884
|
if (!Number.isFinite(startTicks) || startTicks < spawnedAfterTicks) continue;
|
|
16855
16885
|
} catch {
|
|
@@ -17421,7 +17451,7 @@ raise SystemExit(0)
|
|
|
17421
17451
|
|
|
17422
17452
|
// src/cli/doctor.ts
|
|
17423
17453
|
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
17424
|
-
import { existsSync as existsSync15, readFileSync as
|
|
17454
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, readdirSync as readdirSync5 } from "node:fs";
|
|
17425
17455
|
import { join as join21, resolve as resolve10 } from "node:path";
|
|
17426
17456
|
function lifecyclePlatformCheck(platform = process.platform, linuxPython = platform === "linux" ? trustedLinuxPython() : null) {
|
|
17427
17457
|
if (platform === "linux") {
|
|
@@ -17480,7 +17510,7 @@ function pinsInFile(path) {
|
|
|
17480
17510
|
if (!existsSync15(path)) return [];
|
|
17481
17511
|
let src = "";
|
|
17482
17512
|
try {
|
|
17483
|
-
src =
|
|
17513
|
+
src = readFileSync18(path, "utf8");
|
|
17484
17514
|
} catch {
|
|
17485
17515
|
return [];
|
|
17486
17516
|
}
|
|
@@ -17507,7 +17537,7 @@ function workflowPermissionCheck(cwd, workflowRels = [".github/workflows/tamperw
|
|
|
17507
17537
|
}
|
|
17508
17538
|
let doc;
|
|
17509
17539
|
try {
|
|
17510
|
-
doc = yaml.parse(
|
|
17540
|
+
doc = yaml.parse(readFileSync18(path, "utf8"));
|
|
17511
17541
|
} catch (e) {
|
|
17512
17542
|
broken.push(`${rel} is not valid YAML (${e instanceof Error ? e.message : String(e)})`);
|
|
17513
17543
|
continue;
|
|
@@ -17931,7 +17961,7 @@ function diagnose(opts = {}) {
|
|
|
17931
17961
|
}
|
|
17932
17962
|
let doc;
|
|
17933
17963
|
try {
|
|
17934
|
-
doc = yaml.parse(
|
|
17964
|
+
doc = yaml.parse(readFileSync18(workflowPath, "utf8"));
|
|
17935
17965
|
} catch (e) {
|
|
17936
17966
|
return fail(
|
|
17937
17967
|
"ci-verifier",
|
|
@@ -18110,9 +18140,9 @@ import { execFileSync as execFileSync11, spawnSync as spawnSync5 } from "node:ch
|
|
|
18110
18140
|
import {
|
|
18111
18141
|
existsSync as existsSync16,
|
|
18112
18142
|
mkdtempSync as mkdtempSync5,
|
|
18113
|
-
readFileSync as
|
|
18143
|
+
readFileSync as readFileSync19,
|
|
18114
18144
|
readdirSync as readdirSync6,
|
|
18115
|
-
realpathSync as
|
|
18145
|
+
realpathSync as realpathSync9,
|
|
18116
18146
|
rmSync as rmSync9,
|
|
18117
18147
|
symlinkSync as symlinkSync2
|
|
18118
18148
|
} from "node:fs";
|
|
@@ -18129,7 +18159,7 @@ function parseStraceFileAccess(raw) {
|
|
|
18129
18159
|
const call = line.match(/\b(execveat|execve|openat2|openat|open|newfstatat|fstatat|statx|lstat|stat|access|readlinkat|readlink)\s*\(/);
|
|
18130
18160
|
if (!call) continue;
|
|
18131
18161
|
const afterCall = line.slice((call.index ?? 0) + call[0].length);
|
|
18132
|
-
const quoted = afterCall.match(/"((
|
|
18162
|
+
const quoted = afterCall.match(/"([^"\\]*(?:\\.[^"\\]*)*)"/);
|
|
18133
18163
|
if (!quoted) continue;
|
|
18134
18164
|
const path = unescapeStraceString(quoted[1]);
|
|
18135
18165
|
if (!path) continue;
|
|
@@ -18276,7 +18306,7 @@ function rewriteTraceRoot(accesses, actualRoot) {
|
|
|
18276
18306
|
if (!inside3(actualRoot, abs)) return { ...item, path: abs };
|
|
18277
18307
|
const rel = relative6(actualRoot, abs).split(sep4).join("/");
|
|
18278
18308
|
try {
|
|
18279
|
-
const real = resolve11(
|
|
18309
|
+
const real = resolve11(realpathSync9(abs));
|
|
18280
18310
|
if (!inside3(actualRoot, real)) return { ...item, path: real };
|
|
18281
18311
|
} catch {
|
|
18282
18312
|
}
|
|
@@ -18315,7 +18345,7 @@ function straceOnce(root, command, budget) {
|
|
|
18315
18345
|
}
|
|
18316
18346
|
);
|
|
18317
18347
|
const logs = traced.error ? [] : traceFiles(prefix);
|
|
18318
|
-
const accesses = logs.flatMap((path) => parseStraceFileAccess(
|
|
18348
|
+
const accesses = logs.flatMap((path) => parseStraceFileAccess(readFileSync19(path, "utf8")));
|
|
18319
18349
|
const raw = {
|
|
18320
18350
|
spawnError: traced.error ? traced.error.message : null,
|
|
18321
18351
|
status: traced.status,
|
|
@@ -18545,7 +18575,7 @@ var init_trace_verify = __esm({
|
|
|
18545
18575
|
});
|
|
18546
18576
|
|
|
18547
18577
|
// src/runtimes.ts
|
|
18548
|
-
import { existsSync as existsSync17, readFileSync as
|
|
18578
|
+
import { existsSync as existsSync17, readFileSync as readFileSync20 } from "node:fs";
|
|
18549
18579
|
import { join as join23 } from "node:path";
|
|
18550
18580
|
function isRecord4(x) {
|
|
18551
18581
|
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
@@ -18576,7 +18606,7 @@ function claudeSettingsBeyondTamperward(cwd) {
|
|
|
18576
18606
|
let raw;
|
|
18577
18607
|
try {
|
|
18578
18608
|
if (!existsSync17(path)) return false;
|
|
18579
|
-
raw =
|
|
18609
|
+
raw = readFileSync20(path, "utf8");
|
|
18580
18610
|
} catch {
|
|
18581
18611
|
return false;
|
|
18582
18612
|
}
|
|
@@ -18683,7 +18713,7 @@ var init_runtimes = __esm({
|
|
|
18683
18713
|
|
|
18684
18714
|
// src/cli/onboard.ts
|
|
18685
18715
|
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
18686
|
-
import { lstatSync as lstatSync10, mkdtempSync as mkdtempSync6, readFileSync as
|
|
18716
|
+
import { lstatSync as lstatSync10, mkdtempSync as mkdtempSync6, readFileSync as readFileSync21, realpathSync as realpathSync10, rmSync as rmSync10 } from "node:fs";
|
|
18687
18717
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
18688
18718
|
import { join as join24, relative as relative7, resolve as resolve12, sep as sep5 } from "node:path";
|
|
18689
18719
|
import { createInterface } from "node:readline";
|
|
@@ -18756,7 +18786,7 @@ function writeVerifyCommand(cwd, command) {
|
|
|
18756
18786
|
return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
|
|
18757
18787
|
}
|
|
18758
18788
|
const mode = existingMode(path, 420);
|
|
18759
|
-
const original = kind === "file" ?
|
|
18789
|
+
const original = kind === "file" ? readFileSync21(path, "utf8") : null;
|
|
18760
18790
|
let next;
|
|
18761
18791
|
try {
|
|
18762
18792
|
const doc = parseDocument(original && original.trim() ? original : "version: 1\n");
|
|
@@ -18816,7 +18846,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18816
18846
|
const cwd = resolve12(rootText);
|
|
18817
18847
|
let sameRoot = cwd === requestedCwd;
|
|
18818
18848
|
try {
|
|
18819
|
-
sameRoot =
|
|
18849
|
+
sameRoot = realpathSync10(cwd) === realpathSync10(requestedCwd);
|
|
18820
18850
|
} catch {
|
|
18821
18851
|
}
|
|
18822
18852
|
if (!sameRoot) {
|
|
@@ -19156,8 +19186,8 @@ function runDemo(cwd, head, runners, out3) {
|
|
|
19156
19186
|
let worktreeRoot;
|
|
19157
19187
|
let realTarget;
|
|
19158
19188
|
try {
|
|
19159
|
-
worktreeRoot =
|
|
19160
|
-
realTarget =
|
|
19189
|
+
worktreeRoot = realpathSync10(wt);
|
|
19190
|
+
realTarget = realpathSync10(targetPath);
|
|
19161
19191
|
} catch {
|
|
19162
19192
|
out3("Demo skipped: the selected test could not be resolved safely inside the disposable worktree.");
|
|
19163
19193
|
return;
|
|
@@ -19341,8 +19371,8 @@ var init_capture = __esm({
|
|
|
19341
19371
|
});
|
|
19342
19372
|
|
|
19343
19373
|
// src/research/manifest.ts
|
|
19344
|
-
import { createHash as
|
|
19345
|
-
import { readFileSync as
|
|
19374
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
19375
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
19346
19376
|
import { dirname as dirname10, resolve as resolve14 } from "node:path";
|
|
19347
19377
|
function taskFrom(raw, index, manifestDir) {
|
|
19348
19378
|
const where = `task #${index + 1}`;
|
|
@@ -19376,7 +19406,7 @@ function readManifest(path) {
|
|
|
19376
19406
|
const abs = resolve14(path);
|
|
19377
19407
|
let bytes;
|
|
19378
19408
|
try {
|
|
19379
|
-
bytes =
|
|
19409
|
+
bytes = readFileSync22(abs);
|
|
19380
19410
|
} catch (e) {
|
|
19381
19411
|
throw new ResearchError(`cannot read task manifest ${abs}: ${e instanceof Error ? e.message : String(e)}`);
|
|
19382
19412
|
}
|
|
@@ -19399,7 +19429,7 @@ function readManifest(path) {
|
|
|
19399
19429
|
if (seen.has(t.id)) throw new ResearchError(`task manifest ${abs}: duplicate task id "${t.id}"`);
|
|
19400
19430
|
seen.add(t.id);
|
|
19401
19431
|
}
|
|
19402
|
-
return { path: abs, sha256:
|
|
19432
|
+
return { path: abs, sha256: createHash13("sha256").update(bytes).digest("hex"), tasks };
|
|
19403
19433
|
}
|
|
19404
19434
|
var MANIFEST_VERSION;
|
|
19405
19435
|
var init_manifest = __esm({
|
|
@@ -19588,7 +19618,7 @@ var init_record = __esm({
|
|
|
19588
19618
|
|
|
19589
19619
|
// src/research/run.ts
|
|
19590
19620
|
import { execFileSync as execFileSync13 } from "node:child_process";
|
|
19591
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as
|
|
19621
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync23, renameSync as renameSync4, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
19592
19622
|
import { join as join25, resolve as resolve15 } from "node:path";
|
|
19593
19623
|
function git6(args, cwd) {
|
|
19594
19624
|
return execFileSync13("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
@@ -19599,7 +19629,7 @@ function pairRecordPath(ledger, task, pair) {
|
|
|
19599
19629
|
function resumableRecord(path, expected) {
|
|
19600
19630
|
let raw;
|
|
19601
19631
|
try {
|
|
19602
|
-
raw = JSON.parse(
|
|
19632
|
+
raw = JSON.parse(readFileSync23(path, "utf8"));
|
|
19603
19633
|
} catch (e) {
|
|
19604
19634
|
throw new ResearchError(`ledger record ${path} is malformed (${errorMessage(e).split("\n")[0]}); remove it to regenerate the pair, or use a new --out`);
|
|
19605
19635
|
}
|
|
@@ -19639,12 +19669,15 @@ function writeRecordAtomically(path, text) {
|
|
|
19639
19669
|
writeFileSync11(tmp, text);
|
|
19640
19670
|
renameSync4(tmp, path);
|
|
19641
19671
|
}
|
|
19672
|
+
function cloneArgs(repo, ws3) {
|
|
19673
|
+
return ["-c", "protocol.ext.allow=never", "clone", "-q", "--no-hardlinks", "--", repo, ws3];
|
|
19674
|
+
}
|
|
19642
19675
|
function freshWorkspace(ledger, task, pair, arm, sourceBase) {
|
|
19643
19676
|
const ws3 = join25(ledger, "workspaces", `${task.id}--${pair}--${arm}`);
|
|
19644
19677
|
rmSync11(ws3, { recursive: true, force: true });
|
|
19645
19678
|
mkdirSync9(join25(ledger, "workspaces"), { recursive: true });
|
|
19646
19679
|
try {
|
|
19647
|
-
execFileSync13("git",
|
|
19680
|
+
execFileSync13("git", cloneArgs(task.repo, ws3), { stdio: ["ignore", "ignore", "pipe"], encoding: "utf8" });
|
|
19648
19681
|
} catch (e) {
|
|
19649
19682
|
throw new ResearchError(`task "${task.id}": cannot clone ${task.repo}: ${errorMessage(e).split("\n")[0]}`);
|
|
19650
19683
|
}
|
|
@@ -20022,7 +20055,7 @@ var init_run2 = __esm({
|
|
|
20022
20055
|
});
|
|
20023
20056
|
|
|
20024
20057
|
// src/research/summarize.ts
|
|
20025
|
-
import { readdirSync as readdirSync7, readFileSync as
|
|
20058
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync24 } from "node:fs";
|
|
20026
20059
|
import { join as join26, resolve as resolve16 } from "node:path";
|
|
20027
20060
|
function readLedger2(dir) {
|
|
20028
20061
|
const pairsDir = join26(resolve16(dir), "pairs");
|
|
@@ -20037,7 +20070,7 @@ function readLedger2(dir) {
|
|
|
20037
20070
|
const path = join26(pairsDir, n);
|
|
20038
20071
|
let raw;
|
|
20039
20072
|
try {
|
|
20040
|
-
raw = JSON.parse(
|
|
20073
|
+
raw = JSON.parse(readFileSync24(path, "utf8"));
|
|
20041
20074
|
} catch (e) {
|
|
20042
20075
|
throw new ResearchError(`ledger record ${path} is not valid JSON: ${errorMessage(e)}`);
|
|
20043
20076
|
}
|
|
@@ -20744,7 +20777,7 @@ var init_main = __esm({
|
|
|
20744
20777
|
// src/cli/index.ts
|
|
20745
20778
|
init_hook_client();
|
|
20746
20779
|
init_exit();
|
|
20747
|
-
import { readFileSync as
|
|
20780
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
20748
20781
|
function loadMain() {
|
|
20749
20782
|
return Promise.resolve().then(() => (init_main(), main_exports));
|
|
20750
20783
|
}
|
|
@@ -20757,7 +20790,7 @@ async function launch(argv) {
|
|
|
20757
20790
|
if (kind && hookServiceEnabled()) {
|
|
20758
20791
|
let raw = null;
|
|
20759
20792
|
try {
|
|
20760
|
-
raw =
|
|
20793
|
+
raw = readFileSync25(0, "utf8");
|
|
20761
20794
|
} catch {
|
|
20762
20795
|
raw = null;
|
|
20763
20796
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.30.
|
|
3
|
+
"version": "2.30.4",
|
|
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",
|