Add Risk Surface Guard, a deterministic PR-diff risk scanner - #139
Merged
Conversation
…ner (WI-055) Adds a second, fully separate deterministic PR-diff scanner alongside the anti-gaming ratchet: scripts/risk-surface-guard.mjs and its rule catalog scripts/lib/risk-surface-rules.mjs (60 rules across 15 categories) flag diffs that expand execution, credential, workflow, dataset/model-loading, container, network, or sandbox risk, independent of whether any test gate stays intact. See ADR-047 for the design rationale, including the two self-reference safeguards required because this repo's own CI scans its own PRs: content rules are scoped to real source/config extensions (so the should-flag/should-allow fixtures under fixtures/risk-surface/ cannot trigger the scanner shipped beside them), and the scanner's own implementation files are exempt from content rules while remaining protected paths. Ships warn-only by default (CLI --mode warn, action.yml's new risk-surface input), registered as an advisory (non-blocking) entry in check-self-application.mjs and base-pinned like the ratchet. Includes 52 tests, 45 fixtures, and full documentation (docs/risk-surface-guard.md, README/SECURITY/CHANGELOG updates). Does not claim breach prevention and does not replace SAST, secret scanning, dependency review, cloud security, or sandboxing. Known pre-existing, unrelated issue: scripts/check-repo-hygiene.mjs fails on this branch's name (a model-identifier prefix assigned by the task dispatch system), which also drops the passing-gate count reflected in RELEASE-EVIDENCE.md and site/index.html. This is independent of branch content and was confirmed present before any change in this commit.
… Surface Guard (WI-055) Addresses four of the five limitations named when Risk Surface Guard first shipped (ADR-047), continuing the same work item since nothing had merged yet. Findings now upload to the GitHub Security tab as SARIF (action.yml), sharing the ratchet's existing upload-sarif toggle under a distinct modonome-risk-surface category. RS106, RS703, and RS707 were tuned against more realistic code shapes: RS106 exempts a short list of near-universally-benign process.env variable names, RS703 widens its Python verify=False co-occurrence window from adjacent lines to a 4-line span, and RS707 requires a structural egress/outbound match instead of a bare nearby word. Adds a base-branch-loaded suppression allowlist (ADR-047 decisions 9-13): .modonome/risk-surface-allowlist.json and its loader scripts/lib/risk-surface-allowlist.mjs are both base-pinned in ci.yml, so a pull request's own new entry cannot suppress a finding in that same pull request. A new blocking gate, scripts/check-risk-surface-allowlist.mjs, validates a pull request's proposed allowlist edits pre-base-checkout. Suppressed findings stay visible and marked in human and JSON output, are excluded from SARIF, and never count toward the exit code in any mode. Fail-closed is enforced twice: a malformed allowlist file suppresses nothing, and isSuppressed independently re-validates expiry shape rather than trusting the generic schema validator already ran. The fifth limitation (no AST/semantic analysis) remains a deliberate architectural boundary per ADR-045/047 and is unchanged. tests/risk-surface-guard.test.mjs grows to 78 tests; a new tests/check-risk-surface-allowlist.test.mjs adds 11. Seven new fixtures cover the tuned heuristics and the allowlist's valid, expired, glob, and malformed shapes.
…guard # Conflicts: # .modonome/snapshot/map.json # .modonome/snapshot/map.md # .modonome/snapshot/signature.json
Consistency fix: the gate-integrity SARIF upload two steps above was already bumped to v4 in a separate PR; this repeats it for the newer Risk Surface Guard upload step, which didn't exist yet when that bump landed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Adds Risk Surface Guard (ADR-047, WI-055): a deterministic diff scanner that flags PR changes expanding execution, credential, workflow, model-loading, container, or network-egress risk surface. Runs independently alongside the existing gate-integrity ratchet, no shared rule logic.
--mode failblocks on high/critical findings.docs/risk-surface-guard.md; design decisions indocs/adr/ADR-047-risk-surface-guard.md.Not a replacement for SAST, secret scanning, or human review — deterministic line-based scanning by design, documented as a limitation.
Governance checklist
npm run verifypasses locallyTest evidence
npm run verifypasses locally: style, hygiene, self-application conformance, full test suite, AgentProof 25/25 HARDENED.tests/risk-surface-guard.test.mjs(78 tests) andtests/check-risk-surface-allowlist.test.mjs(11 tests) cover the scanner and allowlist, including adversarial cases.