The friend who notices when you can’t ask
pip runs quietly on a night out. When it looks like you can’t ask for help, it asks you first. Your friends hear only if you don’t answer, and your location stays encrypted until then.
pip runs quietly on a night out. When it looks like you can’t ask for help, it asks you first. Your friends hear only if you don’t answer, and your location stays encrypted until then.
1Night mode
Leave your saved home places during your evening window and night mode starts by itself. There is nothing to set up each night, and your home places never leave the phone.
2Detection
A hit above 3 g, a tilt, then no steps and no touch for 15 s. A Rust engine on the phone opens a “down after fall” incident and turns the microphone on for a short listening window.
3Check-in
A full-screen “You okay?” on the lock screen. Prove it’s you with your fingerprint, then type three random words. Nobody else has been told anything yet.
4Heads-up
Two minutes and no answer. Your friends get “Sam might not be okay” and one sentence about what happened. They get no location yet.
5Location unlock
Four minutes after the check-in, your phone seals two hours of location keys to each friend. Before this, nobody could read it: not one friend, and not the server.
6Friends decide
Ring the phone loudly, call, say “I’m going”, mark you found. They can also call campus safety in one tap. The app never calls anyone on its own.
You’re home. Have a good night.
Out with Ava, Jo and Kai. Everyone’s okay.
pip · check-in
You okay?
A possible fall, then no movement.
Type these words
mapleorbittulip
Your friends were told
Tap if you’re OK
Ava found you
Your friends know you’re safe.
pip · now
Sam might not be okay
A possible fall, then down for 2 min, then no answer to a check-in.
Sam
Heads-up · just nowLocation shared · loggedFound safe
9f3a·c41e·77b0·e2d9 A possible fall, then down for 2 min, then no answer to a check-in.
Why pip
A hard fall, unsteady walking, a snatched phone. These are the moments you can’t reach for a button, so pip doesn’t wait for one.
Other safety apps need the person in danger to act: press a button, set a timer, share a location. pip watches how you move, so it works when you can’t.
Before anyone is told, your phone asks “You okay?”. If the cause clears, for example you get up and walk, the check-in withdraws and nobody ever knows.
Your location uploads as ciphertext. Nobody can read it alone: not one friend, and not the company. It unlocks only when a check-in goes unanswered.
Your friends choose what to do: ring you, call, come and find you. pip never calls the police or anyone else by itself.
Detection
A foreground service samples motion all night, with the screen off and the phone in your pocket. A Rust engine on the phone turns it into gait, impact, grab and stillness signals and compares them with your own normal range. Pick a situation to see what opens.
Every measure sits inside your normal range. Nothing opens, and nobody is told anything.
The motion here is synthesized in your browser. The thresholds are the engine’s own, sped up so each situation fits in a few seconds.
Cadence
0 steps/min
Regularity
0
Sway
0 m/s²
Wobble
0 rad/s
10 samples a second by day. 50 a second plus the gyroscope at night, and for 30 min after any incident.
Each walking measure is compared with your range for where the phone is carried: pocket, hand or bag. It is learned on ordinary walks and trusted after 7 different days.
Off by default. After a fall, a grab, a missed check-in or unsteady walking it listens for 10 min. YAMNet on the phone turns each second into scream, shout and snoring scores. Audio is never stored or uploaded.
Activity (still, walking, running, vehicle), speed, screen and unlock events, time since you last touched the phone, battery, distance to home, and whether you are with your friends.
Incidents, not a score
There is no machine-learned danger score. Each signal opens and closes a named incident with a rule for when it clears. That way the phone can always tell you, and your friends, why it asked.
An impact above 3 g, a tilt, then little movement. Or a free fall and a hard landing.
Clears: Steps resume
After a fall or hard impact: no steps and no touch for 15 s.
Clears: Steps resume
Walking again after a possible fall.
Clears: A moment, kept in the log
A hit with a tilt that was neither a fall nor a dropped phone.
Clears: Walking resumes
The first reading above 3 g, shown at once. Mid-walk, a bump is held 10 s and dropped if you keep walking.
Clears: Reclassified ~2.4 s later
Regularity, sway or wobble outside your own normal range for 35 s of walking.
Clears: 2 min of in-range walking
Pace 20 % below your normal for a minute of walking.
Clears: 30 s at your normal pace
One step far off rhythm with a sideways jolt, while walking continues.
Clears: Pruned after 30 min
Three stumbles within 5 min.
Clears: 10 min without one
Phone in hand, a yank with a twist, then running away.
Clears: The owner unlocks the phone
A long free fall, lands flat, dead still, not picked up within 60 s.
Clears: Picked up
Set down and untouched for 20 min while out late.
Clears: Picked up or touched
Over 150 m from every friend for 10 min, and not heading home.
Clears: Back with someone
Was heading home, then stopped for 10 min somewhere that isn’t home.
Clears: Moving again, or home
The phone reports a vehicle.
Clears: Out of the vehicle
“You okay?” unanswered for 2 min.
Clears: Answered
The check-in was typed far off your normal rhythm.
Clears: A normal check-in
Two frames within 2 min of a fall or grab, in a venue that isn’t loud.
Clears: 10 min
Snoring while down after a fall, with a check-in missed.
Clears: Answered, or steps resume
10 % or less, not charging, while out late. Uploads a last encrypted location.
Clears: Charging, or 15 %
The server misses heartbeats for 10 min at night. Friends can start a fallback unlock.
Clears: Heartbeat returns
Entries in the on-device log expire after 8 hours. The rules ship as a TOML file served by the backend and merged over the copy built into the app, so a bad file can’t break the engine.
When it asks
A single odd signal is usually nothing. pip asks “You okay?” only when the evidence adds up.
Answering covers everything that’s open. After that, only a new incident can ask again, after a 5-minute pause.
Open incidents. Tap to add evidence.
Fall
Walking
Phone
Location
Sound
Nothing open
The phone samples at the low rate and logs nothing.
Alerts
Each step waits for the one before it, and the evidence must still hold. If you get up and walk, or rejoin your friends, the episode resolves by itself and friends are never told.
0:00
A full-screen “You okay?” on the lock screen, with what was detected and a countdown. Nobody else is told.
2:00
No answer. Friends get “might not be okay” and a one-line summary. No location.
4:00
Your phone seals the current and next hour’s location keys to each friend and uploads a fresh fix.
10:00
Friends get one tap to campus safety or 911, with text ready to read out.
First you prove it’s you: face unlock where the phone allows it, fingerprint, or PIN. A thief can’t pass this step. Then you type three random words while the phone checks your typing rhythm. If it’s far off your normal rhythm, friends hear “answered, but may be impaired”.
Anyone holding the phone can tap it. It counts as consent and unlocks your location at once.
Skips the check-in. Friends are told at once, with the snatch-moment location and a warning not to chase. Only your biometric dismisses it.
Hold the button in the app, the Quick Settings tile or the home-screen widget. Try holding this one.
The server notices 10 min without a heartbeat, or a battery at 3 %, and tells friends. A dying phone uploads one last encrypted location first.
What friends can do
Try a check-in
A thief can’t answer for you, and a friend can’t answer while you’re slumped in a corner. First the phone checks it’s you. Then it gives you three random words and listens to how you type them: the gaps between keys, how steady they are, how often you go back.
Everything runs in this page. Nothing you type is sent anywhere.
pip · check-in
You okay?
A possible fall, then no movement.
Hold to prove it’s you
Type these words
Check-in dismissed
Privacy
Every day your phone makes a fresh key and splits it among your friends. Any one share is useless. It takes several friends together, and every time they combine shares, everyone sees.
Friends it takes to unlock
Approve shares as Sam’s friends to try to rebuild the key.
This is real Shamir secret sharing over GF(256), running in your browser. With fewer shares than it takes, the combined bytes are noise. Fallback unlock works only while Sam’s phone is offline or dying, and only in groups of three or more.
Each hour’s key comes from the day key with HKDF. An alert releases the current hour and the next, so friends can read two hours at most, never the whole day. Keys are wiped when the day ends.
Each location fix is sealed with XChaCha20-Poly1305 under the hour key. The server keeps only the last 6 hours of it, and has no way to decrypt it. A database test checks that no decrypt path exists.
Every 2 minutes each phone uploads keyed hashes of its map cell and the 8 around it, about 150 m. The server compares hashes and learns only “together” or “separated”. It never sees a coordinate.
You scan each other’s QR code and check that the fingerprints match on both screens. That way the server can’t swap in a key of its own. Both sides have to accept.
For friends
Friends follow along in the app, or on a laptop with the web monitor. It is the same code built for the browser, with the Rust crypto compiled to WebAssembly, so a released location decrypts on the friend’s own device.
Sam
Out tonight · with Ava
Incident log
AI read advisory
Calm
Nothing to read yet
Engine level: idle
Motion and rotation at 10 frames a second over one Realtime connection. Nothing is stored, and it never carries location.
Plain names, “2 min ago”, a status like “Active · 3 min so far”, severity as a coloured edge, and one box per episode.
It appears while an alert is open, turns red and beeps when a step is overdue, and holds every friend action and the map.
The incident timeline (names, order, gaps; never measurements, location or audio) goes to Claude Haiku from the friend’s browser. It is advisory only: the engine’s own alert level sets a floor.
Under the hood
All detection runs in Rust and Kotlin on the phone, never in JavaScript, so it keeps running when the app’s UI is asleep. The server only ever receives ciphertext, hashed tokens and a coarse status.
Sam’s phone
Supabase
can’t decrypt
Friends
On the phone
A foreground service that survives the screen going off, the charger coming out and a reboot. Motion at 10 or 50 Hz, activity, screen and unlock events, battery, and the mic in listening windows only.
On the phone
Pure Rust with no I/O: signals, personal baselines, incident rules, the on-device log and the escalation state machine. Bound to Kotlin with uniffi.
On the phone
Device identity (X25519, Ed25519), Shamir over GF(256), HPKE sealing, XChaCha20-Poly1305 location blobs and proximity tokens. Also compiled to WebAssembly for the monitor.
In the cloud
Postgres with row-level security on every table, Realtime, and Deno edge functions: push, watchdog, proximity, unlock, purge and config. pg_cron runs the watchdog every minute.
For friends
One Expo / React Native code base: the Android UI, and the friends’ console in the browser. No detection logic lives in JavaScript.
Tooling
A Rust CLI replays recorded and synthetic traces through the real engine. CI fails a change that adds false alarms or slows detection.
Try the demo
One phone or emulator plays Sam. A browser plays a friend. Recorded traces stand in for the night, so you don’t have to fall over.
checkin-dismissA check-in appears. Type the three words and it’s dismissed. The friend sees nothing.heads-upIgnore the check-in. The friend gets “might not be okay” with no location.unlock-mapStill down 2 min later, and the friend’s map appears. The database holds only ciphertext.snatchAn immediate “don’t chase” alert with the snatch-moment pin. Only a biometric dismisses it.manual-sosHold the SOS button. Friends are told and the location unlocks at once.Settings → Demo sensitivity swaps in easier thresholds for trying it out in a room: shorter timers, unsteady walking after 12 s, a grab after 2 s of jogging, and a 30 s check-in.
# the engine, the crypto and the trace gate $ cargo test --manifest-path core/Cargo.toml $ cargo run --manifest-path core/Cargo.toml -p sim -- batch core/traces # the backend $ cd supabase && supabase start && supabase db reset $ supabase functions serve # a friend in the browser, Sam on Android $ pnpm --filter mobile web # ?mock=friend $ core/build-mobile.sh && pnpm --filter mobile android $ adb shell am start -a android.intent.action.VIEW \ -d 'safe://debug/inject?trace=heads-up'
Detection is heuristic. It can miss events and raise false alarms. If you are in danger, call your local emergency number. pip is for adults (18+).