protein-first GLP-1 coachingidea→building→beta.

footing.

testflight beta. the period is penciled in.

Coached, not scolded. A protein floor instead of a calorie ceiling, logging that takes a sentence, and a coach that has actually read your day — built as separate native iPhone and Android apps for people on GLP-1 medication.

Started
March 2026
Status
Beta · TestFlight 1.3.5
Next
App Store submission
Built With
SwiftUISwiftDataHealthKitWidgetKitApp IntentsKotlinJetpack ComposeHealth ConnectSupabasePostgres + RLSDeno Edge FunctionsClaude APIFatSecretTelemetryDeckCloudflare WorkersXcodeGenCodeQL
By the Numbers
StartedMarch 2026
StatusBeta (TestFlight)
iOS build1.3.5 (300)
Android build1.4.0 (8)
iOS unit tests498
Android JVM tests727
Pulse eval scenarios32
Next milestoneApp Store submission
Links
Why I Built It

a floor, not a ceiling.

On a GLP-1 the goal flips. The medication already handles eating less. The hard part is eating enough: enough protein to hold on to muscle while the weight comes off. Every nutrition app I tried was built for the opposite problem — a calorie ceiling, a red number when you go over, a streak that breaks the first week your appetite disappears. Every other app draws a ceiling. This one draws a floor.

That number — the minimum grams of protein to clear each day — is your protein floor. It's the only number Footing celebrates. A missed day is never called a failure, a partial diary stays "unknown" rather than becoming a confirmed miss, and the coach never shows you a gap without a path to close it.

a footing: the base poured beneath a floor.

The name is the same idea. A footing is the base poured beneath a floor so nothing above it sinks. Most apps in this category are named after the medication. This one is named after the work.

Who It's For

People using GLP-1 medication (semaglutide, tirzepatide and the like) who need help eating enough protein and calories without judgment-heavy tracking — and who want a coach that understands the weekly injection cycle, the days the appetite comes back, and the days it doesn't.

What I Built

three pieces: today, logging, pulse.

Footing has three pieces: a Today screen built around the floor, four ways to log a meal in seconds, and Pulse, the coach. Everything else — the shot cycle, Progress, goals, widgets, Siri — hangs off those three.

Today — a tiled dashboard: the protein tile fills like liquid toward the floor, calories list carbs, fat and fiber with their own bars, a shot-cycle tile counts the days since your last dose, and water adds your usual amount in one tap. Clearing the floor plays once a day. That's the only confetti in the app.
Logging — Talk to Log (say or type "two eggs, toast with butter, black coffee"), search with protein-dense filters, barcode scan, and Favorites with the last 72 hours of recents. The meal is pre-filled from the time of day, saved entries can be undone, and a meal you eat often becomes a named usual meal you log in one tap.
Pulse — a coach that opens to a start screen with suggestions built on the device from today's data, answers in structured cards (food ideas, a weekly recap with its own chart, follow-up chips), and remembers only what you explicitly tell it to keep.
The shot cycle — hold to log a dose, injection-site rotation, reminders, check-ins on days 1, 3 and 6, a skipped-shot path that moves the next reminder without ever suggesting you make up a dose, and a "check with your prescriber" card after a long gap. Tracking can be paused or stopped and the history stays.
Your Strong Week — a Monday outlook built from the last seven days against the three weeks before: one observation, one food focus, one movement or recovery suggestion. A check-in first asks whether you're traveling, busy, taking it easier or injured, so the week is shaped around real life.
Progress, Goals and Experiments — floor days first, then trends against the previous period; a built-in protein-floor goal plus personal goals measured from Apple Health or logs; and small experiments ("does hitting my protein target change my sleep?") that report what happened without claiming causation.
Everyday tools and Siri — "Make today easier" (try one thing, keep a note, save leftovers, decide between two options) and "Today went sideways", plus App Intents so Siri can record water, save a note or log a sideways day. A dose shortcut only ever opens the app for review.
Lighter tracking and coming back — "Take it easier" pauses goal rings and coaching for three days, a week or until you're ready. After three or more empty days the app offers "Start with today" with no backlog to clear.
Widgets, Health, Body — a protein-floor widget for the Home and Lock Screen (lime once the floor is cleared), HealthKit and Health Connect reads for weight, body composition, HRV, resting heart rate, sleep and active energy, and writes back for weight, body fat and water.
Footing Today screen: a Thursday with a Pulse note, a deep indigo protein tile reading 85 g against a floor of 130, calories with carbs, fat and fiber bars, a lime shot-cycle tile on day 3 of 7, water at 42 oz and a movement tile.
Today — the protein floor, not a calorie ceiling
Footing Today screen after the protein floor is cleared: the protein tile reads 136 g, Floor cleared, with breakfast and lunch listed below.
Floor cleared — the one moment of the day that celebrates
Footing Log sheet on the Talk tab, adding to Snack: a large microphone button under "What did you have?", a text field, and suggestions like "Same breakfast as yesterday".
Talk to Log — say it like you would tell a friend
Footing Shot day screen on a lime background: "The shot does its part. Log it when it's done", a GLP-1 5 mg dose stepper, a large Hold to log dose button, injection-site buttons and the next shot reminder.
Shot day — hold to log, with the next reminder set
Footing Your strong week check-in: "Anything coming up that should shape your week?" with options Traveling, Busy week, Taking it easier, Injured or limited movement, Nothing different, and a Build my outlook button.
Your Strong Week — the only thing Pulse sends on Mondays
Footing Progress screen for a month: 18 of 24 floor days, average protein 127 g, weight trend −2.5 lbs, 20 movement sessions, 24 of 30 days logged, and a "worth noticing" note about water on shot days.
Progress — floor days first, then the trend
How Pulse Works

