tamperward 1.2.0 → 1.2.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 CHANGED
@@ -102,7 +102,7 @@ with the same engine it ships.
102
102
  - `src/engine.ts` — runs the enabled rules over `Change[]`; honours `policy.ignore`.
103
103
  - `src/cli/` — `tamperward check --staged | --worktree | --diff <base>...<head>`,
104
104
  exit 1 on any blocking finding.
105
- - `test/` — 226 tests, including the AST-vs-regex, self-hosting precision, and
105
+ - `test/` — 235 tests, including the AST-vs-regex, self-hosting precision, and
106
106
  pre-go-live audit regression cases, and the renderer accessibility contract.
107
107
 
108
108
  - `src/adapters/claude/` + `src/cli/hook.ts` — the agent layer: `tamperward hook claude`
package/dist/cli/index.js CHANGED
@@ -829,10 +829,15 @@ var coverageLowering = {
829
829
 
830
830
  // src/detectors/ci-tampering.ts
831
831
  var RULE5 = "ci-tampering";
832
- var STEP = /^\s*-?\s*(?:run|uses):/;
832
+ var USES = /^\s*-\s*uses:/;
833
833
  var CHECK = /\b(test|tests|lint|typecheck|type-check|tsc|eslint|jest|vitest|playwright|coverage|tamperward)\b/i;
834
834
  var YAML_KEY = /^\s*-?\s*[A-Za-z_][\w-]*:\s*(?:$|\S)/;
835
- var RUNNER = /\b(npm|npx|pnpm|yarn|bun|make|cargo|pytest|python|jest|vitest|eslint|tsc|playwright|tamperward|gradle|mvn|dotnet)\b/;
835
+ var INVOKES_TOOL = /(?:^\s*|[;&|`]\s*|\$\(\s*|\b(?:npx|yarn|pnpm|bunx?)\s+)(?:jest|vitest|eslint|tsc|playwright|pytest|tamperward)\b/;
836
+ var INVOKES_SCRIPT = /\b(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|tests|lint|typecheck|type-check|coverage)\b|\b(?:make|cargo|go)\s+test\b|\bgradle\w*\s+(?:test|check)\b/;
837
+ var invokesCheck = (line) => INVOKES_TOOL.test(line) || INVOKES_SCRIPT.test(line);
838
+ function commandCore(line) {
839
+ return line.trim().replace(/^-\s*/, "").replace(/^(?:run|uses):\s*/, "").replace(/\s+/g, " ").trim();
840
+ }
836
841
  var uncommented = (v) => v.replace(/\s+#.*$/, "").trim();
837
842
  function isAlwaysFalse(raw) {
838
843
  const v = uncommented(raw);
@@ -885,16 +890,18 @@ var ciTampering = {
885
890
  );
886
891
  }
887
892
  }
888
- const stillPresent = new Set(addedLines(c).map((l) => l.content.trim()));
893
+ const afterCores = new Set(
894
+ (c.after != null ? c.after.split("\n") : addedLines(c).map((l) => l.content)).map(commandCore)
895
+ );
889
896
  for (const l of removedLines(c)) {
890
- if (stillPresent.has(l.content.trim())) continue;
891
- const isStepLine = STEP.test(l.content) && CHECK.test(l.content);
892
- const isRunBodyLine = !YAML_KEY.test(l.content) && RUNNER.test(l.content) && CHECK.test(l.content);
893
- if (!isStepLine && !isRunBodyLine) continue;
897
+ const isUsesLine = USES.test(l.content) && CHECK.test(l.content);
898
+ const isCheckCommand = !isUsesLine && !/^\s*-?\s*uses:/.test(l.content) && (YAML_KEY.test(l.content) ? /^\s*-?\s*run:/.test(l.content) : true) && invokesCheck(l.content);
899
+ if (!isUsesLine && !isCheckCommand) continue;
900
+ if (afterCores.has(commandCore(l.content))) continue;
894
901
  out.push(
895
902
  makeFinding(RULE5, policy, {
896
903
  file: c.path,
897
- message: isStepLine ? "A CI check step (test/lint/typecheck) was removed." : "A CI check command was removed from a run block.",
904
+ message: isUsesLine ? "A CI check step (test/lint/typecheck) was removed." : "A CI check command was removed from a run block.",
898
905
  evidence: l.content.trim(),
899
906
  remediation: "Restore the step. Removing the check that protects main is itself the tamper."
900
907
  })
@@ -1232,7 +1239,7 @@ var testDeletion = {
1232
1239
 
1233
1240
  // src/detectors/snapshot-rewrite.ts
1234
1241
  var RULE8 = "snapshot-rewrite";
1235
- var RUNNER2 = /\b(?:jest|vitest|playwright|ava)\b/;
1242
+ var RUNNER = /\b(?:jest|vitest|playwright|ava)\b/;
1236
1243
  var UPDATE_ANY = /--update-?[sS]napshots?\b/;
1237
1244
  var UPDATE_WITH_RUNNER = /(?:^|\s)(?:-u|--update)(?:\s|$)/;
1238
1245
  var REGEN_SCRIPT = /\b(?:update|regen(?:erate)?|re?bless)[-_.]?(?:golden|snapshots?|baselines?|expected)\b/i;
@@ -1256,7 +1263,7 @@ var snapshotRewrite = {
1256
1263
  for (const seg of segments(c.raw)) {
1257
1264
  let why = null;
1258
1265
  if (UPDATE_ANY.test(seg)) why = "the snapshot-update flag rewrites every failing snapshot to match current output";
1259
- else if (RUNNER2.test(seg) && UPDATE_WITH_RUNNER.test(seg)) why = "running the test runner in update mode rewrites failing snapshots to match current output";
1266
+ else if (RUNNER.test(seg) && UPDATE_WITH_RUNNER.test(seg)) why = "running the test runner in update mode rewrites failing snapshots to match current output";
1260
1267
  else if (REGEN_SCRIPT.test(seg)) why = "a regeneration script rewrites the recorded expected output from current output";
1261
1268
  else {
1262
1269
  const path = MUTATE.test(seg) ? namesProtectedSnapshot(seg, policy) : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "1.2.0",
3
+ "version": "1.2.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",