For Team

Lost threads

The lost-thread detector finds outbound emails you sent that never got replied to. It surfaces them so you can chase, drop, or draft a follow-up.

The premise

You sent an email. You waited. They didn't respond. Now you've forgotten and the deal is rotting.

Laurelin scans your outbound mail (the same Outlook sync that creates interactions) and flags threads where:

These flagged threads become lost-thread candidates — rows in the lost_thread_candidates table — and surface in the Laurelin UI for your review.

Two urgency tiers

The classifier is deterministic. There's no AI deciding urgency; it's rules based on the company/project context attached to the recipients.

What you see

Each candidate shows you:

What you can do with a candidate

Four options per item:

1. Resolve

Mark the thread closed. Use when:

When you resolve, you can optionally link the resolution to an interaction (the call you had instead, the in-person meeting).

2. Dismiss — once

"Don't show this again for this specific message." If the next outbound on the same thread also gets ignored, that becomes a new candidate.

3. Dismiss — forever

"Don't show this thread again, ever." Use when you've decided not to follow up. The thread can still surface for new outbound messages, but this specific stale state is hidden permanently.

4. Draft a reply

Click "Draft" and Laurelin asks Claude to generate a follow-up draft based on the thread context, your usual voice (set in your profile), and a chosen intent (chase / friendly check-in / specific ask). It puts the draft in the candidate row (draft_body) for you to copy into Outlook.

Two important guardrails:

State of the draft flow is recorded on the candidate row: draft_requested_at, draft_intent, draft_voice, draft_started_at, draft_completed_at, draft_body, draft_body_preview. So you can see whether one is in flight.

How candidates are tied to people and companies

Each candidate is also linked to the people and companies involved via lost_thread_candidate_people and lost_thread_candidate_companies. That's how the company-detail and person-detail views surface the candidate ("3 stale threads with this contact") without you having to go hunting in a global list.

Dedup

The detector uses a content_hash on each candidate to avoid re-flagging the same thread on every scan. If you dismiss-forever and the underlying message gets re-summarized (rare but possible if the parser updates), it won't re-surface.

Daily flow

The pragmatic way to use it:

  1. Once a day or so, open the Lost Threads view.
  2. Skim emergencies first. There usually aren't many. Resolve / draft / dismiss.
  3. Skim normals. The good ones to chase are the ones where you go "oh, right, I meant to follow up."
  4. Anything older than a couple of weeks that you're never going to chase — dismiss-forever in bulk. The list shouldn't carry permanent debt.

If you're spending more than 5 minutes a day in here, the urgency thresholds need tuning. Flag in #laurelin.

What it doesn't do

Engineering note

If you want the deeper view of how the detector works — what counts as outbound, the content-hash algorithm, urgency rules, draft state machine — see Sync internals → Lost-thread detector.