Inspiration

First-time managers get handed the hardest conversations of their working lives with no way to practise them. The missed deadline. The resignation you didn't see coming. The promotion you promised and now can't deliver.

You get one attempt, in the room, with a person whose year you're about to affect.

Everything that exists to help is reading — books, frameworks, a workshop once a year. But nobody learned to have a difficult conversation by reading about one, any more than anyone learned to drive by reading about a roundabout. The gap isn't knowledge. It's reps.

You'll have the conversation once. You can rehearse it twenty times.

What it does

Rehearse is a practice room for the conversations managers avoid.

Pick the one you're dreading. Choose how hard the other person pushes back — calm, defensive, or very defensive. Then have it, out loud or typed, with someone who answers what you actually said instead of reciting a script. Soften the expectation and watch it disappear. Stay vague and get vagueness back.

Nothing coaches you mid-conversation, and that's deliberate — nothing coaches you in the room either. The other person's reaction is the feedback.

Afterwards you get a score, how the conversation ended, and the specific sentence that cost you, quoted back with stronger wording to try:

TRY THIS INSTEAD — "just keep me posted" "Posted" has no date and no threshold. STRONGER — "Send me the revised date by Thursday."

Twelve scenarios, from repairing a tense working relationship up to telling your own manager something they won't enjoy hearing.

How we built it

Flutter on the front, a small server in the middle, and a language model doing two separate jobs behind it.

That separation turned out to matter more than anything else. One prompt plays the colleague and never breaks character to comment on how you're doing. A completely different one reads the finished conversation and scores it. When they were one job, the colleague kept helpfully critiquing you mid-argument, which is the opposite of the product.

Subscriptions run on RevenueCat, analytics on PostHog, crash reporting on Sentry. The whole app also works with no network and no keys at all: if the coach can't be reached it falls back to on-device scoring and says so, rather than pretending.

Challenges we ran into

Turning off wifi unlocked everything. With no connection, the app couldn't tell "there's no store configured" — the state that means this is a demo build, don't lock anything — from "the store is configured but unreachable". So aeroplane mode handed over the entire paid library. The fix had to be careful in both directions: gate when the store can't be reached, but never lock out someone who has actually paid and happens to be offline.

The score was making things up. I sent the same weak conversation through three times and got 36, then 0, then 22 — with the four skill ratings underneath matching none of them. The model had been asked for an "overall score" with no definition of what the scale meant, so it invented one each time. Now the four ratings are the score, so the headline can't contradict the breakdown printed beneath it.

Accomplishments that we're proud of

Feedback that quotes you. Advice you can't match to a moment you remember is just advice. Every note in the report is anchored to something you actually said — and anything the model can't quote exactly from your transcript gets dropped before you ever see it.

Nothing you type is used to profile you. Rehearsals are the most sensitive thing in the app, and none of that text ever reaches analytics. The app is built so that it can't — the analytics layer accepts ids and numbers, and there's no way to hand it a sentence.

It's honest when it's degraded. If the AI coach is unreachable, you still get a full conversation and a report, clearly labelled as offline scoring rather than dressed up as the real thing.

It's actually shipped-shaped. Store listings, screenshots for both stores, privacy policy, terms and a support page are all live, and the builds are signed and ready to upload — not a demo held together for a video.

What we learned

Measure the fix, then be willing to bin it. The scores still wobbled between runs, so I rewrote the scoring rubric to be much more precise and measured six runs before and after. Two things improved, one didn't move, and one got worse. I reverted the whole thing. It felt better and did nothing, which is the most expensive kind of change to keep.

The worst bugs are the quiet ones. Three separate problems all had the same shape: nothing crashed, nothing logged, and the app just quietly did the wrong thing. A misconfigured build silently ran as the demo. A wrong analytics key returned "OK" exactly like a right one. An unreachable store looked like no store at all. None of them would have shown up in testing — only in what users got.

Sometimes the obligation is the improvement. Trying to shrink the app, the clever optimisation saved half a megabyte and would have cost me readable crash reports. Raising the minimum iOS version — which Apple is requiring anyway — saved five times as much, for nothing.

What's next for Rehearse

Longer conversations. Three turns is a complete rehearsal but not the full idea. Four to seven, with the conversation ending when it's genuinely resolved rather than when the turns run out.

A colleague with a memory. Right now each reply reacts to the last thing you said. Next is carrying trust and tension across the whole conversation, so backing down in turn two changes how turn three lands.

Rehearse one moment again. The report already names the turn that cost you. The next step is practising that single exchange rather than starting the conversation over.

A reason to come back. Reminders are the most likely thing to turn one good rehearsal into a habit — and a habit is the difference between an app you tried and an app you keep.

Built With

Share this project:

Updates

Submission history