# Multi-thread a single-threaded deal

A step-by-step recipe for an AI agent using the BaseBara connector. Follow it when the user has a live deal that rests on one or two people and wants to bring the missing roles into the conversation.

Tools used: `find_contacts`, `get_contacts`, `get_linkedin_messages`, `send_linkedin_connection_request`, `send_linkedin_message`, `create_contacts`, `log_contact_event`, `list_contact_events`.

## Use when

- The user says a deal is "single-threaded", "all on one champion", "stuck with one contact", or asks "who else should I be talking to at Acme".
- The user has an open deal at a named company and can tell you who is already engaged.

Not for: a contact who has gone silent. That is a revival problem, not a threading problem. Say so and offer `follow_up` instead.

## Inputs to collect

BaseBara does not have the user's CRM, so the deal context comes from the user. Ask for it in one message:

- **The account** (name or domain) and the deal stage in a few words.
- **Who is engaged**: name and title of each person the user is already talking to, and roughly when they last spoke.
- **The committee shape**: which roles usually have to say yes. Default to four slots if the user has none: economic buyer, technical evaluator, end user, champion.

Classify the deal from what they give you. One active contact is critically thin, two is thin, three or more is fine.

## Steps

### 1. Match the engaged people to slots

Place each engaged contact in a slot by title. The slots left empty are the gaps. State them plainly:

"Acme: champion engaged (Sarah, RevOps). Economic buyer not engaged. Technical evaluator not engaged."

If nothing is missing, say the deal is adequately threaded and stop.

### 2. Find one candidate per missing slot

One `find_contacts` call per gap, scoped to the company with `company_name` or `company_domain`. Use `authority_levels` for the tier and `title_contains` or `job_function` for the function. Set `limit` to 5.

Pick the best match per slot. Prefer:

- The most senior person who fits the slot and is not already engaged.
- A direct counterpart to someone already engaged: same level, complementary function.
- Someone with `recent_job_change` true or short `tenure_months`. New arrivals have a mandate and no vendor loyalty.

If a slot returns nothing, the company may not have that role. Flag it and move on.

### 3. Check who on the team already knows them

Read `last_event` on each candidate (the `Activity` column). If a teammate has revealed or contacted the person, that teammate is the warm path. Name them, and call `list_contact_events` for the history if the user wants it. If the user themselves revealed the person earlier, they already have the details.

### 4. Choose the motion per candidate

| Motion | When | How |
| --- | --- | --- |
| Intro from the engaged champion | Champion is warm and willing | Draft a short "would you introduce me to <Name>?" message for the user to send to the champion |
| Intro from a teammate | A teammate shows up in `last_event` | Suggest the user ask that teammate |
| Direct outreach | No warm path, and a reason to write exists | `reach_out`, one message, on whichever channel fits (LinkedIn, email, or phone; `reach_out` picks it) |
| User calls them directly | Economic buyer on a late-stage deal | Reveal the phone and hand off. Do not cold-message the economic buyer past the champion, on any channel. |

Default to the intro motion when a champion exists. Going around the champion to the economic buyer damages trust and can stall the deal.

### 5. Claim, reveal, and draft, one at a time

When the user picks a candidate and a motion, log `claimed` on that contact with a one-line text ("working the CRO thread on the Acme deal, intro via Sarah") so teammates hold off. If the person is not saved yet, `create_contacts` with the `basebara_contact_id` first, without asking.

Call `get_contacts` only for the candidates the user approves. For direct outreach, run `get_linkedin_messages` first when the person has a `linkedin_url` to check for an existing thread, then call `reach_out` and follow it; it picks the channel, and the send lands as `contacted` on that channel (logged by the server on LinkedIn, by you on email or phone). The angle for a new contact is usually "looping you in on what <Champion> and I have been working on", never a cold pitch from scratch.

## Output shape

```
MULTI-THREADING REVIEW — <Company> (<stage>)

CRITICALLY THIN — 1 active contact
  Engaged:  Sarah Chen, RevOps Manager (champion)
  Missing:  economic buyer, technical evaluator

  → Economic buyer:  <Name>, CRO — 2 yrs tenure — no team contact
    Motion: ask Sarah for an intro. Draft attached.
  → Technical evaluator:  <Name>, Director of Sales Systems — new to role (4 mo)
    Motion: direct outreach — LinkedIn, connection request first. Draft on approval.
```

End with: "Want me to draft the intro ask and the outreach?" Wait for approval per person.

## Rules

- Identify the missing slot before suggesting a person. More names is not the goal. The right roles are.
- Default to the intro motion when a champion exists.
- Never cold-message the economic buyer on a late-stage deal with an engaged champion. Use the intro.
- Never suggest someone the user says they engaged in the last 30 days.
- Reveal one person at a time, after the user picks the motion.
- LinkedIn sends are paced. A refusal is final. Report it and stop. Email and calls go through a mail or dialer connector in the chat when there is one, otherwise through the user's own tools, and are logged in BaseBara once they happen.
- Claim the people the user takes on. Log `claimed` so teammates hold off, and `released` if they drop the thread.
