tamperward 2.10.3 → 2.10.4
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 +8 -2
- package/dist/cli/index.js +21 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,13 @@ Earlier controlled experiments → **[the research series](./docs/blog/index.md)
|
|
|
73
73
|
> run had just restored — which was present from v1.9.0 onward, so rounds 2, 3
|
|
74
74
|
> and 3.1 all ran on a verifier carrying it. No evidence any agent used it; the
|
|
75
75
|
> layer's authority in those rounds was nonetheless weaker than described at the
|
|
76
|
-
> time. Round 4 is
|
|
76
|
+
> time. **Round 4 is registered and frozen, not yet run:** a fresh pool of 110
|
|
77
|
+
> paired repositories under `claude-sonnet-5`, treatment **2.10.3** pinned by
|
|
78
|
+
> artefact hash, a confirmatory masked-failure endpoint (exact McNemar), and the
|
|
79
|
+
> whole draw — task order, arm assignment, and a separate 22-pair instability
|
|
80
|
+
> budget — derived from committed seeds before the first counted trajectory. The
|
|
81
|
+
> methodology and preregistration are published, with no counted numbers:
|
|
82
|
+
> [How round 4 is built to be hard to fool](./docs/blog/how-round-4-is-built-to-be-hard-to-fool.md).
|
|
77
83
|
|
|
78
84
|
## Architecture
|
|
79
85
|
|
|
@@ -395,7 +401,7 @@ via npm trusted publishing with SLSA provenance. Full rule:
|
|
|
395
401
|
|
|
396
402
|
```bash
|
|
397
403
|
npm install && npm run build # bundles the CLI to dist/cli/index.js
|
|
398
|
-
npm test #
|
|
404
|
+
npm test # 2,100+ tests — parser, detectors, engine, policy, renderers
|
|
399
405
|
npm run typecheck
|
|
400
406
|
```
|
|
401
407
|
|
package/dist/cli/index.js
CHANGED
|
@@ -1230,12 +1230,16 @@ var lintSuppression = {
|
|
|
1230
1230
|
|
|
1231
1231
|
// src/detectors/test-skip.ts
|
|
1232
1232
|
var RULE3 = "test-skip";
|
|
1233
|
+
var acc = (names) => `(?:\\s*\\.\\s*(?:${names})(?![\\w$])|\\s*\\[\\s*['"\`](?:${names})['"\`]\\s*\\])`;
|
|
1234
|
+
var JS_RUNNER = "\\b(?:it|test|describe|suite)";
|
|
1235
|
+
var JS_MOD = "concurrent|sequential|shuffle";
|
|
1233
1236
|
var PATTERNS2 = {
|
|
1234
1237
|
js: [
|
|
1235
|
-
//
|
|
1236
|
-
|
|
1237
|
-
{ re:
|
|
1238
|
-
{ re:
|
|
1238
|
+
// The skip/only/todo family on a runner, by dot-or-bracket access, with one optional
|
|
1239
|
+
// vitest concurrency modifier hop: test.skip, test . skip, test['skip'], it.concurrent.skip.
|
|
1240
|
+
{ re: new RegExp(JS_RUNNER + acc(JS_MOD) + "?" + acc("skip|only|todo")), why: "a .skip/.only/.todo marker" },
|
|
1241
|
+
{ re: new RegExp(JS_RUNNER + acc("skipIf|runIf") + "\\s*\\("), why: "a .skipIf()/.runIf() condition (the test runs only when the condition allows)" },
|
|
1242
|
+
{ re: new RegExp(JS_RUNNER + acc("fails|failing") + "\\s*\\("), why: "a .fails/.failing marker (the test now passes by failing)" },
|
|
1239
1243
|
{ re: /\b(?:it|test|describe)\.each\s*\(\s*\[\s*\]\s*\)/, why: "an empty .each table (no case ever runs)" },
|
|
1240
1244
|
{ re: /\b(?:xit|xtest|xdescribe)\s*\(/, why: "an x-prefixed disabled test" },
|
|
1241
1245
|
{ re: /\b(?:fit|ftest|fdescribe)\s*\(/, why: "an f-prefixed focused test (narrows the suite)" },
|
|
@@ -1249,7 +1253,7 @@ var PATTERNS2 = {
|
|
|
1249
1253
|
{ re: /\b(?:it|test|describe|suite)\s*\(\s*(['"`])(?:(?!\1).)*\1\s*,\s*\{[^}]*?\bskip:(?!\s*(?:false|0)\b)/, why: "a { skip: ... } option disabling the test (node:test options form)" },
|
|
1250
1254
|
{ re: /\bskip:\s*(?:true|['"`])/, why: "a { skip: ... } option disabling the test (node:test options form)" },
|
|
1251
1255
|
{ re: /\btodo:\s*(?:true|['"`])/, why: "a { todo: ... } option (the test no longer fails the run)" },
|
|
1252
|
-
{ re:
|
|
1256
|
+
{ re: new RegExp("\\b(?:t|ctx|context|this)" + acc("skip") + "\\s*\\("), why: "a runtime t.skip()/this.skip() call" }
|
|
1253
1257
|
],
|
|
1254
1258
|
py: [
|
|
1255
1259
|
// `import pytest as pt` makes the decorator `@pt.mark.skip`; the module alias is free.
|
|
@@ -1306,6 +1310,17 @@ var PATTERNS2 = {
|
|
|
1306
1310
|
{ re: /\bAssert\.Inconclusive\(/, why: "an Assert.Inconclusive() call (the test ends without a verdict)" }
|
|
1307
1311
|
]
|
|
1308
1312
|
};
|
|
1313
|
+
function matchesOutsideString(p, content, lang) {
|
|
1314
|
+
if (p.comment) return p.re.test(content);
|
|
1315
|
+
const re = p.re.global ? p.re : new RegExp(p.re.source, p.re.flags + "g");
|
|
1316
|
+
re.lastIndex = 0;
|
|
1317
|
+
let m;
|
|
1318
|
+
while ((m = re.exec(content)) !== null) {
|
|
1319
|
+
if (!insideStringLiteral(content, m.index, lang)) return true;
|
|
1320
|
+
if (m.index === re.lastIndex) re.lastIndex++;
|
|
1321
|
+
}
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1309
1324
|
var testSkip = {
|
|
1310
1325
|
id: RULE3,
|
|
1311
1326
|
surface: ["file"],
|
|
@@ -1321,7 +1336,7 @@ var testSkip = {
|
|
|
1321
1336
|
const comment = isCommentLine(l.content.trim(), lang);
|
|
1322
1337
|
for (const p of patterns) {
|
|
1323
1338
|
if (comment && !p.comment) continue;
|
|
1324
|
-
if (p
|
|
1339
|
+
if (matchesOutsideString(p, l.content, lang)) {
|
|
1325
1340
|
out2.push(
|
|
1326
1341
|
makeFinding(RULE3, policy, {
|
|
1327
1342
|
file: c.path,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.4",
|
|
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",
|