Traci — DreamBorn SDR Agent Design Spec
internal prototype · canonical JSON + Dreamborn Forge HTML
internal generated
design_doc · markdown

Traci — DreamBorn SDR Agent Design Spec

Traci — DreamBorn SDR Agent Design Spec Date: 2026 04 27 Client: dreamborn Status: Design approved — ready for planning Overview Traci is DreamBorn's outbound SDR agent. Her job is to build a prospect pool on LinkedIn and warm it toward a deal definition call with Justin. She does not close — she hands off to Brooke (Sales) once a meeting is booked. Revenue ...

Traci — DreamBorn SDR Agent Design Spec

Date: 2026-04-27 Client: dreamborn Status: Design approved — ready for planning

---

Overview

Traci is DreamBorn's outbound SDR agent. Her job is to build a prospect pool on LinkedIn and warm it toward a deal-definition call with Justin. She does not close — she hands off to Brooke (Sales) once a meeting is booked.

Revenue pipeline: Traci → Justin (call) → Brooke (close) → Annie (CS)

Phase: Connection + nurture campaign. Justin doesn't have a large AI contact base yet, so v1 is about building the list and making genuine connections before any pitch.

Channel: LinkedIn only (via Unipile from Justin's account)

---

ICP
  • AI companies and startups
  • Thought leaders in AI
  • Large manufacturers and distributors with AI initiatives

DreamBorn sells: AI workflow and orchestration engine for agents — consensus and trust infrastructure. The pitch is what an AI-native company looks like in practice. Audience: founders, operators, builders.

---

Architecture

Traci runs on roles.sales HCS topic. Same runner pattern as all other agents.

  • HCS — workflow-level events: task dispatch, exec gate approvals, batch complete
  • Supabase — granular timing state: send queue, per-send status, activity logging

Individual LinkedIn sends are too frequent and cheap to put on HCS. The traci_send_queue table handles timing; HCS handles meaningful workflow transitions.

---

`prospect_search`

Justin posts a brief (e.g. "50 AI startup founders, Series A-B, US-based"). Traci: 1. Searches LinkedIn via Unipile using the brief as search criteria 2. Deduplicates against existing crm_contacts (skip anyone already in CRM) 3. Writes a prospect_batches row with all candidates + proposed connection message per candidate 4. Posts to roles.exec — Justin reviews in Cockpit, approves/rejects per candidate 5. Approved candidates written to crm_contacts with outreach_status: prospect

`send_connections`

Dispatched by Engine after Justin approves a batch. Traci: 1. Reads approved candidates from prospect_batches 2. Distributes sends across the day (8am–6pm, ~3/hour, randomised within each hour) 3. Writes rows to traci_send_queue with scheduled_at timestamps 4. Enforces 75 send/day cap at queue-write time — rejects overflow 5. Posts task.complete immediately (queue is written, not sends completed) 6. On each subsequent runner tick: checks traci_send_queue for rows where scheduled_at <= now() AND status = 'queued', sends via Unipile, logs to crm_activities, updates outreach_status: connection_sent 7. Posts daily summary to roles.exec: "Traci: sent N connection requests today"

`check_connections`

Traci polls Unipile for accepted connection requests (contacts where outreach_status: connection_sent). For each accepted connection, updates crm_contacts.outreach_status = 'connected' and logs a crm_activities row. This is what arms draft_nurture. Runs on every runner tick — lightweight Unipile + Supabase check, no HCS task needed.

`draft_nurture`

Traci scans crm_contacts where outreach_status: connected and no active pipeline deal. For each: 1. Pulls their profile context (title, company, icp_tags) 2. Drafts a personalised follow-up DM 3. Batches all drafts into a prospect_batches row 4. Posts to roles.exec for review 5. Justin approves per-message → send_message task dispatched for approved items

`send_message`

Same queue pattern as send_connections but for DMs to already-connected contacts. Logs to crm_activities, updates outreach_status: nurturing.

---

New fields on `crm_contacts`

| Field | Type | Notes | |---|---|---| | outreach_status | text | prospect \| connection_sent \| connected \| nurturing \| meeting_booked \| not_interested | | source | text | traci_search \| manual \| inbound | | icp_tags | text[] | e.g. ['ai-startup', 'founder', 'series-a'] |

linkedin_url already exists on Arlo's field list.

New table: `prospect_batches`

``sql id uuid primary key default gen_random_uuid() client_id text not null task_id text -- HCS task topic ID brief text -- Justin's search brief candidates jsonb -- [{name, title, company, linkedin_url, linkedin_urn, proposed_message, approved}] status text -- pending_review | partially_approved | sent created_at timestamptz not null default now() ``

New table: `traci_send_queue`

``sql id uuid primary key default gen_random_uuid() client_id text not null contact_id uuid references crm_contacts(id) send_type text not null -- connection_request | dm message text not null linkedin_urn text not null scheduled_at timestamptz not null sent_at timestamptz status text not null default 'queued' -- queued | sent | failed error text created_at timestamptz not null default now() ``

Activity logging: Every send gets a crm_activities row — type linkedin_connection or linkedin_dm. Traci and Arlo share the same activity log table.

---