The actual problem
Every Action Guard rule currently ships without a measured false-positive rate. The corpus replay tool exists (`scripts/replay-guard-corpus.mts`) but is not referenced by any workflow in `.github/workflows/` and not wired into `npm test`. So precision is discovered in production, on operator boxes.
The bill for that, in the last 72 hours alone, on one box:
Six FPs, one regression, one week. Every one was found by an operator being blocked, not by CI.
Why this is the priority over any individual FP fix
Each fix above is correct and each was shipped fast. That is the trap: we are fixing FPs one at a time, at production speed, and the FP rate is not a number anyone can state. A guard whose precision is unmeasured cannot be tuned — it can only be reacted to. And the operator response to an untrustworthy gate is to route around it, which is strictly worse than no gate.
What to build
- A committed FP corpus of known-good operations that MUST verdict `allow` or at worst `sensitive`: vault-fetched credentials, standards-compliant OAuth refreshes against known IdP hosts, containerised test runs, an agent deleting its own scratch files, source files containing destructive words in comments/strings, package-manager installs inside a venv/container.
- A committed TP corpus of operations that MUST `block` (already largely exists as fixtures — consolidate).
- A CI job that replays both and fails the build on: any TP regression (non-negotiable), or FP rate above a declared threshold. Print the rate on every run so it is a visible number in the PR, not folklore.
- Every new guard rule PR must add to both corpora. No rule merges without its FP cases.
Acceptance
The actual problem
Every Action Guard rule currently ships without a measured false-positive rate. The corpus replay tool exists (`scripts/replay-guard-corpus.mts`) but is not referenced by any workflow in `.github/workflows/` and not wired into `npm test`. So precision is discovered in production, on operator boxes.
The bill for that, in the last 72 hours alone, on one box:
Six FPs, one regression, one week. Every one was found by an operator being blocked, not by CI.
Why this is the priority over any individual FP fix
Each fix above is correct and each was shipped fast. That is the trap: we are fixing FPs one at a time, at production speed, and the FP rate is not a number anyone can state. A guard whose precision is unmeasured cannot be tuned — it can only be reacted to. And the operator response to an untrustworthy gate is to route around it, which is strictly worse than no gate.
What to build
Acceptance