You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bcbb61d
Browse filesBrowse the repository at this point in the historyBrowse files
fix(screening): let a carrier-verified call override only stale database rows
STIR_SHAKEN_TRUSTED (5300) sits above GITHUB_DATABASE (5200), so any number
on the spam database that arrived with a PASSED verification rang through.
PASSED proves the caller owns the line, not that the call is wanted: 44% to
51% of robocalls in 2024 carried A-level attestation. The ranking exists to
protect the real owners of numbers spoofed in old complaint data, which
argues for an age condition rather than trusting every pass.
The trust checker now looks up the matching row and only allows when that
row's evidence is stale: its newest date is more than 365 days old, it isn't
on the hot list (three distinct reporters), and it carries no corroborated
community evidence. Otherwise it passes and DatabaseChecker blocks as it
would for any other call. User blocks and allows keep their ranks.
Community provenance never reached the device: shard rows carry it in a
"sources" field that SpamNumberJson ignored. The field is now parsed, and a
row published without its own evidence list gets a community_reports record
next to the synthesized database one, with the same corroborated/unverified
rule. Rows already on a device pick it up when their shard next changes.
Every community row today is from 2026, inside the 365-day window, so none
depends on it yet.
Tests (new only; no existing assertion changed):
- StirShakenTrustCheckerTest pins the decision table: current row, the
365-day boundary, a newer evidence record, corroborated versus single
community reports, hot-list rows, and undated rows.
- StirShakenDatabaseEvidencePipelineTest runs the whole call pipeline under
Robolectric: a verified call from a current row blocks, from a stale row
rings through, an unverified call from the stale row still blocks, and a
user block still wins.
- SpamRepositorySyncTest parses a real shard body and checks the community
record survives into the stored evidence.
- SpamPipelineIntegrationTest gains the same two pipeline cases on device.
They compile; they have not run on a device in this change.
Making the allow unconditional again fails five of these tests.
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -403,7 +403,7 @@ All detection layers implement a shared `IChecker` interface and run in priority
403
403
| 5400 |**Range Patterns** (A5) | Block | Length-locked `#` patterns like `+33162######`, with schedule + coverage safety rail |
404
404
| 5350 |**Temporary Allow**| Allow | One-off false-positive recovery from the Blocked Log. Beats all downloaded data, never your own rules |
405
405
| 5320 |**Prefix Rules**| Block | Downloaded wangiri country codes, US premium rate (+1900), international premium |
406
-
| 5300 |**STIR/SHAKEN Authenticated**| Allow | Carrier-authenticated caller ID can allow through lower-confidence heuristic/ML suspicion while explicit blocks still win first |
406
+
| 5300 |**STIR/SHAKEN Authenticated**| Allow | Carrier-authenticated caller ID allows through heuristic/ML suspicion, and through a database match only when that row's newest evidence is over a year old, it isn't trending, and it has no corroborated community reports. Explicit blocks still win first |
407
407
| 5200 |**Spam Database**| Block | 51,634 imported spam numbers plus scheduled hot-list data |
0 commit comments