tamperward 2.29.21 → 2.30.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/dist/cli/index.js +75 -56
- package/package.json +3 -2
package/dist/cli/index.js
CHANGED
|
@@ -10980,6 +10980,41 @@ var init_machine_output = __esm({
|
|
|
10980
10980
|
}
|
|
10981
10981
|
});
|
|
10982
10982
|
|
|
10983
|
+
// src/cli/render/status.ts
|
|
10984
|
+
function paint(s, code2, on) {
|
|
10985
|
+
return on ? code2 + s + RESET : s;
|
|
10986
|
+
}
|
|
10987
|
+
function severityColour(sev) {
|
|
10988
|
+
return TONE[sev].colour;
|
|
10989
|
+
}
|
|
10990
|
+
function statusLine(severity, label, text, colour) {
|
|
10991
|
+
const t = TONE[severity];
|
|
10992
|
+
const painted = paint(label.padEnd(STATUS_LABEL_WIDTH), (t.bold ? BOLD : "") + t.colour, colour);
|
|
10993
|
+
return `${painted} ${text}`;
|
|
10994
|
+
}
|
|
10995
|
+
var ESC, RESET, BOLD, DIM, truecolour, RED, YELLOW, GREEN, CYAN, TONE, STATUS_LABEL_WIDTH;
|
|
10996
|
+
var init_status = __esm({
|
|
10997
|
+
"src/cli/render/status.ts"() {
|
|
10998
|
+
"use strict";
|
|
10999
|
+
ESC = "\x1B";
|
|
11000
|
+
RESET = `${ESC}[0m`;
|
|
11001
|
+
BOLD = `${ESC}[1m`;
|
|
11002
|
+
DIM = `${ESC}[2m`;
|
|
11003
|
+
truecolour = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
|
|
11004
|
+
RED = truecolour(255, 107, 107);
|
|
11005
|
+
YELLOW = truecolour(227, 179, 65);
|
|
11006
|
+
GREEN = truecolour(63, 185, 80);
|
|
11007
|
+
CYAN = truecolour(86, 212, 221);
|
|
11008
|
+
TONE = {
|
|
11009
|
+
ok: { colour: GREEN, bold: false },
|
|
11010
|
+
warn: { colour: YELLOW, bold: false },
|
|
11011
|
+
bad: { colour: RED, bold: true },
|
|
11012
|
+
info: { colour: CYAN, bold: false }
|
|
11013
|
+
};
|
|
11014
|
+
STATUS_LABEL_WIDTH = 8;
|
|
11015
|
+
}
|
|
11016
|
+
});
|
|
11017
|
+
|
|
10983
11018
|
// src/cli/render/text.ts
|
|
10984
11019
|
function colourEnabled(env = process.env, stream = process.stdout) {
|
|
10985
11020
|
if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") return false;
|
|
@@ -10992,9 +11027,6 @@ function terminalWidth(stream = process.stdout) {
|
|
|
10992
11027
|
if (!c || c < 40) return 80;
|
|
10993
11028
|
return Math.min(c, 100);
|
|
10994
11029
|
}
|
|
10995
|
-
function paint(s, code2, on) {
|
|
10996
|
-
return on ? code2 + s + RESET : s;
|
|
10997
|
-
}
|
|
10998
11030
|
function wrap(text, width) {
|
|
10999
11031
|
const out3 = [];
|
|
11000
11032
|
let cur = "";
|
|
@@ -11080,20 +11112,12 @@ function renderText(input, opts) {
|
|
|
11080
11112
|
}
|
|
11081
11113
|
return out3.join("\n").replace(/\n+$/, "") + "\n";
|
|
11082
11114
|
}
|
|
11083
|
-
var
|
|
11115
|
+
var SIGNOFF_NOTE;
|
|
11084
11116
|
var init_text = __esm({
|
|
11085
11117
|
"src/cli/render/text.ts"() {
|
|
11086
11118
|
"use strict";
|
|
11087
11119
|
init_policy();
|
|
11088
|
-
|
|
11089
|
-
RESET = `${ESC}[0m`;
|
|
11090
|
-
BOLD = `${ESC}[1m`;
|
|
11091
|
-
DIM = `${ESC}[2m`;
|
|
11092
|
-
truecolour = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
|
|
11093
|
-
RED = truecolour(255, 107, 107);
|
|
11094
|
-
YELLOW = truecolour(227, 179, 65);
|
|
11095
|
-
GREEN = truecolour(63, 185, 80);
|
|
11096
|
-
CYAN = truecolour(86, 212, 221);
|
|
11120
|
+
init_status();
|
|
11097
11121
|
SIGNOFF_NOTE = "A blocking finding clears only with a human sign-off. In CI that sign-off is out-of-band \u2014 a PR label applied by a reviewer \u2014 never a file committed on the branch under review. See SPEC \xA75.4.";
|
|
11098
11122
|
}
|
|
11099
11123
|
});
|
|
@@ -15940,8 +15964,14 @@ function verifyVerdictLine(verdict2, ctx) {
|
|
|
15940
15964
|
}
|
|
15941
15965
|
function runVerify(opts) {
|
|
15942
15966
|
const cwd = opts.cwd ?? process.cwd();
|
|
15967
|
+
const colour = opts.silent ? false : colourEnabled(process.env, process.stdout);
|
|
15968
|
+
const paintVerify = (s) => {
|
|
15969
|
+
if (!s.startsWith("verify:")) return s;
|
|
15970
|
+
const sev = /failing closed/i.test(s) ? "bad" : "info";
|
|
15971
|
+
return paint("verify:", (sev === "bad" ? BOLD : "") + severityColour(sev), colour) + s.slice("verify:".length);
|
|
15972
|
+
};
|
|
15943
15973
|
const out3 = opts.silent ? (_s) => {
|
|
15944
|
-
} : (s) => void process.stdout.write(s + "\n");
|
|
15974
|
+
} : (s) => void process.stdout.write(paintVerify(s) + "\n");
|
|
15945
15975
|
let filesystemCaseSensitive;
|
|
15946
15976
|
const caseReport = () => filesystemCaseSensitive === void 0 ? {} : { filesystem_case_sensitive: filesystemCaseSensitive };
|
|
15947
15977
|
const cannotVerify = (reason, detail, extra = {}) => {
|
|
@@ -16374,6 +16404,8 @@ var init_verify = __esm({
|
|
|
16374
16404
|
init_machine_output();
|
|
16375
16405
|
init_signoff();
|
|
16376
16406
|
init_suite_diagnostics();
|
|
16407
|
+
init_text();
|
|
16408
|
+
init_status();
|
|
16377
16409
|
OVERLAY_CLASSES = ["tests", "snapshots", "config"];
|
|
16378
16410
|
VERIFICATION_SURFACE = [
|
|
16379
16411
|
// Python / pytest — read from the rootdir, and conftest at any depth
|
|
@@ -17626,12 +17658,15 @@ function emitReport(opts, checks, authoritative) {
|
|
|
17626
17658
|
process.stdout.write(JSON.stringify(report2) + "\n");
|
|
17627
17659
|
return;
|
|
17628
17660
|
}
|
|
17661
|
+
const colour = colourEnabled(process.env, process.stdout);
|
|
17629
17662
|
for (const check2 of checks) {
|
|
17630
17663
|
if (check2.id === "observer") {
|
|
17631
17664
|
process.stdout.write(`tamperward doctor: transient observer: ${check2.detail}
|
|
17632
17665
|
`);
|
|
17633
17666
|
} else {
|
|
17634
|
-
|
|
17667
|
+
const sev = check2.state === "OK" ? "ok" : check2.state === "WARN" ? "warn" : check2.state === "BROKEN" ? "bad" : "info";
|
|
17668
|
+
const tag = paint(`[${check2.state}]`, (sev === "bad" ? BOLD : "") + severityColour(sev), colour);
|
|
17669
|
+
process.stdout.write(`tamperward doctor: ${tag} ${check2.id} \u2014 ${check2.detail}
|
|
17635
17670
|
`);
|
|
17636
17671
|
}
|
|
17637
17672
|
}
|
|
@@ -18021,6 +18056,8 @@ var init_doctor = __esm({
|
|
|
18021
18056
|
init_machine_output();
|
|
18022
18057
|
init_narrow();
|
|
18023
18058
|
init_repo_context();
|
|
18059
|
+
init_text();
|
|
18060
|
+
init_status();
|
|
18024
18061
|
VERIFY_COMMAND = /\btamperward(?:@\S+)?\s+verify\b/;
|
|
18025
18062
|
REPOSITORY_REQUIRED_CHECKS = [
|
|
18026
18063
|
"typecheck",
|
|
@@ -18665,9 +18702,6 @@ function readlineAsker(input, output) {
|
|
|
18665
18702
|
};
|
|
18666
18703
|
return ask;
|
|
18667
18704
|
}
|
|
18668
|
-
function paint2(text, code2, on) {
|
|
18669
|
-
return on ? code2 + text + RESET2 : text;
|
|
18670
|
-
}
|
|
18671
18705
|
function terminalText(text) {
|
|
18672
18706
|
return stripControl(text).replace(/\s+/g, " ").trim();
|
|
18673
18707
|
}
|
|
@@ -18733,9 +18767,9 @@ function writeVerifyCommand(cwd, command) {
|
|
|
18733
18767
|
}
|
|
18734
18768
|
async function runOnboard(opts, io = {}) {
|
|
18735
18769
|
const requestedCwd = resolve12(opts.cwd ?? process.cwd());
|
|
18736
|
-
const out3 = io.out ?? ((
|
|
18737
|
-
const errLine = (
|
|
18738
|
-
const rawErr = (
|
|
18770
|
+
const out3 = io.out ?? ((line2) => void process.stdout.write(line2 + "\n"));
|
|
18771
|
+
const errLine = (line2) => void process.stderr.write(line2 + "\n");
|
|
18772
|
+
const rawErr = (line2) => errLine(terminalText(line2));
|
|
18739
18773
|
const platform = io.platform ?? process.platform;
|
|
18740
18774
|
const colour = io.colour ?? colourEnabled(process.env, process.stdout);
|
|
18741
18775
|
const runners = {
|
|
@@ -18747,18 +18781,12 @@ async function runOnboard(opts, io = {}) {
|
|
|
18747
18781
|
};
|
|
18748
18782
|
const interactive = io.interactive ?? (Boolean(process.stdin.isTTY) && !process.env.CI && !process.env.GITHUB_ACTIONS);
|
|
18749
18783
|
const scripted = Boolean(opts.yes);
|
|
18750
|
-
const
|
|
18751
|
-
if (kind === "ok") return GREEN2;
|
|
18752
|
-
if (kind === "warn") return YELLOW2;
|
|
18753
|
-
if (kind === "bad") return RED2;
|
|
18754
|
-
if (kind === "info") return CYAN2;
|
|
18755
|
-
return DIM2;
|
|
18756
|
-
};
|
|
18784
|
+
const line = (label, text, kind) => kind === "dim" ? paint(label.padEnd(8), DIM, colour) + " " + terminalText(text) : statusLine(kind, label, terminalText(text), colour);
|
|
18757
18785
|
const status = (label, text, kind = "info") => {
|
|
18758
|
-
out3(
|
|
18786
|
+
out3(line(label, text, kind));
|
|
18759
18787
|
};
|
|
18760
18788
|
const errStatus = (label, text, kind = "info") => {
|
|
18761
|
-
errLine(
|
|
18789
|
+
errLine(line(label, text, kind));
|
|
18762
18790
|
};
|
|
18763
18791
|
const fail = (text) => errStatus("ERROR", text, "bad");
|
|
18764
18792
|
if (!interactive && !scripted) {
|
|
@@ -18808,7 +18836,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18808
18836
|
const section = (n) => {
|
|
18809
18837
|
sectionNo = n;
|
|
18810
18838
|
out3("");
|
|
18811
|
-
out3(
|
|
18839
|
+
out3(paint(n + "/" + SECTIONS.length + " " + SECTIONS[n - 1], BOLD + CYAN, colour));
|
|
18812
18840
|
};
|
|
18813
18841
|
const wrote = [];
|
|
18814
18842
|
let verifyCommand;
|
|
@@ -18818,9 +18846,9 @@ async function runOnboard(opts, io = {}) {
|
|
|
18818
18846
|
let declined = false;
|
|
18819
18847
|
let doctorOutcome = null;
|
|
18820
18848
|
try {
|
|
18821
|
-
out3(
|
|
18822
|
-
out3(
|
|
18823
|
-
out3(
|
|
18849
|
+
out3(paint("TamperWard onboarding", BOLD, colour));
|
|
18850
|
+
out3(paint("v" + TW_VERSION + " \xB7 Node " + process.versions.node + " \xB7 " + platformLabel(platform) + "/" + process.arch, DIM, colour));
|
|
18851
|
+
out3(paint(terminalText(cwd), DIM, colour));
|
|
18824
18852
|
section(1);
|
|
18825
18853
|
const lifecycle = lifecyclePlatformCheck(platform);
|
|
18826
18854
|
const localVerifySupported = localVerifierShell(platform, "true") !== null;
|
|
@@ -18833,7 +18861,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18833
18861
|
}
|
|
18834
18862
|
const head = git5(cwd, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"])?.trim() ?? null;
|
|
18835
18863
|
const treeStatus = git5(cwd, ["status", "--porcelain", "--untracked-files=all"]) ?? "";
|
|
18836
|
-
const dirty = treeStatus.split("\n").filter(Boolean).map((
|
|
18864
|
+
const dirty = treeStatus.split("\n").filter(Boolean).map((line2) => line2.slice(3).split(" -> ").at(-1) ?? "");
|
|
18837
18865
|
if (!head) {
|
|
18838
18866
|
const count = dirty.length;
|
|
18839
18867
|
status(
|
|
@@ -18955,7 +18983,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18955
18983
|
}
|
|
18956
18984
|
if (!verifyCommand) {
|
|
18957
18985
|
status("ACTION", "Verification is not configured; CI will fail closed until it is.", "warn");
|
|
18958
|
-
out3(
|
|
18986
|
+
out3(paint(' Set it later with: tamperward onboard --verify-command "<suite command>"', DIM, colour));
|
|
18959
18987
|
} else if (!localVerifySupported) {
|
|
18960
18988
|
status("LIMITED", "Local verification is unavailable on " + platformLabel(platform) + "; use a digest-pinned container verifier.", "warn");
|
|
18961
18989
|
} else if (!head) {
|
|
@@ -18981,7 +19009,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18981
19009
|
status("SKIP", "Safe demo becomes available after the first commit.", "dim");
|
|
18982
19010
|
} else {
|
|
18983
19011
|
const wanted = scripted ? Boolean(opts.demo) : opts.demo ? true : await confirm("Run the optional safe tamper demo? (temporary worktree only)", false, false);
|
|
18984
|
-
if (wanted) runDemo(cwd, head, runners, (
|
|
19012
|
+
if (wanted) runDemo(cwd, head, runners, (line2) => out3(terminalText(line2)));
|
|
18985
19013
|
}
|
|
18986
19014
|
}
|
|
18987
19015
|
section(4);
|
|
@@ -19029,14 +19057,14 @@ async function runOnboard(opts, io = {}) {
|
|
|
19029
19057
|
status("OK", "GitHub authority enforced for " + doctorOutcome.github.repo + "#" + doctorOutcome.github.branch + ".", "ok");
|
|
19030
19058
|
} else if (!repo) {
|
|
19031
19059
|
status("ACTION", "GitHub authority is not configured for this repository.", "warn");
|
|
19032
|
-
out3(
|
|
19033
|
-
out3(
|
|
19034
|
-
for (const
|
|
19060
|
+
out3(paint(" If GitHub will provide repository authority, run: " + terminalText(doctorCommand), DIM, colour));
|
|
19061
|
+
out3(paint(" If this repository will use GitHub CI authority, configure:", DIM, colour));
|
|
19062
|
+
for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
|
|
19035
19063
|
} else {
|
|
19036
19064
|
status("ACTION", "GitHub authority is not verified yet.", "warn");
|
|
19037
|
-
out3(
|
|
19038
|
-
out3(
|
|
19039
|
-
for (const
|
|
19065
|
+
out3(paint(" " + terminalText(doctorCommand), DIM, colour));
|
|
19066
|
+
out3(paint(" GitHub authority requires all three controls:", DIM, colour));
|
|
19067
|
+
for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
|
|
19040
19068
|
}
|
|
19041
19069
|
const commitPaths = [...new Set(wrote)].filter((path) => committableSetupPath(cwd, path));
|
|
19042
19070
|
if (commitPaths.length) {
|
|
@@ -19051,7 +19079,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
19051
19079
|
if (verifyResult) {
|
|
19052
19080
|
status("VERIFY", verifyResult.summary?.verdict ?? "exit " + verifyResult.code, verifyResult.code === 0 ? "ok" : "warn");
|
|
19053
19081
|
}
|
|
19054
|
-
out3(
|
|
19082
|
+
out3(paint(" Daily: tamperward check --worktree \xB7 tamperward verify --base <base>", DIM, colour));
|
|
19055
19083
|
return posture === "READY" || posture === "READY WITH WARNINGS" ? 0 : 1;
|
|
19056
19084
|
} catch (e) {
|
|
19057
19085
|
if (e instanceof Aborted) {
|
|
@@ -19069,9 +19097,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
19069
19097
|
}
|
|
19070
19098
|
function renderCheck(check2, out3, colour) {
|
|
19071
19099
|
const broken = check2.state === "BROKEN";
|
|
19072
|
-
|
|
19073
|
-
const code2 = broken ? BOLD2 + RED2 : YELLOW2;
|
|
19074
|
-
out3(paint2(label.padEnd(8), code2, colour) + " " + terminalText(check2.id + " \u2014 " + check2.detail));
|
|
19100
|
+
out3(statusLine(broken ? "bad" : "warn", broken ? "ERROR" : "WARN", terminalText(check2.id + " \u2014 " + check2.detail), colour));
|
|
19075
19101
|
}
|
|
19076
19102
|
function postureOf(outcome) {
|
|
19077
19103
|
if (outcome.failure) return "INCOMPLETE";
|
|
@@ -19150,7 +19176,7 @@ function runDemo(cwd, head, runners, out3) {
|
|
|
19150
19176
|
out3("changed it while the demo ran; inspect with `git status`.");
|
|
19151
19177
|
}
|
|
19152
19178
|
}
|
|
19153
|
-
var Aborted, SECTIONS, MANUAL_CONTROLS,
|
|
19179
|
+
var Aborted, SECTIONS, MANUAL_CONTROLS, JS_TEST_PATH, JS_TEST_BLOCK;
|
|
19154
19180
|
var init_onboard = __esm({
|
|
19155
19181
|
"src/cli/onboard.ts"() {
|
|
19156
19182
|
"use strict";
|
|
@@ -19159,6 +19185,7 @@ var init_onboard = __esm({
|
|
|
19159
19185
|
init_doctor();
|
|
19160
19186
|
init_check();
|
|
19161
19187
|
init_text();
|
|
19188
|
+
init_status();
|
|
19162
19189
|
init_fingerprint();
|
|
19163
19190
|
init_policy();
|
|
19164
19191
|
init_policy_load();
|
|
@@ -19180,14 +19207,6 @@ var init_onboard = __esm({
|
|
|
19180
19207
|
"Code Owner review",
|
|
19181
19208
|
"dismiss stale approvals when new commits are pushed"
|
|
19182
19209
|
];
|
|
19183
|
-
ESC2 = "\x1B";
|
|
19184
|
-
RESET2 = `${ESC2}[0m`;
|
|
19185
|
-
BOLD2 = `${ESC2}[1m`;
|
|
19186
|
-
DIM2 = `${ESC2}[2m`;
|
|
19187
|
-
RED2 = `${ESC2}[31m`;
|
|
19188
|
-
YELLOW2 = `${ESC2}[33m`;
|
|
19189
|
-
GREEN2 = `${ESC2}[32m`;
|
|
19190
|
-
CYAN2 = `${ESC2}[36m`;
|
|
19191
19210
|
JS_TEST_PATH = /(?:^|\/)(?:[^/]+\.(?:test|spec)\.[cm]?[jt]sx?|__tests__\/[^/]+\.[cm]?[jt]sx?)$/;
|
|
19192
19211
|
JS_TEST_BLOCK = /^(\s*)(it|test|describe)(\s*\()/m;
|
|
19193
19212
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.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",
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"test": "vitest run",
|
|
48
48
|
"test:watch": "vitest",
|
|
49
49
|
"test:perf-smoke": "vitest run --config vitest.perf-smoke.config.ts --no-file-parallelism",
|
|
50
|
-
"check": "node dist/cli/index.js check"
|
|
50
|
+
"check": "node dist/cli/index.js check",
|
|
51
|
+
"probe:codex-runtime": "node harness/adapters/codex-probe.mjs"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
54
|
"picomatch": "^4.0.2",
|