Skip to content

Commit 19bde79

Browse files
committed
fix(pipeline): require corroboration before shipping community rows
Re-evaluate legacy community-only rows, retain recent pending evidence, and rebuild signed feed v47 after holding 449 uncorroborated numbers. The previous pipeline assertions expected same-day reports to ship; those expectations contradicted the new two-day promotion rule and were replaced with hold, promotion, and expiry coverage.
1 parent d0bc5c8 commit 19bde79

239 files changed

Lines changed: 12861 additions & 24752 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to CallShield will be documented in this file.
44

55
## Unreleased
66

7+
- New community-only numbers now wait for reports on two UTC days before they
8+
enter the shipped database. Reports with reporter buckets also need three
9+
distinct buckets. Pending reports expire after 30 days. The first pass held
10+
449 older, uncorroborated rows, leaving 51,357 numbers in feed v47.
711
- Setup now finishes once the required phone, message and call screening access
812
is ready. You can skip notifications, caller ID overlay and notification
913
access, see what each choice disables, and return through Settings later.
@@ -12,7 +16,7 @@ All notable changes to CallShield will be documented in this file.
1216
uses the newest complaint date so an empty fetch can't hide a stalled feed.
1317
Release checks now recognise the importer's success and failure statuses.
1418
- A catch-up import processed 500,000 FCC complaints and refreshed evidence on
15-
7,638 existing numbers. The database still holds 51,806 numbers (feed v46).
19+
7,638 existing numbers. That import left 51,806 numbers in feed v46.
1620

1721
## v1.8.1 (2026-09-25)
1822

‎README.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
<p align="center">
88
<strong>Open-source spam call and text blocker for Android</strong><br>
9-
15+ layer detection + Gradient-Boosted Tree ML | 51,806 spam numbers | Real-time caller ID | RCS filter | No required API keys
9+
15+ layer detection + Gradient-Boosted Tree ML | 51,357 spam numbers | Real-time caller ID | RCS filter | No required API keys
1010
</p>
1111

1212
<p align="center">
1313
<a href="https://github.com/SysAdminDoc/CallShield/releases/latest"><img src="https://img.shields.io/github/v/release/SysAdminDoc/CallShield?style=flat-square&color=a6e3a1" alt="Release"></a>
14-
<img src="https://img.shields.io/badge/Spam%20Numbers-51%2C806-f38ba8?style=flat-square" alt="51,806 Numbers">
14+
<img src="https://img.shields.io/badge/Spam%20Numbers-51%2C357-f38ba8?style=flat-square" alt="51,357 Numbers">
1515
<img src="https://img.shields.io/badge/Tests-1541-94e2d5?style=flat-square" alt="1541 Tests">
1616
<img src="https://img.shields.io/badge/Android-10%2B-89b4fa?style=flat-square" alt="Android 10+">
1717
<img src="https://img.shields.io/badge/License-MIT-cba6f7?style=flat-square" alt="MIT License">
@@ -30,7 +30,7 @@
3030

3131
---
3232

33-
CallShield blocks spam calls and texts using a **15+ layer on-device detection engine** with a gradient-boosted tree ML scorer, bounded campaign and churn evidence, conservative carrier identity metadata signals, an RCS notification filter, and real-time caller ID. Its 51,806-number database sits alongside a trending-numbers feed the app checks every 30 minutes. There are no accounts or tracking.
33+
CallShield blocks spam calls and texts using a **15+ layer on-device detection engine** with a gradient-boosted tree ML scorer, bounded campaign and churn evidence, conservative carrier identity metadata signals, an RCS notification filter, and real-time caller ID. Its 51,357-number database sits alongside a trending-numbers feed the app checks every 30 minutes. There are no accounts or tracking.
3434

3535
The database keeps `data/spam_numbers.json` as a stable legacy GitHub-raw
3636
endpoint for older clients, while current builds bundle a hash manifest and
@@ -67,7 +67,7 @@ Version highlights for each release are in [CHANGELOG.md](CHANGELOG.md).
6767

6868
## How It Works
6969

