Contribute to HuShield
This is a small project that needs help, and it is honest about that. Below is real work with real context — not a wall of "good first issue" labels slapped on things nobody scoped.
One rule before you start
HuShield holds no personally identifiable information, anywhere, by design. The only identity in the system is an Apple App Attest key. No accounts, no phone numbers tied to reporters, no contact data, no analytics identifiers.
This is not a preference that might get traded away later — it is the product. A pull request that introduces a user identifier will be declined however well it is written. If a feature seems to need identity, open an issue and let's find another route. There usually is one.
Good first issues
Small, scoped, and they do not require understanding the whole system.
- #10 · Add a CI workflow (build, vet, test, govulncheck)
- #9 · cmd/recompute coverage is 31.4% and it runs unattended on a timer
- #7 · cmd/seed and cmd/server have 0% test coverage
- #6 · internal/dbtest coverage is 59.5% — the lowest in the codebase
- #4 · MemoryChallengeStore is the default and breaks silently on a multi-instance deploy
- #3 · Replace the macOS launchd recompute artifact with a systemd timer
- #2 · scripts/smoke.sh cannot test a production (ATTEST_MODE=apple) deployment
- #1 · Dockerfile has never been built and hardcodes no GOARCH
Help especially wanted
Getting set up
You need Go, MySQL 8+, and — for iOS work — Xcode plus xcodegen.
git clone https://github.com/Hushield/hushield.git
cd hushield
# Backend
DB_DSN='root@tcp(127.0.0.1:3306)/spamfilter_dev?parseTime=true&multiStatements=true' \
ADMIN_TOKEN=changeme go run ./cmd/server
# The full test gate — this is what "green" means
make test
Two things that will save you time
-
ios/SpamFilter.xcodeprojis generated. Never edit it. Changeios/project.ymland runxcodegen generate. A PR that hand-edits the project file will conflict with everyone. -
ATTEST_MODEdefaults tomock, which accepts any attestation. Correct for local development, never for production. Onlymockandappleare accepted — anything else refuses to start rather than quietly falling back to the mock verifier. -
The Go suite runs with
-race. If you add concurrency, expect the detector to find what you missed. That is the point. -
Integration tests self-skip. They need
SPAMFILTER_INTEGRATION_BASE_URLset, so they will not fail your run when no backend is up.
How the code is laid out
internal/scoring and internal/trust are pure, dependency-free, and at
100% and 95% coverage. They are the easiest place to start reading and the easiest to test —
please keep them that way. internal/store is the only package that touches SQL.
ios/SpamFilterKit holds everything shared between the app and its two extensions.
What to expect from us
Reviews come from a small team, so turnaround varies. If a PR sits for a week with no response, comment on it — that is a useful nudge, not nagging.
Not every PR gets merged. If yours is declined it will be about scope or approach, and you will get the reasoning rather than silence.