Pulse is a cornerman, not a drill sergeant, a cheerleader or a doctor. The persona has a non-shaming rule — never make anyone feel guilty for being on the medication, never imply the medication does the work alone — and a short list of banned words (cheat, guilt, failure, willpower). The medical boundary is fixed: Pulse never advises a dose or a schedule change. It reminds you of yours. Diagnoses, side effects, interactions and "is this normal?" all redirect up front rather than being answered halfway first.

the medical boundary never moves.

claude writes the words. swift decides the wins.

Pulse never messages first. Opening the tab generates no check-in and no summary. The start screen's "Suggested for right now" tiles — today's protein gap, the shot-cycle day, a Monday Recap pill — are built on the device with no model call. The recap is generated only when you tap it, and Your Strong Week is the only thing that goes out on Mondays. Proactive coaching lives in notifications, capped at one a day.
Two models, two jobs. Chat, check-ins and the weekly recap run on Claude Sonnet 5.5 through a Supabase edge function. Talk to Log's parsing runs on Claude Haiku 4.5 — structured extraction, not reasoning — and the nutrition numbers come from FatSecret, never from the model. Nothing an AI or a lookup produced is inserted without a confirm card.
Structured replies. The chat returns a reply plus optional food cards and follow-ups; the recap returns a story, what went well, a pattern and a focus. The app draws its own charts from its own data; Pulse only writes the words. Food cards are filtered against allergies and the foods you've said to skip.
Wins are detected in Swift, not by Claude. The app decides when the floor is cleared or a streak is real. Pulse praises only inside a conversation you started.
Memory on your terms. Pulse can propose a practical memory ("avoid cilantro") but never writes one itself; you save it with a tap and can see and delete everything it knows in Profile. Memories are row-level-secured to the account and queried under the caller's own token, never a service role.
Consent is enforced on the server. Pulse and food parsing have separate, explicit consents that name Anthropic and FatSecret. Both edge functions check stored consent before any provider call and fail closed if the row is missing. Per-user rate limits: 60 coaching requests and 40 food parses an hour.
Evaluated blind. A private reviewer runs 32 fictional scenarios (eight held out) and scores grounding, usefulness, Pulse's voice and boundaries; a boundary failure is a release gate, and a prompt-hash check forces the evaluator to be redeployed whenever the prompt changes.
Footing Pulse start screen: "What's on your mind, Dustin?", suggested tiles for a 28 g protein gap, shot day 3 and a Monday Recap, topic chips, and a text box with a mic.
Pulse opens to a start screen and never messages first
Footing Pulse conversation: a weekly recap card with a seven-day bar chart, what went well, a pattern and this week's focus, then a user message about cilantro and Pulse offering to save it as a preference.
Structured replies — recap cards, food cards, follow-ups
Footing Analytics answering "How do shot days change my eating?" with a line chart of protein by day since the shot across 21 logged days.
Analytics as questions, not a chart stack
Two Native Apps

727 jvm tests, most of them ios tests rewritten in kotlin.

Footing started in Base44 in March 2026, paused, and was rebuilt in May as my first fully native Swift app. The biggest architectural fork was going local-first: SwiftData as the on-device cache with Supabase as the source of truth, so logging works on a plane and syncs later. The bundle identifier still carries the old NutriPulse name so existing installs and the widget's App Group survived the rename.

Android followed on August 1 as a separate Kotlin and Jetpack Compose client sharing the same backend, not a cross-platform wrapper. The turning point was a report from an Android tester that logging a dose was unreachable — the action lived only on the "due" card. That became a parity audit against iOS with a ranked gap list, and then a full port of the Daylight redesign, screen by screen. The Android app now carries 727 JVM tests, most of them the iOS logic tests rewritten in Kotlin.

