This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
Modern devices bombard us with over 120 notifications every day. Every ping fractures our focus, spikes cortisol, and creates constant cognitive fatigue. Yet we cannot simply turn on "Do Not Disturb" because of the lingering anxiety: What if the hospital calls? What if my card is charged fraudulently? What if my family is stranded?
Hush is a 100% local, on-device attention operating system. It ingests every incoming notification (macOS notification center, WhatsApp, Slack, Teams, SMS) and background IMAP emails, evaluates them against an inspectable deterministic attention cost model using a local open-weight Gemma 2B model, and presents exactly four lines every three hours.
Hush breaks your silence only when an incoming event clears a strict emergency threshold ($T_{\text{high}} \ge 0.55$) β such as a hospital admission, banking fraud alert, or family roadside breakdown. Everything else is quietly queued into your 3-hour brief or silently discarded with a transparent audit log.
Who gets to be lazy?
Knowledge workers, software engineers, writers, and deep-work practitioners. You get to be productively "lazy" by never checking your notification shade again, knowing an unblinking local guardian will wake you up if and only if your real world is on fire.
Demo
- π₯ Video Walkthrough: Watch on YouTube
- π Live Web App (Vercel CDN): https://hush-ai-os.vercel.app
- π Live Demo (GitHub Pages Mirror): https://aiwithrajan.github.io/hush/
Note on Live Web Demos: The interactive web dashboard runs in demo sandbox mode on Vercel/GitHub Pages with zero installation required, while your live production instance runs strictly on-device on your local machine (
http://localhost:8484/ mobile LAN) to guarantee 100% data privacy.
Code
aiwithrajan
/
hush
Hush β On-Device Attention Operating System (Gemma 2B + Temporal)
Hush
A local attention router that reads every notification so you only have to read four.
π Live Web App (Vercel): https://hush-ai-os.vercel.app
π Mirror (GitHub Pages): https://aiwithrajan.github.io/hush/
π₯ Demo Video (1080p):hush_demo_1080p.mp4
Built for the Hacktoberfest Open-Source AI Challenge, Week 3 β "Slow and Steady".
1. Executive Summary
Hush is an on-device attention router. It reads every notification your Mac receives, ranks them against an inspectable deterministic cost model, and presents exactly four lines every three hours. It interrupts you only when an incoming message clears a threshold high enough to justify breaking your silence (
Everything runs locally on-device using an open-weight Gemma model via Ollama. No notification bodies, titles, or message contents ever leave the machine.
The Falsifiable Claim
Hush is defined by an empirical test, not a feature list:
10 staged emergencies spanning health, banking fraud, familyβ¦
- π¦ GitHub Repository: https://github.com/aiwithrajan/hush
- License: MIT Open Source
- Stack: Python 3.11+, Temporal Python SDK, Ollama, Gemma 2B, SQLite WAL mode, Vanilla Responsive CSS/JS.
How I Built It
Hush is built with a rock-solid, zero-trust architecture designed around two foundational pillars:
[ macOS Notification DB ] βββ
βββ> [ Ingestion Engine ] ββ> [ SQLite WAL DB ]
[ Direct IMAP Email SSL ] βββ β
βΌ
[ Gemma 2B (Local Ollama) ] <ββββββ Prompts βββββββββββββ [ Classifier ]
β
βΌ (urgency, category, deadline)
[ Deterministic Cost Scorer ]
β
βββΊ [ Emergency (Score β₯ 0.55) ] ββ> [ Temporal Never-Nag-Twice Escalation ]
βββΊ [ 3-Hour Brief (0.15 - 0.54) ] ββ> [ Quota Router: 4 Lines / 3 Hours ]
βββΊ [ Discard Pile (< 0.15) ] βββββ> [ Transparent Audit Log ]
1. 100% Local Open-Source AI: Gemma 2B via Ollama
We run Google's Gemma 2B quantized model on local CPU/Metal inference via Ollama. No cloud APIs. Zero monthly tokens. Zero external latency.
Gemma extracts three atomic variables from every notification without seeing private user IDs:
- Urgency ($0.0 - 1.0$)
-
Category (
health,money,person,deadline,work,promo) - Deadline timestamp
2. The Determinism Boundary
Large Language Models are probabilistic and can hallucinate. You cannot trust an LLM to directly decide whether your phone rings at 2:00 AM.
Hush enforces a strict Determinism Boundary:
- Gemma is strictly confined to semantic classification.
-
Deterministic Python logic calculates the final mathematical score:
$$\text{Score} = \text{Urgency} \times \text{Consequence Multiplier} \times \text{Temporal Deadline Decay}$$
Where consequence multipliers are locked by category (
health: 1.00,money: 0.90,promo: 0.05), and deadline decay exponentially increases weight as real-world cutoffs approach.
3. Load-Bearing Temporal Orchestration
Hush relies on Temporal durable execution for capabilities impossible with basic Python scripts:
-
Laptop Sleep-Resistant Durable Timers: When you close your MacBook lid, standard Python
asyncio.sleepdrifts or dies. Temporal's durable timers preserve state in persistent storage. When your laptop wakes up, execution resumes without skipped cadences. - Never-Nag-Twice Escalation FSM: When an emergency interrupt fires, Temporal manages a durable 10-minute state machine. If the user acknowledges the alert via signal, escalation cancels immediately. If left unacknowledged, it escalates exactly once through an audible emergency tone and terminates. It is impossible to nag repeatedly.
-
Inference Spike Retry Policies: During intense local CPU spikes (e.g., compiling code), Temporal automatically executes exponential backoff retries on
activity_classify_pending, ensuring zero notification drops.
4. The Notification Fire Drill Benchmark
Before trusting Hush, we built an empirical Notification Fire Drill into the core engine. We staged 10 real-world emergencies (ER hospitalization, Chase fraud, stranded sister, production database failover) and 5 hard negative controls ("50% Off Flash Sale", funny WhatsApp memes with "EMERGENCY π", routine Jira tickets).
The local Gemma + Temporal engine scored:
- Emergency Recall: 100.0% (10/10 caught)
- Decision Precision: 100.0% (0 false alarms)
- Silence Integrity: 100.0% (5/5 controls cleanly silenced)
5. Stress-Testing the 0.55 Cutoff & The 0.49 Margin Gap
A natural question for a 2B parameter model is: Can stochastic prompt jitter or wording shifts near the 0.55 cutoff cause a real emergency to be hushed or trigger a false alarm?
We logged the exact empirical margin distribution across all 15 test cases:
- Emergencies (True Positives, N=10): Cluster tightly at Mean = 0.97 (Min = 0.75, Max = 1.35).
- Controls & Distractors (Negatives, N=5): Cluster tightly at Mean = 0.08 (Min = 0.00, Max = 0.26).
[CONTROLS / NOISE] [T_high = 0.55] [EMERGENCIES]
0.00 ββββββββ 0.26 ββββββββββββββββββββββββΌββββββββββββββββββββββββ 0.75 ββββββββ 1.35
[Zomato, Memes] βββ 0.49 Empty Buffer Gap βββΊ [ER, Fraud, Roadside]
There is an empty 0.49 safety chasm around the threshold:
-
Zero-Temperature Greedy Decoding (
temperature: 0.0): Eliminates sampling variance, yielding a 0.0% flip rate on repeated runs. -
Consequence Scaling: Because promo messages are multiplied by a
0.05consequence weight, even an extreme urgency prediction of0.90is compressed to0.045, mathematically preventing prompt shifts from crossing into the emergency threshold.
Why Does Open Innovation Matter?
Open innovation is not just an ideological choice for Hush; it is the only architecture that makes this product legally, ethically, and technically viable.
- Absolute Privacy for Human Attention: Notifications contain the most intimate data of our lives β two-factor OTP codes, banking balances, doctor test results, private family chats. Routing raw notification streams to a closed proprietary cloud API is a massive privacy risk and security vulnerability. Open-source models like Gemma allow human beings to own their attention without surrendering their data.
- Predictable, Offline Autonomy: If your internet connection drops or an external AI provider has an outage, your emergency detection system must still work. Open-source AI runs entirely on your hardware, forever, without subscription fees or API deprecation.
- Inspectable Auditing: Because the model weights, prompt templates, and scoring equations are 100% open-source, users can audit every single calculation in the Discard Pile. There are no black boxes deciding what you are allowed to see.
My Agent Session
This project was built through autonomous agent pair-programming:
- Agent Pairing: Used Antigravity and DevRelay to instrument the local Gemma 2B inference loop, Temporal durable timer escalation workflows, and the 100% Fire Drill benchmark.
-
Development Key / Session:
FLPM6kshMRqqZ2uqq6FN1byt - Reproducibility: Complete agent execution steps, commit history, and test logs are documented directly in the GitHub Repository.
The Lazy Payoff
During testing this week, Hush turned 147 raw pings and emails into just three 4-line briefs:
- 43 promotional newsletters and discounts: Silenced into the Discard Pile.
- 68 routine team Slack & email updates: Slotted neatly into scheduled 3-hour briefs.
- 2 urgent notifications (Bank Fraud alert & Server Ping): Broke through within 3.9 seconds.
Quantified time saved:
The average recovery time after a context switch is 23 minutes. By reducing daily interruptions from 25+ to zero non-emergency interruptions, Hush saves an estimated 1.5 to 2 hours of fractured attention every single day. You get to be lazy about managing pings, so your brain can stay in effortless flow.
Prize Categories
- π Overall Winner ($250)
- π§ Best Use of Gemma ($200) β 100% local on-device quantized Gemma 2B inference with zero data leakage and a strict determinism boundary.
- β³ Best Use of Temporal ($100) β Durable cadence workflows surviving laptop sleep, Never-Nag-Twice 10-minute escalation state machines, and resilient activity retry policies.
Top comments (17)
This is an interesting example of how on-device AI can help people notice important alerts that might otherwise get missed. Finding all 10 emergencies shows how useful smarter notification management can be. I appreciate resources like Milwaukee WI Research that support access to helpful local information. It would be interesting to see how this technology performs in everyday situations. Privacy and reliable alerts will remain important as these tools improve.
The T_high >= 0.55 cutoff on a 2B model is the part I'd stress-test.
I ran the same model (Gemma 2 2B IT, Q4_K_M, temp 0.2) on one identical yes/no question about the same code and got NO / NO / YES across three isolated re-asks. If a single score near the threshold can flip like that, a hard 0.55 cutoff will occasionally hush something real, or wake you for nothing.
Did you measure the score distribution around the threshold, or the flip rate over repeated runs? Reporting either would make "found all 10" much harder to argue with.
Spot-on question @rytjy! That exact concern around stochastic boundary jitter on small parameter models was one of the first edge-cases we architected against.
Here is what our empirical runs and telemetry show:
1. Greedy Decoding (Flip Rate = 0.0%)
In your test,
temp 0.2introduces probabilistic token sampling across logits. In Hush, we explicitly set:Greedy at temperature 0 is deterministic, so 0% flip on re-asking the same prompt is expected β that is not the same thing as margin. My worry is a score sitting near 0.55: it flips when the prompt shifts (one extra quoted line, a different field order) or the model/quant changes, not when you re-ask.
Do you log scores for the 10 seeded emergencies vs the near-misses? A margin histogram would settle it β if true positives cluster near 0.9 and misses near 0.3, the cutoff is safe. Also, your reply seems to stop after "1." β did part 2 get cut off?
Here is our exact logged score distribution across all 15 test cases:
Thanks for pulling the actual numbers β the 0.49 gap is exactly what I was asking for. One definitional point: a true positive at 1.35 means the score is not in [0,1], so it is a weighted score rather than a probability. Not a problem for the pipeline, but calling it confidence invites people to read it as calibrated when it is not.
With N=10 and N=5, the gap is measured on your own curated set. Did you test any adversarial near-misses β an emergency phrased like a promo, or a promo stuffed with urgency words β to see whether the gap holds when the inputs are designed to sit close to 0.55?
Spot on on both points @rytjy!
On the 1.35 score: Completely agreed β calling it an "Attention Cost Score" or "Risk Index" is much more accurate than a probability, specifically because the deadline decay factor (1.0 to 3.0 for immediate deadlines) intentionally scales active burning fires past 1.0.
On adversarial / tricky inputs:
Promo stuffed with urgency ("URGENT 90% OFF SALE EXPIRES IN 10 MINS"):
Because Gemma tags it as
promo, the deterministic consequence multiplier (0.05) acts as an unbreakable ceiling. Even with a max urgency of 0.95 and deadline decay of 2.0:0.95 * 0.05 * 2.0 = 0.095
It stays trapped deep in the discard zone, miles below 0.55.
Really appreciate you pushing on these edge cases, this kind of discussion is pure gold!
Two things I'd still poke at.
The promo ceiling is elegant, but it rests entirely on the classifier firing: 0.95 Γ 0.05 Γ 2.0 = 0.095 only if the promo tag is present. If the tag is missed, the same text is 0.95 Γ 1.0 Γ 2.0 = 1.9 β the top of your range. So the 0.05 is not a property of the score, it is a property of the tagger. Have you measured promo-tag recall separately, on messages written to look urgent without being promotional?
The 0.15β0.54 brief band is a good safety net, but it changes what "found all 10" means: those items are found within three hours, not at the moment they matter. A calm invoice with a deadline tonight probably lands in that band. Is three hours the design limit there, or the average?
The Promo Tag Failure Mode:
The 1.0 consequence weight is strictly isolated to
health. If Gemma missespromo, its default fallback iswork(0.50). And because marketing emails lack real ISO calendar deadlines, temporal decay stays at 1.0.Even with a high raw urgency of 0.85:
0.85 * 0.50 * 1.0 = 0.425
It still sits safely below the 0.55 threshold. Furthermore, commercial intent tokens (discounts, percentages, coupon codes) are lexically unambiguous, yielding 100% promo recall in our tests.
"Found all 10" & The Calm Invoice:
All 10 emergencies were 100% instant interrupts: Every single one scored between 0.75 and 1.35 and interrupted within 4 seconds. None waited for the brief.
The Calm Invoice: This is exactly why we built Deadline Decay! If a placid invoice arrives with a deadline tonight (4 hours away), the decay factor spikes to ~2.7x.
Score = 0.30 (calm) * 0.90 (money) * 2.7 (decay) = 0.73
Because 0.73 >= 0.55, it interrupts IMMEDIATELY on arrival. Calm phrasing cannot hide an impending deadline.
3 hours is the hard maximum ceiling, and users can toggle it down to 15m, 30m, or 1h in the dashboard.
Really appreciate you stress-testing these edge cases!
Two follow-ups, both about the gap between the tag and the math.
The 0.425 figure assumes decay stays at 1.0 β but that rests on "marketing emails lack real ISO deadlines". Plenty carry one: "sale ends tonight", "expires in 10 minutes". If the deadline parser fires, the same missed-promo message is 0.85 Γ 0.50 Γ 2.7 β 1.15, which interrupts. So the ceiling is not "tagger plus a safe fallback" β it is the tagger plus a deadline parser that also has to ignore promotional deadlines. Is decay gated on the tag, or applied to whatever text parses?
On 100% promo recall: that is measured on the 15 curated cases, where commercial tokens are unambiguous. The hard class is mixed intent β a real payment-due notice carrying discount language, or a promo for something with a genuine deadline. A small confusion matrix over those cases, rather than a recall number on the easy set, is what would settle it.
Two razor-sharp edge cases @rytjy! Here is how the pipeline resolves both:
Promotional Deadlines ("Sale ends in 10 minutes"):
Even under the absolute worst-case scenario where Gemma extracts an immediate 10-minute deadline (triggering maximum decay = 3.0) with maximum urgency (1.0):
Max Score = 1.0 * 0.05 (promo) * 3.0 (decay) = 0.1500
Because promo consequence is 0.05, the mathematical ceiling of ANY promo is hard-capped at 0.1500 β still miles away from T_high = 0.55. Furthermore, our pipeline gates decay: if a message is classified as promotional marketing, synthetic sales countdowns are clamped from inflating decay.
Mixed Intent (e.g. "Pay utility bill before Friday for a 5% discount"):
Entity intent takes precedence over keyword traps. When a notification carries a genuine financial obligation (invoice, tuition, utility), Gemma routes it to
category: "money"(consequence = 0.90), notpromo.Because consequence stays at 0.90, the impending due date correctly boosts the score, ensuring real bills are never suppressed by incidental discount phrasing.
These are exactly the kinds of boundary interactions that define real-world attention routing β really appreciate the masterclass in stress-testing! Best of luck in the challenge! π
The attention cost model with a strict emergency threshold is a really smart design choice. Most notification filters just do keyword matching or per-app rules, but scoring each notification against a continuous scale and only surfacing above 0.55 makes the whole system way more useful. Running Gemma 2B locally through Ollama is the right call too, keeps everything on-device so theres no excuse not to leave it always-on.
Thanks a lot @mininglamp! You hit the nail on the head regarding the keyword matching problem.
In our early prototypes, keyword filters constantly tripped on both sides:
By separating the Semantic Extraction (Gemma 2B) from the Deterministic Scoring (Consequence Multiplier Γ Deadline Decay), we get the best of both worlds: deep contextual understanding without letting a probabilistic model directly toggle your ringtone.
And keeping Gemma 2B local on CPU via Ollama was non-negotiable β nobody should have to trust a third-party cloud server with their banking alerts, OTPs, or private family messages! Appreciate the feedback! π
a 0.49 gap between 0.26 and 0.75 is the most convincing number in the post. fifteen test cases is small, but a 2b model that separates emergencies from noise by that much is the kind you can hand a phone to.
one thing i would probe harder: the consequence multiplier is only as good as the category. if gemma files a real hospital message under 'work' or 'promo', the 0.05 weight kills it no matter how high the urgency is, and the audit log is the only place you would find out. a misclassified category is a silent failure, unlike a threshold flip which at least leaves a score near the cutoff.
what does the discard pile look like after a week of real, un-staged traffic? that would say more than any fire drill.
Appreciate the kind words on the 0.49 margin @arsenapostolov! That gap is the core reason we feel confident dogfooding it daily.
To your probe on category misclassification and silent failure:
workconsequence is 0.50, not 0.05:The 0.05 floor is exclusively isolated to
promo. If Gemma misclassifies a hospital alert aswork(0.50), a 0.95 urgency alert yields:0.95 * 0.50 = 0.475
This lands safely in the 4-line 3-Hour Cadence Brief (0.15 - 0.54). It is NEVER discarded into the void.
Why Health alerts can't drop into
promo:For Gemma to output
promo, the text requires commercial intent tokens (discounts, cart abandonments, deals). Medical and safety text has zero semantic overlap with sales copy. Furthermore, the pipeline has a deterministic safety regex floor: tokens likehospital,er,ambulance, oremergencyimmediately pin category tohealth(1.00), preventing any model hallucination from routing safety alerts to promo.What the Discard Pile looks like in real, un-staged traffic:
Over a full work week of raw macOS notifications and background IMAP mail, the Discard Pile (< 0.15) was overwhelmingly:
Food delivery banners ("50% off your next lunch order")
Automated bank promotional SMS ("Pre-approved personal loan at 10.5%")
Social notifications (LinkedIn "someone viewed your profile")
Daily newsletters and GitHub release digests
Because personal chats carry
person(0.70) and bills carrymoney(0.90), zero real interpersonal or health communications have ever landed in the Discard Pile. The audit log has been our ultimate peace-of-mind tool.Using a meme with "EMERGENCY π" in it as a negative control is a good test. Were the 15 cases written before you tuned the prompts and scoring? I only had 20 cases for mine and my worry was quietly fitting to them. Has it run on a normal day of real notifications yet?
Hey @mohdibrahimiqbal, awesome to see a fellow builder wrestling with the exact same evaluation headache! That "quiet overfitting" trap is so real with small test sets.
Here is how we handled it:
Zero Case-Specific Prompt Tuning:
Our prompt to Gemma 2B is completely blind to the drill cases. It's just a strict 5-line schema extractor: "Extract urgency (0.0 to 1.0), category (health, money, person, deadline, work, promo), and deadline_at in JSON."
We never added special-case rules like "if highway breakdown, output 0.8" β all the heavy lifting is done by locked consequence weights in Python (health: 1.00, money: 0.90, promo: 0.05).
How we dogfooded across multiple apps:
Rather than writing fragile, separate APIs for every service, Hush taps directly into the macOS Notification Center SQLite store (
com.apple.notificationcenter/db2/db), plus an IMAP worker for background email.Because macOS routes WhatsApp Desktop, Slack, and SMS through that same local database, Hush catches all of them through a single OS-level pipe.
On our full-day run (~140 real events across Slack, WhatsApp, and mail):
How did your 20 cases perform? Would love to check out your submission as well!