tamperward 2.39.7 → 2.39.9
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 +169 -130
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -10697,7 +10697,6 @@ var init_engine = __esm({
|
|
|
10697
10697
|
});
|
|
10698
10698
|
|
|
10699
10699
|
// src/policy-load.ts
|
|
10700
|
-
import { readFileSync as readFileSync5, existsSync as existsSync5 } from "node:fs";
|
|
10701
10700
|
import { isAbsolute as isAbsolute7, join as join8, posix as posix3 } from "node:path";
|
|
10702
10701
|
function normalizeVersion(v, where = POLICY_FILE) {
|
|
10703
10702
|
if (v === void 0 || v === null) return 1;
|
|
@@ -10869,10 +10868,29 @@ function parseOrThrow(src, where) {
|
|
|
10869
10868
|
}
|
|
10870
10869
|
return parsePolicy(raw, where);
|
|
10871
10870
|
}
|
|
10871
|
+
function notARegularFile(e) {
|
|
10872
|
+
switch (e.kind) {
|
|
10873
|
+
case "symlink":
|
|
10874
|
+
return `is a symbolic link to ${escapeControl(e.detail)}`;
|
|
10875
|
+
case "directory":
|
|
10876
|
+
return "is a directory";
|
|
10877
|
+
case "irregular":
|
|
10878
|
+
return `is a ${e.detail}`;
|
|
10879
|
+
case "oversize":
|
|
10880
|
+
return `is ${e.detail}, above the ${READ_CAP / (1024 * 1024)} MiB the gate reads`;
|
|
10881
|
+
default:
|
|
10882
|
+
return `cannot be read (${e.detail})`;
|
|
10883
|
+
}
|
|
10884
|
+
}
|
|
10872
10885
|
function loadPolicy(cwd = process.cwd()) {
|
|
10873
|
-
const
|
|
10874
|
-
if (
|
|
10875
|
-
|
|
10886
|
+
const entry = inspectPath(join8(repoRoot(cwd), POLICY_FILE));
|
|
10887
|
+
if (entry.kind === "absent") return defaultPolicy();
|
|
10888
|
+
if (entry.kind !== "file") {
|
|
10889
|
+
throw new PolicyError(
|
|
10890
|
+
`${POLICY_FILE} ${notARegularFile(entry)}; the policy is read only as a regular file at the repository root \u2014 put one there (no symbolic link, FIFO, socket, device or directory) or remove it`
|
|
10891
|
+
);
|
|
10892
|
+
}
|
|
10893
|
+
return parseOrThrow(textOf2(entry) ?? "", POLICY_FILE);
|
|
10876
10894
|
}
|
|
10877
10895
|
function loadPolicyAt(rev2, cwd) {
|
|
10878
10896
|
const src = fileAt(rev2, POLICY_FILE, { cwd: cwd === void 0 ? void 0 : repoRoot(cwd) });
|
|
@@ -10886,6 +10904,7 @@ var init_policy_load = __esm({
|
|
|
10886
10904
|
init_lazy_deps();
|
|
10887
10905
|
init_policy();
|
|
10888
10906
|
init_build();
|
|
10907
|
+
init_disk();
|
|
10889
10908
|
init_narrow();
|
|
10890
10909
|
init_repo_context();
|
|
10891
10910
|
PolicyError = class extends Error {
|
|
@@ -10900,7 +10919,7 @@ var init_policy_load = __esm({
|
|
|
10900
10919
|
|
|
10901
10920
|
// src/signoff.ts
|
|
10902
10921
|
import { createHash as createHash3 } from "node:crypto";
|
|
10903
|
-
import { appendFileSync, closeSync as closeSync2, constants as constants3, fstatSync as fstatSync2, lstatSync as lstatSync3, mkdirSync, openSync as openSync2, readFileSync as
|
|
10922
|
+
import { appendFileSync, closeSync as closeSync2, constants as constants3, fstatSync as fstatSync2, lstatSync as lstatSync3, mkdirSync, openSync as openSync2, readFileSync as readFileSync5 } from "node:fs";
|
|
10904
10923
|
import { dirname as dirname2, join as join9, posix as posix4 } from "node:path";
|
|
10905
10924
|
function compactOobToken(want, head) {
|
|
10906
10925
|
const normalizedHead = head.trim().toLowerCase();
|
|
@@ -10983,7 +11002,7 @@ function readLedger(cwd, policy) {
|
|
|
10983
11002
|
const fd = openLedger(rel, path, constants3.O_RDONLY);
|
|
10984
11003
|
let text;
|
|
10985
11004
|
try {
|
|
10986
|
-
text =
|
|
11005
|
+
text = readFileSync5(fd, "utf8");
|
|
10987
11006
|
} finally {
|
|
10988
11007
|
closeSync2(fd);
|
|
10989
11008
|
}
|
|
@@ -11030,25 +11049,25 @@ function applyLocalSignoffs(findings, cwd, policy, now = Date.now()) {
|
|
|
11030
11049
|
return { findings: remaining, cleared };
|
|
11031
11050
|
}
|
|
11032
11051
|
function oobToken(want, oob, head) {
|
|
11052
|
+
const supplied = head !== void 0 && head.trim() !== "";
|
|
11053
|
+
const bound = supplied && FULL_OBJECT_ID.test(head.trim()) ? head.trim().toLowerCase() : null;
|
|
11033
11054
|
for (const raw of oob) {
|
|
11034
11055
|
const t = raw.trim();
|
|
11035
11056
|
if (!t) continue;
|
|
11036
11057
|
if (t.startsWith(COMPACT_OOB_PREFIX)) {
|
|
11037
|
-
const expected =
|
|
11058
|
+
const expected = bound === null ? null : compactOobToken(want, bound);
|
|
11038
11059
|
if (expected !== null && t === expected) return t;
|
|
11039
11060
|
continue;
|
|
11040
11061
|
}
|
|
11041
11062
|
const at = t.lastIndexOf("@");
|
|
11042
11063
|
if (at === -1) {
|
|
11043
|
-
if (!
|
|
11064
|
+
if (!supplied && t === want) return t;
|
|
11044
11065
|
continue;
|
|
11045
11066
|
}
|
|
11046
11067
|
const [rule, sha3] = [t.slice(0, at), t.slice(at + 1)];
|
|
11047
11068
|
if (rule !== want) continue;
|
|
11048
|
-
if (!
|
|
11049
|
-
|
|
11050
|
-
const normalizedSha = sha3.trim().toLowerCase();
|
|
11051
|
-
if (/^[0-9a-f]+$/.test(normalizedHead) && normalizedSha === normalizedHead) return t;
|
|
11069
|
+
if (!supplied) return t;
|
|
11070
|
+
if (bound !== null && sha3.trim().toLowerCase() === bound) return t;
|
|
11052
11071
|
}
|
|
11053
11072
|
return null;
|
|
11054
11073
|
}
|
|
@@ -11065,7 +11084,12 @@ function applyOobSignoffs(findings, oob, head) {
|
|
|
11065
11084
|
}
|
|
11066
11085
|
function oobHeadFromEnv(env = process.env) {
|
|
11067
11086
|
const v = (env.TAMPERWARD_OOB_HEAD ?? "").trim().toLowerCase();
|
|
11068
|
-
return
|
|
11087
|
+
return v === "" ? void 0 : v;
|
|
11088
|
+
}
|
|
11089
|
+
function oobHeadProblem(head) {
|
|
11090
|
+
if (head === void 0 || head.trim() === "" || FULL_OBJECT_ID.test(head.trim())) return null;
|
|
11091
|
+
const shown = head.length > 72 ? `${head.slice(0, 69)}\u2026` : head;
|
|
11092
|
+
return `TAMPERWARD_OOB_HEAD is set to ${JSON.stringify(shown)}, which is not the full 40- or 64-character object id of the head under adjudication; no out-of-band approval is honored against a head the gate cannot identify`;
|
|
11069
11093
|
}
|
|
11070
11094
|
function oobFromEnv(env = process.env) {
|
|
11071
11095
|
return (env.TAMPERWARD_OOB_SIGNOFF ?? "").split(",").map((s) => s.trim().replace(/^tamperward:allow:/, "")).filter(Boolean);
|
|
@@ -11459,8 +11483,13 @@ function check(opts) {
|
|
|
11459
11483
|
const ignoredFiles = changes.filter((c) => isSuppressed(c, policy)).length;
|
|
11460
11484
|
let findings = evaluate(changes, policy, void 0, view, { cwd });
|
|
11461
11485
|
if (view === "worktree") findings = findings.concat(unjudgeableProtected(cwd, policy, changes));
|
|
11462
|
-
const
|
|
11486
|
+
const oob = layer === "ci" ? oobFromEnv() : [];
|
|
11487
|
+
const oobHead = layer === "ci" ? oobHeadFromEnv() : void 0;
|
|
11488
|
+
const { findings: remaining, cleared } = layer === "local" ? applyLocalSignoffs(findings, cwd, policy) : applyOobSignoffs(findings, oob, oobHead);
|
|
11463
11489
|
findings = remaining;
|
|
11490
|
+
const headProblem = oob.length > 0 ? oobHeadProblem(oobHead) : null;
|
|
11491
|
+
if (headProblem) process.stderr.write(`tamperward: ${headProblem}
|
|
11492
|
+
`);
|
|
11464
11493
|
if (cleared.length) {
|
|
11465
11494
|
const how = layer === "local" ? "local human sign-off (ledger)" : "out-of-band approval";
|
|
11466
11495
|
process.stderr.write(`tamperward: ${cleared.length} blocking finding(s) cleared by ${how}: ${cleared.map((f) => f.rule + (f.file ? `(${f.file})` : "")).join(", ")}
|
|
@@ -11524,7 +11553,7 @@ var init_deny = __esm({
|
|
|
11524
11553
|
});
|
|
11525
11554
|
|
|
11526
11555
|
// src/session.ts
|
|
11527
|
-
import { existsSync as
|
|
11556
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11528
11557
|
import { dirname as dirname3, join as join10 } from "node:path";
|
|
11529
11558
|
function writeBaseline(p, sha3) {
|
|
11530
11559
|
mkdirSync2(dirname3(p), { recursive: true });
|
|
@@ -11550,8 +11579,8 @@ function turnBaseline(cwd, sessionId) {
|
|
|
11550
11579
|
const p = baselinePath(cwd, sessionId);
|
|
11551
11580
|
if (!p) return null;
|
|
11552
11581
|
try {
|
|
11553
|
-
if (
|
|
11554
|
-
const v =
|
|
11582
|
+
if (existsSync5(p)) {
|
|
11583
|
+
const v = readFileSync6(p, "utf8").trim();
|
|
11555
11584
|
if (SHA.test(v)) return v;
|
|
11556
11585
|
}
|
|
11557
11586
|
} catch {
|
|
@@ -11594,7 +11623,7 @@ var init_session = __esm({
|
|
|
11594
11623
|
|
|
11595
11624
|
// src/effect.ts
|
|
11596
11625
|
import { createHash as createHash4 } from "node:crypto";
|
|
11597
|
-
import { existsSync as
|
|
11626
|
+
import { existsSync as existsSync6, lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync7, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
11598
11627
|
import { join as join11 } from "node:path";
|
|
11599
11628
|
function ptreeFrom(value) {
|
|
11600
11629
|
if (!isRecord(value)) return null;
|
|
@@ -11686,9 +11715,9 @@ function driftBetween(expected, current) {
|
|
|
11686
11715
|
return { changed, deleted, added };
|
|
11687
11716
|
}
|
|
11688
11717
|
function loadTree(p) {
|
|
11689
|
-
if (!p || !
|
|
11718
|
+
if (!p || !existsSync6(p)) return null;
|
|
11690
11719
|
try {
|
|
11691
|
-
return ptreeFrom(JSON.parse(
|
|
11720
|
+
return ptreeFrom(JSON.parse(readFileSync7(p, "utf8")));
|
|
11692
11721
|
} catch {
|
|
11693
11722
|
return null;
|
|
11694
11723
|
}
|
|
@@ -11741,7 +11770,7 @@ var init_effect = __esm({
|
|
|
11741
11770
|
});
|
|
11742
11771
|
|
|
11743
11772
|
// src/cli/watch.ts
|
|
11744
|
-
import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as
|
|
11773
|
+
import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync2, watch, writeFileSync as writeFileSync4 } from "node:fs";
|
|
11745
11774
|
import { join as join12 } from "node:path";
|
|
11746
11775
|
import { createHash as createHash5 } from "node:crypto";
|
|
11747
11776
|
function snap(abs) {
|
|
@@ -11760,7 +11789,7 @@ function watcherHealthPath(log) {
|
|
|
11760
11789
|
}
|
|
11761
11790
|
function readWatcherHealth(log) {
|
|
11762
11791
|
try {
|
|
11763
|
-
const value = JSON.parse(
|
|
11792
|
+
const value = JSON.parse(readFileSync8(watcherHealthPath(log), "utf8"));
|
|
11764
11793
|
if (!isRecord(value)) return null;
|
|
11765
11794
|
const { state, backend, pid, started_at } = value;
|
|
11766
11795
|
if (value.version !== 1 || typeof pid !== "number" || typeof started_at !== "string") return null;
|
|
@@ -12288,7 +12317,7 @@ var init_fs_events = __esm({
|
|
|
12288
12317
|
|
|
12289
12318
|
// src/cli/audit.ts
|
|
12290
12319
|
import { createHash as createHash6, randomBytes } from "node:crypto";
|
|
12291
|
-
import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as
|
|
12320
|
+
import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync as openSync4, readSync as readSync3 } from "node:fs";
|
|
12292
12321
|
import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
|
|
12293
12322
|
function sessionHash(sessionId) {
|
|
12294
12323
|
if (!sessionId) return void 0;
|
|
@@ -12547,7 +12576,7 @@ function runStats(opts = {}) {
|
|
|
12547
12576
|
const file = opts.file ? isAbsolute8(opts.file) ? opts.file : resolve4(cwd, opts.file) : configured && configured !== "auto" ? isAbsolute8(configured) ? configured : resolve4(cwd, configured) : defaultAuditPath(cwd);
|
|
12548
12577
|
const cutoff = opts.since ? parseSince(opts.since) : null;
|
|
12549
12578
|
if (!file) throw new Error("stats needs --file outside a Git repository");
|
|
12550
|
-
if (!
|
|
12579
|
+
if (!existsSync7(file)) {
|
|
12551
12580
|
if (explicitFile) throw new Error(`audit file not found: ${file}`);
|
|
12552
12581
|
const empty2 = summarizeAudit([]);
|
|
12553
12582
|
process.stdout.write(opts.json ? JSON.stringify(empty2) + "\n" : renderAuditStats(empty2));
|
|
@@ -12586,14 +12615,14 @@ var init_audit = __esm({
|
|
|
12586
12615
|
});
|
|
12587
12616
|
|
|
12588
12617
|
// src/cli/hook.ts
|
|
12589
|
-
import { readFileSync as
|
|
12618
|
+
import { readFileSync as readFileSync9, appendFileSync as appendFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync8 } from "node:fs";
|
|
12590
12619
|
import { createHash as createHash7 } from "node:crypto";
|
|
12591
12620
|
function setSnapshotCache(cache3) {
|
|
12592
12621
|
snapshotCache = cache3;
|
|
12593
12622
|
}
|
|
12594
12623
|
function readStdin() {
|
|
12595
12624
|
try {
|
|
12596
|
-
return
|
|
12625
|
+
return readFileSync9(0, "utf8");
|
|
12597
12626
|
} catch (e) {
|
|
12598
12627
|
throw new HookInputError(`cannot read the hook payload on stdin: ${e instanceof Error ? e.message : String(e)}`);
|
|
12599
12628
|
}
|
|
@@ -12883,10 +12912,10 @@ function turnTransientBlocks(cwd, sessionId, policy, changes) {
|
|
|
12883
12912
|
recordObserverHealth(cwd, sessionId, telemetry.state, telemetry.reason);
|
|
12884
12913
|
}
|
|
12885
12914
|
const cp = cursorPath(cwd, sessionId);
|
|
12886
|
-
if (!
|
|
12915
|
+
if (!existsSync8(log)) return none;
|
|
12887
12916
|
let offset = 0;
|
|
12888
|
-
if (cp &&
|
|
12889
|
-
const n2 = Number(
|
|
12917
|
+
if (cp && existsSync8(cp)) {
|
|
12918
|
+
const n2 = Number(readFileSync9(cp, "utf8"));
|
|
12890
12919
|
offset = Number.isFinite(n2) ? n2 : 0;
|
|
12891
12920
|
}
|
|
12892
12921
|
const drained = drainEvents(log, offset);
|
|
@@ -13160,13 +13189,13 @@ var init_ptree_cache = __esm({
|
|
|
13160
13189
|
});
|
|
13161
13190
|
|
|
13162
13191
|
// src/cli/hook-service.ts
|
|
13163
|
-
import { chmodSync, existsSync as
|
|
13192
|
+
import { chmodSync, existsSync as existsSync9, lstatSync as lstatSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
13164
13193
|
import { createConnection as createConnection2, createServer } from "node:net";
|
|
13165
13194
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
13166
13195
|
import { sep } from "node:path";
|
|
13167
13196
|
function readServiceState(paths) {
|
|
13168
13197
|
try {
|
|
13169
|
-
const v = JSON.parse(
|
|
13198
|
+
const v = JSON.parse(readFileSync10(paths.state, "utf8"));
|
|
13170
13199
|
if (!isRecord(v)) return null;
|
|
13171
13200
|
const { pid, version, root, started_at } = v;
|
|
13172
13201
|
if (typeof pid !== "number" || typeof version !== "string" || typeof root !== "string" || typeof started_at !== "string") return null;
|
|
@@ -13248,7 +13277,7 @@ function removeQuietly(p) {
|
|
|
13248
13277
|
}
|
|
13249
13278
|
}
|
|
13250
13279
|
function ensurePrivateDir(dir, uid) {
|
|
13251
|
-
if (!
|
|
13280
|
+
if (!existsSync9(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
13252
13281
|
const st = lstatSync7(dir);
|
|
13253
13282
|
if (!st.isDirectory()) throw new Error(`${dir} is not a directory`);
|
|
13254
13283
|
if (st.uid !== uid) throw new Error(`${dir} is owned by uid ${st.uid}, not ${uid}; refusing to serve from it`);
|
|
@@ -13445,7 +13474,7 @@ async function stopHookService(paths, expectedRoot) {
|
|
|
13445
13474
|
process.kill(st.pid, "SIGTERM");
|
|
13446
13475
|
} catch {
|
|
13447
13476
|
}
|
|
13448
|
-
const gone = () => !pidAlive2(st.pid) || !
|
|
13477
|
+
const gone = () => !pidAlive2(st.pid) || !existsSync9(paths.socket);
|
|
13449
13478
|
const until = Date.now() + STOP_WAIT_MS;
|
|
13450
13479
|
while (!gone() && Date.now() < until) sleepSync(50);
|
|
13451
13480
|
if (!gone()) throw new Error(`hook service pid ${st.pid} did not exit within ${STOP_WAIT_MS / 1e3}s`);
|
|
@@ -13727,7 +13756,7 @@ var init_safe_write = __esm({
|
|
|
13727
13756
|
// src/cli/init.ts
|
|
13728
13757
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
13729
13758
|
import { createHash as createHash8 } from "node:crypto";
|
|
13730
|
-
import { existsSync as
|
|
13759
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync11, realpathSync as realpathSync5 } from "node:fs";
|
|
13731
13760
|
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, relative as relative4, resolve as resolve6 } from "node:path";
|
|
13732
13761
|
function gitConfig(cwd, key2) {
|
|
13733
13762
|
try {
|
|
@@ -13821,34 +13850,34 @@ function verifierCandidates(cwd) {
|
|
|
13821
13850
|
if (!candidates.includes(command)) candidates.push(command);
|
|
13822
13851
|
};
|
|
13823
13852
|
try {
|
|
13824
|
-
const pkg = JSON.parse(
|
|
13853
|
+
const pkg = JSON.parse(readFileSync11(join15(cwd, "package.json"), "utf8"));
|
|
13825
13854
|
const test = isRecord(pkg) && isRecord(pkg.scripts) ? pkg.scripts.test : void 0;
|
|
13826
13855
|
if (typeof test === "string" && test.trim() !== "" && !/error:\s*no test specified/i.test(test)) add("npm test");
|
|
13827
13856
|
} catch {
|
|
13828
13857
|
}
|
|
13829
13858
|
try {
|
|
13830
|
-
const pyproject =
|
|
13859
|
+
const pyproject = readFileSync11(join15(cwd, "pyproject.toml"), "utf8");
|
|
13831
13860
|
if (/^\s*\[tool\.pytest(?:\.ini_options)?\]\s*$/m.test(pyproject)) add("pytest");
|
|
13832
13861
|
} catch {
|
|
13833
13862
|
}
|
|
13834
|
-
if (
|
|
13863
|
+
if (existsSync10(join15(cwd, "pytest.ini"))) add("pytest");
|
|
13835
13864
|
try {
|
|
13836
|
-
const setupCfg =
|
|
13865
|
+
const setupCfg = readFileSync11(join15(cwd, "setup.cfg"), "utf8");
|
|
13837
13866
|
if (/^\s*\[tool:pytest\]\s*$/m.test(setupCfg)) add("pytest");
|
|
13838
13867
|
} catch {
|
|
13839
13868
|
}
|
|
13840
13869
|
try {
|
|
13841
|
-
const tox =
|
|
13870
|
+
const tox = readFileSync11(join15(cwd, "tox.ini"), "utf8");
|
|
13842
13871
|
if (/^\s*\[tox\]\s*$/m.test(tox)) add("tox");
|
|
13843
13872
|
} catch {
|
|
13844
13873
|
}
|
|
13845
13874
|
try {
|
|
13846
|
-
const cargo =
|
|
13875
|
+
const cargo = readFileSync11(join15(cwd, "Cargo.toml"), "utf8");
|
|
13847
13876
|
if (/^\s*\[(?:package|workspace)\]\s*(?:#.*)?$/m.test(cargo)) add("cargo test");
|
|
13848
13877
|
} catch {
|
|
13849
13878
|
}
|
|
13850
13879
|
try {
|
|
13851
|
-
const goMod =
|
|
13880
|
+
const goMod = readFileSync11(join15(cwd, "go.mod"), "utf8");
|
|
13852
13881
|
if (/^\s*module\s+\S+\s*(?:\/\/.*)?$/m.test(goMod)) add("go test ./...");
|
|
13853
13882
|
} catch {
|
|
13854
13883
|
}
|
|
@@ -13891,7 +13920,7 @@ function planPolicy(cwd) {
|
|
|
13891
13920
|
const path = join15(cwd, POLICY_FILE);
|
|
13892
13921
|
const refused = refuseNonRegular(path);
|
|
13893
13922
|
if (refused) return { item: "policy", path: POLICY_FILE, status: "error", detail: refused };
|
|
13894
|
-
if (
|
|
13923
|
+
if (existsSync10(path)) {
|
|
13895
13924
|
try {
|
|
13896
13925
|
loadPolicy(cwd);
|
|
13897
13926
|
} catch (e) {
|
|
@@ -13910,7 +13939,7 @@ function planPolicy(cwd) {
|
|
|
13910
13939
|
function planGitignore(cwd) {
|
|
13911
13940
|
const rel = ".gitignore";
|
|
13912
13941
|
const path = join15(cwd, rel);
|
|
13913
|
-
if (!
|
|
13942
|
+
if (!existsSync10(join15(cwd, "node_modules"))) return null;
|
|
13914
13943
|
let existing = "";
|
|
13915
13944
|
let kind;
|
|
13916
13945
|
try {
|
|
@@ -13920,7 +13949,7 @@ function planGitignore(cwd) {
|
|
|
13920
13949
|
}
|
|
13921
13950
|
const refused = refuseNonRegular(path);
|
|
13922
13951
|
if (refused) return { item: "gitignore", path: rel, status: "error", detail: refused };
|
|
13923
|
-
if (kind === "file") existing =
|
|
13952
|
+
if (kind === "file") existing = readFileSync11(path, "utf8");
|
|
13924
13953
|
try {
|
|
13925
13954
|
const tracked = execFileSync6("git", ["ls-files", "--cached", "--", "node_modules"], {
|
|
13926
13955
|
cwd,
|
|
@@ -13975,10 +14004,10 @@ function planClaudeHooks(cwd) {
|
|
|
13975
14004
|
const refused = refuseNonRegular(path);
|
|
13976
14005
|
if (refused) return { item: "agent", path: rel, status: "error", detail: refused };
|
|
13977
14006
|
let settings = {};
|
|
13978
|
-
if (
|
|
14007
|
+
if (existsSync10(path)) {
|
|
13979
14008
|
let parsed;
|
|
13980
14009
|
try {
|
|
13981
|
-
parsed = JSON.parse(
|
|
14010
|
+
parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
13982
14011
|
} catch {
|
|
13983
14012
|
return {
|
|
13984
14013
|
item: "agent",
|
|
@@ -14027,7 +14056,7 @@ function planClaudeHooks(cwd) {
|
|
|
14027
14056
|
return {
|
|
14028
14057
|
item: "agent",
|
|
14029
14058
|
path: rel,
|
|
14030
|
-
status:
|
|
14059
|
+
status: existsSync10(path) ? "update" : "create",
|
|
14031
14060
|
detail: [
|
|
14032
14061
|
needPre && "wire PreToolUse deny",
|
|
14033
14062
|
needStop && "wire Stop sweep",
|
|
@@ -14071,7 +14100,7 @@ function hooksDir(cwd) {
|
|
|
14071
14100
|
if (out3) return resolve6(cwd, out3);
|
|
14072
14101
|
} catch {
|
|
14073
14102
|
}
|
|
14074
|
-
return
|
|
14103
|
+
return existsSync10(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
|
|
14075
14104
|
}
|
|
14076
14105
|
function display(cwd, path) {
|
|
14077
14106
|
const rel = relative4(cwd, path);
|
|
@@ -14098,11 +14127,11 @@ function planPreCommit(cwd) {
|
|
|
14098
14127
|
const skip = (detail) => ({ item: "pre-commit", path: "(none)", status: "skip", detail });
|
|
14099
14128
|
let path;
|
|
14100
14129
|
let note;
|
|
14101
|
-
if (
|
|
14130
|
+
if (existsSync10(join15(cwd, ".husky"))) {
|
|
14102
14131
|
path = join15(cwd, ".husky", "pre-commit");
|
|
14103
14132
|
note = "husky";
|
|
14104
14133
|
} else {
|
|
14105
|
-
const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) =>
|
|
14134
|
+
const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync10(join15(cwd, c))));
|
|
14106
14135
|
if (managed) {
|
|
14107
14136
|
return skip(`${managed.name} manages this repository's hooks and regenerates them on install, so a line in the hooks directory would not last \u2014 ${managed.hint}`);
|
|
14108
14137
|
}
|
|
@@ -14120,7 +14149,7 @@ function planPreCommit(cwd) {
|
|
|
14120
14149
|
const rel = display(cwd, path);
|
|
14121
14150
|
const refused = refuseNonRegular(path);
|
|
14122
14151
|
if (refused) return { item: "pre-commit", path: rel, status: "error", detail: refused };
|
|
14123
|
-
const existing =
|
|
14152
|
+
const existing = existsSync10(path) ? readFileSync11(path, "utf8") : null;
|
|
14124
14153
|
const hookMode = () => existingMode(path, 493) | 73;
|
|
14125
14154
|
if (existing === null) {
|
|
14126
14155
|
return {
|
|
@@ -14211,7 +14240,7 @@ function planCodeowners(cwd) {
|
|
|
14211
14240
|
const path = join15(cwd, existingRel ?? rel);
|
|
14212
14241
|
const refused = refuseNonRegular(path);
|
|
14213
14242
|
if (refused) return { item: "codeowners", path: existingRel ?? rel, status: "error", detail: refused };
|
|
14214
|
-
const existing = existingRel ?
|
|
14243
|
+
const existing = existingRel ? readFileSync11(path, "utf8") : null;
|
|
14215
14244
|
const missing = CODEOWNERS_PATHS.filter((p) => existing === null || !coveredBy(existing, p));
|
|
14216
14245
|
if (existingRel !== void 0 && missing.length === 0) {
|
|
14217
14246
|
return { item: "codeowners", path: existingRel, status: "ok", detail: "gate paths already have code owners" };
|
|
@@ -14251,7 +14280,7 @@ function planWorkflow(cwd, force) {
|
|
|
14251
14280
|
};
|
|
14252
14281
|
const refused = refuseNonRegular(path);
|
|
14253
14282
|
if (refused) return { item: "ci", path: rel, status: "error", detail: refused };
|
|
14254
|
-
if (!
|
|
14283
|
+
if (!existsSync10(path)) {
|
|
14255
14284
|
return {
|
|
14256
14285
|
item: "ci",
|
|
14257
14286
|
path: rel,
|
|
@@ -14262,7 +14291,7 @@ function planWorkflow(cwd, force) {
|
|
|
14262
14291
|
}
|
|
14263
14292
|
let src;
|
|
14264
14293
|
try {
|
|
14265
|
-
src =
|
|
14294
|
+
src = readFileSync11(path, "utf8");
|
|
14266
14295
|
} catch {
|
|
14267
14296
|
return { item: "ci", path: rel, status: "error", detail: "exists but cannot be read \u2014 refusing to overwrite" };
|
|
14268
14297
|
}
|
|
@@ -14609,10 +14638,10 @@ var init_fingerprint = __esm({
|
|
|
14609
14638
|
// src/dependency-env.ts
|
|
14610
14639
|
import { createHash as createHash10 } from "node:crypto";
|
|
14611
14640
|
import {
|
|
14612
|
-
existsSync as
|
|
14641
|
+
existsSync as existsSync11,
|
|
14613
14642
|
lstatSync as lstatSync9,
|
|
14614
14643
|
readdirSync as readdirSync3,
|
|
14615
|
-
readFileSync as
|
|
14644
|
+
readFileSync as readFileSync12,
|
|
14616
14645
|
readlinkSync as readlinkSync2,
|
|
14617
14646
|
realpathSync as realpathSync6,
|
|
14618
14647
|
statSync as statSync3
|
|
@@ -14670,7 +14699,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
14670
14699
|
st = statSync3(path);
|
|
14671
14700
|
if (!st.isFile()) throw new Error("not a regular file");
|
|
14672
14701
|
h.update(label + "\0external-file\0" + path + "\0" + String(st.mode) + "\0");
|
|
14673
|
-
h.update(
|
|
14702
|
+
h.update(readFileSync12(path));
|
|
14674
14703
|
h.update("\0");
|
|
14675
14704
|
} catch (e) {
|
|
14676
14705
|
throw new Unattestable(
|
|
@@ -14704,7 +14733,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
14704
14733
|
h.update(rel + "\0" + ident.kind + "\0" + String(ident.mode) + "\0");
|
|
14705
14734
|
if (ident.kind === "file") {
|
|
14706
14735
|
try {
|
|
14707
|
-
h.update(
|
|
14736
|
+
h.update(readFileSync12(path));
|
|
14708
14737
|
h.update("\0");
|
|
14709
14738
|
} catch (e) {
|
|
14710
14739
|
throw new Unattestable(
|
|
@@ -14763,7 +14792,7 @@ function snapshot(roots, probes, cwd) {
|
|
|
14763
14792
|
const h = createHash10("sha256");
|
|
14764
14793
|
for (const probe of probes) {
|
|
14765
14794
|
h.update(
|
|
14766
|
-
"probe\0" + probe.kind + "\0" + probe.path + "\0" + (
|
|
14795
|
+
"probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync11(probe.path) ? "present" : "absent") + "\0"
|
|
14767
14796
|
);
|
|
14768
14797
|
}
|
|
14769
14798
|
for (const root of roots) fingerprintRoot(root, cwd, h);
|
|
@@ -14822,7 +14851,7 @@ function resolveExecutable(token, cwd, env) {
|
|
|
14822
14851
|
if (token.includes("/") || token.includes("\\")) {
|
|
14823
14852
|
const path = isAbsolute10(token) ? token : resolve7(cwd, token);
|
|
14824
14853
|
try {
|
|
14825
|
-
return
|
|
14854
|
+
return existsSync11(path) ? realpathSync6(path) : null;
|
|
14826
14855
|
} catch {
|
|
14827
14856
|
return null;
|
|
14828
14857
|
}
|
|
@@ -14830,7 +14859,7 @@ function resolveExecutable(token, cwd, env) {
|
|
|
14830
14859
|
for (const entry of (env.PATH ?? "").split(delimiter).filter(Boolean)) {
|
|
14831
14860
|
const candidate = resolve7(entry, token);
|
|
14832
14861
|
try {
|
|
14833
|
-
if (
|
|
14862
|
+
if (existsSync11(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
|
|
14834
14863
|
} catch {
|
|
14835
14864
|
}
|
|
14836
14865
|
}
|
|
@@ -14853,7 +14882,7 @@ function inferredVenvFromToken(token, cwd) {
|
|
|
14853
14882
|
const parentName = basename4(parent).toLowerCase();
|
|
14854
14883
|
if (parentName !== "bin" && parentName !== "scripts") return null;
|
|
14855
14884
|
const root = dirname6(parent);
|
|
14856
|
-
return
|
|
14885
|
+
return existsSync11(join16(root, "pyvenv.cfg")) ? root : null;
|
|
14857
14886
|
}
|
|
14858
14887
|
function unsupportedEcosystem(command, token) {
|
|
14859
14888
|
const name = token ? basename4(token).toLowerCase() : "";
|
|
@@ -14869,13 +14898,13 @@ function inferredVenv(executable) {
|
|
|
14869
14898
|
const parentName = basename4(parent).toLowerCase();
|
|
14870
14899
|
if (parentName !== "bin" && parentName !== "scripts") return null;
|
|
14871
14900
|
const root = dirname6(parent);
|
|
14872
|
-
return
|
|
14901
|
+
return existsSync11(join16(root, "pyvenv.cfg")) ? root : null;
|
|
14873
14902
|
}
|
|
14874
14903
|
function venvProblem(root) {
|
|
14875
14904
|
const cfg = join16(root, "pyvenv.cfg");
|
|
14876
|
-
if (!
|
|
14905
|
+
if (!existsSync11(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
|
|
14877
14906
|
try {
|
|
14878
|
-
const body =
|
|
14907
|
+
const body = readFileSync12(cfg, "utf8");
|
|
14879
14908
|
if (/^\s*include-system-site-packages\s*=\s*true\s*$/im.test(body)) {
|
|
14880
14909
|
return "Python environment " + JSON.stringify(root) + " enables system site-packages; those external package roots are not bounded";
|
|
14881
14910
|
}
|
|
@@ -14900,7 +14929,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
|
|
|
14900
14929
|
};
|
|
14901
14930
|
try {
|
|
14902
14931
|
const nodeModules = join16(cwd, "node_modules");
|
|
14903
|
-
if (
|
|
14932
|
+
if (existsSync11(nodeModules)) addRoot("node_modules", nodeModules);
|
|
14904
14933
|
else probes.push({ kind: "node_modules", path: nodeModules });
|
|
14905
14934
|
const token = firstExecutable(command);
|
|
14906
14935
|
const executable = resolveExecutable(token, cwd, env);
|
|
@@ -14912,7 +14941,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
|
|
|
14912
14941
|
venv = resolve7(env.VIRTUAL_ENV);
|
|
14913
14942
|
} else {
|
|
14914
14943
|
venv = inferredVenv(executable) ?? inferredVenvFromToken(token, cwd);
|
|
14915
|
-
if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) &&
|
|
14944
|
+
if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync11(join16(cwd, ".venv", "pyvenv.cfg"))) {
|
|
14916
14945
|
venv = join16(cwd, ".venv");
|
|
14917
14946
|
}
|
|
14918
14947
|
}
|
|
@@ -15391,7 +15420,7 @@ if (child) {
|
|
|
15391
15420
|
// src/verifier-backend.ts
|
|
15392
15421
|
import { createHash as createHash11, randomUUID } from "node:crypto";
|
|
15393
15422
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
15394
|
-
import { accessSync as accessSync2, constants as constants4, readFileSync as
|
|
15423
|
+
import { accessSync as accessSync2, constants as constants4, readFileSync as readFileSync13, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
|
|
15395
15424
|
import { delimiter as delimiter2, dirname as dirname7, join as join18, resolve as resolve8 } from "node:path";
|
|
15396
15425
|
function identity() {
|
|
15397
15426
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -15436,7 +15465,7 @@ function findExecutable(name) {
|
|
|
15436
15465
|
return null;
|
|
15437
15466
|
}
|
|
15438
15467
|
function fileSha256(path) {
|
|
15439
|
-
return createHash11("sha256").update(
|
|
15468
|
+
return createHash11("sha256").update(readFileSync13(path)).digest("hex");
|
|
15440
15469
|
}
|
|
15441
15470
|
function engineClientEnv() {
|
|
15442
15471
|
return {
|
|
@@ -15870,7 +15899,7 @@ var init_verifier_backend = __esm({
|
|
|
15870
15899
|
// src/verification-state.ts
|
|
15871
15900
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
15872
15901
|
import { createHash as createHash12 } from "node:crypto";
|
|
15873
|
-
import { mkdirSync as mkdirSync8, readFileSync as
|
|
15902
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync14, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
15874
15903
|
import { dirname as dirname8, join as join19 } from "node:path";
|
|
15875
15904
|
function git2(args, cwd) {
|
|
15876
15905
|
return execFileSync8("git", args, {
|
|
@@ -15929,7 +15958,7 @@ function interventionWiring(cwd) {
|
|
|
15929
15958
|
return sources.map(([source, path]) => {
|
|
15930
15959
|
let parsed;
|
|
15931
15960
|
try {
|
|
15932
|
-
parsed = JSON.parse(
|
|
15961
|
+
parsed = JSON.parse(readFileSync14(path, "utf8"));
|
|
15933
15962
|
} catch {
|
|
15934
15963
|
return { source, present: false };
|
|
15935
15964
|
}
|
|
@@ -16082,7 +16111,7 @@ function readVerificationRecord(cwd) {
|
|
|
16082
16111
|
if (!path) return null;
|
|
16083
16112
|
let raw;
|
|
16084
16113
|
try {
|
|
16085
|
-
raw =
|
|
16114
|
+
raw = readFileSync14(path, "utf8");
|
|
16086
16115
|
} catch {
|
|
16087
16116
|
return null;
|
|
16088
16117
|
}
|
|
@@ -16131,7 +16160,7 @@ function readVerifyingMarker(cwd) {
|
|
|
16131
16160
|
if (!path) return null;
|
|
16132
16161
|
let parsed;
|
|
16133
16162
|
try {
|
|
16134
|
-
parsed = JSON.parse(
|
|
16163
|
+
parsed = JSON.parse(readFileSync14(path, "utf8"));
|
|
16135
16164
|
} catch {
|
|
16136
16165
|
return null;
|
|
16137
16166
|
}
|
|
@@ -16495,7 +16524,7 @@ var init_verification_receipt = __esm({
|
|
|
16495
16524
|
// src/cli/verify.ts
|
|
16496
16525
|
import { execFileSync as execFileSync9, spawnSync as spawnSync3 } from "node:child_process";
|
|
16497
16526
|
import { createHash as createHash14 } from "node:crypto";
|
|
16498
|
-
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as
|
|
16527
|
+
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as readFileSync15, readlinkSync as readlinkSync3, rmSync as rmSync9, symlinkSync, writeFileSync as writeFileSync11, existsSync as existsSync12 } from "node:fs";
|
|
16499
16528
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
16500
16529
|
import { dirname as dirname10, isAbsolute as isAbsolute11, join as join21, relative as relative6, resolve as resolve9, sep as sep4 } from "node:path";
|
|
16501
16530
|
function oracleAssuranceReport() {
|
|
@@ -16691,7 +16720,7 @@ function probeFilesystemCaseSensitivity(dir) {
|
|
|
16691
16720
|
const lower = join21(dir, ".tw-case-probe-a");
|
|
16692
16721
|
try {
|
|
16693
16722
|
writeFileSync11(upper, "", { flag: "wx" });
|
|
16694
|
-
return !
|
|
16723
|
+
return !existsSync12(lower);
|
|
16695
16724
|
} finally {
|
|
16696
16725
|
rmSync9(upper, { force: true });
|
|
16697
16726
|
}
|
|
@@ -16755,7 +16784,7 @@ function overlayDigest(dest, paths) {
|
|
|
16755
16784
|
try {
|
|
16756
16785
|
const st = lstatSync10(p);
|
|
16757
16786
|
h.update(String(st.mode));
|
|
16758
|
-
h.update(st.isSymbolicLink() ? readlinkSync3(p) :
|
|
16787
|
+
h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync15(p));
|
|
16759
16788
|
} catch {
|
|
16760
16789
|
h.update("<gone>");
|
|
16761
16790
|
}
|
|
@@ -17350,8 +17379,13 @@ function runVerifyImpl(opts) {
|
|
|
17350
17379
|
} catch {
|
|
17351
17380
|
}
|
|
17352
17381
|
}
|
|
17353
|
-
const
|
|
17382
|
+
const oob = oobFromEnv();
|
|
17383
|
+
const oobHead = oobHeadFromEnv();
|
|
17384
|
+
const signedOff = verdict2 === "MASKED_FAILURE" ? oobToken("verify", oob, oobHead) : null;
|
|
17354
17385
|
if (signedOff) code2 = 0;
|
|
17386
|
+
const headProblem = verdict2 === "MASKED_FAILURE" && oob.length > 0 ? oobHeadProblem(oobHead) : null;
|
|
17387
|
+
if (headProblem) process.stderr.write(`tamperward: ${headProblem}
|
|
17388
|
+
`);
|
|
17355
17389
|
if (opts.json) {
|
|
17356
17390
|
out3(
|
|
17357
17391
|
JSON.stringify({
|
|
@@ -17564,7 +17598,7 @@ var init_verify = __esm({
|
|
|
17564
17598
|
// src/cli/run.ts
|
|
17565
17599
|
import { execFileSync as execFileSync10, spawn, spawnSync as spawnSync4 } from "node:child_process";
|
|
17566
17600
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
17567
|
-
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as
|
|
17601
|
+
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync16, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as rmSync10, statSync as statSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
17568
17602
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
17569
17603
|
import { dirname as dirname11, join as join22, resolve as resolve10 } from "node:path";
|
|
17570
17604
|
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
@@ -17718,7 +17752,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
|
|
|
17718
17752
|
}
|
|
17719
17753
|
let state = {};
|
|
17720
17754
|
try {
|
|
17721
|
-
state = JSON.parse(
|
|
17755
|
+
state = JSON.parse(readFileSync16(resultFile, "utf8"));
|
|
17722
17756
|
} catch {
|
|
17723
17757
|
return {
|
|
17724
17758
|
exit: 1,
|
|
@@ -17762,7 +17796,7 @@ function observerExited(pid) {
|
|
|
17762
17796
|
if (!pidAlive4(pid)) return true;
|
|
17763
17797
|
if (process.platform !== "linux") return false;
|
|
17764
17798
|
try {
|
|
17765
|
-
const stat =
|
|
17799
|
+
const stat = readFileSync16(`/proc/${pid}/stat`, "utf8");
|
|
17766
17800
|
const state = stat.slice(stat.lastIndexOf(")") + 2).split(" ")[0];
|
|
17767
17801
|
return state === "Z" || state === "X";
|
|
17768
17802
|
} catch (e) {
|
|
@@ -17884,7 +17918,7 @@ function git4(args, cwd) {
|
|
|
17884
17918
|
}
|
|
17885
17919
|
function nowTicks() {
|
|
17886
17920
|
try {
|
|
17887
|
-
return Math.floor(parseFloat(
|
|
17921
|
+
return Math.floor(parseFloat(readFileSync16("/proc/uptime", "utf8").split(" ")[0]) * 100);
|
|
17888
17922
|
} catch {
|
|
17889
17923
|
return Number.POSITIVE_INFINITY;
|
|
17890
17924
|
}
|
|
@@ -17907,7 +17941,7 @@ function survivorsHoldingTree(cwd, spawnedAfterTicks) {
|
|
|
17907
17941
|
const n2 = Number(pid);
|
|
17908
17942
|
if (n2 === process.pid) continue;
|
|
17909
17943
|
try {
|
|
17910
|
-
const stat =
|
|
17944
|
+
const stat = readFileSync16(`/proc/${pid}/stat`, "utf8");
|
|
17911
17945
|
const startTicks = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19]);
|
|
17912
17946
|
if (!Number.isFinite(startTicks) || startTicks < spawnedAfterTicks) continue;
|
|
17913
17947
|
} catch {
|
|
@@ -18480,7 +18514,7 @@ raise SystemExit(0)
|
|
|
18480
18514
|
|
|
18481
18515
|
// src/cli/doctor.ts
|
|
18482
18516
|
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
18483
|
-
import { existsSync as
|
|
18517
|
+
import { existsSync as existsSync13, readFileSync as readFileSync17, readdirSync as readdirSync5 } from "node:fs";
|
|
18484
18518
|
import { join as join23, resolve as resolve11 } from "node:path";
|
|
18485
18519
|
function lifecyclePlatformCheck(platform = process.platform, linuxPython = platform === "linux" ? trustedLinuxPython() : null) {
|
|
18486
18520
|
if (platform === "linux") {
|
|
@@ -18536,10 +18570,10 @@ function wiringState(status, authority) {
|
|
|
18536
18570
|
return authority ? "BROKEN" : "WARN";
|
|
18537
18571
|
}
|
|
18538
18572
|
function pinsInFile(path) {
|
|
18539
|
-
if (!
|
|
18573
|
+
if (!existsSync13(path)) return [];
|
|
18540
18574
|
let src = "";
|
|
18541
18575
|
try {
|
|
18542
|
-
src =
|
|
18576
|
+
src = readFileSync17(path, "utf8");
|
|
18543
18577
|
} catch {
|
|
18544
18578
|
return [];
|
|
18545
18579
|
}
|
|
@@ -18560,13 +18594,13 @@ function workflowPermissionCheck(cwd, workflowRels = [".github/workflows/tamperw
|
|
|
18560
18594
|
const warnings = [];
|
|
18561
18595
|
for (const rel of workflowRels) {
|
|
18562
18596
|
const path = resolve11(cwd, rel);
|
|
18563
|
-
if (!
|
|
18597
|
+
if (!existsSync13(path)) {
|
|
18564
18598
|
broken.push(`${rel} is missing`);
|
|
18565
18599
|
continue;
|
|
18566
18600
|
}
|
|
18567
18601
|
let doc;
|
|
18568
18602
|
try {
|
|
18569
|
-
doc = yaml.parse(
|
|
18603
|
+
doc = yaml.parse(readFileSync17(path, "utf8"));
|
|
18570
18604
|
} catch (e) {
|
|
18571
18605
|
broken.push(`${rel} is not valid YAML (${e instanceof Error ? e.message : String(e)})`);
|
|
18572
18606
|
continue;
|
|
@@ -18965,7 +18999,7 @@ function diagnose(opts = {}) {
|
|
|
18965
18999
|
} else {
|
|
18966
19000
|
const workflowDirRel = ".github/workflows";
|
|
18967
19001
|
const workflowDir = resolve11(cwd, workflowDirRel);
|
|
18968
|
-
if (!
|
|
19002
|
+
if (!existsSync13(workflowDir)) {
|
|
18969
19003
|
return fail("ci-verifier", `${workflowDirRel}: workflow directory does not exist`);
|
|
18970
19004
|
}
|
|
18971
19005
|
let entries;
|
|
@@ -18985,12 +19019,12 @@ function diagnose(opts = {}) {
|
|
|
18985
19019
|
const authorityWorkflows = [];
|
|
18986
19020
|
for (const workflowRel of workflowRels) {
|
|
18987
19021
|
const workflowPath = resolve11(cwd, workflowRel);
|
|
18988
|
-
if (!
|
|
19022
|
+
if (!existsSync13(workflowPath)) {
|
|
18989
19023
|
return fail("ci-verifier", `${workflowRel}: workflow does not exist`);
|
|
18990
19024
|
}
|
|
18991
19025
|
let doc;
|
|
18992
19026
|
try {
|
|
18993
|
-
doc = yaml.parse(
|
|
19027
|
+
doc = yaml.parse(readFileSync17(workflowPath, "utf8"));
|
|
18994
19028
|
} catch (e) {
|
|
18995
19029
|
return fail(
|
|
18996
19030
|
"ci-verifier",
|
|
@@ -19301,9 +19335,9 @@ var init_status2 = __esm({
|
|
|
19301
19335
|
// src/cli/trace-verify.ts
|
|
19302
19336
|
import { execFileSync as execFileSync12, spawnSync as spawnSync5 } from "node:child_process";
|
|
19303
19337
|
import {
|
|
19304
|
-
existsSync as
|
|
19338
|
+
existsSync as existsSync14,
|
|
19305
19339
|
mkdtempSync as mkdtempSync5,
|
|
19306
|
-
readFileSync as
|
|
19340
|
+
readFileSync as readFileSync18,
|
|
19307
19341
|
readdirSync as readdirSync6,
|
|
19308
19342
|
realpathSync as realpathSync9,
|
|
19309
19343
|
rmSync as rmSync11,
|
|
@@ -19560,7 +19594,7 @@ function materializeBase(base, cwd, dest) {
|
|
|
19560
19594
|
}
|
|
19561
19595
|
const hostModules = join24(cwd, "node_modules");
|
|
19562
19596
|
const tracedModules = join24(dest, "node_modules");
|
|
19563
|
-
if (
|
|
19597
|
+
if (existsSync14(hostModules) && !existsSync14(tracedModules)) {
|
|
19564
19598
|
symlinkSync2(resolve12(hostModules), tracedModules, "dir");
|
|
19565
19599
|
}
|
|
19566
19600
|
}
|
|
@@ -19617,7 +19651,7 @@ function straceOnce(root, command, budget) {
|
|
|
19617
19651
|
}
|
|
19618
19652
|
);
|
|
19619
19653
|
const logs = traced.error ? [] : traceFiles(prefix);
|
|
19620
|
-
const accesses = logs.flatMap((path) => parseStraceFileAccess(
|
|
19654
|
+
const accesses = logs.flatMap((path) => parseStraceFileAccess(readFileSync18(path, "utf8"), TRACE_ROOT));
|
|
19621
19655
|
const raw = {
|
|
19622
19656
|
spawnError: traced.error ? traced.error.message : null,
|
|
19623
19657
|
status: traced.status,
|
|
@@ -19872,7 +19906,7 @@ var init_immutable = __esm({
|
|
|
19872
19906
|
});
|
|
19873
19907
|
|
|
19874
19908
|
// src/runtimes.ts
|
|
19875
|
-
import { existsSync as
|
|
19909
|
+
import { existsSync as existsSync15, readFileSync as readFileSync19 } from "node:fs";
|
|
19876
19910
|
import { join as join25 } from "node:path";
|
|
19877
19911
|
function isRecord6(x) {
|
|
19878
19912
|
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
@@ -19902,8 +19936,8 @@ function claudeSettingsBeyondTamperward(cwd) {
|
|
|
19902
19936
|
const path = join25(cwd, ".claude", "settings.json");
|
|
19903
19937
|
let raw;
|
|
19904
19938
|
try {
|
|
19905
|
-
if (!
|
|
19906
|
-
raw =
|
|
19939
|
+
if (!existsSync15(path)) return false;
|
|
19940
|
+
raw = readFileSync19(path, "utf8");
|
|
19907
19941
|
} catch {
|
|
19908
19942
|
return false;
|
|
19909
19943
|
}
|
|
@@ -19929,7 +19963,7 @@ function detectRuntimes(cwd) {
|
|
|
19929
19963
|
for (const rt of KNOWN_RUNTIMES) {
|
|
19930
19964
|
const marker = rt.markers.find((m) => {
|
|
19931
19965
|
try {
|
|
19932
|
-
return
|
|
19966
|
+
return existsSync15(join25(cwd, m));
|
|
19933
19967
|
} catch {
|
|
19934
19968
|
return false;
|
|
19935
19969
|
}
|
|
@@ -20954,7 +20988,7 @@ var init_adapter3 = __esm({
|
|
|
20954
20988
|
|
|
20955
20989
|
// src/adapters/copilot-sdk/changes.ts
|
|
20956
20990
|
import { execFileSync as execFileSync13 } from "node:child_process";
|
|
20957
|
-
import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as
|
|
20991
|
+
import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as readFileSync20, rmSync as rmSync12, existsSync as existsSync16, realpathSync as realpathSync10 } from "node:fs";
|
|
20958
20992
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
20959
20993
|
import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute16, relative as relative11, resolve as resolve15, join as join26 } from "node:path";
|
|
20960
20994
|
function asStr4(v) {
|
|
@@ -20973,7 +21007,7 @@ function canonicalContainedTarget(abs, root) {
|
|
|
20973
21007
|
}
|
|
20974
21008
|
let dir = abs;
|
|
20975
21009
|
const tail = [];
|
|
20976
|
-
while (!
|
|
21010
|
+
while (!existsSync16(dir)) {
|
|
20977
21011
|
const parent = dirname12(dir);
|
|
20978
21012
|
if (parent === dir) break;
|
|
20979
21013
|
tail.unshift(basename5(dir));
|
|
@@ -21048,7 +21082,7 @@ function reconstructAfterViaGit(rawDiff, display2, before, isCreate) {
|
|
|
21048
21082
|
if (statPath !== TARGET) throw new Error(`write diff reconstructs a different file (${statPath}) than the bound target`);
|
|
21049
21083
|
git8(["--check"]);
|
|
21050
21084
|
git8([]);
|
|
21051
|
-
return op === "delete" ? null :
|
|
21085
|
+
return op === "delete" ? null : readFileSync20(targetPath, "utf8");
|
|
21052
21086
|
} catch (e) {
|
|
21053
21087
|
throw new Error(`could not reconstruct the write to ${display2} from its diff via git apply: ${e instanceof Error ? e.message : String(e)}`);
|
|
21054
21088
|
} finally {
|
|
@@ -21801,7 +21835,7 @@ var init_runtime_qualification = __esm({
|
|
|
21801
21835
|
|
|
21802
21836
|
// src/cli/runtime.ts
|
|
21803
21837
|
import { execFileSync as execFileSync14 } from "node:child_process";
|
|
21804
|
-
import { existsSync as
|
|
21838
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync14 } from "node:fs";
|
|
21805
21839
|
import { join as join27, dirname as dirname13 } from "node:path";
|
|
21806
21840
|
function storePath(cwd) {
|
|
21807
21841
|
const dir = gitDir(cwd);
|
|
@@ -21809,9 +21843,9 @@ function storePath(cwd) {
|
|
|
21809
21843
|
}
|
|
21810
21844
|
function readStore(cwd) {
|
|
21811
21845
|
const path = storePath(cwd);
|
|
21812
|
-
if (!path || !
|
|
21846
|
+
if (!path || !existsSync17(path)) return null;
|
|
21813
21847
|
try {
|
|
21814
|
-
const parsed = JSON.parse(
|
|
21848
|
+
const parsed = JSON.parse(readFileSync21(path, "utf8"));
|
|
21815
21849
|
if (parsed && typeof parsed === "object" && parsed.records && typeof parsed.records === "object") return parsed;
|
|
21816
21850
|
} catch {
|
|
21817
21851
|
return null;
|
|
@@ -21980,9 +22014,9 @@ function resolveHookConfigHash(canonicalId, cwd) {
|
|
|
21980
22014
|
"github-copilot-cli": join27(cwd, ".github", "hooks", "tamperward.json")
|
|
21981
22015
|
};
|
|
21982
22016
|
const file = files[canonicalId];
|
|
21983
|
-
if (!file || !
|
|
22017
|
+
if (!file || !existsSync17(file)) return null;
|
|
21984
22018
|
try {
|
|
21985
|
-
const raw =
|
|
22019
|
+
const raw = readFileSync21(file, "utf8");
|
|
21986
22020
|
let hooks = raw;
|
|
21987
22021
|
try {
|
|
21988
22022
|
const parsed = JSON.parse(raw);
|
|
@@ -22261,7 +22295,7 @@ var init_runtime = __esm({
|
|
|
22261
22295
|
|
|
22262
22296
|
// src/cli/onboard.ts
|
|
22263
22297
|
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
22264
|
-
import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as
|
|
22298
|
+
import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as readFileSync22, realpathSync as realpathSync11, rmSync as rmSync13 } from "node:fs";
|
|
22265
22299
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
22266
22300
|
import { join as join28, relative as relative12, resolve as resolve16, sep as sep6 } from "node:path";
|
|
22267
22301
|
import { createInterface } from "node:readline";
|
|
@@ -22334,7 +22368,7 @@ function writeVerifyCommand(cwd, command) {
|
|
|
22334
22368
|
return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
|
|
22335
22369
|
}
|
|
22336
22370
|
const mode = existingMode(path, 420);
|
|
22337
|
-
const original = kind === "file" ?
|
|
22371
|
+
const original = kind === "file" ? readFileSync22(path, "utf8") : null;
|
|
22338
22372
|
let next;
|
|
22339
22373
|
try {
|
|
22340
22374
|
const doc = parseDocument(original && original.trim() ? original : "version: 1\n");
|
|
@@ -22989,7 +23023,7 @@ var init_capture = __esm({
|
|
|
22989
23023
|
|
|
22990
23024
|
// src/research/manifest.ts
|
|
22991
23025
|
import { createHash as createHash16 } from "node:crypto";
|
|
22992
|
-
import { readFileSync as
|
|
23026
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
22993
23027
|
import { dirname as dirname14, resolve as resolve18 } from "node:path";
|
|
22994
23028
|
function taskFrom(raw, index, manifestDir) {
|
|
22995
23029
|
const where = `task #${index + 1}`;
|
|
@@ -23023,7 +23057,7 @@ function readManifest(path) {
|
|
|
23023
23057
|
const abs = resolve18(path);
|
|
23024
23058
|
let bytes;
|
|
23025
23059
|
try {
|
|
23026
|
-
bytes =
|
|
23060
|
+
bytes = readFileSync23(abs);
|
|
23027
23061
|
} catch (e) {
|
|
23028
23062
|
throw new ResearchError(`cannot read task manifest ${abs}: ${e instanceof Error ? e.message : String(e)}`);
|
|
23029
23063
|
}
|
|
@@ -23442,7 +23476,7 @@ var init_record = __esm({
|
|
|
23442
23476
|
// src/research/run.ts
|
|
23443
23477
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
23444
23478
|
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
23445
|
-
import { closeSync as closeSync5, existsSync as
|
|
23479
|
+
import { closeSync as closeSync5, existsSync as existsSync18, linkSync, mkdirSync as mkdirSync12, openSync as openSync5, readFileSync as readFileSync24, renameSync as renameSync4, rmSync as rmSync14, unlinkSync, writeFileSync as writeFileSync15, writeSync } from "node:fs";
|
|
23446
23480
|
import { hostname } from "node:os";
|
|
23447
23481
|
import { join as join29, resolve as resolve19 } from "node:path";
|
|
23448
23482
|
function git7(args, cwd) {
|
|
@@ -23456,7 +23490,7 @@ function researchLockPath(ledger) {
|
|
|
23456
23490
|
}
|
|
23457
23491
|
function readLockOwner(path) {
|
|
23458
23492
|
try {
|
|
23459
|
-
const parsed = JSON.parse(
|
|
23493
|
+
const parsed = JSON.parse(readFileSync24(path, "utf8"));
|
|
23460
23494
|
if (!isRecord(parsed) || typeof parsed.pid !== "number" || !Number.isInteger(parsed.pid) || parsed.pid <= 0) return null;
|
|
23461
23495
|
if (typeof parsed.host !== "string" || typeof parsed.started_at !== "string" || typeof parsed.token !== "string") return null;
|
|
23462
23496
|
return { pid: parsed.pid, host: parsed.host, started_at: parsed.started_at, token: parsed.token };
|
|
@@ -23479,7 +23513,7 @@ function lockHolder(path) {
|
|
|
23479
23513
|
function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
23480
23514
|
mkdirSync12(ledger, { recursive: true });
|
|
23481
23515
|
const path = researchLockPath(ledger);
|
|
23482
|
-
if (breakStaleLock &&
|
|
23516
|
+
if (breakStaleLock && existsSync18(path)) {
|
|
23483
23517
|
const owner2 = readLockOwner(path);
|
|
23484
23518
|
if (!owner2) {
|
|
23485
23519
|
throw new ResearchError(`research output ${ledger} has an unreadable lock at ${path}; verify no run is active, then remove it deliberately`);
|
|
@@ -23541,7 +23575,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
|
23541
23575
|
if (released) return;
|
|
23542
23576
|
released = true;
|
|
23543
23577
|
try {
|
|
23544
|
-
if (
|
|
23578
|
+
if (readFileSync24(path, "utf8") === text) unlinkSync(path);
|
|
23545
23579
|
} catch {
|
|
23546
23580
|
}
|
|
23547
23581
|
}
|
|
@@ -23550,7 +23584,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
|
23550
23584
|
function resumableRecord(path, expected) {
|
|
23551
23585
|
let raw;
|
|
23552
23586
|
try {
|
|
23553
|
-
raw = JSON.parse(
|
|
23587
|
+
raw = JSON.parse(readFileSync24(path, "utf8"));
|
|
23554
23588
|
} catch (e) {
|
|
23555
23589
|
throw new ResearchError(`ledger record ${path} is malformed (${errorMessage(e).split("\n")[0]}); remove it to regenerate the pair, or use a new --out`);
|
|
23556
23590
|
}
|
|
@@ -23852,7 +23886,7 @@ function runResearch(opts) {
|
|
|
23852
23886
|
try {
|
|
23853
23887
|
for (let pair = 1; pair <= pairs; pair++) {
|
|
23854
23888
|
const path = pairRecordPath(ledger, task.id, pair);
|
|
23855
|
-
if (!
|
|
23889
|
+
if (!existsSync18(path)) continue;
|
|
23856
23890
|
const existing = resumableRecord(path, {
|
|
23857
23891
|
task: task.id,
|
|
23858
23892
|
pair,
|
|
@@ -23972,7 +24006,7 @@ var init_run2 = __esm({
|
|
|
23972
24006
|
});
|
|
23973
24007
|
|
|
23974
24008
|
// src/research/ledger-files.ts
|
|
23975
|
-
import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as
|
|
24009
|
+
import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as readFileSync25, readdirSync as readdirSync7, realpathSync as realpathSync12 } from "node:fs";
|
|
23976
24010
|
import { join as join30, resolve as resolve20 } from "node:path";
|
|
23977
24011
|
function lstatOrNull(path) {
|
|
23978
24012
|
try {
|
|
@@ -24015,7 +24049,7 @@ function readRegularFile(path, realPairsDir, name) {
|
|
|
24015
24049
|
if (!opened.isFile() || !sameInode || opened.nlink !== 1) {
|
|
24016
24050
|
throw new ResearchError(`ledger record ${path} changed between listing and reading; refusing to read it`);
|
|
24017
24051
|
}
|
|
24018
|
-
return
|
|
24052
|
+
return readFileSync25(fd);
|
|
24019
24053
|
} finally {
|
|
24020
24054
|
closeSync6(fd);
|
|
24021
24055
|
}
|
|
@@ -24188,7 +24222,7 @@ var init_summarize = __esm({
|
|
|
24188
24222
|
|
|
24189
24223
|
// src/research/init.ts
|
|
24190
24224
|
import { createHash as createHash17 } from "node:crypto";
|
|
24191
|
-
import { existsSync as
|
|
24225
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync13, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "node:fs";
|
|
24192
24226
|
import { basename as basename6, dirname as dirname15, resolve as resolve21 } from "node:path";
|
|
24193
24227
|
function idFrom(repo) {
|
|
24194
24228
|
const clean = repo.replace(/[\\/]$/, "").split(/[\\/]/).pop() || "task";
|
|
@@ -24200,7 +24234,7 @@ function createResearchManifest(opts) {
|
|
|
24200
24234
|
if (!opts.prompt) throw new ResearchError("research init requires --prompt");
|
|
24201
24235
|
if (!opts.verifyCommand) throw new ResearchError("research init requires --verify-command");
|
|
24202
24236
|
const out3 = resolve21(opts.out);
|
|
24203
|
-
if (
|
|
24237
|
+
if (existsSync19(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
|
|
24204
24238
|
const id = opts.id ?? idFrom(opts.repo);
|
|
24205
24239
|
if (!/^[A-Za-z0-9._-]+$/.test(id)) throw new ResearchError(`research init id must match [A-Za-z0-9._-] (got "${id}")`);
|
|
24206
24240
|
if (opts.verifyBudget !== void 0 && (!Number.isFinite(opts.verifyBudget) || opts.verifyBudget <= 0)) {
|
|
@@ -24240,7 +24274,7 @@ function runResearchInit(opts) {
|
|
|
24240
24274
|
}
|
|
24241
24275
|
}
|
|
24242
24276
|
function requireHash(path) {
|
|
24243
|
-
return createHash17("sha256").update(
|
|
24277
|
+
return createHash17("sha256").update(readFileSync26(path)).digest("hex");
|
|
24244
24278
|
}
|
|
24245
24279
|
var init_init2 = __esm({
|
|
24246
24280
|
"src/research/init.ts"() {
|
|
@@ -24308,7 +24342,7 @@ var init_report2 = __esm({
|
|
|
24308
24342
|
import { createHash as createHash18 } from "node:crypto";
|
|
24309
24343
|
import { isDeepStrictEqual } from "node:util";
|
|
24310
24344
|
import { gzipSync, gunzipSync } from "node:zlib";
|
|
24311
|
-
import { mkdirSync as mkdirSync14, readFileSync as
|
|
24345
|
+
import { mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync17 } from "node:fs";
|
|
24312
24346
|
import { dirname as dirname16, resolve as resolve22 } from "node:path";
|
|
24313
24347
|
function octal(value, width) {
|
|
24314
24348
|
return value.toString(8).padStart(width - 1, "0") + "\0";
|
|
@@ -24414,7 +24448,7 @@ function jsonBytes(value) {
|
|
|
24414
24448
|
function validateResearchBundle(path) {
|
|
24415
24449
|
let files;
|
|
24416
24450
|
try {
|
|
24417
|
-
files = parseTar(gunzipSync(
|
|
24451
|
+
files = parseTar(gunzipSync(readFileSync27(resolve22(path))));
|
|
24418
24452
|
} catch (e) {
|
|
24419
24453
|
throw new ResearchError(`cannot read research bundle ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
24420
24454
|
}
|
|
@@ -24484,7 +24518,7 @@ function createResearchBundle(opts) {
|
|
|
24484
24518
|
const { records, entries } = packagedRecords(ledger);
|
|
24485
24519
|
const summary = summarizeRecords(records);
|
|
24486
24520
|
if (opts.manifest) {
|
|
24487
|
-
const manifest =
|
|
24521
|
+
const manifest = readFileSync27(resolve22(opts.manifest));
|
|
24488
24522
|
const sha3 = createHash18("sha256").update(manifest).digest("hex");
|
|
24489
24523
|
if (sha3 !== summary.manifest_sha256) throw new ResearchError(`manifest sha256 ${sha3} does not match ledger ${summary.manifest_sha256}`);
|
|
24490
24524
|
entries.push({ name: "manifest.json", bytes: manifest });
|
|
@@ -24655,7 +24689,7 @@ var init_research = __esm({
|
|
|
24655
24689
|
});
|
|
24656
24690
|
|
|
24657
24691
|
// src/cli/receipt.ts
|
|
24658
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
24692
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync28, writeFileSync as writeFileSync18 } from "node:fs";
|
|
24659
24693
|
function parseReceipt(args) {
|
|
24660
24694
|
const [sub, ...rest] = args;
|
|
24661
24695
|
const exportOpts = {};
|
|
@@ -24782,7 +24816,7 @@ function ciAdjudicate(cwd, opts) {
|
|
|
24782
24816
|
if (opts.ciResult !== void 0) {
|
|
24783
24817
|
let doc;
|
|
24784
24818
|
try {
|
|
24785
|
-
doc = JSON.parse(
|
|
24819
|
+
doc = JSON.parse(readFileSync28(opts.ciResult, "utf8"));
|
|
24786
24820
|
} catch (e) {
|
|
24787
24821
|
return {
|
|
24788
24822
|
ci: { verdict: "CANNOT_VERIFY", binding, binding_error: `unreadable CI verify result: ${e instanceof Error ? e.message : String(e)}` },
|
|
@@ -24793,7 +24827,12 @@ function ciAdjudicate(cwd, opts) {
|
|
|
24793
24827
|
if (check2.reason !== void 0) {
|
|
24794
24828
|
return { ci: { verdict: "CANNOT_VERIFY", binding, binding_error: check2.reason }, exit: 2 };
|
|
24795
24829
|
}
|
|
24796
|
-
const
|
|
24830
|
+
const oob = oobFromEnv();
|
|
24831
|
+
const oobHead = oobHeadFromEnv();
|
|
24832
|
+
const signedOff = check2.verdict === "MASKED_FAILURE" && oobToken("verify", oob, oobHead) !== null;
|
|
24833
|
+
const headProblem = check2.verdict === "MASKED_FAILURE" && oob.length > 0 ? oobHeadProblem(oobHead) : null;
|
|
24834
|
+
if (headProblem) process.stderr.write(`tamperward: ${headProblem}
|
|
24835
|
+
`);
|
|
24797
24836
|
return {
|
|
24798
24837
|
ci: {
|
|
24799
24838
|
verdict: check2.verdict,
|
|
@@ -24923,7 +24962,7 @@ function loadClaimedReceipt(path) {
|
|
|
24923
24962
|
}
|
|
24924
24963
|
let raw;
|
|
24925
24964
|
try {
|
|
24926
|
-
raw =
|
|
24965
|
+
raw = readFileSync28(path, "utf8");
|
|
24927
24966
|
} catch (e) {
|
|
24928
24967
|
return { disposition: "MALFORMED", detail: `receipt file could not be read (${e instanceof Error ? e.message : String(e)})` };
|
|
24929
24968
|
}
|
|
@@ -25784,7 +25823,7 @@ var init_main = __esm({
|
|
|
25784
25823
|
// src/cli/index.ts
|
|
25785
25824
|
init_hook_client();
|
|
25786
25825
|
init_exit();
|
|
25787
|
-
import { readFileSync as
|
|
25826
|
+
import { readFileSync as readFileSync29 } from "node:fs";
|
|
25788
25827
|
function loadMain() {
|
|
25789
25828
|
return Promise.resolve().then(() => (init_main(), main_exports));
|
|
25790
25829
|
}
|
|
@@ -25797,7 +25836,7 @@ async function launch(argv) {
|
|
|
25797
25836
|
if (kind && hookServiceEnabled()) {
|
|
25798
25837
|
let raw = null;
|
|
25799
25838
|
try {
|
|
25800
|
-
raw =
|
|
25839
|
+
raw = readFileSync29(0, "utf8");
|
|
25801
25840
|
} catch {
|
|
25802
25841
|
raw = null;
|
|
25803
25842
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.9",
|
|
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",
|