Skip to content

feat(detection): B3.2 false-positive reduction (fp 0.125 -> 0.0, recall held)#37

Merged
rennf93 merged 3 commits into
feat/phase-b3-1-scoringfrom
feat/phase-b3-2-fp
Jul 1, 2026
Merged

feat(detection): B3.2 false-positive reduction (fp 0.125 -> 0.0, recall held)#37
rennf93 merged 3 commits into
feat/phase-b3-1-scoringfrom
feat/phase-b3-2-fp

Conversation

@rennf93

@rennf93 rennf93 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Stacks on #36 (B3.1). Closes out the B3 precision arc. Retarget to master once #36 merges.

Result (harness, expanded 56-sample benign corpus)

  • fp_rate: 0.125 -> 0.000 — every benign category now clean, including the pre-existing SELECT…FROM-in-prose (0.67) and the 4 FP vectors Phase B introduced.
  • detection_rate: 0.8568 (held exactly) — zero recall loss; the ratchet floor was the guardrail.

How

  • SELECT…FROM corroboration scoring: its weight drops to 0.5 (via B3.1's override map); two new 0.5-weight signals (SELECT *, a WHERE <op> clause) push real SQLi back over the 1.0 threshold. SELECT * FROM users and … WHERE id=1 still flag; "select items from the catalog" no longer does.
  • Surgical tightening: ORDER BY requires a terminator; DDL requires the ; separator; ERB requires dangerous content (not @user.name); NoSQL split into always-dangerous operators ($where/$regex/$type/$exists/…) vs comparison operators gated on injection-shaped values (""/null/{/[), so {"$gt": 5} is clean while {"$ne":null}/{"$where":…} still flag.
  • Expanded benign corpus (+40 realistic samples: keyword-bearing prose, legit Mongo/JSON, template docs, code comments, URL params) — the FP measurement instrument.

Verification

358 tests pass (full detection + sync-mirror + attack-sim ratchet). 13 new FP-reduction unit tests pin each fix in both directions (attack flagged, benign near-miss clean). ruff/format/vulture clean; async/sync byte-identical.

Note

One over-reach caught mid-work by the ratchet: value-gating $type dropped the {"$type":"string"} seed (recall 0.92->0.68); fixed by moving diagnostic operators to the always-dangerous group. Recall restored to 0.8568 exactly. No API/route changes.

@github-actions github-actions Bot added area: handlers Touches guard_core/handlers/ area: sync Touches guard_core/sync/ (sync mirror generated by unasync) tests Test suite changes labels Jul 1, 2026
@rennf93 rennf93 self-assigned this Jul 1, 2026
@rennf93
rennf93 merged commit 1282de9 into feat/phase-b3-1-scoring Jul 1, 2026
2 of 3 checks passed
@rennf93
rennf93 deleted the feat/phase-b3-2-fp branch July 1, 2026 00:36
rennf93 added a commit that referenced this pull request Jul 1, 2026
…eutral) (#36)

* feat(detection): add detection_threat_score_threshold config field (default 1.0)

* feat(detection): per-pattern weight map + resolver; attach weight to regex threats

* feat(detection): additive anomaly scoring + threshold gate on is_threat

* style(detection): consolidate anomaly-scoring test imports (ruff E402/I001/E501)

* feat(detection): B3.2 false-positive reduction (fp 0.125 -> 0.0, recall held) (#37)

* feat(detection): SELECT..FROM corroboration scoring (low weight + star/WHERE signals)

* feat(detection): tighten ORDER BY / DDL / ERB / NoSQL patterns to require attack context

* test(attack-sim): expand benign corpus + re-baseline after B3.2 FP reduction (fp 0.125 -> 0.0)

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>

* fix(tests): align comment-stripping tests to detect-not-reconstruct contract; harden SusPatternsManager singleton isolation in reset_state

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
rennf93 added a commit that referenced this pull request Jul 1, 2026
…-mirror repair (#38)

Assembles the 3.3.0 release from the detection work merged since v3.2.0 (#33-#37) plus the ipinfo-None deprecation fix from the 3.2.1 line.

- ipinfo_token/ipinfo_db_path DeprecationWarning no longer fires when the field is explicitly None (spurious warning for callers forwarding an optional setting).

- Declare SusPatternsManager._threat_score_threshold and coerce _regex_anomaly to float, fixing the mypy attr-defined / no-any-return errors introduced by #36.

- Exclude the async-only attack_simulation harness from unasync mirroring (its data corpus is not Python-transformable) and regenerate the previously-missing sync test mirrors; check-sync is green.

- Bump version to 3.3.0 and add CHANGELOG / release-notes entries.

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: handlers Touches guard_core/handlers/ area: sync Touches guard_core/sync/ (sync mirror generated by unasync) tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant