Inspiration

Here's a fact that stops most people cold: when researchers ask pregnant women and their partners to independently rate how she's doing, they often don't agree. Not a little. In a meaningful share of couples, one partner sees warning signs the other doesn't. And the science is clear on something surprising that disagreement isn't measurement error to be smoothed over. The partner's read on the situation carries real, independent information. Sometimes he sees what she can't see in herself, or won't say out loud.

Almost every pregnancy wellbeing app on the market ignores this completely. They ask one person, usually the mother, to self-report, and they build the entire product around her voice alone. If the gap between two people's perceptions is genuinely where the risk hides, then an app that only ever listens to one of them isn't just incomplete. It's missing the point.

A lot of thought went into how not to build this. Multi-agent AI systems that vote on a "correct" answer sound appealing in theory, but the research on cascading errors in clinical settings is a real warning sign: a handful of language models shouldn't be deciding who's right about someone's inner life. From the outset, one thing was off the table, anything that smelled like surveillance. No secret logging. No one-sided monitoring. No app quietly deciding one partner's account is more true than the other's.

So the brief was short: design for the disagreement, not around it. Keep a human in the loop for anything serious. And never let the product become a referee.

What it does

We Are Expecting is a pregnancy wellbeing app built on a simple premise most apps get wrong: her experience and his observations are both data, and both deserve a place in the record.

Each partner writes free-text check-ins in their own words, she describes how she's actually feeling, he describes what he's noticed. Two separate agents turn those check-ins into structured signals: mood, level of concern, whether something sounds minimized or brushed off. A reconciliation step then compares the two most recent entries and returns one of three read-outs: things are aligned, this is worth a conversation, or this needs attention now. What it never returns is a verdict on who's right. It offers a gentle nudge toward a conversation, not a diagnosis.

Underneath that, either partner can log quick daily scores mood, sleep, anxiety, energy, interest, connection and over time those numbers build into a clinician-ready report: trends, averages, open questions worth raising at the next appointment. The language stays strict on purpose. Nothing in the report labels a condition. It describes a pattern and leaves the interpretation to the people trained to make it.

Everything either partner logs is visible to both of them. Nothing hidden, nothing one-sided. Couples join with an invite code, and the database itself enforces that no one outside that couple can ever see their data.

How it was built

The stack was kept deliberately small, leaving room to focus on the parts that actually mattered: a plain Node server, static HTML/CSS/JS on the front end, Supabase for auth and Postgres, and Groq powering the language model calls.

Four agent-style paths sit inside the API:

  • Self-report — her free text, turned into structured JSON
  • Partner observation — his free text, turned into structured JSON
  • Reconciliation — the two structured entries compared, producing a status and human wording
  • Report generation — the stats computed first in plain code, then wrapped in a short narrative

The decision protected above all others: the model never decides the outcome. Status and escalation come from fixed, testable rules written in code. The language model only writes the words a human reads after that decision has already been made. Same principle for the reports, the averages and trends are calculated first, and the model never invents a number, it only explains one.

Supabase Auth handles accounts, invite codes pair couples together, and Row-Level Security makes it structurally impossible for one couple's data to leak into another's. For the demo, several full couple journeys were seeded: one aligned, one drifting apart, one recovering, one escalating, so judges could log in and see real history.

Challenges faced

The hardest part of this project was never the code. It was keeping the ethics and the engineering pointed in the same direction.

Early on, it was genuinely tempting to let the language model just decide the reconciliation outcome directly that would have saved a lot of API design work. But the more these systems were examined in clinical-adjacent contexts, the more one pattern kept showing up: a model can sound completely confident while being completely wrong. That risk was unacceptable for something this sensitive, so the status logic was pulled back out into deterministic rules, and the model was restricted to wording only. It meant reworking a chunk of the API, but it was the right call.

The second challenge was quieter but just as important: how do two people get a shared view into something this personal without it curdling into surveillance? The answer stayed consistent throughout everything stays visible to both partners, always. Every feature idea that involved one person watching the other silently got refused. And when the two accounts don't match up, the app frames it as this is worth talking about, never as a scorecard showing who was wrong.

On the practical side, the first instinct was a serverless deployment, and it fought back the entire way. It got swapped for a local Node server that could be demoed reliably under time pressure, and that single decision saved the demo. The seed data mattered more than expected, too an empty dashboard convinces nobody that an idea works, so real time went into building believable histories for judges to actually explore.

And prompting for structured JSON that still sounds warm, human, and non-diagnostic turned into its own small research project. It took more iteration than any part of the interface.

Accomplishments

The idea survived contact with a real build, and that's rarer than it sounds. Discrepancy is the signal, not a bug to average away that stayed true from the first sketch to the final demo.

The line drawn between rules and language stands out as a highlight. The escalation logic is deterministic and testable, which means it can't quietly drift into a false red flag just because a prompt got reworded somewhere. That boundary was a deliberate engineering choice, and it's the piece most worth defending under scrutiny.

The app runs end to end: sign-up, pairing, dual logging from both partners, reconciliation, a tracker, a report that looks like something a provider could actually use, and an interface that feels like it was built for a couple, not a hospital intake form. With seeded couples and a schema built around row-level security from day one, judges can see both the front door and the plumbing underneath it.

But if one thing stands above the rest, it's this: nothing about this app is the creepy version of the idea. Consent and shared visibility aren't a slide in a deck. They're built into the data model itself.

Lessons learned

The biggest lesson was empirical, not technical: asking the partner isn't a nice bonus feature. For perinatal mental health, it's frequently where the information that actually matters is hiding. Leave that voice out, and only half a product gets built.

The architectural lesson was almost the mirror image of that. Multi-agent systems are genuinely useful for splitting up responsibility cleanly, but the moment a system moves anywhere near a clinical context, those agents need hard boundaries on what they're allowed to conclude. Separation of concerns is good design. Separation of judgment from code is what makes it safe.

Warm-sounding copy and sound decision logic turned out not to be the same skill, and conflating them is exactly how a system ends up feeling caring on the surface while behaving unpredictably underneath. On the practical side: a boring server that works beats an elegant deployment that doesn't, every single time, under a deadline. Writing for an audience of clinicians forced an unexpected discipline once diagnostic language is banned outright, sloppy LLM phrasing has nowhere left to hide.

What's next for We Are Expecting

The most immediate fix is live updates. Right now a new entry only shows up after a manual refresh, and that's the first thing to change post-hackathon. Right behind it: pairing entries by the day they were logged instead of always comparing whichever two are most recent, since that's currently a rough approximation.

Beyond that, the report generation could use more testing against a wider range of check-in styles, the structured JSON extraction was tuned on a handful of examples during the hackathon, and it would need to hold up against messier, more varied real writing before it's trustworthy.

There's also unfinished polish: mobile responsiveness wasn't a priority given the time limit, and the invite-code flow could use better error handling for edge cases like expired or reused codes.

Longer term, and further out than a next sprint, the real test would be showing the reconciliation feature to actual couples and seeing whether the prompts land the way they're intended to, whether "worth a conversation" actually starts one, instead of just sitting in a dashboard. That's not something a hackathon weekend can answer, but it's the question the whole project is really trying to get at.

That's really the idea at the core of this: catch the gap between two people's perceptions early enough that it becomes a conversation, not a crisis. The app doesn't try to settle who's right, it just makes the disagreement visible enough that it's easier to talk about, and hopefully easier to bring up with a doctor when it matters.

Note: The project represents the three themes - wellness, happiness and health

Share this project:

Updates