promptwheel 0.7.0 → 0.7.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
@@ -75,6 +75,8 @@ npx promptwheel run # detection ON by default · exit 0 wi
75
75
 
76
76
  Deterministic, zero-LLM, zero-network: an LLM judge asking "did you cheat?" is itself gameable; this is a diff partition plus a re-run, so a flag is trustworthy without a human in the loop. The 50%-of-gain-survives threshold is the default and is tunable via `gamingThreshold` (config-level, or per-metric).
77
77
 
78
+ **An intentional goalpost change has a sanctioned path.** When you *do* mean to change a test, config, or grader, declare it: a `Sawbuck-Allow: <reason>` trailer on the commit (or `--allow "<reason>"` on the CLI, or the `allow` option on `check()`) turns what would read `GAMED` into a `pass` with the reason recorded in `report.allowed`. An *undeclared* test-only win is still `gamed`, and a reasonless declaration does not override; the check never judges intent, it just forces intent to be explicit and auditable (the reason lives in the commit, so a reviewer sees it instead of a silent green).
79
+
78
80
  This is **one layer**, not a silver bullet: it catches the evaluator-tampering class (test/grader/golden/config edits) deterministically and for free, so the expensive layers, held-out tests for semantically-weak wins, an LLM judge or a human for intent and leakage, are reserved for the calls only they can make. See **[docs/DETECTION-LAYERS.md](docs/DETECTION-LAYERS.md)** for the coverage matrix and honest scope, and **[bench/RESULTS.md](bench/RESULTS.md)** for the measured numbers (`node bench/gaming-bench.mjs` to reproduce, it includes a cross-stack table with a real pytest run + a numeric eval-pass-rate metric). **Gate your own stack**, pytest · tsc · coverage · bundle · llm-eval, copy a config from **[examples/](examples/)**.
79
81
 
80
82
  ## Use
@@ -250,5 +252,8 @@ The engine is one importable file; pure helpers are exported for unit tests, the
250
252
  - [x] `--detect-gaming`, reward-hack detection: re-prove the win from source edits alone + `antihack` preset
251
253
  - [x] npm publish, `promptwheel@0.4.2` (the lead magnet)
252
254
  - [x] outcome-curated learning + UCB work-discovery, `playbook` + `suggest` + the compounding A/B harness (**experimental**; compounding *claims* stay gated on real-data proof, see [docs/LEARNING.md](docs/LEARNING.md))
255
+ - [x] gate integrity: a win that disables a guard or deletes a guarded metric in the same diff reads `GAMED` (SHA-256 gate fingerprint; 0.5.0)
256
+ - [x] zero-config: `run` and `check()` auto-detect the gate with no committed config, `init` becomes optional (0.6.0)
257
+ - [x] declared override (`Sawbuck-Allow:` trailer / `--allow`) + `init` build-setup detection, so a build-gated test measures instead of reading inert (0.7.0)
253
258
 
254
- > Status: **published** (npm `promptwheel`, v0.4.2), all core phases built. Lineage: CommandLayer → BlockSpool → PromptWheel (orchestrator, archived) → **PromptWheel (outcome gate)**.
259
+ > Status: **published** (npm `promptwheel`, v0.7.0), all core phases built. Lineage: CommandLayer → BlockSpool → PromptWheel (orchestrator, archived) → **PromptWheel (outcome gate)**.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptwheel",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "A deterministic, zero-LLM check for your coding loop. It proves every change earned its win by re-running the result from the agent's source edits alone, so a green that came from editing the test reads GAMED. Runs in CI or a Claude Code hook, or import { check } in process.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,4 +50,4 @@
50
50
  "detect-gaming",
51
51
  "reward-hack-detection"
52
52
  ]
53
- }
53
+ }
@@ -5,7 +5,7 @@
5
5
  // The full AST+dataflow engine (the other 75 recommended patterns) is the follow-up.
6
6
  //
7
7
  // Usage: node scan.mjs [path] → prints the finding count (for `promptwheel` metrics)
8
- // node scan.mjs [path] --list → prints each finding (file:line — id — message)
8
+ // node scan.mjs [path] --list → prints each finding (file:line · id · message)
9
9
  import { readFileSync, readdirSync, statSync } from 'node:fs';
10
10
  import { join, extname } from 'node:path';
11
11
  import { fileURLToPath } from 'node:url';
@@ -50,7 +50,7 @@ for (const file of walk(ROOT)) {
50
50
  }
51
51
 
52
52
  if (LIST) {
53
- for (const f of findings) console.error(` [${f.sev}] ${f.file}:${f.line} — ${f.id} — ${f.msg}`);
53
+ for (const f of findings) console.error(` [${f.sev}] ${f.file}:${f.line} · ${f.id} · ${f.msg}`);
54
54
  console.error(`\n${findings.length} security-invariant violation(s)`);
55
55
  }
56
56
  // the metric value: lower is better, 0 is clean