tamperward 2.29.21 → 2.30.2

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.
Files changed (2) hide show
  1. package/dist/cli/index.js +90 -58
  2. package/package.json +3 -2
package/dist/cli/index.js CHANGED
@@ -9837,7 +9837,8 @@ var init_test_deletion = __esm({
9837
9837
  fed.push(...toks);
9838
9838
  const testToks = source.filter((t) => expand(t).some(specPath));
9839
9839
  const dirToks = source.filter((t) => !t.startsWith("-") && !testToks.includes(t) && expand(t).some(dirPath));
9840
- if (testToks.length === 0 && dirToks.length === 0) continue;
9840
+ const gitResetHard = toks.some((t) => t === "git" || t.endsWith("/git")) && toks.some((t) => t === "--hard" || t === "--merge" || t === "--keep");
9841
+ if (testToks.length === 0 && dirToks.length === 0 && !(gitResetHard && rootHasProtected())) continue;
9841
9842
  const named = [...testToks, ...dirToks];
9842
9843
  let at = 0;
9843
9844
  while (at < toks.length && WRAPPERS.test(toks[at])) at++;
@@ -9856,9 +9857,19 @@ var init_test_deletion = __esm({
9856
9857
  const gitSub = cmd === "git" ? gitSubcommand(cmdToks) : null;
9857
9858
  const gitRestoresOld = (gitSub === "checkout" || gitSub === "restore") && (() => {
9858
9859
  const src = seg.match(/--source[= ]\s*(\S+)/)?.[1];
9860
+ const stagedRequested = cmdToks.includes("--staged") || cmdToks.includes("-S");
9861
+ const worktreeRequested = cmdToks.includes("--worktree") || cmdToks.includes("-W");
9862
+ const stagedOnly = stagedRequested && !worktreeRequested;
9863
+ if (stagedOnly) return false;
9859
9864
  const revIdx = cmdToks.findIndex((t, i) => i >= 2 && !t.startsWith("-") && !named.includes(t) && t !== "--");
9860
9865
  const rev2 = src ?? (revIdx >= 0 ? cmdToks[revIdx] : void 0);
9861
- if (!rev2 || rev2 === "HEAD" || rev2 === "@" || revIsHead(rev2, ctx) === true) return false;
9866
+ if (rev2 && (rev2 === "HEAD" || rev2 === "@" || revIsHead(rev2, ctx) === true)) return false;
9867
+ if (!rev2) {
9868
+ const stagedRequested2 = cmdToks.includes("--staged") || cmdToks.includes("-S");
9869
+ const worktreeRequested2 = cmdToks.includes("--worktree") || cmdToks.includes("-W");
9870
+ const stagedOnly2 = stagedRequested2 && !worktreeRequested2;
9871
+ return !stagedOnly2 && gitSub === "restore";
9872
+ }
9862
9873
  if (src || seg.includes(" -- ")) return true;
9863
9874
  return revIdx >= 0 && cmdToks.some((t, i) => i > revIdx && named.includes(t));
9864
9875
  })();
@@ -9894,6 +9905,8 @@ var init_test_deletion = __esm({
9894
9905
  why = "find -delete removes test files";
9895
9906
  } else if (gitRestoresOld) {
9896
9907
  why = "git checkout <rev> replaces a test file with an older version";
9908
+ } else if (gitSub === "reset" && gitResetHard) {
9909
+ why = "git reset can discard changes to a test file";
9897
9910
  } else if (cmd === "mv") {
9898
9911
  const dest = positional[positional.length - 1];
9899
9912
  if (dest && testToks.length > 0 && !isSpec(dest)) {
@@ -10980,6 +10993,41 @@ var init_machine_output = __esm({
10980
10993
  }
10981
10994
  });
10982
10995
 
10996
+ // src/cli/render/status.ts
10997
+ function paint(s, code2, on) {
10998
+ return on ? code2 + s + RESET : s;
10999
+ }
11000
+ function severityColour(sev) {
11001
+ return TONE[sev].colour;
11002
+ }
11003
+ function statusLine(severity, label, text, colour) {
11004
+ const t = TONE[severity];
11005
+ const painted = paint(label.padEnd(STATUS_LABEL_WIDTH), (t.bold ? BOLD : "") + t.colour, colour);
11006
+ return `${painted} ${text}`;
11007
+ }
11008
+ var ESC, RESET, BOLD, DIM, truecolour, RED, YELLOW, GREEN, CYAN, TONE, STATUS_LABEL_WIDTH;
11009
+ var init_status = __esm({
11010
+ "src/cli/render/status.ts"() {
11011
+ "use strict";
11012
+ ESC = "\x1B";
11013
+ RESET = `${ESC}[0m`;
11014
+ BOLD = `${ESC}[1m`;
11015
+ DIM = `${ESC}[2m`;
11016
+ truecolour = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
11017
+ RED = truecolour(255, 107, 107);
11018
+ YELLOW = truecolour(227, 179, 65);
11019
+ GREEN = truecolour(63, 185, 80);
11020
+ CYAN = truecolour(86, 212, 221);
11021
+ TONE = {
11022
+ ok: { colour: GREEN, bold: false },
11023
+ warn: { colour: YELLOW, bold: false },
11024
+ bad: { colour: RED, bold: true },
11025
+ info: { colour: CYAN, bold: false }
11026
+ };
11027
+ STATUS_LABEL_WIDTH = 8;
11028
+ }
11029
+ });
11030
+
10983
11031
  // src/cli/render/text.ts
10984
11032
  function colourEnabled(env = process.env, stream = process.stdout) {
10985
11033
  if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") return false;
@@ -10992,9 +11040,6 @@ function terminalWidth(stream = process.stdout) {
10992
11040
  if (!c || c < 40) return 80;
10993
11041
  return Math.min(c, 100);
10994
11042
  }
10995
- function paint(s, code2, on) {
10996
- return on ? code2 + s + RESET : s;
10997
- }
10998
11043
  function wrap(text, width) {
10999
11044
  const out3 = [];
11000
11045
  let cur = "";
@@ -11080,20 +11125,12 @@ function renderText(input, opts) {
11080
11125
  }
11081
11126
  return out3.join("\n").replace(/\n+$/, "") + "\n";
11082
11127
  }
11083
- var ESC, RESET, BOLD, DIM, truecolour, RED, YELLOW, GREEN, CYAN, SIGNOFF_NOTE;
11128
+ var SIGNOFF_NOTE;
11084
11129
  var init_text = __esm({
11085
11130
  "src/cli/render/text.ts"() {
11086
11131
  "use strict";
11087
11132
  init_policy();
11088
- ESC = "\x1B";
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);
11133
+ init_status();
11097
11134
  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
11135
  }
11099
11136
  });
@@ -15940,8 +15977,14 @@ function verifyVerdictLine(verdict2, ctx) {
15940
15977
  }
15941
15978
  function runVerify(opts) {
15942
15979
  const cwd = opts.cwd ?? process.cwd();
15980
+ const colour = opts.silent ? false : colourEnabled(process.env, process.stdout);
15981
+ const paintVerify = (s) => {
15982
+ if (!s.startsWith("verify:")) return s;
15983
+ const sev = /failing closed/i.test(s) ? "bad" : "info";
15984
+ return paint("verify:", (sev === "bad" ? BOLD : "") + severityColour(sev), colour) + s.slice("verify:".length);
15985
+ };
15943
15986
  const out3 = opts.silent ? (_s) => {
15944
- } : (s) => void process.stdout.write(s + "\n");
15987
+ } : (s) => void process.stdout.write(paintVerify(s) + "\n");
15945
15988
  let filesystemCaseSensitive;
15946
15989
  const caseReport = () => filesystemCaseSensitive === void 0 ? {} : { filesystem_case_sensitive: filesystemCaseSensitive };
15947
15990
  const cannotVerify = (reason, detail, extra = {}) => {
@@ -16374,6 +16417,8 @@ var init_verify = __esm({
16374
16417
  init_machine_output();
16375
16418
  init_signoff();
16376
16419
  init_suite_diagnostics();
16420
+ init_text();
16421
+ init_status();
16377
16422
  OVERLAY_CLASSES = ["tests", "snapshots", "config"];
16378
16423
  VERIFICATION_SURFACE = [
16379
16424
  // Python / pytest — read from the rootdir, and conftest at any depth
@@ -17626,12 +17671,15 @@ function emitReport(opts, checks, authoritative) {
17626
17671
  process.stdout.write(JSON.stringify(report2) + "\n");
17627
17672
  return;
17628
17673
  }
17674
+ const colour = colourEnabled(process.env, process.stdout);
17629
17675
  for (const check2 of checks) {
17630
17676
  if (check2.id === "observer") {
17631
17677
  process.stdout.write(`tamperward doctor: transient observer: ${check2.detail}
17632
17678
  `);
17633
17679
  } else {
17634
- process.stdout.write(`tamperward doctor: [${check2.state}] ${check2.id} \u2014 ${check2.detail}
17680
+ const sev = check2.state === "OK" ? "ok" : check2.state === "WARN" ? "warn" : check2.state === "BROKEN" ? "bad" : "info";
17681
+ const tag = paint(`[${check2.state}]`, (sev === "bad" ? BOLD : "") + severityColour(sev), colour);
17682
+ process.stdout.write(`tamperward doctor: ${tag} ${check2.id} \u2014 ${check2.detail}
17635
17683
  `);
17636
17684
  }
17637
17685
  }
@@ -18021,6 +18069,8 @@ var init_doctor = __esm({
18021
18069
  init_machine_output();
18022
18070
  init_narrow();
18023
18071
  init_repo_context();
18072
+ init_text();
18073
+ init_status();
18024
18074
  VERIFY_COMMAND = /\btamperward(?:@\S+)?\s+verify\b/;
18025
18075
  REPOSITORY_REQUIRED_CHECKS = [
18026
18076
  "typecheck",
@@ -18665,9 +18715,6 @@ function readlineAsker(input, output) {
18665
18715
  };
18666
18716
  return ask;
18667
18717
  }
18668
- function paint2(text, code2, on) {
18669
- return on ? code2 + text + RESET2 : text;
18670
- }
18671
18718
  function terminalText(text) {
18672
18719
  return stripControl(text).replace(/\s+/g, " ").trim();
18673
18720
  }
@@ -18733,9 +18780,9 @@ function writeVerifyCommand(cwd, command) {
18733
18780
  }
18734
18781
  async function runOnboard(opts, io = {}) {
18735
18782
  const requestedCwd = resolve12(opts.cwd ?? process.cwd());
18736
- const out3 = io.out ?? ((line) => void process.stdout.write(line + "\n"));
18737
- const errLine = (line) => void process.stderr.write(line + "\n");
18738
- const rawErr = (line) => errLine(terminalText(line));
18783
+ const out3 = io.out ?? ((line2) => void process.stdout.write(line2 + "\n"));
18784
+ const errLine = (line2) => void process.stderr.write(line2 + "\n");
18785
+ const rawErr = (line2) => errLine(terminalText(line2));
18739
18786
  const platform = io.platform ?? process.platform;
18740
18787
  const colour = io.colour ?? colourEnabled(process.env, process.stdout);
18741
18788
  const runners = {
@@ -18747,18 +18794,12 @@ async function runOnboard(opts, io = {}) {
18747
18794
  };
18748
18795
  const interactive = io.interactive ?? (Boolean(process.stdin.isTTY) && !process.env.CI && !process.env.GITHUB_ACTIONS);
18749
18796
  const scripted = Boolean(opts.yes);
18750
- const tone = (kind) => {
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
- };
18797
+ const line = (label, text, kind) => kind === "dim" ? paint(label.padEnd(8), DIM, colour) + " " + terminalText(text) : statusLine(kind, label, terminalText(text), colour);
18757
18798
  const status = (label, text, kind = "info") => {
18758
- out3(paint2(label.padEnd(8), (kind === "bad" ? BOLD2 : "") + tone(kind), colour) + " " + terminalText(text));
18799
+ out3(line(label, text, kind));
18759
18800
  };
18760
18801
  const errStatus = (label, text, kind = "info") => {
18761
- errLine(paint2(label.padEnd(8), (kind === "bad" ? BOLD2 : "") + tone(kind), colour) + " " + terminalText(text));
18802
+ errLine(line(label, text, kind));
18762
18803
  };
18763
18804
  const fail = (text) => errStatus("ERROR", text, "bad");
18764
18805
  if (!interactive && !scripted) {
@@ -18808,7 +18849,7 @@ async function runOnboard(opts, io = {}) {
18808
18849
  const section = (n) => {
18809
18850
  sectionNo = n;
18810
18851
  out3("");
18811
- out3(paint2(n + "/" + SECTIONS.length + " " + SECTIONS[n - 1], BOLD2 + CYAN2, colour));
18852
+ out3(paint(n + "/" + SECTIONS.length + " " + SECTIONS[n - 1], BOLD + CYAN, colour));
18812
18853
  };
18813
18854
  const wrote = [];
18814
18855
  let verifyCommand;
@@ -18818,9 +18859,9 @@ async function runOnboard(opts, io = {}) {
18818
18859
  let declined = false;
18819
18860
  let doctorOutcome = null;
18820
18861
  try {
18821
- out3(paint2("TamperWard onboarding", BOLD2, colour));
18822
- out3(paint2("v" + TW_VERSION + " \xB7 Node " + process.versions.node + " \xB7 " + platformLabel(platform) + "/" + process.arch, DIM2, colour));
18823
- out3(paint2(terminalText(cwd), DIM2, colour));
18862
+ out3(paint("TamperWard onboarding", BOLD, colour));
18863
+ out3(paint("v" + TW_VERSION + " \xB7 Node " + process.versions.node + " \xB7 " + platformLabel(platform) + "/" + process.arch, DIM, colour));
18864
+ out3(paint(terminalText(cwd), DIM, colour));
18824
18865
  section(1);
18825
18866
  const lifecycle = lifecyclePlatformCheck(platform);
18826
18867
  const localVerifySupported = localVerifierShell(platform, "true") !== null;
@@ -18833,7 +18874,7 @@ async function runOnboard(opts, io = {}) {
18833
18874
  }
18834
18875
  const head = git5(cwd, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"])?.trim() ?? null;
18835
18876
  const treeStatus = git5(cwd, ["status", "--porcelain", "--untracked-files=all"]) ?? "";
18836
- const dirty = treeStatus.split("\n").filter(Boolean).map((line) => line.slice(3).split(" -> ").at(-1) ?? "");
18877
+ const dirty = treeStatus.split("\n").filter(Boolean).map((line2) => line2.slice(3).split(" -> ").at(-1) ?? "");
18837
18878
  if (!head) {
18838
18879
  const count = dirty.length;
18839
18880
  status(
@@ -18955,7 +18996,7 @@ async function runOnboard(opts, io = {}) {
18955
18996
  }
18956
18997
  if (!verifyCommand) {
18957
18998
  status("ACTION", "Verification is not configured; CI will fail closed until it is.", "warn");
18958
- out3(paint2(' Set it later with: tamperward onboard --verify-command "<suite command>"', DIM2, colour));
18999
+ out3(paint(' Set it later with: tamperward onboard --verify-command "<suite command>"', DIM, colour));
18959
19000
  } else if (!localVerifySupported) {
18960
19001
  status("LIMITED", "Local verification is unavailable on " + platformLabel(platform) + "; use a digest-pinned container verifier.", "warn");
18961
19002
  } else if (!head) {
@@ -18981,7 +19022,7 @@ async function runOnboard(opts, io = {}) {
18981
19022
  status("SKIP", "Safe demo becomes available after the first commit.", "dim");
18982
19023
  } else {
18983
19024
  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, (line) => out3(terminalText(line)));
19025
+ if (wanted) runDemo(cwd, head, runners, (line2) => out3(terminalText(line2)));
18985
19026
  }
18986
19027
  }
18987
19028
  section(4);
@@ -19029,14 +19070,14 @@ async function runOnboard(opts, io = {}) {
19029
19070
  status("OK", "GitHub authority enforced for " + doctorOutcome.github.repo + "#" + doctorOutcome.github.branch + ".", "ok");
19030
19071
  } else if (!repo) {
19031
19072
  status("ACTION", "GitHub authority is not configured for this repository.", "warn");
19032
- out3(paint2(" If GitHub will provide repository authority, run: " + terminalText(doctorCommand), DIM2, colour));
19033
- out3(paint2(" If this repository will use GitHub CI authority, configure:", DIM2, colour));
19034
- for (const line of MANUAL_CONTROLS) out3(paint2(" " + line, DIM2, colour));
19073
+ out3(paint(" If GitHub will provide repository authority, run: " + terminalText(doctorCommand), DIM, colour));
19074
+ out3(paint(" If this repository will use GitHub CI authority, configure:", DIM, colour));
19075
+ for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
19035
19076
  } else {
19036
19077
  status("ACTION", "GitHub authority is not verified yet.", "warn");
19037
- out3(paint2(" " + terminalText(doctorCommand), DIM2, colour));
19038
- out3(paint2(" GitHub authority requires all three controls:", DIM2, colour));
19039
- for (const line of MANUAL_CONTROLS) out3(paint2(" " + line, DIM2, colour));
19078
+ out3(paint(" " + terminalText(doctorCommand), DIM, colour));
19079
+ out3(paint(" GitHub authority requires all three controls:", DIM, colour));
19080
+ for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
19040
19081
  }
19041
19082
  const commitPaths = [...new Set(wrote)].filter((path) => committableSetupPath(cwd, path));
19042
19083
  if (commitPaths.length) {
@@ -19051,7 +19092,7 @@ async function runOnboard(opts, io = {}) {
19051
19092
  if (verifyResult) {
19052
19093
  status("VERIFY", verifyResult.summary?.verdict ?? "exit " + verifyResult.code, verifyResult.code === 0 ? "ok" : "warn");
19053
19094
  }
19054
- out3(paint2(" Daily: tamperward check --worktree \xB7 tamperward verify --base <base>", DIM2, colour));
19095
+ out3(paint(" Daily: tamperward check --worktree \xB7 tamperward verify --base <base>", DIM, colour));
19055
19096
  return posture === "READY" || posture === "READY WITH WARNINGS" ? 0 : 1;
19056
19097
  } catch (e) {
19057
19098
  if (e instanceof Aborted) {
@@ -19069,9 +19110,7 @@ async function runOnboard(opts, io = {}) {
19069
19110
  }
19070
19111
  function renderCheck(check2, out3, colour) {
19071
19112
  const broken = check2.state === "BROKEN";
19072
- const label = broken ? "ERROR" : "WARN";
19073
- const code2 = broken ? BOLD2 + RED2 : YELLOW2;
19074
- out3(paint2(label.padEnd(8), code2, colour) + " " + terminalText(check2.id + " \u2014 " + check2.detail));
19113
+ out3(statusLine(broken ? "bad" : "warn", broken ? "ERROR" : "WARN", terminalText(check2.id + " \u2014 " + check2.detail), colour));
19075
19114
  }
19076
19115
  function postureOf(outcome) {
19077
19116
  if (outcome.failure) return "INCOMPLETE";
@@ -19150,7 +19189,7 @@ function runDemo(cwd, head, runners, out3) {
19150
19189
  out3("changed it while the demo ran; inspect with `git status`.");
19151
19190
  }
19152
19191
  }
19153
- var Aborted, SECTIONS, MANUAL_CONTROLS, ESC2, RESET2, BOLD2, DIM2, RED2, YELLOW2, GREEN2, CYAN2, JS_TEST_PATH, JS_TEST_BLOCK;
19192
+ var Aborted, SECTIONS, MANUAL_CONTROLS, JS_TEST_PATH, JS_TEST_BLOCK;
19154
19193
  var init_onboard = __esm({
19155
19194
  "src/cli/onboard.ts"() {
19156
19195
  "use strict";
@@ -19159,6 +19198,7 @@ var init_onboard = __esm({
19159
19198
  init_doctor();
19160
19199
  init_check();
19161
19200
  init_text();
19201
+ init_status();
19162
19202
  init_fingerprint();
19163
19203
  init_policy();
19164
19204
  init_policy_load();
@@ -19180,14 +19220,6 @@ var init_onboard = __esm({
19180
19220
  "Code Owner review",
19181
19221
  "dismiss stale approvals when new commits are pushed"
19182
19222
  ];
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
19223
  JS_TEST_PATH = /(?:^|\/)(?:[^/]+\.(?:test|spec)\.[cm]?[jt]sx?|__tests__\/[^/]+\.[cm]?[jt]sx?)$/;
19192
19224
  JS_TEST_BLOCK = /^(\s*)(it|test|describe)(\s*\()/m;
19193
19225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.29.21",
3
+ "version": "2.30.2",
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",