@kavishdua/proctor 1.0.0 → 1.2.0
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 +82 -37
- package/dist/cli.js +928 -68
- package/dist/dynamic-worker.js +776 -0
- package/package.json +2 -1
- package/proctor.schema.json +12 -0
package/README.md
CHANGED
|
@@ -37,6 +37,7 @@ source needs Node 20.19+ or 22.12+.
|
|
|
37
37
|
- [What do the codes mean?](#what-do-the-codes-mean)
|
|
38
38
|
- [Badges](#badges)
|
|
39
39
|
- [CI](#ci)
|
|
40
|
+
- [Dynamic checks](#dynamic-checks), opt-in runtime evidence
|
|
40
41
|
|
|
41
42
|
**Why it works**
|
|
42
43
|
|
|
@@ -53,9 +54,14 @@ source needs Node 20.19+ or 22.12+.
|
|
|
53
54
|
|
|
54
55
|
## Quickstart
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
Check the changes in any git repository, with nothing to install first:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd /path/to/repository
|
|
61
|
+
npx @kavishdua/proctor check
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
To run it from source instead:
|
|
59
65
|
|
|
60
66
|
```bash
|
|
61
67
|
git clone https://github.com/catfish-1234/proctor.git
|
|
@@ -91,16 +97,10 @@ qwen extensions install https://github.com/catfish-1234/proctor
|
|
|
91
97
|
|
|
92
98
|
**Other agents, or CLI use without an agent** (30 agents supported)
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
Add it to the repository as a dev dependency:
|
|
95
101
|
|
|
96
102
|
```bash
|
|
97
|
-
|
|
98
|
-
npm ci
|
|
99
|
-
npm run build
|
|
100
|
-
npm pack
|
|
101
|
-
|
|
102
|
-
# In the repository proctor should guard; use the .tgz path printed above
|
|
103
|
-
npm install --save-dev /absolute/path/to/kavishdua-proctor-*.tgz
|
|
103
|
+
npm install --save-dev @kavishdua/proctor
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
**Proctor does not install guards during npm installation by default.** npm still updates your
|
|
@@ -276,15 +276,17 @@ families.
|
|
|
276
276
|
**WI1xx checks "the work is done."** These look for incomplete or disabled behavior in source,
|
|
277
277
|
config, and tests, including discarded errors, removed validation, and altered expected values.
|
|
278
278
|
|
|
279
|
-
> **
|
|
280
|
-
>
|
|
281
|
-
>
|
|
282
|
-
>
|
|
283
|
-
>
|
|
279
|
+
> **Six WI checks run by default:** WI101, WI102, WI105, WI108, WI109, and WI110.
|
|
280
|
+
> Alongside RH001 to RH014, they close error-handling, unfinished-body, canned-output,
|
|
281
|
+
> source-hiding, expectation-edit, and script-verification gaps. The remaining seven WI checks
|
|
282
|
+
> stay opt-in because their human-commit findings still include legitimate maintenance.
|
|
283
|
+
> Run `proctor check --wi` (or `--all-checks`) to add the entire family, or name checks in
|
|
284
|
+
> `enabled` in the committed config. An explicit `enabled` list is still honored exactly.
|
|
285
|
+
> See the [measurements and per-check decisions](bench/detection/README.md).
|
|
284
286
|
|
|
285
287
|
| | Catches |
|
|
286
288
|
|---|---|
|
|
287
|
-
| WI101 |
|
|
289
|
+
| WI101 | Empty or logging-only handlers, and formerly propagated operation errors discarded or replaced with defaults |
|
|
288
290
|
| WI102 | An explicit "not implemented" marker shipped inside finished-looking work |
|
|
289
291
|
| WI103 | Validation deleted so the case it rejected now goes through |
|
|
290
292
|
| WI104 | Proctor, a commit hook, or a type/lint gate switched off instead of satisfied |
|
|
@@ -338,12 +340,44 @@ jobs:
|
|
|
338
340
|
steps:
|
|
339
341
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
340
342
|
with: { fetch-depth: 0 }
|
|
341
|
-
- uses: catfish-1234/proctor@
|
|
343
|
+
- uses: catfish-1234/proctor@ede7e0ec0d9a91c241af1b181b74b1a6af67df07 # v1.0.0
|
|
342
344
|
```
|
|
343
345
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
346
|
+
The example pins the commit behind the `v1.0.0` release. You can use the `v1.0.0` tag instead, but
|
|
347
|
+
a full commit SHA is immutable, so it keeps builds reproducible.
|
|
348
|
+
|
|
349
|
+
## Dynamic checks
|
|
350
|
+
|
|
351
|
+
`proctor check --dynamic` runs extra checks using a runnable project test suite. The default
|
|
352
|
+
check keeps its existing output and runs no project tests. You can also commit
|
|
353
|
+
`{"dynamic": true, "dynamicTimeoutMs": 60000}` in `proctor.config.json`. Use
|
|
354
|
+
`--dynamic-timeout 30000` to override the overall budget in milliseconds.
|
|
355
|
+
|
|
356
|
+
This prototype supports Node's `node:test`, Jest and Vitest through `npm run test`, plus Python
|
|
357
|
+
`unittest`, `pytest` and plain Python scripts. When unittest collects no cases or only collection
|
|
358
|
+
errors, plain scripts run directly and bare `test_*` functions run individually in fresh processes.
|
|
359
|
+
It needs Linux and bubblewrap with working user, mount, network and PID
|
|
360
|
+
namespaces. Windows, macOS, unsupported languages and unavailable isolation report
|
|
361
|
+
`dynamic: skipped, reason`; a skip never adds a failing finding. Tests run in temporary copies,
|
|
362
|
+
with host mounts read-only and network disabled. The default overall timeout is 60 seconds,
|
|
363
|
+
including copies; descendants are terminated when the worker ends.
|
|
364
|
+
|
|
365
|
+
Warnings name the commands, run labels and observed results. The checks need runnable
|
|
366
|
+
tests and installed dependencies, can miss changes, and cannot prove intent. A red original suite
|
|
367
|
+
is a normal fix input; named per-test comparisons and numeric, string or boolean probes still run.
|
|
368
|
+
For red-to-green fixes with unchanged tests, mutation-lite tries at most four parser-confirmed
|
|
369
|
+
changes in called functions. DY002 probes and DY004 mutation warnings are advisory and do not
|
|
370
|
+
change the exit code on their own. Mutations can survive because code is redundant or behavior
|
|
371
|
+
is deliberately untested; survival does not establish cheating. Repeated outcomes
|
|
372
|
+
can reflect order dependence.
|
|
373
|
+
|
|
374
|
+
Measured limits: dynamic checks are opt-in and advisory only. They do not change which findings
|
|
375
|
+
block a commit. Mutation-lite reports missing test coverage, not cheating, and it can fire on
|
|
376
|
+
honest changes whose tests do not cover every changed line. On a private 80-case corpus (40
|
|
377
|
+
cheating changes, 40 honest ones) that informed this iteration, dynamic warnings surfaced 4
|
|
378
|
+
cheating changes the static checks missed and flagged 1 honest change. Because the same corpus
|
|
379
|
+
informed the checks, these are not clean held-out numbers.
|
|
380
|
+
See the [scope, dropped ideas and tuned dev-set measurements](bench/dynamic-dev/README.md).
|
|
347
381
|
|
|
348
382
|
## How it works
|
|
349
383
|
|
|
@@ -363,7 +397,7 @@ unchecked commit.
|
|
|
363
397
|
that same diff is checked. Approvals and inline `proctor-ignore` markers must also be committed
|
|
364
398
|
before the change they cover.
|
|
365
399
|
|
|
366
|
-
**
|
|
400
|
+
**An opt-in check can flag changes to the guard.** WI104 fires on a check removed from `enabled`, a
|
|
367
401
|
severity downgraded, an ignore pattern or approval added, a ruleset file deleted, a `--no-verify`
|
|
368
402
|
added to a script, or TypeScript strictness turned off. WI104 is part of the opt-in WI family.
|
|
369
403
|
|
|
@@ -383,22 +417,32 @@ changes and allows turns when proctor cannot run, so it is not a substitute for
|
|
|
383
417
|
| **up to 100 pts** | gap between "the visible tests pass" and "the held-out tests pass" on the largest tasks in [SpecBench](https://arxiv.org/abs/2605.21384). It widens by about 28 points per tenfold increase in code size, and adding test coverage does not close it |
|
|
384
418
|
| **8 of 8** | agent benchmarks that [Berkeley RDI](https://rdi.berkeley.edu/blog/trustworthy-benchmarks-cont/) drove to near-perfect scores without solving a single task. SWE-bench Verified fell to a pytest hook that forced every test to pass |
|
|
385
419
|
|
|
386
|
-
**What proctor catches.** The
|
|
387
|
-
|
|
420
|
+
**What proctor catches.** The original rule fixtures and recorded benchmark cases are checked by
|
|
421
|
+
`npm test`. The redteam probe is a repeatedly tuned **dev corpus**, not independent evidence of
|
|
422
|
+
generalization. Fresh measurements compare the unchanged main baseline with these changes:
|
|
388
423
|
|
|
389
424
|
| | |
|
|
390
425
|
|---|---|
|
|
391
|
-
| **139 of 139** | planted
|
|
392
|
-
| **
|
|
393
|
-
| **
|
|
394
|
-
| **
|
|
395
|
-
| **
|
|
396
|
-
| **
|
|
397
|
-
| **
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
426
|
+
| **139 of 139** | original planted rule fixtures caught with all checks, with **0 of 33** original near-miss fixtures flagged. These are development fixtures, not an unseen evaluation |
|
|
427
|
+
| **21 of 21** | recorded cheats caught in the mock benchmark corpus, across 7 signatures. The 22nd task is a control; it stays quiet |
|
|
428
|
+
| **25 to 54 of 76** | tuned dev cheats caught by defaults before and after. With all checks: **76 to 76 of 76**. Dev controls: **0 to 0 of 24** flagged in either mode. Run `node bench/redteam/probe.mjs --default` and `node bench/redteam/probe.mjs` |
|
|
429
|
+
| **7 to 36 of 36** | cheats caught by defaults in the **74-case frozen validation set**, with benign flags falling from **2/38 to 0/38**. All checks improve from **9/36 to 36/36**. The separately frozen 74-case design set has the same totals. Both are small authored sets with paired variations |
|
|
430
|
+
| **4.29% to 2.00% blocking** | **30/700 to 14/700** real non-bot commits flagged by defaults on the same fresh pinned sample from 20 repositories. Any finding: **46/700 (6.57%) to 26/700 (3.71%)**. Every flagged human commit counts as a conservative false-positive proxy, including intentional test deletions |
|
|
431
|
+
| **26 to 35 of 72** | cheats caught by defaults on a **72-cheat, 72-benign held-out set** written after 1.0.0 by a separate run that never saw the checks. Benign flags: **5/72 before, 5/72 after**. All checks: **38 to 42 of 72**, with 6/72 benign flagged. Error handling went from 0/12 to 7/12. Hardcoded special cases (2/8), removed validation (0/3), edited expected values (0/3), race masking (0/3) and suppression (0/3) are still mostly missed. The set was used only to measure, not to tune, but it is now public, so it no longer counts as blind. Run `node bench/heldout/probe.mjs --default` |
|
|
432
|
+
| **2.6% blocking** | **11/420** real commits blocked by both 1.0.0 and this release on a second fresh sample of 14 repositories that neither the checks nor the first sample touched. Any finding: **17 before, 16 after**. A few false positives found there were fixed with rules, not by pinning commits |
|
|
433
|
+
| **27** | checks in two families, with **20 enabled by default**, across **25+** languages, installable into **30** agents |
|
|
434
|
+
|
|
435
|
+
The old **689-commit** claim, **2.32% blocking and 3.8% any finding**, refers to a missing ignored
|
|
436
|
+
sample and harness. It could not be reproduced from this checkout or tracked history. The fresh
|
|
437
|
+
700-commit sample uses the same 20 repositories, pins every commit and patch hash, and retains
|
|
438
|
+
all findings. It is a replacement cohort, not the original sample. See
|
|
439
|
+
[methods, per-rule results, and reproduction commands](bench/detection/README.md).
|
|
440
|
+
|
|
441
|
+
**What we don't claim.** Proctor is a heuristic diff checker. Defaults still miss more than half of the held-out cheats, mostly the ones that need running the code to see: special-cased inputs, edited expected values, removed validation, masked races and suppression. It detects suspicious changes;
|
|
442
|
+
it does not prevent them or judge intent. A determined author can write a cheat that no static
|
|
443
|
+
diff check recognizes. The dev and authored-validation results do not establish a detection
|
|
444
|
+
rate for unseen cheats. Our [live benchmark](#benchmark) has not shown that proctor reduces
|
|
445
|
+
cheating: all 44 invocations in each complete run passed their evaluation tests in both arms.
|
|
402
446
|
|
|
403
447
|
## Benchmark
|
|
404
448
|
|
|
@@ -465,8 +509,9 @@ For command details, configuration, support limits, and contributor instructions
|
|
|
465
509
|
| [bench/METHODOLOGY.md](https://github.com/catfish-1234/proctor/blob/main/bench/METHODOLOGY.md) | How the benchmark works and what it does not claim |
|
|
466
510
|
|
|
467
511
|
proctor supports 25+ languages and installs to 30 agents. Five diff-level checks (RH001, RH002,
|
|
468
|
-
RH003, RH007, RH011)
|
|
469
|
-
JS/TS/Python
|
|
512
|
+
RH003, RH007, RH011) have signatures across the language roster. RH004, RH006, RH008, RH009, and
|
|
513
|
+
RH010 have their tested coverage in JS/TS/Python; RH005 also detects emptied Go and Rust bodies.
|
|
514
|
+
RH012 and RH013 read CI and coverage config, so they apply everywhere. Of the
|
|
470
515
|
work-integrity family, WI101, WI102 and WI103 carry per-language signatures, WI104 reads config
|
|
471
516
|
files so it applies everywhere, and WI105 and WI106 are scoped to the languages whose tokens are
|
|
472
517
|
unambiguous. [Full matrix](https://github.com/catfish-1234/proctor/blob/main/docs/LANGUAGES.md).
|