Porting turned out to be the best code review iOS ever got. Rewriting each screen surfaced data-correctness bugs that had lived on iPhone for months — body goals overwriting stored values, search's "+" logging a different portion than the row described — and both platforms got the fixes the same week.

The Daylight Redesign

all of the motion switches off under reduce motion.

At the end of September every screen was redrawn in a direction I called Daylight: a bright tiled layout on a cool neutral ground, white tiles with soft radii, a deep indigo hero tile, lime for wins and the Log button, sky blue for water. Bricolage Grotesque for display and numbers, Figtree for body. Tiles spring in, the protein tile fills like liquid, numbers count up — and all of it switches off under Reduce Motion.

The redesign also settled the brand's cast. Footing is the product. Pulse is the coach, drawn as a faceless ring with a fixed signature node whose geometry carries its state (ready, listening, thinking, coaching). Cove is the companion — a small sculptural character who observes and accompanies but never delivers advice. Cove became the dot of the i in the wordmark and the face of the app icon in 1.3.3, and greets you on the first onboarding screen in 1.3.5.

Footing onboarding, first screen, with the Cove companion character above "What would feel easier?" and options Keep my strength, Make meals simpler, Find a steady routine, Something else, plus an "I'm 18 or older" toggle.
Onboarding (1.3.5) — start with what matters, Cove included
Footing Today on a first day: a "Your first day · 1 of 4" checklist with log your first meal, log your shot, add a glass of water and ask Pulse anything.
Your first day — four small things, no backlog
Footing widgets: small protein-floor widgets in indigo and lime, a medium widget with Log food and water buttons, and a Lock Screen ring reading 94 of 140 g.
Widgets — the floor on the Home and Lock Screen
Shipping in Public

build number = commit count.

Build numbers equal the commit count, so the TestFlight history reads like a changelog: 1.3.0 (build 183) in mid-September, 1.3.1 (286) on October 1 with Daylight, then 1.3.2 through 1.3.5 (296 to 300) between October 19 and 21. Three of those versions landed in one evening, driven by two tester screenshots: a usual-meal Save button that looked inactive because the name field started empty, and a "shot marked as skipped" card that couldn't be dismissed.

The same week a tester hit a crash opening Profile. The cause was stack exhaustion from one enormous SwiftUI view — the root view's value was 30,648 bytes — and the fix restructured it down to 88. The 1.3.5 release runs 498 unit tests plus three UI walkthroughs, with backend contract suites running the real Postgres migrations against two authenticated users and an anonymous one.

What I Learned

effortless in. honest but actionable. earned celebration.

Honesty is what makes celebration mean something. The product spine was written before the first screen: effortless in, honest but actionable, earned celebration. The hardest of those was the middle one — the discipline of never showing a number without a next step — and it's the one testers mention.

Consent is product work, not paperwork. A pre-submission audit against App Store guideline 5.1.2 found that Talk to Log sent text to a model with no explicit consent of its own. Fixing it meant a second consent flow, a server-side gate that fails closed, and a coordinated backend rollout, because older builds couldn't parse until the new app granted permission. It also made the privacy disclosure better copy than it had been.

A second platform is a mirror. The Android port found more iOS bugs than any test suite had, because rewriting a screen forces you to say what it actually does.

And a few smaller ones that cost real time: the build number had silently been 1 on every build until a script derived it from git; a concurrent notification-scheduler race could leave the Monday reminder unscheduled; and Apple's hosted Xcode couldn't type-check the giant SwiftUI bodies that the local one accepted, which is how two views got split.

Where It's Going

oct 20 audit. the list is short now.

Footing is in a closed TestFlight beta, and a read-only readiness audit on October 20 said "not ready to submit." The list is now short:

App Store submission — accept the updated developer agreement, finish Apple-linked account deletion with real token revocation (the server-side pieces shipped in 1.3.5; the signing secrets are pending), complete the privacy labels and declarations, refresh the privacy policy against what the app collects today, and attach store screenshots and reviewer notes that say Footing, not NutriPulse.
Google Play — the Android app is held at 1.4.0 until five QA gates close: a cross-platform account test, lifecycle checks, TalkBack and visual QA, and physical-device notifications.
A live safety pass on Pulse — exercising dose-change requests, severe symptoms, allergies and restrictive-eating prompts against the production prompt before launch.
Then the product work — photo logging as the v2 headline, separate Pulse conversations instead of one stream, and a model A/B with server-side assignment.

seriously. ask. questions, intros, beta invites.

say hi

or emaildustin@hidustin.fyi

© 2026 hidustin labs.serious apps. made with a smile.hidustin.fyi · v3.0