70-
1. **51,806 imported spam numbers.** Sources include FCC consumer complaints (2+ reports each), FTC Do Not Call, ToastedSpam, and community reports.
70+
1. **51,357 imported spam numbers.** Sources include FCC consumer complaints (2+ reports each), FTC Do Not Call, ToastedSpam, and corroborated community reports.
7171
2. **15+ layer detection + ML**. Database, heuristics, bounded campaign/churn detection, on-device gradient-boosted tree, SMS content/burst analysis, RCS filter, STIR/SHAKEN, and more
7272
3. **Real-time caller ID overlay**. An optional SkipCalls spam check for locally suspicious calls, with SIT tone anti-autodialer
7373
4. **Trending feeds**. The app checks for trending spam numbers and campaign ranges every 30 minutes. The maintainer regenerates them by hand from new community reports
@@ -92,7 +92,7 @@ A fix release, from a review of the work that went into 1.8.0.
9292
- **Signed protection data.** Every feed the app downloads now carries the maintainer's signature, the certificate pins that had refused downloads since August are fixed, and a feed mirror covers places where GitHub is blocked.
9393
- **Region rules** reach outside North America, and Settings gains telemarketing ranges for Spain, India and Brazil.
9494
- **Chinese** now covers every line of system text, and the block log, Lookup and the "why was this blocked" panel are translatable.
95-
- **Community reports** go out once and wait for a connection when you're offline. The database grows to 51,806 numbers.
95+
- **Community reports** go out once and wait for a connection when you're offline. A new number enters the database after reports on two different UTC days. Reports with reporter buckets also need three distinct buckets.
9696

9797
## Detection Pipeline (v1.8.1)
9898

@@ -113,7 +113,7 @@ All detection layers implement a shared `IChecker` interface and run in priority
113113
| 5310 | **Regulatory Prefix** | Block | Opt-in (Settings > Telemarketing ranges) blocks for ranges regulators set aside for sales calls: Spain 400 (from 17 October 2026), India 140 (TRAI), Brazil 0303 (ANATEL). Matches the number with its country code, and without it on a phone from that country |
114114
| 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, community reports included, is over a year old and the number isn't trending right now. Explicit blocks still win first |
115115
| 5250 | **Regulatory Allow** | Allow | Opt-in protected series that rings through past the database and statistics. India 1600 (banks, insurers and government offices, per TRAI) |
116-
| 5200 | **Spam Database** | Block | 51,806 imported spam numbers plus the trending-numbers feed |
116+
| 5200 | **Spam Database** | Block | 51,357 imported spam numbers plus the trending-numbers feed |
117117
| 5150 | **Database Prefix Expansion** | Block | Auto-blocks last-two-digit siblings of confirmed database entries |
118118
| 5000 | **Recently Dialed** | Allow | Numbers you called in the last 24h. They're probably calling back |
119119
| 4980 | **Emergency Callback** | Allow | Unknown callbacks can ring through after a local emergency call during the configured grace window |
@@ -278,7 +278,7 @@ by locale and message type without shipping personal data:
278278

279279
## Data Sources
280280

281-
### Database (51,806 numbers + 653 range prefixes, locally maintained)
281+
### Database (51,357 numbers + 653 range prefixes, locally maintained)
282282
| Source | Method |
283283
|--------|--------|
284284
| **FCC Consumer Complaints** | Socrata API, 500K records, min 2 reports |

‎data/README.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This directory contains the spam number database that the CallShield app pulls f
1616
- `spam_domains_review.json`: Generated domain candidates awaiting approval
1717
- `not_spam_review.json`: Generated community false-positive review candidates
1818
- `merged_report_ids.json`: Ids of reports merged in the last 14 days, so a report the app resends after its original was merged counts once. The ids are random and already appear in the report files
19+
- `community_pending.json`: Community-only reports waiting for the two-day and reporter-bucket promotion threshold
1920
- `reports/*.json`: Pending community reports. `reports/rejected/` holds quarantined files
2021

2122
## Consuming this data
@@ -187,6 +188,13 @@ python scripts/evaluate_model.py # exits non-zero if CV F1 regresses
187188
python scripts/feed_signing.py sign
188189
```
189190

191+
The merge holds a number supported only by community reports in
192+
`community_pending.json` until reports span two UTC days. If those reports have
193+
reporter buckets, at least three distinct buckets are also needed. Pending
194+
reports expire after 30 days. The merge applies this rule to older
195+
community-only database rows too, including a run with no queued reports.
196+
Rows backed by FCC, FTC or another source aren't held by this gate.
197+
190198
`train_spam_model.py` prints the learned per-feature weights and writes a
191199
version-stamped `spam_model_weights.json` (GBT trees + a logistic-regression
192200
fallback). `evaluate_model.py` reports precision/recall/F1 two ways: with the

0 commit comments

Comments
 (0)