Fundraising OS - Gap Analysis
Warm Intros is half-built: the data exists, the UI doesn't show it
36 warm intro records are in the database but invisible in the app. The Network page renders a different table (intro_paths), the PATCH endpoint was never wired, and 8 columns from the spec are missing. Here is every gap, prioritized.
The core problem
Two parallel systems were built to solve the same problem and never connected:
intro_paths is the AI-scored path discovery system. It lives on the candidates table and the Network page renders it. It is what you see when you open the Network tab.
warm_intros is the founder-facing intro tracking system described in the spec. It has its own table, a working POST endpoint, and 36 records. It has no UI surface at all.
The spec describes warm_intros. The app shows intro_paths. That is the root of every gap below.
Gap inventory
1. Database schema
The warm_intros table has 16 columns. The spec calls for 24. Eight are missing:
| Missing column | Purpose | Impact |
|---|---|---|
connector_person_id | FK to people directory | No canonical identity for connectors, no dedup |
target_person_id | FK to people directory | Target investor is free-text only, can't resolve to profile |
target_firm_id | FK to firms directory | No firm logo rendering, no join to candidates |
relationship_evidence | Source of the edge | No provenance trail for connection claims |
connector_willingness | Connector sentiment tracking | Can't distinguish willing vs reluctant vs unknown |
suggested_angle | AI-suggested approach framing | Missing from draft workflow |
forwardable_blurb | Paragraph connector can forward | Missing from draft workflow (only draft_email/draft_text exist) |
priority | 1-10 sorting score | No smart-sort, only updated_at ordering |
2. API endpoints
| Endpoint | Status | Notes |
|---|---|---|
POST /api/warm-intros | Works | Creates a record. Missing new-column support. |
PATCH /api/warm-intros/:id | Dead code | The patch schema is fully defined in api.ts but no route handler was ever wired. Inline editing is impossible. |
DELETE /api/warm-intros/:id | Missing | Only a maintenance endpoint exists (POST /api/maintenance/delete-warm-intro). No RESTful delete. |
POST /api/warm-intros/bulk | Missing | Can't batch-create intros during activation or import. |
Pipeline side-effect on accepted | Missing | When status hits accepted, candidate should advance to intro-made. No such logic exists. |
3. Status enum
The current enum is out of alignment with the spec:
| Current | Spec | Action |
|---|---|---|
draft | identified | Rename. "Draft" conflates status with having draft content. |
| (none) | permission-requested | Add. Critical workflow step between identifying and connector approval. |
requested | approved | Rename. "Requested" is ambiguous. |
sent | sent | Matches. |
accepted | accepted | Matches. |
declined | declined | Matches. |
no-response | no-response | Matches. |
The PATH_STATUSES array (used by intro_paths) already has the correct values. Only INTRO_STATUSES (used by warm_intros) needs migration. The data migration: update 36 rows from draft to identified, update the CHECK constraint, add permission-requested.
4. UI / Network page
The Network page queries and renders intro_paths. It has zero interaction with the warm_intros table. Everything below is missing:
| UI feature | Status |
|---|---|
| Warm intros table/tab | Not built |
| Fostable integration (inline edit, sort, filter, search) | Not built |
| New columns (evidence, forwardable, priority) | Missing |
| Group by target firm / group by connector | Missing |
| Smart sort (priority, strength, status, recency) | Missing |
| Filters (strength, status, target firm, has draft, needs action) | Missing |
| Copy-to-clipboard for drafts and forwardable blurbs | Missing |
| Status pipeline visualization | Missing |
| Mobile card view (< 768px) | Missing |
| "Add intro" button | Missing |
| Empty state for warm intros | Missing |
5. Candidate linkage
0 of 36 warm intros are linked to a candidate. The target_candidate_id column exists and has a proper FK, but every row is NULL.
Root cause: No auto-resolution logic. When a warm intro is created with target_firm = "Sequoia Capital", nothing resolves that to the matching candidate in the active round. The POST handler passes through whatever the caller sends, and Boo's skill doesn't supply it. Without the target_firm_id FK column, there is no reliable join path for resolution.
6. Boo skill integration
| Integration point | Status |
|---|---|
intro-path skill writes to intro_paths, not warm_intros | No bridge |
| API contract (api-contract.md) doesn't document warm intros endpoints | Missing |
draft-outreach writes to action_drafts, not warm_intros.draft_email | Two draft stores |
| heartbeat-compose doesn't surface warm intro follow-ups | Missing |
| import-mapper doesn't create warm intros from imported contacts | Missing |
| conversational-edit can't handle warm intro commands | Missing |
Priority matrix
| Gap | Severity | Effort |
|---|---|---|
| PATCH endpoint (dead schema, no handler) | Critical | Low |
| Network page shows intro_paths, not warm_intros | Critical | Medium |
| Status enum misalignment | High | Low |
| 8 missing DB columns | High | Medium |
| Candidate linkage (0/36) | High | Medium |
| Pipeline side-effect on accepted | High | Low |
| intro_paths / warm_intros bridge | High | Medium |
| API contract docs missing warm intros | Medium | Low |
| DELETE endpoint (RESTful) | Medium | Low |
| Bulk create endpoint | Medium | Low |
| Heartbeat integration | Medium | Medium |
| UI: filters, grouping, smart sort, mobile | Medium | Medium |
| Draft storage unification | Medium | Design decision |
Recommended path forward
Wire the PATCH handler and fix the status enum. The schema is already written. Add the route, run the status migration (draft to identified, add permission-requested). This unblocks everything else.
Low effort, high unlockAdd the 8 missing columns and update the API schemas. ALTER TABLE for the new fields, extend warmIntroSchema and warmIntroPatchSchema, add FK constraints with SET NULL.
Medium effort, enables resolutionBuild the warm intros table into the Network page. Use the existing fostable component (already in use on Round, Investors, Competitors). Add a "Warm Intros" tab alongside the existing intro_paths view.
Medium effort, makes feature visibleAuto-resolve candidate linkage. When a warm intro is created or patched, match target_firm + target_investor against the firms/people directory and populate the FK columns. Backfill the 36 existing rows.
Medium effort, enables pipeline side-effectUpdate the skill references and bridge the two systems. Document warm intros endpoints in api-contract.md. Have the intro-path skill create warm_intros records when a founder activates a discovered path. Unify draft storage.
Medium effort, completes the loopAudited against Warm Intros Tab Product Spec v1, the live Fundraising OS app source, API responses, and the installed Boo skills (boo-fundraising-os, intro-path, draft-outreach). All data is as of Aug 16, 2026.