An autonomous, self-learning agent.
Life is the app. Lify is the agent inside it: it plans your day with you, steps in when you're stuck
scrolling, and learns every night what works on you.
Powered by Meta's Muse Spark, Muse Spark Open, Muse Image and Muse Voice Transcribe.
Demo Β· Measured Β· Benchmark Β· The night shift Β· Moments Β· Why it matters Β· Meta's Muse Β· Under the hood Β· Architecture Β· Verify it Β· Your own key Β· Permissions Β· Your control Β· Privacy Β· What's next
It's 1 AM. You said you'd be off your phone by 11. You've been doomscrolling for two hours.
A card slides over the video: "Gym at 6. The feed will still be here." One button: Let's hit the gym!.
You've never seen that sentence before. Lify wrote it last night, after studying the last 30 nudges it sent you and finding the ones that actually made you put the phone down.
Life is not a planner with a chatbot on top. Screen-time apps count your minutes and block apps. Life also notices why you picked up the phone (you opened Gmail, and three minutes later you're deep in a feed) and hands you a way back. Every night it tests which nudges actually get you off the feed, and keeps only what works.
It is a closed loop that runs on your phone every day:
| π It watches | Real screen time from Android's usage events: which app, for how long, and when your phone went quiet last night. |
| β It steps in | A personal card on top of the app you're stuck in, at the right moment, with one tap to get out. |
| π It measures | Did you leave the app right after (within 2 minutes; 20 seconds in demo mode), and stay off the feeds? Going straight back to a feed within 10 minutes doesn't count. Your phone's own usage data says so. |
| π± Day one | Before Lify knows you, it starts from what tends to work for most people: concrete next steps, short and direct lines. Then it shifts to what works on you. |
| π§ͺ It learns | Every night Muse Spark Open reads your whole history, proposes theories about you, verifies them against your results, and writes tomorrow's experiment. |
On my own phone so far: I left the app after 47% of Lify's nudges, and it worked out what works on me: nudges about my own goal (left 10 of 17 times). The numbers
On 300 simulated people with known answers (npm run bench, no key, about 20 s): after 120 nudges people leave
after 43% of Life's nudges vs 34% for a fixed app, and Life names each person's best idea for 73% of them.
The benchmark
Nobody has to press anything. Each night Lify decides on its own what to test tomorrow, and during the day it decides when to step in, which line to use, and whether to hold a nudge back. It sets the alarms and calendar reminders for the plan you agreed on, lowers your daily target only when you've earned it, and drops ideas that stop working.
Planning your day, alarms and study material are there too, but they serve this loop. The agent's job is to get you off the phone and onto what you said matters.
Before the hackathon I built an early prototype of this idea: an Android app with Google login, a screen-time display and app limits with generic notifications. Its backend only handled the Google sign-in: no other APIs, no data processing. It had no AI agent and no AI features of any kind.
Everything in this repository is brand new and was built during the hackathon:
- a new codebase, written from scratch: no code from the prototype is reused;
- a new stack (Flutter + Kotlin, Supabase Edge Functions and Postgres, Meta's Muse Spark, Muse Spark Open, Muse Image and Muse Voice Transcribe);
- a new UI, new screens, a new logo and new branding;
- everything that makes Life what it is: the agent Lify, the night shift, the theories verified on real results, the experiments with Thompson sampling, the off-policy evaluation, the personal nudge cards and the phone-down nights.
This repository starts at the tag hackathon-start,
its first commit (26 Oct 2026). I worked locally and pushed in large batches, so each commit holds a lot of work; the
commit dates, the day-by-day migrations and the tests show how it was built.
βΆ Watch the 3-minute demo Β· β¬ Download the APK (Android 10+; install it, then follow How judges can verify)
The demo opens with Jake showing the problem: scrolling at night and the "let's plan tomorrow" notification. Then it's the real app on a real phone:
- planning tomorrow by voice, with a PDF in and a PDF out;
- a nudge card sliding over the app you're stuck in, and Pull me out;
- Your path (the step-down targets);
- the night shift, and Lify's theories verified on real results.
Cards over the app, as they appeared on my phone. Moments: facts from the phone, words by Muse Spark Open, and a button straight back to the app you came for:
An exit point on Twitch ("you usually leave around minute 9, this is minute 13"), and a line from last night's bank with Pull me out:
What Lify learned about me, and how my plan changed:
Planning with Lify, and the day it set up:
More screenshots (onboarding, a CV in and a cover letter out, the evening review, step-down targets, alarms, more cards)
Me, on my own Samsung phone, as of 3 November 2026: the learning loop working on a real device, with real scrolling.
| What | Result |
|---|---|
| Left the app after a nudge | 33 of 70 nudges (47%), measured by Android's usage events, not by the model |
| It found what works on me | Nudges about my own goal: I left 10 of 17 times (59%), vs 11 of 26 for my next task and 12 of 27 for what the time costs. Lify rates "my own goal" 75% likely the best style for me, and now sends more of them |
| A second, independent method agrees | Off-policy evaluation on the same logs, which never sees Lify's ratings, also picks "my own goal" as the best style: about 56% if sent every time, up from the 47% so far, while Lify was still trying every style to find out. That is where it is heading now |
| Left and stayed off (no feed within 10 minutes, outside demo mode) | 27 of 52 |
| Night shift, end to end | Muse Spark Open read the whole history, wrote theories and tomorrow's nudge bank, and the critic finished 41 s after the draft |
| Control group | Running: about 1 in 10 nudges is held back on purpose and only measured, so "with Lify" can be compared with "without" as the days add up |
Every number above comes from the app's own logs; the queries are in docs/MEASURED.md.
One person can't prove a learning loop works, so Life ships a benchmark anyone can rerun: npm run bench. It needs no
API key and no phone, and it's seeded, so you get exactly these numbers. The people are simulated, so the right
answer is known in advance: each of 300 people has a hidden chance of leaving the app for each of 6 nudge ideas, the
idea that works on them is usually not the one that works for most people, and for half of them a different idea works
at night. It runs Life's real theory judge, off-policy estimator and line checks; the phone's picker is mirrored from
core/Bank.kt, and a test checks the mirror uses the same formula and constants.
1. Does it find what works on each person? (how often they left the app after a nudge; 240 simulated nudges per person, run in seconds. In real use, about 30 nudges is a week.)
| Policy | Nudges 1-30 | 31-60 | 61-120 | 121-240 |
|---|---|---|---|---|
| Random idea each time | 34% | 35% | 35% | 35% |
| Always "what works for most people" (a fixed app) | 34% | 34% | 34% | 34% |
| Life | 37% | 39% | 41% | 43% |
| Knowing the hidden answer (best possible) | 53% | 52% | 53% | 53% |
Life keeps improving while a fixed app stays flat: from nudge 121 on, people leave 26% more often, and Life names each person's best idea for 44% of them after 30 nudges and 73% after 240. For 86% of the people, the best idea isn't the one that works for most people, so an app that doesn't learn never finds it.
2. Are theories judged right? 3,521 theories put to Life's real judge on each person's first 60 nudges:
| Kept, and actually true | 324 of 411 (79%) |
| Rejected, and actually false | 213 of 230 (93%) |
| Clearly false (10+ points worse), but kept anyway | 17 of 1,096 |
| Not enough evidence yet, so still "testing" | 2,880 |
Without this check, every theory the model wrote would be shown as a fact.
3. Does the second opinion tell the truth? Off-policy evaluation, from the logged choice probabilities alone, on 70 nudges per person (about what I have): each style's estimate is off by 8.6 points on average, and it picks the truly best style for 61% of people (chance would be 33%).
4. Do the guards stop bad lines? A hand-written set of 26 drafts (invented numbers, meter talk, health words, a line already sent, a reminder that drifts off what the user asked): 16 of 16 bad ones stopped, 0 of 10 good ones.
Full report: docs/BENCHMARK.md Β· code: bench/bench.ts
Most "AI nudge" apps send the same kind of message forever. Life runs the scientific method on one person, every night: Muse Spark Open proposes theories about you, and every one is verified against your real results.
ββββββββββββββ THE NIGHT SHIFT Β· Muse Spark Open, reasoning_effort "medium" ββββββββββββββ
your β 1. READ every nudge it ever sent you + what you did next, your nights, your plans β
whole βββΊβ ONE request, 1M-token context, no retrieval, no summaries in between β
history β 2. THEORIZE testable claims: WHEN (app, time of day, weekday/weekend, how far over the β
β limit, task coming up) + WHAT (tone, topic) works better than the rest β
β e.g. "a feed, at night, way over: blunt lines about tomorrow's task" β
β 2b. VERIFY on your real results: Beta posteriors for "with it" vs "without it" in those β
β exact moments β P(true). β₯90% kept, β€10% rejected. "left 5/7 vs 1/6" β
β 3. DESIGN tomorrow's NUDGE BANK: ~30 short lines grouped by ANGLE (the idea behind β
β them). Winning angles get new words; 1-2 new angles to test; losers dropped β
β 4. CRITIC a second pass plays your "inner skeptic" (reasoning "low") reads each line β
β as you'll see it and cuts the generic, preachy, repeated or garbled ones β
β 5. CHECK β€12 words, no minute counts, no "you're at your limit", no health language, β
β never a line you've already seen. Every line is checked before it's used. β
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ the bank goes to the phone
ββββββββββββββ DURING THE DAY Β· on the phone, instant, works offline ββββββββββββββββββββββββ
β stuck scrolling β Thompson sampling over ANGLES picks the idea most likely to work on you β
β HERE (this app, this time of day) β shows a line from it you've never seen β measures β
β whether you left. The idea that works keeps coming back, always in new words. β
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ results go back up, and the next night checks the theories
In the app, "Lify's theories about you" says when it was written and what it read ("written at 22:48 by Muse Spark Open after reading 39 nudges and 7 nights in one request"), shows how each theory moved since last night ("testing 54% β kept 93%", or "new tonight"), and lists the lines the critic threw out, crossed out, with its reason. Every theory shows the probability it's true, computed from your results, and the counts behind it ("Checked on your data: left 5/7 with it vs 1/6 without (Instagram, at night)"). When the data disagrees with the first guess, it says so: Lify guessed "kept"; your results say "rejected". You also see tomorrow's ideas with "you left 4 of 6 times", Lify's starting assumptions about most people, and "How Lify thought about it": an excerpt of the open model's own visible reasoning.
Why the hour and the app matter: scrolling at 1 AM on a weekday, 40 minutes over the limit, the night before the gym, is not scrolling on a Sunday morning. Every nudge is logged with its moment (app, time of day, weekday or weekend, near or way over the limit, important task within 2 hours) and the tone and topic of the line. Theories are checked only on the moments they are about.
Learning from "most people" without anyone's data: before you have results, each idea starts from a small starting assumption (for example, a concrete next step tends to beat general advice), worth about 3 nudges. The learning has three levels, each borrowing from the one above until it has its own data: most people β you everywhere β you on this app at this time. Your results outweigh the assumptions within a day or two. The top level can later take anonymous totals from all Life users (opt-in).
Code: nightshift.ts Β· theories.ts Β·
Bank.kt Β·
LimitWatcherService.kt
- Less, one step at a time, using a known method. Life uses the changing-criterion method (step-by-step targets, each one earned). It starts from your typical day (the median of the last 7, not your worst), sets a target about 15% lower, and steps down again only after you hit it on 2 of the last 3 days. A missed day never raises it, and it stops at your own goal: the aim is less, not zero. When a target drops, Muse Spark Open writes what to do with the minutes you won back, from your own plan ("25 minutes back: two pages of your thesis at 22:15"). That is an implementation intention, and the nudge at the target uses it. Home shows it as Your path: Instagram: 3 h β 2 h 35 β today 2 h 10 Β· goal 30 min.
- The problem everyone has: hours a day lost to scrolling, and the knowledge that it's happening doesn't stop it. Screen-time apps show charts or block apps; people ignore the charts and switch the blocker off.
- Life doesn't lock your apps: it gets you to leave them yourself. A personal line at the right moment and one tap out, then it checks whether you actually left, and gets better at it every night.
- It works on what you care about: every nudge points at your own goal, tomorrow's plan, or your real phone-down time last night ("Phone down at 03:30 last night. Tonight?"). Never a generic "take a break".
- It respects you: at most 4 nudges per app per day, at least 20 minutes apart, spaced further out the longer you go over (+15, +45, +105 minutes). A rule you set ("every 30 minutes on any app, remind me to do 10 push-ups") fires on top, in the same 20-minute spacing.
Generic nudges could be sent to anyone. A moment carries one fact that is only true for this person at this second. The phone works out the fact from its own data; Muse Spark Open turns it into a line; the server keeps that line only if every number in it is one of the real facts.
| Moment | When | Example | Button |
|---|---|---|---|
| Lost intent | You picked the phone up for one app and drifted into feeds | "You picked up your phone for WhatsApp 14 minutes ago. Since then: Instagram, then YouTube." | Back to WhatsApp |
| Your exit point | This session passed the minute you usually leave on your own | "You usually leave YouTube around minute 6. This is minute 9." | Open: your next task |
| Planned now | Your own plan says this time is for a task | "You planned 'Finish chapter 3' for 21:00. It's 21:10." | Open: Finish chapter 3 |
| Phone-down | You're past the phone-down time you chose | "You said phone down at 23:00. Tomorrow starts with Gym at 07:00." | Done for tonight |
Thompson sampling learns which moment works on you, and the night shift writes theories about them.
Four Meta models, each used for what it is uniquely good at:
| Model | Job in Life | Why this model |
|---|---|---|
| Muse Spark (Chat Completions, Responses) | The agent: planning chats with 18 tools (calendar, alarms, app limits, PDFs, documents), web search with sources, reading photos and scanned PDFs | Agentic tool calling, multimodal input |
| Muse Image (Image generation) | Pictures Lify makes for your day and your tasks | Image generation |
| Muse Voice Transcribe (Transcribe) | Talk to Lify instead of typing | Speech to text |
Muse Spark Open (open weights, served on Baseten as meta-models/muse-spark-open-1026) |
The night shift (theories + nudge bank + critic), live nudges, the evening "let's plan tomorrow" notification | 1M-token context: reads your whole history at once instead of retrieval. Controllable reasoning: thinks hard at night (medium), almost not at all for live nudges (low). Visible reasoning: shown in the app as "how Lify thought about it". Open weights: Life runs it on Baseten's inference platform, one of Meta's launch partners, and the same pipeline can be self-hosted so your history never leaves your servers. |
- Muse Spark and Muse Spark Open back each other up, so a nudge still arrives if one is down.
Talk to Lify any way you like, and get back what you need:
| You send | What reads it | Lify sends back | What makes it |
|---|---|---|---|
| Text | Muse Spark | A plan, tasks, alarms, app limits, your own rules | Muse Spark (tool calls) |
| Your voice | Muse Voice Transcribe | Spoken answers | the phone's voice |
| A PDF (a CV, a course, an article) | Text PDFs read on the server; scanned ones by Muse Spark (vision) | A real PDF (a study sheet, a cover letter) | Muse Spark writes it, the server lays it out |
| A photo (timetable, whiteboard, notes) | Muse Spark (vision) | A picture (a card for your day) | Muse Image |
| A link, or "find meβ¦" | the server reads the page; Muse Spark web search with sources | Links in the task, checked before they're saved | Muse Spark |
- Code:
muse.ts(model setup, routing, failover, reasoning effort),nudge.ts,evening.ts.
Muse writes, plans and forms theories; Life's engine tests, measures and learns from every result.
- Contextual Thompson sampling with a 3-level prior (phone, Kotlin): each idea has a Beta posterior for this app at this time of day. Its prior comes from your other moments, and theirs from a starting assumption about most people (hierarchical shrinkage), so a new user and a new moment start from what is already known.
- Theories verified on real results (server): every theory must be testable (moments + property). Life compares "with it" vs "without it" in exactly those moments with Beta posteriors and 4000 seeded joint draws, and sets the status and confidence. The tests show the model's own "kept 95%" being overruled by the data.
- Propensity logging: the chance of each choice is computed by Monte Carlo (400 draws) and logged with the result.
- Off-policy evaluation (server): self-normalised inverse propensity scoring estimates how "always send style X" would have done on the same moments. Life's lift over the best fixed nudge comes with a 90% bootstrap interval. The tests check that the estimator recovers known rates from heavily biased logs.
- A real control group: about 1 in 10 nudges is held back on purpose (no card) and only measured. The lab notebook compares "with a nudge" vs "without one", so Life can show what its nudges actually add, not just how often people left anyway.
- Facts computed in code, phrased by Muse: a moment's numbers come from the phone's own data; any line from the model with a number that isn't one of those facts is thrown away.
- Strategy memory: each evening review writes a new strategy version. The server refuses any change that doesn't cite a number, never shrinks your plan below 3 tasks, and keeps every version (day 1 vs. today).
- Real Android engineering:
- a foreground watcher reading
UsageStatsManagerevents; - a custom overlay card with a "Pull me out" button. On phones that hide overlays it falls back to a heads-up notification automatically;
- a watchdog alarm that restarts the watcher if the phone kills it;
- exact alarms and real Clock-app alarms;
- phone-down detection from unlock events, which ignores notification wake-ups, alarms and calls.
- a foreground watcher reading
- Production basics:
- anonymous auth with row-level security on every table;
- per-user and global daily caps;
- keys only in server secrets;
- every link checked before it is saved;
- 400+ automated tests.
- Open source: MIT license.
Code: Experiment.kt Β·
experiments.ts Β· strategy.ts Β·
Nights.kt
Pop-ups and limits measurably reduce phone use. But nudge effects vary a lot between people, so Lify doesn't assume any nudge works: it tests them on you, the way researchers do in micro-randomized trials.
- Pop-ups reduce app use. In a 6-week field study with 280 people, a pop-up before a chosen app made people close it 36% of the time, and actual openings fell 57% (GrΓΌning et al., PNAS 2023). The easy exit was the strongest ingredient, not the message. That's why Life's card leads with one tap: Pull me out.
- People want limits. When about 2,000 Android users were offered a tool to set their own app limits, 89% used it and their social media time fell 17% (Allcott, Gentzkow & Song, AER 2022).
- Just-in-time suggestions work, then fade. In the HeartSteps micro-randomized trial, walking suggestions raised the next 30 minutes' steps, but the effect shrank over the weeks (Klasnja et al., 2019). Life uses the same design (randomize at each moment, measure the next minutes) and keeps the wording fresh.
- Nudge effects vary a lot between people. Across 200+ studies, what works for one person often doesn't for another (Mertens et al., PNAS 2022). So Life doesn't assume any nudge works. It measures what works for each person.
These studies support the approach, not Life's exact numbers: one sec steps in when you open an app, Life steps in after you've been in it for a while.
- Plans tomorrow with you (text or voice, a notification one hour before your bedtime). It checks your calendar, estimates task durations itself, and puts tasks and alarms on the phone the moment the plan is saved.
- Picks the right alarm per task: a real Clock alarm for things away from the screen (gym, prayer, leaving home), or an in-app alarm that opens the task's own screen with everything ready (links, PDFs, pictures, steps, chat notes).
- Makes what you need: study sheets as real PDFs and pictures. It reads web pages, PDFs and photos you send, and searches the web with sources.
- Your own rules: "whenever I'm on any app for 30 minutes straight, pull me out" becomes a rule on the phone. Short breaks (the screen going off, a quick reply) don't reset the count.
- Step-down targets: each distracting app's daily target goes down one earned step at a time (see Why it matters), with Muse Spark Open's trade for the minutes you win back.
- Knows your nights: when the phone went quiet and was picked up again, measured from unlock events. "Phone down at 03:30 last night. Tonight?"
- Learns: the night shift, the lab notebook (every nudge, why it was picked, what you did next), and the strategy memory with every version kept.
- Talks: voice in (Muse Voice Transcribe), voice out.
- Check Lify: a self-diagnosis screen showing the account, server, watcher, battery and pop-up permissions, your last nights, and a log of every nudge (shown as a card or a notification, or skipped and why), with Fix buttons.
The small details that make it work:
- A night is measured from unlocks, not from the screen. A notification lighting up the screen, an alarm or a call doesn't count as you picking the phone up.
- Your nights are part of what it studies. The night shift reads when the phone went down and when it was picked up again, next to every nudge and what you did after it.
- Morning is not night. Every result is filed by time of day, weekday or weekend, how far over the limit you were, and whether a task was coming up, so what works at 1 AM is never assumed to work at 9 AM.
- A short break doesn't end a session. Locking the phone for a moment or a quick reply (under 3 minutes) still counts as one session. Leaving the app but opening a feed again within 10 minutes doesn't count as leaving.
- It knows when you came on purpose. "Lost intent" looks at the first app you opened after unlocking: if it was already a feed, Lify stays quiet.
- Your exit point is yours. It's the middle of your finished sessions on that app over the last 14 days, and it's only used once there are at least 5 of them.
- It measures itself. About 1 in 10 nudges is held back on purpose, to see what you'd do without one.
- It doesn't nag. Never two cards within 20 minutes, across all apps, and at most 4 limit nudges per app a day.
Meta's Muse models are the brain of Life at every moment of the day: they listen, read, plan, act on your phone, study you overnight and write every line you see. The phone and the server give them senses, hands and a memory.
ββ EVENING Β· you talk to Lify (voice, text, a PDF, a photo) ββββββββββββββββββββββββββββββββββββββ
β MUSE VOICE TRANSCRIBE your voice β text β
β MUSE SPARK (agent) reads your CV, notes and photos (vision), searches the web (sources), β
β plans tomorrow with you, writes study sheets as PDFs, and ACTS on your β
β phone with 18 tool calls: tasks, alarms, app limits, calendar, rules β
β MUSE IMAGE pictures for your day and your tasks β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ tomorrow is on your phone the moment the plan is saved
ββ NIGHT SHIFT Β· Muse Spark Open on Baseten studies you (1M-token context, reasoning "medium") βββ
β reads ALL of it in one request: every nudge + what you did next, nights, plans, your path β
β β THEORIES about what gets you off your phone, and when β verified against your results β
β β tomorrow's NUDGE BANK: fresh lines grouped by idea β a critic pass cuts weak lines β
β β the minutes you won back on Your path become a plan ("25 min back: 2 pages at 22:15") β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ the bank and today's targets go to the phone
ββ DAY Β· on your phone (Kotlin), instant, works offline ββββββββββββββββββββββββββββββββββββββββββ
β usage watcher sees a feed at 1 AM, 40 min over today's target β
β β Thompson sampling picks the idea most likely to work on you HERE β a line you've never seen β
β β the card slides over the feed: "Gym at 6. The feed will still be here." [Pull me out] β
β β no line fits? MUSE SPARK OPEN writes one live (reasoning "low", lands in seconds) β
β β did you leave? measured from Android's usage events β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ every result goes back up: tonight's night shift learns from it
ββ SUPABASE Β· the memory βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Edge Function "agent" (agent loop, 3 modes, night shift, theory checks, off-policy evaluation) β
β Postgres + row-level security: plans, chats, strategies, nudges + outcomes, nights, shifts, β
β step-down paths Β· Storage: PDFs and pictures (deleted after 3 days) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Three agent modes, one agent:
- planning (evening): asks until it has everything, then saves the plan;
- execute (morning): sets up the day on the phone through device tool calls;
- review (evening): compares the plan with real usage and updates the strategy.
- The server remembers the conversation; the phone sends only new messages and tool results.
- API reference: docs/API.md.
| Path | What |
|---|---|
supabase/functions/_shared/ |
prompts, tools, agent loop, Muse clients, night shift, experiments and evaluation |
supabase/migrations/ |
Postgres schema with row-level security |
tests/ |
backend tests with a scripted model and an in-memory store (no network, no keys) |
app/lib/ |
Flutter: screens, agent client, device tools, plan applier |
app/android/.../kotlin/ |
Kotlin: watcher, Thompson sampling, nudge bank, overlay card, alarms, nights |
docs/API.md |
every request and answer |
Backend (Node 22.6+ and the Supabase CLI):
npm install
npm test
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase db push
npx supabase secrets set MUSE_BASE_URL=... MUSE_API_KEY=... MUSE_MODEL=... OPEN_API_KEY=...
npx supabase functions deploy agent
Turn on Anonymous sign-ins in Supabase Authentication.
App (Flutter 3.41+, Android SDK):
cd app
flutter pub get
flutter run --release --dart-define=SUPA_KEY=sb_publishable_YOUR_KEY
See app/README.md for permissions and first run.
- Install the APK on an Android phone (Android 10+). No Android phone? Install Android Studio (free, Mac or Windows), open Device Manager, start an emulator (any phone with Android 10+), and drag the APK onto it.
- Finish the 5 onboarding slides. Allow Usage access, Show over other apps and Notifications. Lify pre-chooses the feed apps on the phone (TikTok, Instagram, YouTubeβ¦) as Apps that pull me away, even with no screen-time history yet; change them in Settings. In Settings β Check Lify, set Battery to unrestricted.
- Talk to Lify: tap Plan tomorrow and plan by voice or text. Saving the plan puts tomorrow's tasks and alarms on the phone right away (check your Clock app).
- See a nudge: Settings β Experiments β turn on Experiments, then Demo mode. Lock and unlock the phone, open Gmail or Chrome for a few seconds, then one of the apps you chose: a moment slides in ("You picked up your phone for Gmailβ¦", with Back to Gmail). Stay a minute: the next card is a nudge from tonight's bank with Pull me out. In demo mode the two take turns.
- See the night shift: Home β TEST β Night shift (test) (up to 2 minutes), then open Lify's theories about you: theories verified on your results, tomorrow's lines, and "How Lify thought about it".
- See everything that happened: Settings β Check Lify β What the watcher did: every card shown, held back or skipped, and why there's no card yet ("12/30 min today; first nudge at 24 min").
- Run the benchmark:
npm run bench(Node 22+, no key, no install, about 20 s). See above. - Run the tests:
npm test(backend),cd app && flutter test(app). They also run on every push: GitHub Actions.
The judging build uses a shared demo backend with a daily cap per user, so a judge's account works on its own.
You can download the ready-to-use APK from Releases: it works as is, nothing to set up. If you want to use your own keys, follow these steps. No code changes are needed: every key is a server secret.
1. Backend (about 10 minutes): a free Supabase project, Node 22.6+:
git clone https://github.com/ayoubna99/life-agent && cd life-agent
npm install
npx supabase login
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase db push
npx supabase secrets set MUSE_BASE_URL=https://.../v1 MUSE_API_KEY=YOUR_META_KEY MUSE_MODEL=YOUR_MUSE_SPARK_MODEL
npx supabase functions deploy agent
In Supabase β Authentication β Providers, turn on Anonymous sign-ins.
Optional, for Muse Spark Open: npx supabase secrets set OPEN_API_KEY=YOUR_BASETEN_KEY.
Without it, every job (including the night shift) runs on Muse Spark.
2a. Quick check from a terminal, no phone needed. It talks to your backend exactly like the app does:
$env:SUPA_URL = "https://YOUR_PROJECT_REF.supabase.co"; $env:SUPA_KEY = "sb_publishable_..."
node scripts/chat.mjs --fake-usage # planning chat with tool calls
node scripts/chat.mjs --voice C:\path\recording.wav # Muse Voice Transcribe
node scripts/chat.mjs --attach C:\path\notes.pdf # reading a PDF or a photo
node scripts/chat.mjs nudge --app TikTok --used 52 --limit 30 # the line a nudge card would show
.\scripts\smoke.ps1 # the whole flow in one go
2b. The full app on your backend:
cd app
flutter build apk --release --dart-define=SUPA_URL=https://YOUR_PROJECT_REF.supabase.co --dart-define=SUPA_KEY=sb_publishable_...
Install app/build/app/outputs/flutter-apk/app-release.apk and follow the steps in
How judges can verify.
Life asks for each permission on its own screen and explains it first. Only Usage access is needed for the core loop; everything else makes Life better but is optional. Settings β Check Lify shows which ones are on, with a Fix button.
| Permission | Why | Needed? |
|---|---|---|
| Usage access | To see which app is in front and for how long (never what's in it). Screen time, nudges, nights and step-down targets all come from this. | Required |
| Notifications | The evening "let's plan tomorrow" notification, reminders, and nudges when a card can't be shown | Recommended |
| Show over other apps | The nudge card on top of the app you're in. Without it, nudges come as notifications. | Optional |
| Alarms and reminders (exact alarms) | In-app task alarms at the exact minute, and the evening notification on time. Without it, Life can't set in-app task alarms (Clock-app alarms still work). | Recommended |
| Battery: unrestricted | Some phones (Samsung, Xiaomi) stop background apps, and the watcher with them. | Optional, recommended |
| Calendar (read only) | Plan around your real events, and remind you before them | Optional |
| Microphone | Talk to Lify instead of typing | Optional |
| Internet, run in the background, start after a reboot, set a Clock alarm | Granted by Android automatically, no prompt. The background watcher shows a silent "Life" notification, as Android requires. | Automatic |
Life never asks for contacts, location, SMS, the camera roll or your accounts. Photos and PDFs are only read when you pick them yourself.
Lify acts on what you ask it for: the plan you make with it, the rules you set. Everything else can be turned off or changed in Settings.
- Choose which apps it watches: only the apps in Apps that pull me away. Take one off the list and its limits and nudges go too.
- Nudges as notifications: prefer a notification to a card over the app? One switch in Settings β Check Lify.
- Your own rules: see them in Settings β Your reminders and remove any of them there, or just ask Lify.
- Experiments off: nothing about your nudges is sent to the server; the learning stays on your phone.
- Every alarm is a normal one: phone alarms are in your Clock app, where you can change or delete them like any other.
- The silent "Life" notification: Android requires it while the watcher runs; you can hide its category in your phone's notification settings.
- Your data: see Privacy for what is stored and how to delete it.
| What | Where it goes | Kept |
|---|---|---|
| Screen time: minutes per app per day (never what you watch) | Supabase (your private rows, row-level security) | Until deleted |
| When the phone went quiet each night (two times, no content) | Supabase | Until deleted |
| Plans, chats, your settings (name, sleep time, apps, focus) | Supabase; chats go to Muse Spark (Meta) to answer | Until deleted |
| Live nudges and the evening notification: your plan, settings and the last few nudge lines | Muse Spark Open on Baseten, to write the line | Not stored by Life outside Supabase |
| Each nudge: app name, time, the words, whether you left | Supabase | Until deleted |
| Night shift: the last 30 days of the rows above, sent once a night | Muse Spark Open on Baseten (inference only) | Not stored by Life outside Supabase; see Baseten's terms |
| Voice recordings | Transcribed by Muse Voice Transcribe, then deleted | Not kept |
| Photos, PDFs you send | Read, kept as text; photos deleted after reading | Files: 3 days |
- Never collected: the content of other apps, what you watch, messages, location, contacts. The watcher only sees which app is in front and for how long, from Android's usage statistics.
- Accounts are anonymous: no email, no phone number. The account lives on your phone.
- Delete your data: email the first 8 characters of your account id (Settings β Check Lify β Account) to ayoub.nadjem09@gmail.com. Deleting the account removes every row about you (every table is linked to it and deleted with it) and your files. A one-tap "Delete my data" button is next on the list.
- "Totals from all users" is a design option only. Nothing is pooled today. If it is ever built, it will be opt-in and share only counts per kind of nudge, nothing personal.
- Open weights: because Muse Spark Open's weights are open, the night shift can run on servers you control, so your
history never leaves them. The code needs only a different
OPEN_BASE_URL.
- From one person to many. The measured results come from my own phone (about 70 nudges), and the benchmark from 300 simulated people. Next: more real users, and the anonymous "what works for most people" totals that every new user starts from (the slot is already in the code).
- The control group grows every day. About 1 in 10 nudges is already held back on purpose; as they add up, Life will show exactly how much a nudge adds over none.
- Beyond "did you leave". Today Life measures that you left and didn't go back to a feed within 10 minutes. Next: whether you then started the task the card pointed to.
- Android first. Life is built on Android's usage events and overlay cards; iOS doesn't give apps those yet.
- Works offline, learns online. Cards and the nudge bank run on the phone with no network; the night shift needs one connection a night to study and write tomorrow's bank.
- Tested end to end on a real Android phone (Samsung):
- planning chats with live Muse Spark tool calls;
- Muse Spark Open on Baseten;
- the night shift and the nudge bank;
- the nudge cards and "Pull me out";
- screen time and phone-down nights;
- the evening notification;
- alarms and calendar;
- voice;
- Check Lify.
- License: MIT.
- Automated tests: 400+ (backend, Flutter and Kotlin). The Android code compiles against the real Android 15 classes.
- Results in the app come with their sample sizes, so you always see how much data a number rests on.



















