A personal relationship intelligence tool that surfaces the right moment to reach out — before the connection quietly fades.
Most AI tools built around relationships solve scheduling: reminders, calendar follow-ups, CRM nudges. They are good at answering "when do we meet next?" They are almost completely silent on "have I been meaning to reach out to this person for three months and still haven't?"
Julie Zhuo's essay on AI and social connection identified three tasks: get together, become closer, and find each other. The first is largely solved. Instinct raised $1B at a $10B valuation building agent-to-agent logistics for it. Almost nothing meaningful has been built for the second — the task of noticing, nudging, and maintaining closeness over time.
"Silicon Valley keeps building me a husband when what I really want is a wife."
Sonia Baschez · viral tweet that framed the whole productA husband handles logistics. A wife notices. She remembers that your friend just went through something hard. She suggests reaching out before you even think of it. She finds the moment, not just the calendar slot.
That noticing layer does not exist as a software product. The gap is not technical — it is a product design question about where AI should act and where the human must remain in the loop.
Ember Signal was designed around three deliberate constraints, not because of technical limitations but as product principles.
Rule-based first. AI is used for exactly one thing: drafting a warm personal message. Everything else — scanning contacts, filtering by threshold, ranking by neglect, picking the right moment — is deterministic logic the user can inspect and understand. Steps 1 through 4 involve no model inference.
Context over cadence. A nudge without a moment is noise. Ember Signal only surfaces a contact if there is a real, specific reason to reach out right now. A contact who has gone quiet but has no natural hook stays hidden until one exists.
Human in the loop, always. The tool notices and drafts. The human decides and sends. Zero messages are sent automatically. This is a principle about where human judgment belongs — not a limitation to be engineered away later.
Flags anyone where days since last contact exceeds 30. Transparent, configurable, no model inference. Every contact either passes or fails a single numeric check. The threshold and the result are both visible to the user in real time during the scan animation.
Of the flagged contacts, only those with an attached context signal are surfaced. A signal is a specific, time-relevant reason to reach out: a birthday, a shared interest in a recent event, an anniversary. Contacts over the threshold but without a signal receive a "no moment yet" label — they are flagged but not surfaced until one appears.
Claude receives the contact's name, relationship type, shared history notes, and the specific context signal. It returns a 2-sentence warm personal message that references the moment naturally, without lifting the signal text word for word. The prompt is constrained to produce something the user could send without editing: warm, specific, human-sounding.
The draft is a starting point. The user reads it, edits it if they want, and sends it as themselves. "0 messages sent automatically" is pinned as a persistent badge throughout the entire interface. This is not a disclaimer. It is the product principle that makes the tool trustworthy enough to use with real relationships.
Three contacts surfaced from ten, each with a live draft generated via Claude Haiku. The scan states, context signals, and drafts shown here are from a real API call.
Ten synthetic contacts loaded from an in-memory dataset. Each contact carries name, relationship type, days since last contact, shared history notes, and a list of context signals (zero or more).
Filter the full contact list. Any contact where days_since_last_contact exceeds the threshold is added to the flagged set. Contacts below the threshold are marked as quiet and dimmed in the UI.
Of the flagged set, remove any contact with an empty signals array. These contacts are shown in the UI with a "no moment yet" label — they are over the threshold but there is no natural hook to reach out.
Sort the filtered set by days descending and take the top 3. These are the contacts surfaced in the results section. The ranking logic is visible and predictable: longest neglect with a real moment wins.
On button click, pass the contact's context to Claude with a constrained prompt. Output is capped at exactly 2 sentences. The message references the specific moment without copying it, sounds like something the user would actually send, and contains no template language or AI markers. Fresh generation on each request.
The constraint of "0 messages sent automatically" is a product decision about where human judgment belongs — not a technical limitation waiting to be removed.
AI is used for exactly one task: the one where language generation genuinely beats a rule. Everything else is logic the user can inspect, understand, and trust.
Designed for someone managing real human relationships. Not a CRM, not enterprise. The language, the aesthetic, and the interaction model are all deliberate choices for a consumer audience.
A Substack essay and a viral tweet became a named product, a working demo, and a live Claude API integration. End to end, without an engineering team.