BLA
BLA는 오픈소스 Blue Defense MCP와 CLI로, 소프트웨어 자산을 자동 AI 리버스 엔지니어링으로부터 보호합니다
나이지리아 가정을 위한 가벼운 AI 사기 검사기, 영어·피진·요루바·하우사·이그보 지원, 스마트폰·버튼폰 모두 사용 가능
Open-weight AI scam checker for Nigerian families. English, Pidgin, Yorùbá, Hausa, Igbo. Smartphone or button phone.
보안TypeScript · PythonGitHub @daodudestiny56-netizen온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Ṣọ́ra (Yorùbá): “be careful.” Written with tone marks so it isn't confused with other products named “Sora”.
Ṣọ́ra checks a suspicious SMS, WhatsApp message or screenshot, points at the exact words that give the scam away, and tells the person what to do in English, Nigerian Pidgin, Yorùbá, Hausa or Igbo, with a voice note they can play. It reaches people wherever they are: the web, an installable app that works offline, a WhatsApp bot, and USSD and SMS for button phones. A one-minute practice game teaches the signs before the next scam arrives. It runs on Gemma 4, an open-weight model under Apache 2.0.
🥈 2nd place out of 52 teams at OPEN//BUILD 2026 (OSCA Ile-Ife Hacktoberfest).
| Live demo | https://sora-ecru-kappa.vercel.app |
| Demo video | Watch the 90-second demo |
| Run locally | Setup: npm install && npm run dev |
| Headline result | On 50 fresh messages nobody tuned on, Gemma 4 + rules caught all 30 scams with 1 false alarm in 20 real messages, and every quoted red flag was really in the message (§8) |
| Licence | Code: Apache-2.0 · Eval data: CC BY 4.0 |
| Name | University |
|---|---|
| Daodu Destiny | Obafemi Awolowo University (OAU), Ile-Ife |
| Oyewole Caleb | Obafemi Awolowo University (OAU), Ile-Ife |
Nigerian families get a steady stream of scam messages: "your BVN is blocked, click to verify", lookalike bank sender IDs, fake credit alerts followed by "I sent it by mistake, please refund", "this is my new number" requests, and fake government grants that need a "registration fee". The people most at risk, often older parents, may read English slowly, trust official-looking messages, and have nobody to ask in the moment. Many use button phones or have little mobile data. Their children end up as the family's fraud desk, usually after the money is gone.
Existing tools (carrier spam filters) label a message at best. They don't say why, don't cover WhatsApp or screenshots, don't speak Yorùbá, Hausa, Igbo or Pidgin, and don't help people without smartphones.
| Feature | What it does |
|---|---|
| Verdict | Likely scam, Suspicious, or No red flags found. Never “safe”. |
| Evidence highlights | Each red flag quotes the exact phrase from the message, highlighted in place, with a one-line reason. |
| What to do | 1–3 concrete steps, e.g. “Check your balance in your bank app, not the SMS.” |
| Five languages | English, Pidgin, Yorùbá, Hausa and Igbo, with full tone marks on the web and WhatsApp. |
| Screenshots | Gemma 4 reads text from screenshots (sender ID, links, amounts). Without a model, or if it fails, Tesseract.js reads them on the device, so the image never leaves the phone. |
| Voice notes | YarnGPT2 Nigerian-accent TTS. Play, download or share. |
| WhatsApp bot | Forward a suspicious message or screenshot to the Ṣọ́ra WhatsApp number and get the verdict, steps and red flags back in your language, plus a voice note. Built on Twilio (guide). |
| Installable app (PWA) | Add to home screen. On Android, share a suspicious SMS straight into Ṣọ́ra from the share sheet. Works offline: the rules and reviewed explanations run on the phone. |
| Button phones | USSD menu and SMS forwarding on the same engine, replies sized for 2G screens. A live simulator on the website. |
| Practice game | “Scam or real?”: eight messages in five languages. Each answer highlights the giveaway words using the same rules as the checker, and ends with a WhatsApp challenge to send to family. |
| Share to family | One tap sends the explanation to WhatsApp. |
| Works without the model | If the model is unreachable, deterministic rules and hand-written translations still answer. |
| Feature | Status on the live demo |
|---|---|
| Checker (text + screenshots), five languages, highlights | ✅ Live with Gemma 4 |
| Installable app, offline check, Android share target | ✅ Live |
| Practice game | ✅ Live |
| USSD and SMS | ✅ Endpoints and website simulator live. Real phone numbers need a paid Africa's Talking shortcode. |
| WhatsApp bot | ✅ Built and tested locally. Needs Twilio sandbox keys to receive real WhatsApp messages. |
| Voice notes (YarnGPT2) | ⏳ Service built (services/voice) and run locally in Docker: it returns audio in all four voices. Not yet hosted, so the live site does not use it. English and Pidgin use the device voice meanwhile. |
| Role | (1) Reads screenshots (OCR). (2) Judges whether a message is a scam using context. (3) Quotes the exact evidence. (4) Writes the explanation and actions in up to five languages. |
| Variants | gemma-4-26b-a4b-it via the Gemini API for the hosted demo (free tier, no GPU needed). gemma4:e4b via Ollama for fully local, offline use on a laptop. The same prompts work for both through one provider interface. |
| Licence | Apache 2.0. Commercial use, modification and redistribution allowed. We comply by attributing and not implying endorsement. |
| Why Gemma 4 | Open weights under a permissive licence; reads images (needed for screenshots); claims 140+ languages; the E4B size runs on a student laptop; available hosted for a public demo. |
| Limitations | Yorùbá, Hausa and Igbo output quality is lower than English and has not yet been rated by native speakers. In testing we saw a wrong Yorùbá word choice and a garbled Igbo sentence. It can be overconfident and could invent quotes, which the grounding check catches (§6). Hosted calls have rate limits, need internet, and occasionally fail with HTTP 500 (§8). |
Alternatives we considered (detail in docs/planning/01-RESEARCH.md):
| Role | Text-to-speech for voice notes in Yorùbá, Hausa, Igbo and Nigerian-accent English (also used for Pidgin). |
| Licence | Apache 2.0 |
| Why | Nigerian voices under an open licence. facebook/mms-tts-yor is CC-BY-NC (non-commercial). |
| Limitations | Needs PyTorch, so it runs as a separate service (services/voice); slow on CPU; the model card notes audio can be rushed. |
Not a generative model. It reads English text from screenshots in the browser when Gemma 4 isn't available or the phone is offline. It is weaker on tone-marked Yorùbá text.
web / installed app WhatsApp (Twilio) button phone (Africa's Talking)
text · screenshot · text · screenshot USSD menu · SMS forward
Android share sheet │ │
│ ▼ ▼
│ /api/channels/whatsapp /api/channels/ussd · /sms
│ (signature check, ack now, (language menu or YO/HA/IG/PCM
│ reply in background) prefix, GSM-7 replies)
▼ │ │
/api/analyze ◄──────────────────┴──────────────────────────────┘
│ screenshot? → Gemma 4 reads it (or Tesseract.js on the device)
▼
┌────────────────────────────────────────────────────┐
│ 1. Rules engine (TypeScript regex) │ → flags with exact spans
│ 2. Gemma 4 → JSON {verdict, red_flags[quote], │
│ explanations{en,pcm,yo,ha,ig}} │
│ 3. Grounding: drop any quote not in the message │
│ 4. Merge: rules set a floor under the verdict │
│ 5. Fill any missing language from templates │
└──────────────────────────┬─────────────────────────┘
▼
verdict · highlights · 5 languages · voice note (/api/voice → YarnGPT2 service)
Offline (service worker): rules + templates run in the browser (lib/sora/local.ts)
Key decisions
lib/sora/analyze.ts) lets the model raise a verdict, but the model can
never turn a rules warning green: any rules warning stays at least suspicious, and a strong rules
case (a PIN/OTP/BVN request, fee before reward, mistaken-transfer refund, or rules score 5+) stays
likely scam. When the model disagrees with the rules, the reviewed templates write the explanation,
so text injected into a scam message cannot shape what the user reads.lib/sora/grounding.ts).
Quotes that don't match are dropped and counted, and the eval reports the grounding rate.analyze() pipeline,
so a fix or new rule improves every channel at once.after()). Requests without a valid X-Twilio-Signature are rejected, and media is only
ever downloaded from Twilio's own host, so the webhook can't be used to fetch other URLs.Dependencies: Next.js 16, React 19, TypeScript 5.9, Tailwind CSS 4, Motion, Phosphor Icons, Zod, Tesseract.js (runtime); Vitest, tsx, ESLint (dev). Voice service: Python 3.11, FastAPI, PyTorch, transformers, YarnGPT.
Requirements: Node.js 20+ (tested on 24) and npm. Optional: a free Google AI Studio key or Ollama.
git clone https://github.com/daodudestiny56-netizen/Sora.git
cd Sora
npm install
cp .env.example .env # then pick ONE model option below
npm run dev # http://localhost:3000
Model options (in .env):
GEMINI_API_KEY=.... Uses gemma-4-26b-a4b-it.ollama pull gemma4:e4b, then set SORA_BACKEND=openai and
uncomment the OPENAI_* lines.Optional extras (all in .env.example): VOICE_SERVICE_URL/VOICE_SERVICE_TOKEN for voice notes,
TWILIO_* for WhatsApp, AT_* for SMS/USSD.
Tests and checks
npm test # 65 tests: rules, grounding, merge, prompt, providers, OCR, offline, game, channels, hardening
npm run typecheck
npm run lint
npm run build
Reproduce the evaluation
npm run eval # rules only, no key needed
npm run eval -- --backend gemini # Gemma 4 26B A4B + rules
npm run eval -- --backend openai # local Gemma 4 E4B + rules
npm run eval -- --backend gemini --langs en,yo --limit 20 # quicker run that also generates Yorùbá
Results go to eval/results/<run>.json (per-message rows) and eval/results/summary.json (what the
website and the table below show).
Try the other channels locally
# USSD: Yorùbá → check a message
curl -X POST localhost:3000/api/channels/ussd -d "text=3*1*send your BVN and OTP"
# SMS forward with a language prefix
curl -X POST localhost:3000/api/channels/sms -H "Content-Type: application/json" \
-d '{"text":"YO Congratulations! Pay N3,500 registration fee to claim your grant"}'
# WhatsApp (without Twilio keys the reply comes back directly as TwiML)
curl -X POST localhost:3000/api/channels/whatsapp --data-urlencode "From=whatsapp:+2348000000001" \
--data-urlencode "Body=HA I need N2,000 for fuel before I can deliver your order" --data-urlencode "NumMedia=0"
Dataset: data/eval.jsonl, 150 messages (89 scam / 61 legitimate; en 121, pcm 10,
yo 8, ha 6, ig 5). Synthetic, written from public scam warnings, no personal data. See the
dataset card.
Metrics: scam recall (scams flagged as suspicious or likely scam, because missing a scam is the worst failure); false-alarm rate (legitimate messages flagged, because crying wolf teaches people to ignore warnings); accuracy; precision; grounding rate (model quotes found in the message); latency.
| Engine | Scam recall | Strict recall¹ | False alarms | Accuracy | Grounding² | p50 / p95 latency |
|---|---|---|---|---|---|---|
| Rules only, revision 1 | 83.1% | 49.4% | 1.6% | 89.3% | n/a | <1 ms |
| Rules only, revision 2 (current; also the offline mode) | 98.9% | 56.2% | 1.6% | 98.7% | n/a | <1 ms |
| Gemma 4 26B A4B + rules ³ | 98.9% | 95.5% | 1.6% | 98.7% | 100% | 6.6 s / 8.7 s |
| Gemma 4 E4B + rules (local) | pending: needs a machine with Ollama | |||||
| Rules only, revision 2, on 50 fresh messages ⁴ | 43.3% | 26.7% | 5.0% | 64.0% | n/a | <1 ms |
| Gemma 4 26B A4B + rules, on the same 50 fresh messages ⁴ | 100% | 100% | 5.0% | 98.0% | 100% | 6.6 s / 9.5 s |
¹ Flagged as likely scam rather than suspicious. ² Share of the model's quoted evidence found word
for word in the message (0 invented quotes on this set). ³ Measured with rules revision 1 and before the
prompt hardening; being re-run with the current code. ⁴ data/holdout.jsonl: 30
scams and 20 legitimate messages in English and Pidgin, written after the rules were frozen. No rule was
tuned on them. They are still synthetic and AI-assisted, and small, so treat them as a rough check, not a
benchmark.
Run on 2026-10-25 with npm run eval -- --backend gemini (English explanations only, to keep the run
short). Per language, Gemma 4 + rules caught every scam in Pidgin (7/7), Yorùbá (5/5), Hausa (4/4) and
Igbo (3/3), but these subsets are tiny.
What went wrong, and why:
e058, a fake "Shell is recruiting drivers" job asking for a form fee). Google's
API returned an internal error (HTTP 500) for this message even after retries, so it was judged by the
rules alone, which miss it. 6 of 150 calls failed this way and fell back to rules. We report them as
they happened rather than re-running only the failures. When we re-ran e058 by itself, Gemma flagged
it as a likely scam.e147, a real bank reminder to "update your BVN details at any of our branches").
Gemma judged it fine, but the rules flag any BVN-update request and the safety floor keeps it at
suspicious. We accept this trade-off on purpose: a real bank can always be checked by calling it,
while a missed BVN phish can empty an account.Reading the rules rows honestly: the rules were revised twice after looking at their misses on this
set, so both rows are optimistic, and revision 2 is no longer a fair baseline. It was written to catch
exactly the 15 scams revision 1 missed (fake jobs and delivery or meter fees, "lost my phone" and
relative-in-danger requests, a "pastor" asking for money, investment pitches, a "fine" to avoid arrest).
One scam still gets through: a romance request for a gift card (e070).
Short regex rules are brittle when a scammer rewords, and the held-out row shows it. On 50 messages
written after the rules were frozen, the rules alone caught 43.3% of the scams (13 of 30) and raised 1
false alarm in 20 (a real "your card has been blocked at your request" notice). So 98.9% describes how
well the rules fit the eval set, not how well they work on new scams. The offline mode uses only the
rules, so it has the same limit. Gemma 4 is the part that handles wording we did not anticipate. It also
quotes the evidence, reads screenshots and writes the explanation in five languages. On the same 50
fresh messages (run 2026-10-30 with the current code, 0 model failures), Gemma 4 + rules caught all 30
scams, all of them as likely scam, with the same single false alarm, and every quote it gave was found
in the message. That is the gap the model closes: 43% → 100% scam recall on wording nobody tuned for.
Fifty messages is a small sample, so treat it as strong evidence, not a guarantee. The held-out
messages are synthetic and AI-assisted like the rest of the data;
real, anonymised messages from our parent testing will be added (see data/README.md).
Yorùbá/Hausa/Igbo quality will be reported as a native-speaker rating (1–5 on 30 explanations), not as a benchmark.
| Channel | How it works | Guide |
|---|---|---|
| Web / installed app | Paste, upload, or (Android) share a message into Ṣọ́ra. Works offline with the rules engine. | §6 |
Forward a message or screenshot to the Ṣọ́ra number. Start with YO, HA, IG or PCM for another language. Replies keep tone marks and can include a voice note. | docs/WHATSAPP.md | |
| USSD | Dial the code, pick a language → 1. Check a message · 2. Common scams · 3. How to check by SMS. One-screen verdict (≤182 chars). | docs/FEATURE_PHONES.md |
| SMS | Forward the suspicious text, optionally with a language prefix. Reply fits two GSM-7 segments. | docs/FEATURE_PHONES.md |
USSD and SMS use the Africa's Talking callback format (the common aggregator for MTN, Airtel, Glo and 9mobile). The website has a live button-phone simulator that calls the same endpoints. Going live needs a paid shortcode provisioned through telcos.
| Part | Where | Notes |
|---|---|---|
| Web app + API | Vercel | vercel --prod. Set GEMINI_API_KEY and any optional keys in project env. |
| Reasoning model | Gemini API (hosted Gemma 4) | Free tier, rate-limited. Or self-host Gemma 4 with vLLM/Ollama and set SORA_BACKEND=openai. |
| Voice model | Hugging Face Docker Space | services/voice. Set VOICE_SERVICE_URL and VOICE_SERVICE_TOKEN. |
| WhatsApp bot | Twilio (free sandbox) | Point the sandbox webhook at /api/channels/whatsapp. |
| USSD / SMS | Africa's Talking | Point the USSD and SMS callbacks at the Vercel URLs. |
Full guide: docs/DEPLOYMENT.md.
docs/LANGUAGES.md.join code. A public
number needs a Meta-approved WhatsApp Business sender.app/ Next.js pages, API routes, web manifest, icons
api/analyze the checker
api/channels/ ussd · sms · whatsapp webhooks
api/voice YarnGPT2 proxy (POST for the web, signed GET for WhatsApp)
api/health which engine is live
components/ UI: Checker, ResultCard, Quiz, FeaturePhone simulator, Nav, Pwa, landing sections
lib/sora/ the engine
rules.ts deterministic red-flag rules with exact spans
prompt.ts Gemma 4 prompts + JSON schema
providers.ts Gemini API and OpenAI-compatible (Ollama/vLLM) backends, with retries
grounding.ts quote grounding check
analyze.ts pipeline: OCR → rules → model → grounding → merge
templates.ts reviewed explanations in 5 languages (fallback + phones)
channels.ts USSD menu, SMS replies, GSM-7 folding
whatsapp.ts Twilio: signature check, reply format, media, signed voice links
local.ts offline, in-browser check (rules + templates)
lib/ocr.ts on-device OCR (Tesseract.js) and line unwrapping
lib/quiz.ts "Scam or real?" game data in five languages
public/sw.js service worker (offline shell, OCR cache; never caches messages)
public/icons/ app icons
data/eval.jsonl 150-message eval set + dataset card
scripts/eval.ts evaluation script
eval/results/ recorded results
services/voice/ YarnGPT2 voice service (FastAPI, Docker)
tests/ Vitest unit tests
docs/ deployment, WhatsApp, phones, languages, planning (research, PRD)
Issues and PRs are welcome, especially native-speaker review of Yorùbá, Hausa, Igbo and Pidgin text, new anonymised scam examples, new practice-game messages, and new rules. See CONTRIBUTING.md.
docs/planning/01-RESEARCH.md.en-NG-EzinneNeural
voice) and the music was generated in code for this video. All app scenes are real screen captures of
the live site; the opening phone scenes are illustrations of a typical scam.Native-speaker evaluation of all five languages · a Gemma 4 E4B vs 26B vs 31B comparison on the same eval · an approved WhatsApp Business number · a live USSD shortcode with a telco partner · voice input so parents can speak the message (NCAIR Yorùbá ASR) · Gemma 4 E2B running inside the app on the phone for full offline AI · a community-reported scam feed.
timeoutrate_limitedshare_target and a
hand-written service worker (public/sw.js). The app shell, icons and OCR engine are
cached so the app opens and checks messages with no data. /api/* is never cached, so checked
messages are not stored on the device.SORA_BACKEND=gemini|openai|rules. The openai backend talks to any
OpenAI-compatible server (Ollama, vLLM, llama.cpp, LM Studio).