tamperward 2.23.14 → 2.23.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 +115 -82
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -10885,10 +10885,55 @@ var init_verifier_limits = __esm({
|
|
|
10885
10885
|
}
|
|
10886
10886
|
});
|
|
10887
10887
|
|
|
10888
|
+
// src/safe-write.ts
|
|
10889
|
+
import { randomBytes } from "node:crypto";
|
|
10890
|
+
import { lstatSync as lstatSync7, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
10891
|
+
function writeTargetKind(path) {
|
|
10892
|
+
let st;
|
|
10893
|
+
try {
|
|
10894
|
+
st = lstatSync7(path, { throwIfNoEntry: false });
|
|
10895
|
+
} catch (e) {
|
|
10896
|
+
if (errnoCode(e) === "ENOTDIR") return "absent";
|
|
10897
|
+
throw e;
|
|
10898
|
+
}
|
|
10899
|
+
if (!st) return "absent";
|
|
10900
|
+
if (st.isSymbolicLink()) return "symlink";
|
|
10901
|
+
return st.isFile() ? "file" : "irregular";
|
|
10902
|
+
}
|
|
10903
|
+
function refuseNonRegular(path) {
|
|
10904
|
+
switch (writeTargetKind(path)) {
|
|
10905
|
+
case "symlink":
|
|
10906
|
+
return "refusing: symlink \u2014 the target would be written instead of this path; replace the link with a regular file, then re-run";
|
|
10907
|
+
case "irregular":
|
|
10908
|
+
return "refusing: not a regular file \u2014 a directory or special file stands where a file is expected; remove it, then re-run";
|
|
10909
|
+
default:
|
|
10910
|
+
return null;
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10913
|
+
function existingMode(path, fallback) {
|
|
10914
|
+
if (writeTargetKind(path) !== "file") return fallback;
|
|
10915
|
+
return lstatSync7(path).mode & 511;
|
|
10916
|
+
}
|
|
10917
|
+
function atomicReplaceFile(path, content, mode) {
|
|
10918
|
+
const tmp = `${path}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`;
|
|
10919
|
+
try {
|
|
10920
|
+
writeFileSync7(tmp, content, { encoding: "utf8", flag: "wx", mode });
|
|
10921
|
+
renameSync3(tmp, path);
|
|
10922
|
+
} finally {
|
|
10923
|
+
rmSync5(tmp, { force: true });
|
|
10924
|
+
}
|
|
10925
|
+
}
|
|
10926
|
+
var init_safe_write = __esm({
|
|
10927
|
+
"src/safe-write.ts"() {
|
|
10928
|
+
"use strict";
|
|
10929
|
+
init_narrow();
|
|
10930
|
+
}
|
|
10931
|
+
});
|
|
10932
|
+
|
|
10888
10933
|
// src/cli/init.ts
|
|
10889
10934
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
10890
10935
|
import { createHash as createHash6 } from "node:crypto";
|
|
10891
|
-
import { existsSync as existsSync11,
|
|
10936
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync12, realpathSync as realpathSync4 } from "node:fs";
|
|
10892
10937
|
import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute8, join as join14, relative as relative3, resolve as resolve4 } from "node:path";
|
|
10893
10938
|
function gitConfig(cwd, key2) {
|
|
10894
10939
|
try {
|
|
@@ -11050,6 +11095,8 @@ function verifierSetupMessage(cwd) {
|
|
|
11050
11095
|
}
|
|
11051
11096
|
function planPolicy(cwd) {
|
|
11052
11097
|
const path = join14(cwd, POLICY_FILE);
|
|
11098
|
+
const refused = refuseNonRegular(path);
|
|
11099
|
+
if (refused) return { item: "policy", path: POLICY_FILE, status: "error", detail: refused };
|
|
11053
11100
|
if (existsSync11(path)) {
|
|
11054
11101
|
try {
|
|
11055
11102
|
loadPolicy(cwd);
|
|
@@ -11063,7 +11110,7 @@ function planPolicy(cwd) {
|
|
|
11063
11110
|
path: POLICY_FILE,
|
|
11064
11111
|
status: "create",
|
|
11065
11112
|
detail: "baseline policy with commented overrides",
|
|
11066
|
-
apply: () =>
|
|
11113
|
+
apply: () => atomicReplaceFile(path, POLICY_CONTENT, 420)
|
|
11067
11114
|
};
|
|
11068
11115
|
}
|
|
11069
11116
|
function planGitignore(cwd) {
|
|
@@ -11071,23 +11118,15 @@ function planGitignore(cwd) {
|
|
|
11071
11118
|
const path = join14(cwd, rel);
|
|
11072
11119
|
if (!existsSync11(join14(cwd, "node_modules"))) return null;
|
|
11073
11120
|
let existing = "";
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
return { item: "gitignore", path: rel, status: "error", detail: "cannot inspect \u2014 " + errText3(e) };
|
|
11080
|
-
}
|
|
11081
|
-
if (!st.isFile()) {
|
|
11082
|
-
return {
|
|
11083
|
-
item: "gitignore",
|
|
11084
|
-
path: rel,
|
|
11085
|
-
status: "error",
|
|
11086
|
-
detail: st.isSymbolicLink() ? "is a symbolic link \u2014 refusing to follow it" : "exists but is not a regular file \u2014 refusing to write"
|
|
11087
|
-
};
|
|
11088
|
-
}
|
|
11089
|
-
existing = readFileSync12(path, "utf8");
|
|
11121
|
+
let kind;
|
|
11122
|
+
try {
|
|
11123
|
+
kind = writeTargetKind(path);
|
|
11124
|
+
} catch (e) {
|
|
11125
|
+
return { item: "gitignore", path: rel, status: "error", detail: "cannot inspect \u2014 " + errText3(e) };
|
|
11090
11126
|
}
|
|
11127
|
+
const refused = refuseNonRegular(path);
|
|
11128
|
+
if (refused) return { item: "gitignore", path: rel, status: "error", detail: refused };
|
|
11129
|
+
if (kind === "file") existing = readFileSync12(path, "utf8");
|
|
11091
11130
|
try {
|
|
11092
11131
|
const tracked = execFileSync6("git", ["ls-files", "--cached", "--", "node_modules"], {
|
|
11093
11132
|
cwd,
|
|
@@ -11120,14 +11159,16 @@ function planGitignore(cwd) {
|
|
|
11120
11159
|
return {
|
|
11121
11160
|
item: "gitignore",
|
|
11122
11161
|
path: rel,
|
|
11123
|
-
status:
|
|
11162
|
+
status: kind === "file" ? "update" : "create",
|
|
11124
11163
|
detail: "exclude installed Node dependencies from repository diffs",
|
|
11125
|
-
apply: () =>
|
|
11164
|
+
apply: () => atomicReplaceFile(path, next, existingMode(path, 420))
|
|
11126
11165
|
};
|
|
11127
11166
|
}
|
|
11128
11167
|
function planClaudeHooks(cwd) {
|
|
11129
11168
|
const rel = ".claude/settings.json";
|
|
11130
11169
|
const path = join14(cwd, rel);
|
|
11170
|
+
const refused = refuseNonRegular(path);
|
|
11171
|
+
if (refused) return { item: "agent", path: rel, status: "error", detail: refused };
|
|
11131
11172
|
let settings = {};
|
|
11132
11173
|
if (existsSync11(path)) {
|
|
11133
11174
|
let parsed;
|
|
@@ -11194,7 +11235,7 @@ function planClaudeHooks(cwd) {
|
|
|
11194
11235
|
}
|
|
11195
11236
|
if (needDisableFalse) settings.disableAllHooks = false;
|
|
11196
11237
|
mkdirSync6(dirname4(path), { recursive: true });
|
|
11197
|
-
|
|
11238
|
+
atomicReplaceFile(path, JSON.stringify(settings, null, 2) + "\n", existingMode(path, 420));
|
|
11198
11239
|
}
|
|
11199
11240
|
};
|
|
11200
11241
|
}
|
|
@@ -11251,10 +11292,10 @@ function planPreCommit(cwd) {
|
|
|
11251
11292
|
}
|
|
11252
11293
|
}
|
|
11253
11294
|
const rel = display(cwd, path);
|
|
11254
|
-
|
|
11255
|
-
|
|
11256
|
-
}
|
|
11295
|
+
const refused = refuseNonRegular(path);
|
|
11296
|
+
if (refused) return { item: "pre-commit", path: rel, status: "error", detail: refused };
|
|
11257
11297
|
const existing = existsSync11(path) ? readFileSync12(path, "utf8") : null;
|
|
11298
|
+
const hookMode = () => existingMode(path, 493) | 73;
|
|
11258
11299
|
if (existing === null) {
|
|
11259
11300
|
return {
|
|
11260
11301
|
item: "pre-commit",
|
|
@@ -11263,10 +11304,9 @@ function planPreCommit(cwd) {
|
|
|
11263
11304
|
detail: `create via ${note}`,
|
|
11264
11305
|
apply: () => {
|
|
11265
11306
|
mkdirSync6(dirname4(path), { recursive: true });
|
|
11266
|
-
|
|
11307
|
+
atomicReplaceFile(path, `#!/bin/sh
|
|
11267
11308
|
${block.join("\n")}
|
|
11268
|
-
|
|
11269
|
-
chmodSync2(path, 493);
|
|
11309
|
+
`, hookMode());
|
|
11270
11310
|
}
|
|
11271
11311
|
};
|
|
11272
11312
|
}
|
|
@@ -11277,10 +11317,7 @@ ${block.join("\n")}
|
|
|
11277
11317
|
const lines = existing.split("\n");
|
|
11278
11318
|
const dead = unconditionalExitAt(lines);
|
|
11279
11319
|
const at = lines.findIndex((l) => PRECOMMIT_RE.test(l));
|
|
11280
|
-
const write = (out3) =>
|
|
11281
|
-
writeFileSync7(path, out3.join("\n"));
|
|
11282
|
-
chmodSync2(path, 493);
|
|
11283
|
-
};
|
|
11320
|
+
const write = (out3) => atomicReplaceFile(path, out3.join("\n"), hookMode());
|
|
11284
11321
|
if (at !== -1 && (dead === -1 || at < dead)) {
|
|
11285
11322
|
if (!stalePin(lines[at])) {
|
|
11286
11323
|
return { item: "pre-commit", path: rel, status: "ok", detail: "already runs the staged check" };
|
|
@@ -11343,9 +11380,11 @@ ${block.join("\n")}
|
|
|
11343
11380
|
function planCodeowners(cwd) {
|
|
11344
11381
|
const rel = ".github/CODEOWNERS";
|
|
11345
11382
|
const existingRel = [".github/CODEOWNERS", "CODEOWNERS", "docs/CODEOWNERS"].find(
|
|
11346
|
-
(r) =>
|
|
11383
|
+
(r) => writeTargetKind(join14(cwd, r)) !== "absent"
|
|
11347
11384
|
);
|
|
11348
11385
|
const path = join14(cwd, existingRel ?? rel);
|
|
11386
|
+
const refused = refuseNonRegular(path);
|
|
11387
|
+
if (refused) return { item: "codeowners", path: existingRel ?? rel, status: "error", detail: refused };
|
|
11349
11388
|
const existing = existingRel ? readFileSync12(path, "utf8") : null;
|
|
11350
11389
|
const missing = CODEOWNERS_PATHS.filter((p) => existing === null || !coveredBy(existing, p));
|
|
11351
11390
|
if (existingRel !== void 0 && missing.length === 0) {
|
|
@@ -11373,7 +11412,7 @@ ${CODEOWNERS_MARK}
|
|
|
11373
11412
|
} : {},
|
|
11374
11413
|
apply: () => {
|
|
11375
11414
|
mkdirSync6(dirname4(path), { recursive: true });
|
|
11376
|
-
|
|
11415
|
+
atomicReplaceFile(path, existing === null ? block.replace(/^\n/, "") : existing.replace(/\n?$/, "\n") + block, existingMode(path, 420));
|
|
11377
11416
|
}
|
|
11378
11417
|
};
|
|
11379
11418
|
}
|
|
@@ -11382,8 +11421,10 @@ function planWorkflow(cwd, force) {
|
|
|
11382
11421
|
const path = join14(cwd, rel);
|
|
11383
11422
|
const write = () => {
|
|
11384
11423
|
mkdirSync6(dirname4(path), { recursive: true });
|
|
11385
|
-
|
|
11424
|
+
atomicReplaceFile(path, workflowFile(WORKFLOW_CONTENT), existingMode(path, 420));
|
|
11386
11425
|
};
|
|
11426
|
+
const refused = refuseNonRegular(path);
|
|
11427
|
+
if (refused) return { item: "ci", path: rel, status: "error", detail: refused };
|
|
11387
11428
|
if (!existsSync11(path)) {
|
|
11388
11429
|
return {
|
|
11389
11430
|
item: "ci",
|
|
@@ -11519,6 +11560,7 @@ var init_init = __esm({
|
|
|
11519
11560
|
init_wiring();
|
|
11520
11561
|
init_narrow();
|
|
11521
11562
|
init_repo_context();
|
|
11563
|
+
init_safe_write();
|
|
11522
11564
|
errText3 = (e) => (e instanceof Error ? e.message : String(e)).replace(/\s+/g, " ").trim();
|
|
11523
11565
|
isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11524
11566
|
HOOK_RE = /\btamperward(?:@\S+)?\s+hook\s+claude\b/;
|
|
@@ -11693,7 +11735,7 @@ import {
|
|
|
11693
11735
|
readFileSync as readFileSync13,
|
|
11694
11736
|
readlinkSync as readlinkSync2,
|
|
11695
11737
|
realpathSync as realpathSync5,
|
|
11696
|
-
statSync as
|
|
11738
|
+
statSync as statSync3
|
|
11697
11739
|
} from "node:fs";
|
|
11698
11740
|
import {
|
|
11699
11741
|
basename as basename3,
|
|
@@ -11735,7 +11777,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
11735
11777
|
root.kind + " root moved from " + JSON.stringify(root.realPath) + " to " + JSON.stringify(currentReal)
|
|
11736
11778
|
);
|
|
11737
11779
|
}
|
|
11738
|
-
if (!
|
|
11780
|
+
if (!statSync3(root.path).isDirectory()) {
|
|
11739
11781
|
throw new Unattestable(root.kind + " root " + JSON.stringify(root.path) + " is not a directory");
|
|
11740
11782
|
}
|
|
11741
11783
|
h.update("root\0" + root.kind + "\0" + root.path + "\0" + root.realPath + "\0" + String(rootStat.mode) + "\0");
|
|
@@ -11745,7 +11787,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
11745
11787
|
const hashFile = (path, label) => {
|
|
11746
11788
|
let st;
|
|
11747
11789
|
try {
|
|
11748
|
-
st =
|
|
11790
|
+
st = statSync3(path);
|
|
11749
11791
|
if (!st.isFile()) throw new Error("not a regular file");
|
|
11750
11792
|
h.update(label + "\0external-file\0" + path + "\0" + String(st.mode) + "\0");
|
|
11751
11793
|
h.update(readFileSync13(path));
|
|
@@ -11811,7 +11853,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
11811
11853
|
} catch {
|
|
11812
11854
|
continue;
|
|
11813
11855
|
}
|
|
11814
|
-
const followed =
|
|
11856
|
+
const followed = statSync3(path);
|
|
11815
11857
|
if (followed.isFile()) {
|
|
11816
11858
|
hashFile(resolved, "@target:" + rel);
|
|
11817
11859
|
continue;
|
|
@@ -11859,7 +11901,7 @@ function measuredSnapshot(roots, probes, cwd, metrics) {
|
|
|
11859
11901
|
}
|
|
11860
11902
|
function freezeRoot(kind, path) {
|
|
11861
11903
|
try {
|
|
11862
|
-
if (!
|
|
11904
|
+
if (!statSync3(path).isDirectory()) {
|
|
11863
11905
|
throw new Error("not a directory");
|
|
11864
11906
|
}
|
|
11865
11907
|
return { kind, path: resolve5(path), realPath: realpathSync5(path) };
|
|
@@ -11908,7 +11950,7 @@ function resolveExecutable(token, cwd, env) {
|
|
|
11908
11950
|
for (const entry of (env.PATH ?? "").split(delimiter).filter(Boolean)) {
|
|
11909
11951
|
const candidate = resolve5(entry, token);
|
|
11910
11952
|
try {
|
|
11911
|
-
if (existsSync12(candidate) &&
|
|
11953
|
+
if (existsSync12(candidate) && statSync3(candidate).isFile()) return realpathSync5(candidate);
|
|
11912
11954
|
} catch {
|
|
11913
11955
|
}
|
|
11914
11956
|
}
|
|
@@ -12095,7 +12137,7 @@ var init_dependency_env = __esm({
|
|
|
12095
12137
|
|
|
12096
12138
|
// src/suite-diagnostics.ts
|
|
12097
12139
|
import { spawnSync } from "node:child_process";
|
|
12098
|
-
import { mkdtempSync as mkdtempSync2, rmSync as
|
|
12140
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
12099
12141
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
12100
12142
|
import { join as join16 } from "node:path";
|
|
12101
12143
|
function emptySuiteDiagnostics() {
|
|
@@ -12224,7 +12266,7 @@ function runCapturedProcessSync(executable, args, opts) {
|
|
|
12224
12266
|
}
|
|
12225
12267
|
return parsed;
|
|
12226
12268
|
} finally {
|
|
12227
|
-
|
|
12269
|
+
rmSync6(stateDir, { recursive: true, force: true });
|
|
12228
12270
|
}
|
|
12229
12271
|
}
|
|
12230
12272
|
var DIAGNOSTIC_TAIL_BYTES, EMPTY_STREAM, CAPTURE_SUPERVISOR;
|
|
@@ -12414,7 +12456,7 @@ if (child) {
|
|
|
12414
12456
|
// src/verifier-backend.ts
|
|
12415
12457
|
import { createHash as createHash9, randomUUID } from "node:crypto";
|
|
12416
12458
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
12417
|
-
import { accessSync as accessSync2, constants as constants3, readFileSync as readFileSync15, realpathSync as realpathSync6, statSync as
|
|
12459
|
+
import { accessSync as accessSync2, constants as constants3, readFileSync as readFileSync15, realpathSync as realpathSync6, statSync as statSync4 } from "node:fs";
|
|
12418
12460
|
import { delimiter as delimiter2, dirname as dirname6, join as join17, resolve as resolve6 } from "node:path";
|
|
12419
12461
|
function identity() {
|
|
12420
12462
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -12423,7 +12465,7 @@ function identity() {
|
|
|
12423
12465
|
}
|
|
12424
12466
|
function writableByCaller(path) {
|
|
12425
12467
|
try {
|
|
12426
|
-
const st =
|
|
12468
|
+
const st = statSync4(path);
|
|
12427
12469
|
const { uid, groups } = identity();
|
|
12428
12470
|
if (uid === 0) return true;
|
|
12429
12471
|
if ((st.mode & 2) !== 0) return true;
|
|
@@ -12893,7 +12935,7 @@ var init_verifier_backend = __esm({
|
|
|
12893
12935
|
// src/cli/verify.ts
|
|
12894
12936
|
import { execFileSync as execFileSync8, spawnSync as spawnSync3 } from "node:child_process";
|
|
12895
12937
|
import { createHash as createHash10 } from "node:crypto";
|
|
12896
|
-
import { chmodSync as
|
|
12938
|
+
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync9, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, readlinkSync as readlinkSync3, rmSync as rmSync7, symlinkSync, writeFileSync as writeFileSync9, existsSync as existsSync13 } from "node:fs";
|
|
12897
12939
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
12898
12940
|
import { dirname as dirname7, isAbsolute as isAbsolute10, join as join18, relative as relative5, resolve as resolve7, sep as sep3 } from "node:path";
|
|
12899
12941
|
function oracleAssuranceReport() {
|
|
@@ -12941,7 +12983,7 @@ function safeSymlink(target, out3, root, label) {
|
|
|
12941
12983
|
if (rootedLinkTarget(target) || !inside2(root, resolve7(dirname7(out3), target))) {
|
|
12942
12984
|
throw linkEscape(label, target);
|
|
12943
12985
|
}
|
|
12944
|
-
|
|
12986
|
+
rmSync7(out3, { force: true });
|
|
12945
12987
|
symlinkSync(target, out3);
|
|
12946
12988
|
}
|
|
12947
12989
|
function validateSymlinkGraph(target, out3, root, dependencyRoot, label) {
|
|
@@ -13032,7 +13074,7 @@ function materialize(cwd, dest, dependencyRoot) {
|
|
|
13032
13074
|
links.push({ rel, out: out3, target });
|
|
13033
13075
|
} else if (st.isFile()) {
|
|
13034
13076
|
cpSync(src, out3, { dereference: true });
|
|
13035
|
-
|
|
13077
|
+
chmodSync2(out3, st.mode);
|
|
13036
13078
|
} else {
|
|
13037
13079
|
throw new Error(`${rel} is ${st.isDirectory() ? "a directory" : "a special file"} where git expects a file`);
|
|
13038
13080
|
}
|
|
@@ -13052,7 +13094,7 @@ function probeFilesystemCaseSensitivity(dir) {
|
|
|
13052
13094
|
writeFileSync9(upper, "", { flag: "wx" });
|
|
13053
13095
|
return !existsSync13(lower);
|
|
13054
13096
|
} finally {
|
|
13055
|
-
|
|
13097
|
+
rmSync7(upper, { force: true });
|
|
13056
13098
|
}
|
|
13057
13099
|
}
|
|
13058
13100
|
function foldCase(p) {
|
|
@@ -13070,7 +13112,7 @@ function caseFoldCollision(paths) {
|
|
|
13070
13112
|
}
|
|
13071
13113
|
function dropSymlink(p) {
|
|
13072
13114
|
try {
|
|
13073
|
-
if (lstatSync9(p).isSymbolicLink())
|
|
13115
|
+
if (lstatSync9(p).isSymbolicLink()) rmSync7(p, { force: true });
|
|
13074
13116
|
} catch {
|
|
13075
13117
|
}
|
|
13076
13118
|
}
|
|
@@ -13146,14 +13188,14 @@ function overlayPristine(cwd, base, dest, policy, cmd, dependencyRoot, caseSensi
|
|
|
13146
13188
|
const content = execFileSync8("git", ["show", `${base}:${e.path}`], { cwd, maxBuffer: 1 << 28, env: trustedGitEnv() });
|
|
13147
13189
|
const out3 = join18(dest, e.path);
|
|
13148
13190
|
mkdirSync7(dirname7(out3), { recursive: true });
|
|
13149
|
-
|
|
13191
|
+
rmSync7(out3, { force: true });
|
|
13150
13192
|
if (e.mode === "120000") {
|
|
13151
13193
|
const target = content.toString("utf8");
|
|
13152
13194
|
safeSymlink(target, out3, dest, `the base's ${e.path}`);
|
|
13153
13195
|
restoredLinks.push({ path: e.path, out: out3, target });
|
|
13154
13196
|
} else {
|
|
13155
13197
|
writeFileSync9(out3, content);
|
|
13156
|
-
|
|
13198
|
+
chmodSync2(out3, parseInt(e.mode.slice(-4), 8) & 511);
|
|
13157
13199
|
}
|
|
13158
13200
|
restored.push(e.path);
|
|
13159
13201
|
}
|
|
@@ -13161,7 +13203,7 @@ function overlayPristine(cwd, base, dest, policy, cmd, dependencyRoot, caseSensi
|
|
|
13161
13203
|
const inCopy = workingTreePaths(cwd);
|
|
13162
13204
|
for (const rel of inCopy) {
|
|
13163
13205
|
if (!isOverlay(rel) || baseProtected.has(fold(rel))) continue;
|
|
13164
|
-
|
|
13206
|
+
rmSync7(join18(dest, rel), { force: true });
|
|
13165
13207
|
removed++;
|
|
13166
13208
|
}
|
|
13167
13209
|
for (const link of restoredLinks) {
|
|
@@ -13248,7 +13290,7 @@ function runLocalSuite(dir, cmd, budgetSecs) {
|
|
|
13248
13290
|
}
|
|
13249
13291
|
return { exit: r.exit, secs, diagnostics: r.diagnostics };
|
|
13250
13292
|
} finally {
|
|
13251
|
-
|
|
13293
|
+
rmSync7(scratch, { recursive: true, force: true });
|
|
13252
13294
|
}
|
|
13253
13295
|
}
|
|
13254
13296
|
function diagnosticsJson(diagnostics, includeTail) {
|
|
@@ -13401,7 +13443,7 @@ function runVerify(opts) {
|
|
|
13401
13443
|
const visDir = join18(visRoot, "t");
|
|
13402
13444
|
const cleanup = (dirs) => {
|
|
13403
13445
|
if (opts.keep) return;
|
|
13404
|
-
for (const d of dirs)
|
|
13446
|
+
for (const d of dirs) rmSync7(d, { recursive: true, force: true });
|
|
13405
13447
|
};
|
|
13406
13448
|
filesystemCaseSensitive = (opts.probeCaseSensitivity ?? probeFilesystemCaseSensitivity)(visRoot);
|
|
13407
13449
|
if (!filesystemCaseSensitive) {
|
|
@@ -13767,8 +13809,8 @@ var init_verify = __esm({
|
|
|
13767
13809
|
|
|
13768
13810
|
// src/cli/run.ts
|
|
13769
13811
|
import { execFileSync as execFileSync9, spawn, spawnSync as spawnSync4 } from "node:child_process";
|
|
13770
|
-
import { randomBytes } from "node:crypto";
|
|
13771
|
-
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync17, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as
|
|
13812
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
13813
|
+
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";
|
|
13772
13814
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
13773
13815
|
import { dirname as dirname8, join as join19, resolve as resolve8 } from "node:path";
|
|
13774
13816
|
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
@@ -13824,7 +13866,7 @@ function trustedLinuxPython(candidates = DEFAULT_TRUSTED_PYTHON_CANDIDATES) {
|
|
|
13824
13866
|
for (const candidate of candidates) {
|
|
13825
13867
|
try {
|
|
13826
13868
|
const real = realpathSync8(candidate);
|
|
13827
|
-
const st =
|
|
13869
|
+
const st = statSync5(real);
|
|
13828
13870
|
if (!st.isFile() || writableByCaller2(real)) continue;
|
|
13829
13871
|
const probe = spawnSync4(
|
|
13830
13872
|
real,
|
|
@@ -13947,7 +13989,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
|
|
|
13947
13989
|
...state.failure ? { failure: state.failure } : {}
|
|
13948
13990
|
};
|
|
13949
13991
|
} finally {
|
|
13950
|
-
|
|
13992
|
+
rmSync8(stateDir, { recursive: true, force: true });
|
|
13951
13993
|
}
|
|
13952
13994
|
}
|
|
13953
13995
|
function waitMs(ms) {
|
|
@@ -13978,7 +14020,7 @@ function supervisedObserverLog(cwd) {
|
|
|
13978
14020
|
return join19(
|
|
13979
14021
|
gd,
|
|
13980
14022
|
"tamperward",
|
|
13981
|
-
`run-observer-${process.pid}-${Date.now()}-${
|
|
14023
|
+
`run-observer-${process.pid}-${Date.now()}-${randomBytes2(4).toString("hex")}.jsonl`
|
|
13982
14024
|
);
|
|
13983
14025
|
}
|
|
13984
14026
|
function startSupervisedObserver(cwd, base, entry) {
|
|
@@ -15320,7 +15362,7 @@ import {
|
|
|
15320
15362
|
readFileSync as readFileSync19,
|
|
15321
15363
|
readdirSync as readdirSync6,
|
|
15322
15364
|
realpathSync as realpathSync9,
|
|
15323
|
-
rmSync as
|
|
15365
|
+
rmSync as rmSync9,
|
|
15324
15366
|
symlinkSync as symlinkSync2
|
|
15325
15367
|
} from "node:fs";
|
|
15326
15368
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
@@ -15518,8 +15560,8 @@ function runOneTrace(cwd, base, command, budget) {
|
|
|
15518
15560
|
accesses: rewriteTraceRoot(accesses, root)
|
|
15519
15561
|
};
|
|
15520
15562
|
} finally {
|
|
15521
|
-
|
|
15522
|
-
|
|
15563
|
+
rmSync9(root, { recursive: true, force: true });
|
|
15564
|
+
rmSync9(traceDir, { recursive: true, force: true });
|
|
15523
15565
|
}
|
|
15524
15566
|
}
|
|
15525
15567
|
function renderText2(report2) {
|
|
@@ -15703,8 +15745,7 @@ var init_trace_verify = __esm({
|
|
|
15703
15745
|
|
|
15704
15746
|
// src/cli/onboard.ts
|
|
15705
15747
|
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
15706
|
-
import {
|
|
15707
|
-
import { lstatSync as lstatSync10, mkdtempSync as mkdtempSync6, readFileSync as readFileSync20, realpathSync as realpathSync10, renameSync as renameSync3, rmSync as rmSync9, writeFileSync as writeFileSync11 } from "node:fs";
|
|
15748
|
+
import { lstatSync as lstatSync10, mkdtempSync as mkdtempSync6, readFileSync as readFileSync20, realpathSync as realpathSync10, rmSync as rmSync10 } from "node:fs";
|
|
15708
15749
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
15709
15750
|
import { join as join22, relative as relative7, resolve as resolve11, sep as sep5 } from "node:path";
|
|
15710
15751
|
import { createInterface } from "node:readline";
|
|
@@ -15773,23 +15814,14 @@ function explainVerdict(v, code2) {
|
|
|
15773
15814
|
return `Could not verify${v?.reason ? ` (${v.reason})` : ""} \u2014 TamperWard failed closed${v?.detail ? `: ${v.detail}` : "."}`;
|
|
15774
15815
|
}
|
|
15775
15816
|
}
|
|
15776
|
-
function atomicReplaceFile(path, content, mode) {
|
|
15777
|
-
const tmp = `${path}.${process.pid}.${randomBytes2(8).toString("hex")}.tmp`;
|
|
15778
|
-
try {
|
|
15779
|
-
writeFileSync11(tmp, content, { encoding: "utf8", flag: "wx", mode });
|
|
15780
|
-
renameSync3(tmp, path);
|
|
15781
|
-
} finally {
|
|
15782
|
-
rmSync9(tmp, { force: true });
|
|
15783
|
-
}
|
|
15784
|
-
}
|
|
15785
15817
|
function writeVerifyCommand(cwd, command) {
|
|
15786
15818
|
const path = join22(cwd, POLICY_FILE);
|
|
15787
|
-
const
|
|
15788
|
-
if (
|
|
15819
|
+
const kind = writeTargetKind(path);
|
|
15820
|
+
if (kind === "symlink" || kind === "irregular") {
|
|
15789
15821
|
return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
|
|
15790
15822
|
}
|
|
15791
|
-
const mode =
|
|
15792
|
-
const original =
|
|
15823
|
+
const mode = existingMode(path, 420);
|
|
15824
|
+
const original = kind === "file" ? readFileSync20(path, "utf8") : null;
|
|
15793
15825
|
let next;
|
|
15794
15826
|
try {
|
|
15795
15827
|
const doc = parseDocument(original && original.trim() ? original : "version: 1\n");
|
|
@@ -15806,7 +15838,7 @@ function writeVerifyCommand(cwd, command) {
|
|
|
15806
15838
|
if (loaded2.verify?.command !== command) throw new Error("verify.command did not round-trip");
|
|
15807
15839
|
return null;
|
|
15808
15840
|
} catch (e) {
|
|
15809
|
-
if (original === null)
|
|
15841
|
+
if (original === null) rmSync10(path, { force: true });
|
|
15810
15842
|
else atomicReplaceFile(path, original, mode);
|
|
15811
15843
|
return `the updated ${POLICY_FILE} does not load (${errorMessage(e)}); restored the previous file`;
|
|
15812
15844
|
}
|
|
@@ -16206,7 +16238,7 @@ function runDemo(cwd, head, runners, out3) {
|
|
|
16206
16238
|
} finally {
|
|
16207
16239
|
git5(cwd, ["worktree", "remove", "--force", wt]);
|
|
16208
16240
|
git5(cwd, ["worktree", "prune"]);
|
|
16209
|
-
|
|
16241
|
+
rmSync10(wt, { recursive: true, force: true });
|
|
16210
16242
|
}
|
|
16211
16243
|
const after = treeFingerprint(cwd);
|
|
16212
16244
|
out3(`working tree fingerprint after: ${after.slice(0, 16)}`);
|
|
@@ -16231,6 +16263,7 @@ var init_onboard = __esm({
|
|
|
16231
16263
|
init_policy_load();
|
|
16232
16264
|
init_narrow();
|
|
16233
16265
|
init_wiring();
|
|
16266
|
+
init_safe_write();
|
|
16234
16267
|
Aborted = class extends Error {
|
|
16235
16268
|
};
|
|
16236
16269
|
SECTIONS = [
|
|
@@ -16621,7 +16654,7 @@ var init_record = __esm({
|
|
|
16621
16654
|
|
|
16622
16655
|
// src/research/run.ts
|
|
16623
16656
|
import { execFileSync as execFileSync13 } from "node:child_process";
|
|
16624
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync8, readFileSync as readFileSync22, renameSync as renameSync4, rmSync as
|
|
16657
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync8, readFileSync as readFileSync22, renameSync as renameSync4, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
16625
16658
|
import { join as join23, resolve as resolve14 } from "node:path";
|
|
16626
16659
|
function git6(args, cwd) {
|
|
16627
16660
|
return execFileSync13("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
@@ -16669,12 +16702,12 @@ function resumableRecord(path, expected) {
|
|
|
16669
16702
|
}
|
|
16670
16703
|
function writeRecordAtomically(path, text) {
|
|
16671
16704
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
16672
|
-
|
|
16705
|
+
writeFileSync11(tmp, text);
|
|
16673
16706
|
renameSync4(tmp, path);
|
|
16674
16707
|
}
|
|
16675
16708
|
function freshWorkspace(ledger, task, pair, arm, sourceBase) {
|
|
16676
16709
|
const ws2 = join23(ledger, "workspaces", `${task.id}--${pair}--${arm}`);
|
|
16677
|
-
|
|
16710
|
+
rmSync11(ws2, { recursive: true, force: true });
|
|
16678
16711
|
mkdirSync8(join23(ledger, "workspaces"), { recursive: true });
|
|
16679
16712
|
try {
|
|
16680
16713
|
execFileSync13("git", ["clone", "-q", "--no-hardlinks", task.repo, ws2], { stdio: ["ignore", "ignore", "pipe"], encoding: "utf8" });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.23.
|
|
3
|
+
"version": "2.23.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",
|