tamperward 2.13.3 → 2.14.1
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/README.md +10 -1
- package/dist/cli/index.js +179 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,6 +158,15 @@ This distinguishes “healthy observer, zero events” from “observer telemetr
|
|
|
158
158
|
unavailable” without turning absence of watcher telemetry into an enforcement pass
|
|
159
159
|
or failure.
|
|
160
160
|
|
|
161
|
+
Since **2.14.0**, `tamperward run --observe-transients -- <agent...>` can supervise
|
|
162
|
+
that observer as part of the envelope lifecycle. It creates a unique session log under
|
|
163
|
+
the repository git directory, pins the watcher's protected-path policy to the same
|
|
164
|
+
trusted base used by the envelope, waits for observer health before launching the
|
|
165
|
+
agent, consumes the temporal events itself after the agent exits, and shuts the
|
|
166
|
+
observer down deterministically. Observer health remains advisory; transient findings
|
|
167
|
+
remain warnings by default and affect the envelope only when the operator explicitly
|
|
168
|
+
sets `TAMPERWARD_TRANSIENT=block`.
|
|
169
|
+
|
|
161
170
|
After the runtime exits its exit code is treated as untrusted, and the envelope
|
|
162
171
|
checks that post-agent `HEAD` still descends from the entry commit; the committed
|
|
163
172
|
changes over `entry...HEAD`; staged, unstaged and untracked non-ignored worktree
|
|
@@ -356,7 +365,7 @@ option can never be reinterpreted as the agent command.
|
|
|
356
365
|
| `check` | one view — `--staged` · `--worktree` · `--diff <base>...<head>` — plus `--format text\|json\|github\|auto` (default `auto`) · `--json` (alias for `--format json`) · `--cwd <dir>` |
|
|
357
366
|
| `verify` | `--base <rev>` (default `HEAD`) · `--cmd <suite command>` · `--budget <seconds>` · `--json` · `--keep` (keep the two materialised copies and report their paths) · `--require-ancestor` (refuse a base that is not an ancestor of `HEAD`) · `--cwd <dir>` |
|
|
358
367
|
| `doctor` | `--base <rev>` (trusted policy revision) · `--workflow <path>` (default `.github/workflows/tamperward.yml`) · `--cwd <dir>` — validates every job that runs `tamperward verify` has a static outer timeout covering visible + pristine + authority reserve |
|
|
359
|
-
| `run` | `--base <rev>` · `--cmd <suite command>` · `--budget <seconds>` (per verifier suite) · `--agent-budget <seconds>` (optional wrapped-agent wall clock) · `--allow-dirty` · `--settle <seconds>` (wait before the final quiescence check) · `--allow-dep-drift` · `--cwd <dir>` · then `-- <agent command...>` |
|
|
368
|
+
| `run` | `--base <rev>` · `--cmd <suite command>` · `--budget <seconds>` (per verifier suite) · `--agent-budget <seconds>` (optional wrapped-agent wall clock) · `--observe-transients` (start a session-scoped transient observer) · `--allow-dirty` · `--settle <seconds>` (wait before the final quiescence check) · `--allow-dep-drift` · `--cwd <dir>` · then `-- <agent command...>` |
|
|
360
369
|
| `allow` | `<rule>` · `--file <path>` · `--reason "<why>"` (required) · `--cwd <dir>` |
|
|
361
370
|
| `init` | `--cwd <dir>` · `--dry-run` · `--force-workflow` |
|
|
362
371
|
| `watch` | `--dir <dir>` · `--log <file>` — a daemon; it runs until signalled |
|
package/dist/cli/index.js
CHANGED
|
@@ -7226,15 +7226,28 @@ function startWatcher(dir, log, policy) {
|
|
|
7226
7226
|
function runWatch(args) {
|
|
7227
7227
|
let dir = process.cwd();
|
|
7228
7228
|
let log = null;
|
|
7229
|
+
let base = null;
|
|
7229
7230
|
for (let i = 0; i < args.length; i++) {
|
|
7230
7231
|
if (args[i] === "--dir" && args[i + 1]) dir = args[++i];
|
|
7231
7232
|
else if (args[i] === "--log" && args[i + 1]) log = args[++i];
|
|
7233
|
+
else if (args[i] === "--base" && args[i + 1]) base = args[++i];
|
|
7232
7234
|
}
|
|
7233
|
-
const policy = loadPolicy(dir);
|
|
7235
|
+
const policy = base ? loadPolicyAt(base, dir) ?? defaultPolicy() : loadPolicy(dir);
|
|
7234
7236
|
const out2 = log ?? defaultEventLog(dir);
|
|
7235
|
-
startWatcher(dir, out2, policy);
|
|
7236
|
-
|
|
7237
|
-
|
|
7237
|
+
const watcher = startWatcher(dir, out2, policy);
|
|
7238
|
+
let closing = false;
|
|
7239
|
+
const shutdown = () => {
|
|
7240
|
+
if (closing) return;
|
|
7241
|
+
closing = true;
|
|
7242
|
+
watcher.close();
|
|
7243
|
+
process.exit(0);
|
|
7244
|
+
};
|
|
7245
|
+
process.once("SIGTERM", shutdown);
|
|
7246
|
+
process.once("SIGINT", shutdown);
|
|
7247
|
+
process.stdout.write(
|
|
7248
|
+
`tamperward watch: recording protected-file events under ${dir} -> ${out2} (health: ${watcherHealthPath(out2)}${base ? `; trusted base: ${base}` : ""})
|
|
7249
|
+
`
|
|
7250
|
+
);
|
|
7238
7251
|
return -1;
|
|
7239
7252
|
}
|
|
7240
7253
|
|
|
@@ -10182,7 +10195,8 @@ function parseVerify(args) {
|
|
|
10182
10195
|
}
|
|
10183
10196
|
|
|
10184
10197
|
// src/cli/run.ts
|
|
10185
|
-
import { execFileSync as execFileSync10, spawnSync as spawnSync3 } from "node:child_process";
|
|
10198
|
+
import { execFileSync as execFileSync10, spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
10199
|
+
import { randomBytes } from "node:crypto";
|
|
10186
10200
|
import { mkdtempSync as mkdtempSync3, readdirSync as readdirSync5, readFileSync as readFileSync17, readlinkSync as readlinkSync4, realpathSync as realpathSync6, rmSync as rmSync4 } from "node:fs";
|
|
10187
10201
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
10188
10202
|
import { join as join17, resolve as resolve8 } from "node:path";
|
|
@@ -10404,6 +10418,124 @@ function runAgentWithBudget(argv2, cwd, budgetSecs) {
|
|
|
10404
10418
|
rmSync4(stateDir, { recursive: true, force: true });
|
|
10405
10419
|
}
|
|
10406
10420
|
}
|
|
10421
|
+
var waitCell = new Int32Array(new SharedArrayBuffer(4));
|
|
10422
|
+
function waitMs(ms) {
|
|
10423
|
+
Atomics.wait(waitCell, 0, 0, ms);
|
|
10424
|
+
}
|
|
10425
|
+
function pidAlive2(pid) {
|
|
10426
|
+
if (!pid || !Number.isInteger(pid) || pid <= 0) return false;
|
|
10427
|
+
try {
|
|
10428
|
+
process.kill(pid, 0);
|
|
10429
|
+
return true;
|
|
10430
|
+
} catch (e) {
|
|
10431
|
+
return e.code === "EPERM";
|
|
10432
|
+
}
|
|
10433
|
+
}
|
|
10434
|
+
function supervisedObserverLog(cwd) {
|
|
10435
|
+
const gd = gitDir(cwd) ?? join17(cwd, ".git");
|
|
10436
|
+
return join17(
|
|
10437
|
+
gd,
|
|
10438
|
+
"tamperward",
|
|
10439
|
+
`run-observer-${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}.jsonl`
|
|
10440
|
+
);
|
|
10441
|
+
}
|
|
10442
|
+
function startSupervisedObserver(cwd, base, entry) {
|
|
10443
|
+
const log = supervisedObserverLog(cwd);
|
|
10444
|
+
const cliEntry = entry ?? process.argv[1];
|
|
10445
|
+
if (!cliEntry) return { log, pid: null, finished: false };
|
|
10446
|
+
let child;
|
|
10447
|
+
try {
|
|
10448
|
+
child = spawn(
|
|
10449
|
+
process.execPath,
|
|
10450
|
+
[resolve8(cliEntry), "watch", "--dir", cwd, "--log", log, "--base", base],
|
|
10451
|
+
{
|
|
10452
|
+
cwd,
|
|
10453
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
10454
|
+
env: process.env
|
|
10455
|
+
}
|
|
10456
|
+
);
|
|
10457
|
+
} catch {
|
|
10458
|
+
return { log, pid: null, finished: false };
|
|
10459
|
+
}
|
|
10460
|
+
const pid = child.pid ?? null;
|
|
10461
|
+
const deadline = Date.now() + 3e3;
|
|
10462
|
+
while (Date.now() < deadline) {
|
|
10463
|
+
const telemetry = watcherTelemetry(log);
|
|
10464
|
+
if (telemetry.state === "healthy" || telemetry.state === "degraded") break;
|
|
10465
|
+
if (!pidAlive2(pid)) break;
|
|
10466
|
+
waitMs(25);
|
|
10467
|
+
}
|
|
10468
|
+
return { log, pid, finished: false };
|
|
10469
|
+
}
|
|
10470
|
+
function stopObserverProcess(observer) {
|
|
10471
|
+
waitMs(100);
|
|
10472
|
+
const beforeStop = watcherTelemetry(observer.log);
|
|
10473
|
+
const pid = observer.pid;
|
|
10474
|
+
if (pidAlive2(pid)) {
|
|
10475
|
+
try {
|
|
10476
|
+
process.kill(pid, "SIGTERM");
|
|
10477
|
+
} catch {
|
|
10478
|
+
}
|
|
10479
|
+
const deadline = Date.now() + 2e3;
|
|
10480
|
+
while (Date.now() < deadline) {
|
|
10481
|
+
const health = watcherTelemetry(observer.log);
|
|
10482
|
+
if (health.health?.state === "stopped" || !pidAlive2(pid)) break;
|
|
10483
|
+
waitMs(25);
|
|
10484
|
+
}
|
|
10485
|
+
if (pidAlive2(pid)) {
|
|
10486
|
+
try {
|
|
10487
|
+
process.kill(pid, "SIGKILL");
|
|
10488
|
+
} catch {
|
|
10489
|
+
}
|
|
10490
|
+
}
|
|
10491
|
+
}
|
|
10492
|
+
observer.finished = true;
|
|
10493
|
+
return beforeStop;
|
|
10494
|
+
}
|
|
10495
|
+
function observerSummary(observer, telemetry) {
|
|
10496
|
+
const h = telemetry.health;
|
|
10497
|
+
const counts = h ? `${h.event_count} event(s), ${h.dropped_events} dropped, ${h.error_count} error(s)` : "no valid health record";
|
|
10498
|
+
const reason = telemetry.reason ? `; ${telemetry.reason}` : "";
|
|
10499
|
+
out(
|
|
10500
|
+
`tamperward run \u2014 transient observer: ${telemetry.state} (advisory; ${counts}; log ${observer.log}${reason})`
|
|
10501
|
+
);
|
|
10502
|
+
}
|
|
10503
|
+
function collectObserverFindings(observer, telemetry, cwd, base, head, policy) {
|
|
10504
|
+
observerSummary(observer, telemetry);
|
|
10505
|
+
const { events } = readEvents(observer.log, 0);
|
|
10506
|
+
if (events.length === 0) return { blocking: false };
|
|
10507
|
+
let persistent = /* @__PURE__ */ new Set();
|
|
10508
|
+
try {
|
|
10509
|
+
const changes = [
|
|
10510
|
+
...head !== base ? diffRange(base, head, { cwd }) : [],
|
|
10511
|
+
...diffWorktreeWithUntracked({ cwd }, (rel) => isProtected(rel, policy))
|
|
10512
|
+
];
|
|
10513
|
+
persistent = new Set(
|
|
10514
|
+
changes.filter((change) => change.kind === "file").map((change) => change.path)
|
|
10515
|
+
);
|
|
10516
|
+
} catch (e) {
|
|
10517
|
+
out(
|
|
10518
|
+
`tamperward run \u2014 transient observer: recorded ${events.length} event(s), but could not classify them against the final diff (${e instanceof Error ? e.message : String(e)}).`
|
|
10519
|
+
);
|
|
10520
|
+
return { blocking: false };
|
|
10521
|
+
}
|
|
10522
|
+
const finalHash = (path) => {
|
|
10523
|
+
const e = inspectRel(cwd, path);
|
|
10524
|
+
return e.kind === "file" && e.content != null ? contentHash(e.content) : null;
|
|
10525
|
+
};
|
|
10526
|
+
const findings = transientFindings(events, persistent, policy, finalHash);
|
|
10527
|
+
for (const finding of findings) {
|
|
10528
|
+
out(
|
|
10529
|
+
`[observer] ${finding.severity === "block" ? "BLOCK" : "warn"} ${finding.rule}${finding.file ? " " + finding.file : ""}: ${finding.message}`
|
|
10530
|
+
);
|
|
10531
|
+
}
|
|
10532
|
+
return { blocking: findings.some((finding) => finding.severity === "block") };
|
|
10533
|
+
}
|
|
10534
|
+
function finishObserverAdvisory(observer) {
|
|
10535
|
+
if (!observer || observer.finished) return;
|
|
10536
|
+
const telemetry = stopObserverProcess(observer);
|
|
10537
|
+
observerSummary(observer, telemetry);
|
|
10538
|
+
}
|
|
10407
10539
|
function git3(args, cwd) {
|
|
10408
10540
|
return execFileSync10("git", args, { cwd, encoding: "utf8", maxBuffer: 1 << 28, env: trustedGitEnv() });
|
|
10409
10541
|
}
|
|
@@ -10530,6 +10662,10 @@ function runEnvelope(opts) {
|
|
|
10530
10662
|
} else {
|
|
10531
10663
|
out(`tamperward run \u2014 dependency environment: verifier-owned by ${verifierBackend.image ?? "isolated image"}`);
|
|
10532
10664
|
}
|
|
10665
|
+
const observer = opts.observeTransients ? startSupervisedObserver(cwd, base, opts.observerEntry) : null;
|
|
10666
|
+
if (!observer) {
|
|
10667
|
+
out("tamperward run \u2014 transient observer: disabled (advisory; pass --observe-transients to enable)");
|
|
10668
|
+
}
|
|
10533
10669
|
const rewritesBefore = objectRewriteState(cwd);
|
|
10534
10670
|
const spawnTicks = nowTicks();
|
|
10535
10671
|
const agentRun = opts.agentBudget === void 0 ? (() => {
|
|
@@ -10557,6 +10693,7 @@ function runEnvelope(opts) {
|
|
|
10557
10693
|
err2("read against the anchor we started from. That is the finding.");
|
|
10558
10694
|
out(`
|
|
10559
10695
|
tamperward run \u2014 agent exit ${agentExit}; OBJECT_REWRITE \u2192 ENFORCEMENT_FAILED`);
|
|
10696
|
+
finishObserverAdvisory(observer);
|
|
10560
10697
|
return 1;
|
|
10561
10698
|
}
|
|
10562
10699
|
const dependencyBeforeAdjudication = dependencyEnvironment ? checkDependencyEnvironment(cwd, dependencyEnvironment) : { ok: true };
|
|
@@ -10566,6 +10703,7 @@ tamperward run \u2014 agent exit ${agentExit}; OBJECT_REWRITE \u2192 ENFORCEMENT
|
|
|
10566
10703
|
if (!opts.allowDepDrift) {
|
|
10567
10704
|
out(`
|
|
10568
10705
|
tamperward run \u2014 agent exit ${agentExit}; DEPENDENCY_DRIFT \u2192 ENFORCEMENT_FAILED`);
|
|
10706
|
+
finishObserverAdvisory(observer);
|
|
10569
10707
|
return 1;
|
|
10570
10708
|
}
|
|
10571
10709
|
err2("(--allow-dep-drift: proceeding anyway, on the operator's judgement.)");
|
|
@@ -10577,6 +10715,7 @@ tamperward run \u2014 agent exit ${agentExit}; DEPENDENCY_DRIFT \u2192 ENFORCEME
|
|
|
10577
10715
|
err2("the agent rewrote history out from under the anchor. That is the finding.");
|
|
10578
10716
|
out(`
|
|
10579
10717
|
tamperward run \u2014 agent exit ${agentExit}; HISTORY_REWRITE \u2192 ENFORCEMENT_FAILED`);
|
|
10718
|
+
finishObserverAdvisory(observer);
|
|
10580
10719
|
return 1;
|
|
10581
10720
|
}
|
|
10582
10721
|
const protectedIgnored = (rel) => isProtected(rel, frozenPolicy);
|
|
@@ -10627,11 +10766,24 @@ tamperward run \u2014 agent exit ${agentExit}; HISTORY_REWRITE \u2192 ENFORCEMEN
|
|
|
10627
10766
|
err2(`tamperward run: ${survivors.length} process(es) started during this run still hold the`);
|
|
10628
10767
|
err2(`working tree (pid ${survivors.join(", ")}). A verdict cannot outlive the tree it describes.`);
|
|
10629
10768
|
}
|
|
10769
|
+
let observerBlocked = false;
|
|
10770
|
+
if (observer && !observer.finished) {
|
|
10771
|
+
const telemetry = stopObserverProcess(observer);
|
|
10772
|
+
const observed = collectObserverFindings(
|
|
10773
|
+
observer,
|
|
10774
|
+
telemetry,
|
|
10775
|
+
cwd,
|
|
10776
|
+
base,
|
|
10777
|
+
head,
|
|
10778
|
+
frozenPolicy
|
|
10779
|
+
);
|
|
10780
|
+
observerBlocked = observed.blocking;
|
|
10781
|
+
}
|
|
10630
10782
|
const notQuiescent = mutatedDuringAdjudication || survivors.length > 0 || depsDrifted || rewrote;
|
|
10631
10783
|
const cannot = !notQuiescent && (diffCode === 2 || workCode === 2 || verifyCode === 2);
|
|
10632
|
-
const blocked = diffCode === 1 || workCode === 1 || verifyCode === 1 || notQuiescent;
|
|
10784
|
+
const blocked = diffCode === 1 || workCode === 1 || verifyCode === 1 || notQuiescent || observerBlocked;
|
|
10633
10785
|
const enforcement = cannot ? 2 : blocked ? 1 : 0;
|
|
10634
|
-
const verdict2 = enforcement === 2 ? "CANNOT_ADJUDICATE (fail closed)" : rewrote ? "OBJECT_REWRITE \u2014 the base the checks read is not the base we anchored to" : depsDrifted ? "DEPENDENCY_DRIFT \u2014 the suite runner changed under the envelope" : notQuiescent ? "NOT_QUIESCENT \u2014 the tree moved, or something still holds it" : enforcement === 1 ? "ENFORCEMENT_FAILED \u2014 the tree the runtime released does not stand" : agentTimedOut ? "AGENT_TIMEOUT \u2014 runtime budget expired; post-timeout enforcement clean" : agentExit !== 0 ? `agent exited ${agentExit} (enforcement clean)` : "GREEN MEANS GREEN";
|
|
10786
|
+
const verdict2 = enforcement === 2 ? "CANNOT_ADJUDICATE (fail closed)" : rewrote ? "OBJECT_REWRITE \u2014 the base the checks read is not the base we anchored to" : depsDrifted ? "DEPENDENCY_DRIFT \u2014 the suite runner changed under the envelope" : notQuiescent ? "NOT_QUIESCENT \u2014 the tree moved, or something still holds it" : observerBlocked ? "TRANSIENT_OBSERVER_BLOCK \u2014 observed temporal weakening under strict transient policy" : enforcement === 1 ? "ENFORCEMENT_FAILED \u2014 the tree the runtime released does not stand" : agentTimedOut ? "AGENT_TIMEOUT \u2014 runtime budget expired; post-timeout enforcement clean" : agentExit !== 0 ? `agent exited ${agentExit} (enforcement clean)` : "GREEN MEANS GREEN";
|
|
10635
10787
|
const agentSummary = agentTimedOut ? `AGENT_TIMEOUT (${opts.agentBudget}s; exit 124)` : `agent exit ${agentExit}`;
|
|
10636
10788
|
out(`
|
|
10637
10789
|
tamperward run \u2014 ${agentSummary}; checks diff=${diffCode} worktree=${workCode} verify=${verifyCode} \u2192 ${verdict2}`);
|
|
@@ -10651,6 +10803,7 @@ function parseRun(args) {
|
|
|
10651
10803
|
else if (a === "--allow-dirty") o.allowDirty = true;
|
|
10652
10804
|
else if (a === "--settle") o.settle = Number(args[++i]);
|
|
10653
10805
|
else if (a === "--allow-dep-drift") o.allowDepDrift = true;
|
|
10806
|
+
else if (a === "--observe-transients") o.observeTransients = true;
|
|
10654
10807
|
else if (a === "--cwd") o.cwd = args[++i];
|
|
10655
10808
|
else {
|
|
10656
10809
|
o.argv = args.slice(i);
|
|
@@ -10784,7 +10937,7 @@ function validateCliArgs(cmd, args) {
|
|
|
10784
10937
|
const prefix = args.slice(0, delimiter3);
|
|
10785
10938
|
const command = args.slice(delimiter3 + 1);
|
|
10786
10939
|
const parsed = validateFlatArgs(prefix, {
|
|
10787
|
-
flags: ["--allow-dirty", "--allow-dep-drift"],
|
|
10940
|
+
flags: ["--allow-dirty", "--allow-dep-drift", "--observe-transients"],
|
|
10788
10941
|
values: {
|
|
10789
10942
|
"--base": "string",
|
|
10790
10943
|
"--cmd": "string",
|
|
@@ -10851,7 +11004,7 @@ function validateCliArgs(cmd, args) {
|
|
|
10851
11004
|
}
|
|
10852
11005
|
if (cmd === "watch") {
|
|
10853
11006
|
return validateFlatArgs(args, {
|
|
10854
|
-
values: { "--dir": "string", "--log": "string" }
|
|
11007
|
+
values: { "--dir": "string", "--log": "string", "--base": "string" }
|
|
10855
11008
|
}).error;
|
|
10856
11009
|
}
|
|
10857
11010
|
return void 0;
|
|
@@ -10878,8 +11031,10 @@ Formats:
|
|
|
10878
11031
|
tamperward hook claude PreToolUse gate (reads hook JSON on stdin)
|
|
10879
11032
|
tamperward sweep claude Stop sweep (re-scan the turn's working tree)
|
|
10880
11033
|
tamperward watch [--dir D] [--log F] filesystem-event observer daemon: records
|
|
10881
|
-
|
|
10882
|
-
observe supported transient effects
|
|
11034
|
+
[--base R] protected-file events so the sweep can
|
|
11035
|
+
observe supported transient effects.
|
|
11036
|
+
--base freezes observer policy to a
|
|
11037
|
+
trusted revision
|
|
10883
11038
|
tamperward verify [--base R] [--cmd C] pristine-suite re-execution: run the suite
|
|
10884
11039
|
[--budget S] [--json] [--keep] as-is AND with protected files restored
|
|
10885
11040
|
[--require-ancestor] [--cwd D] from the trusted base; a visible-green /
|
|
@@ -10891,9 +11046,13 @@ Formats:
|
|
|
10891
11046
|
[--base R] [--cmd C] base, run the agent, treat its exit as
|
|
10892
11047
|
[--budget S] [--agent-budget S] untrusted, then re-adjudicate the tree it
|
|
10893
11048
|
[--allow-dirty] [--settle S] left (policy over base...HEAD and the
|
|
10894
|
-
[--allow-dep-drift] [--cwd D] worktree, plus verify).
|
|
10895
|
-
|
|
10896
|
-
|
|
11049
|
+
[--allow-dep-drift] [--cwd D] worktree, plus verify).
|
|
11050
|
+
[--observe-transients] --observe-transients starts a session-
|
|
11051
|
+
scoped observer before the agent and
|
|
11052
|
+
reports temporal evidence/health after it.
|
|
11053
|
+
--agent-budget bounds the agent runtime
|
|
11054
|
+
itself and still adjudicates after timeout.
|
|
11055
|
+
Exit: agent's
|
|
10897
11056
|
code when clean; 124 on clean AGENT_TIMEOUT;
|
|
10898
11057
|
1 on any blocking finding/masked failure;
|
|
10899
11058
|
2 when it cannot adjudicate (fails closed)
|
|
@@ -10956,7 +11115,12 @@ function main(argv2) {
|
|
|
10956
11115
|
case "verify":
|
|
10957
11116
|
return runVerify(parseVerify(rest));
|
|
10958
11117
|
case "run":
|
|
10959
|
-
return runEnvelope(
|
|
11118
|
+
return runEnvelope({
|
|
11119
|
+
...parseRun(rest),
|
|
11120
|
+
// The supervised observer re-launches this exact TamperWard CLI under
|
|
11121
|
+
// process.execPath rather than resolving another binary from PATH.
|
|
11122
|
+
observerEntry: process.argv[1]
|
|
11123
|
+
});
|
|
10960
11124
|
case void 0:
|
|
10961
11125
|
case "-h":
|
|
10962
11126
|
case "--help":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.1",
|
|
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",
|