Assignment
Design an automated email follow-up system that fires after cold calls (Salesfinity) or discovery calls (Fireflies), classifies signal + side, and threads a draft on the deal page for human polish → Gmail send.
Subset: `pure-strategy` — no contact discovery needed; no independent audit-quality (conductor ran maker-checker inline due to context constraints)
Roster
What we found
65% of the infrastructure already exists. Both webhook listeners (Salesfinity for cold calls, Fireflies for discovery meetings) are built and verified. The email draft generator, Gmail OAuth, template loader, extraction pipeline, and feature permission system are all live. The missing pieces are: (1) the 10 email templates themselves, (2) a signal classifier that routes calls to the right template, (3) wiring the webhooks to trigger the pipeline, and (4) a deal-page UI that shows threaded drafts for review + send.
Why this matters
Every sales call that ends without a same-day follow-up email loses momentum. The current process requires Ewing to manually remember what was said, open Gmail, and write the email from scratch. This system turns a 15-minute manual task into a 30-second review-and-send, and it runs on every call without exception.
Where we agreed
All six agents agreed on the core architecture: webhook → classify → extract → template select → draft to Supabase → deal page UI → Gmail push. All agreed the existing pieces should be extended, not replaced. All agreed signal classification should happen server-side via Claude (Haiku for cold calls, Sonnet for discovery transcripts).
Where we disagreed
Template granularity: Writer created 10 full templates (5 signals × 2 sides). Market-analyst wanted 200+ field extraction per template. Draper wanted emotional routing rules. Resolution: templates stay at 10 variants, extraction stays scoped to 15-20 merge fields that templates actually use, emotional context lives in the voice_prompt frontmatter (already there).
Table design: Architect proposed a new `followup_signals` table. Draper proposed `follow_up_drafts`. Resolution: extend the existing `email_drafts` table with `signal_type`, `side`, and `source_type` columns. No new table — one query surface is better than two.
What surprised us
- The `email_drafts.deal_id` column is NOT NULL, which means cold-call followups (where no deal exists yet) can't be stored without a schema change.
- `gmail-drafts.ts` only supports text/plain. All the templates generate HTML. Needs multipart MIME.
- `listTemplates()` doesn't recurse subdirectories, so the flat layout in `templates/email/` is actually correct — don't reorganize into folders.
- `TemplateFrontmatter` type in the template loader drops `side` and `signal_type` during coercion — the YAML parser reads them but `coerce()` discards unknown fields.
What we'd do differently
- Run the "what already exists" search as a formal Phase 0 checklist, not an ad-hoc discovery during Phase 1
- For plan-then-handoff assignments, skip the full 10-template content draft and produce structural stubs — Mark will rewrite the content anyway
Currency events
| From → To | Action | Multiplier | Base | Score | Notes |
|---|---|---|---|---|---|
| architect → writer | Discovered gmail-drafts.ts HTML gap that affects template design | 1x | 3 | 3 | Writer's HTML templates depend on this fix |
| listener → quarterback | Surfaced edge cases (no-deal cold calls, DNC suppression) that became tasks | 1x | 2 | 2 | Prevented post-build rework |
| draper → writer | Voice prompts and no-go rules shaped template tone | 2x | 2 | 4 | Direct quality lift on all 10 templates |
Cross-system gaps
| Flagger | Affected | Gap | Recommended change |
|---|---|---|---|
| architect | webhook routes | Salesfinity webhook ends after `call_log` upsert — no followup trigger | Add `triggerFollowupPipeline(callLogId)` call after line 177 in salesfinity/route.ts |
| architect | webhook routes | Fireflies webhook ends after `saveExtractions()` — no followup trigger | Add `triggerFollowupPipeline(meetingId)` call after line 204 in fireflies/route.ts |
| writer | email-templates.ts | `TemplateFrontmatter` type missing `side` and `signal_type` fields | Add optional fields to type + coerce() function |
| quarterback | email-templates.ts | `listTemplates()` only reads flat directory, no subdirectory support | Templates use flat layout — not a bug, but document this constraint |
| architect | gmail-drafts.ts | Only text/plain MIME — templates are HTML | Add multipart/alternative with text/plain + text/html parts |
| architect | 0010_deal_tracker.sql | `email_drafts.deal_id` is NOT NULL — cold-call drafts have no deal | Migration to ALTER COLUMN deal_id DROP NOT NULL |