Smart Meeting-to-Ticket Pipeline PRD (V2)

TL;DR

Extend the existing meeting-to-ticket pipeline with two key capabilities: (1) cross-reference against existing Linear tickets to prevent duplicates and update existing tickets instead, and (2) route pending tickets to Slack for engagement planner approval with one-click actions. This builds on the working V0 platform UI.


Summary

This PRD defines enhancements to the existing meeting-to-ticket pipeline. V0 already works: meetings are ingested, action items are extracted into linear_ticket_generations with pending status, and a platform UI allows reviewers to edit titles, descriptions, priorities, and assignees before creating tickets in Linear.

What V1 adds:

  1. Cross-reference engine — Before staging tickets, check against existing open Linear tickets in participants’ teams. Classify items as CREATE (new), UPDATE (add comment to existing), or NEEDS_REVIEW (ambiguous match).
  2. Slack approval workflow — Push pending tickets to Slack for review, routed to the right people based on meeting type. Enable Approve/Reject/Reassign directly in Slack.

Prompt management is already handled in Langfuse. Documentation for how to edit prompts will be added to brainforge-playbook.


Background and Context

What Already Exists (V0 — Working)

Supabase Table: linear_ticket_generations (2,585 records)

Current schema:

ColumnTypeNotes
iduuidAuto-generated primary key
meeting_iduuidFK to zoom_meeting_recording_files
titletextAction item title
descriptiontextAction item description
team_idtextLinear team ID
team_nametextLinear team name
assignee_idtextLinear user ID (nullable)
assignee_nametextAssignee display name (nullable)
statustext’pending’ (default), ‘approved’, ‘declined’
linear_issue_idtextPopulated after creation in Linear
linear_issue_urltextLinear ticket URL
linear_issue_identifiertexte.g., “OPS-123”
created_in_linear_attimestampWhen ticket was created in Linear
generation_metadatajsonbExtraction metadata
linksjsonbRelated links (defaults to [])
preferred_statejsonbPreferred Linear state
created_at, updated_attimestampTimestamps

Current Status Distribution:

  • pending: 2,557
  • approved: 25
  • declined: 3

Working Flow:

  1. Meeting ingested → zoom_meeting_recording_files
  2. Extraction service → action items written to linear_ticket_generations (status: pending)
  3. Platform UI → reviewer edits title, description, assignee, priority
  4. Approve → ticket created in Linear, linear_issue_id populated, status → approved
  5. Decline → status → declined, no Linear ticket created

Prompt Management:

  • Prompts are managed in Langfuse (not a custom UI)
  • Documentation needed in brainforge-playbook for how to edit prompts

What V0 Lacks (The Problem)

  • No deduplication: System creates new tickets even when similar tickets already exist in Linear
  • No cross-referencing: Action items don’t check against open tickets before staging
  • No Slack integration: Reviewers must go to the platform to review; no push notifications
  • No comment updates: Cannot add meeting context as comments to existing tickets

Result:

  • Ticket overload in Linear backlogs
  • Duplicate tickets for the same work item
  • Meeting context lost instead of appended to existing tickets
  • Reviewers forget to check platform; pending tickets pile up (2,557 pending)

Problem and Value

Specific Pain Points:

Pain PointQuantified Impact
Duplicate tickets createdManual cleanup; cluttered Linear backlogs
No cross-reference with existing ticketsSame action item creates new ticket instead of updating existing
Reviewers must visit platformNo push notification; 2,557 pending tickets piling up
Multi-project standupsCross-project action items may duplicate work already tracked

Stakeholder Value:

StakeholderValue
Engagement PlannersSlack push notifications; one-click approve without leaving Slack
Service LeadsCleaner backlogs; existing tickets enriched with meeting context
Individual ContributorsExisting tickets updated with new info instead of duplicate tickets

Goals and Non-Goals

Goals (What V1 Adds):

  • NEW: Cross-reference extracted action items against open Linear tickets in participants’ teams
  • NEW: Classify items as CREATE (new ticket), UPDATE (add comment to existing), or NEEDS_REVIEW (ambiguous)
  • NEW: Route pending tickets to Slack based on meeting type (standup → team channel; client call → planner DM)
  • NEW: Enable Approve / Reject / Reassign actions directly in Slack
  • NEW: Add comments to existing Linear tickets when UPDATE is approved
  • EXISTING (unchanged): Action item extraction from transcripts (already works)
  • EXISTING (unchanged): Platform UI for detailed editing (already works)
  • EXISTING (unchanged): Prompt management via Langfuse (document in playbook)

Non-Goals (Explicit Exclusions):

  • Rebuilding the extraction pipeline (already works in V0)
  • Rebuilding the platform review UI (already works in V0)
  • Building a prompt editing UI (use Langfuse; document workflow in playbook)
  • Historical backfill of existing 2,557 pending tickets
  • Automatic approval without human review
  • Replacing platform UI with Slack (Slack is for quick approval; platform remains for detailed edits)

Staged Milestones

V0: Existing System (Already Complete)

What’s Working:

  • Meeting ingestion pipeline (Zoom → Supabase)
  • Action item extraction from transcripts (LLM-based, prompts in Langfuse)
  • Staging in linear_ticket_generations with pending status
  • Platform UI for review: edit titles, descriptions, priorities, assignees
  • Approve action creates ticket in Linear
  • Decline action marks as declined

What’s Missing:

  • No cross-reference against existing Linear tickets
  • No Slack notifications or approval workflow
  • No ability to update existing tickets with meeting context

POC: Cross-Reference Engine

Goal: Validate that semantic similarity can reliably match action items to existing Linear tickets.

Scope:

  • Build similarity matching function (embeddings or keyword-based)
  • Fetch open tickets from Linear via MCP (scoped to participant teams)
  • Test on 20 sample meetings with known duplicates
  • Measure precision/recall of duplicate detection

Success Criteria:

  • 80%+ of known duplicates correctly identified
  • False positive rate less than 15%

Timeline: [TBD, needs technical review]


V1: Cross-Reference + Slack Approval

Goal: Add cross-reference deduplication and Slack-based approval workflow to the existing pipeline.

Scope (Cross-Reference Engine):

  • Participant-aware ticket lookup (assignee teams + all participant teams as fallback)
  • Similarity scoring against open Linear tickets
  • Classification logic: CREATE / UPDATE / NEEDS_REVIEW
  • Store classification in linear_ticket_generations (new columns)

Scope (Slack Integration):

  • Meeting type classification based on folder name patterns
  • Routing: internal meetings → per-team Slack channels (tag participants)
  • Routing: client meetings → DM to engagement planner (from mapping table)
  • Interactive Slack messages with Approve / Reject / Reassign buttons
  • Webhook handler for Slack button actions
  • On CREATE approval: create new Linear ticket (existing behavior)
  • On UPDATE approval: add comment to existing Linear ticket (new behavior)

Scope (Config Tables):

  • project_planner_mapping: project → engagement planner Slack user
  • team_slack_channels: Linear team → Slack channel
  • meeting_type_patterns: folder name patterns for internal vs. external

Scope (Documentation):

  • Document Langfuse prompt management workflow in brainforge-playbook

Not in V1:

  • Configurable similarity thresholds (use fixed 80%/50%)
  • Historical backfill of existing pending tickets

Success Criteria:

  • 90%+ of items correctly routed to the right Slack destination
  • 50%+ reduction in duplicate tickets created
  • Reviewer can complete review in less than 30 seconds per item

Timeline: [TBD, needs technical review]


V2: Analytics and Tuning

Goal: Add pipeline analytics and enable threshold tuning.

Scope:

  • Dashboard showing pipeline throughput (items created, updated, rejected)
  • Configurable similarity thresholds per project
  • Optional: retroactive backfill tool for historical meetings

Timeline: [TBD, needs technical review]


Technical Approach

Architecture Overview

V0 (Existing Flow):

Meeting Ingested → Extraction Service (Langfuse prompts) → linear_ticket_generations (pending)
                                                                    ↓
                                                              Platform UI (review/edit)
                                                                    ↓
                                                              Linear (create ticket)

V1 (Enhanced Flow):

Meeting Ingested → Extraction Service (unchanged)
                         ↓
              ┌──────────────────────┐
              │  Cross-Reference     │ ← NEW: Check against open Linear tickets
              │  Engine              │   (scoped to participant teams)
              └──────────────────────┘
                         ↓
              ┌──────────────────────┐
              │  Classification      │ ← NEW: CREATE / UPDATE / NEEDS_REVIEW
              └──────────────────────┘
                         ↓
              linear_ticket_generations (pending, with action_type + linked_issue)
                         ↓
              ┌──────────────────────┐
              │  Slack Router        │ ← NEW: Route based on meeting type
              └──────────────────────┘
                    ↓           ↓
           Internal mtg    Client mtg
                ↓              ↓
         Team channel    Planner DM
                ↓              ↓
              [Approve] [Reject] [Reassign]
                         ↓
                    Linear MCP
              (create_issue OR create_comment)

Key Components

ComponentStatusTechnologyNotes
Meeting IngestionEXISTINGZoom pipelineTriggers on new recording
Action ExtractionEXISTINGLLM + LangfusePrompts managed in Langfuse
Staging DBEXISTINGSupabaselinear_ticket_generations table
Platform Review UIEXISTINGWeb appEdit/approve pending tickets
Cross-Reference EngineNEWLinear MCP + similarityFetches open tickets, computes match
Classification LogicNEWService codeCREATE / UPDATE / NEEDS_REVIEW
Slack RouterNEWService codeDetermines channel/user by meeting type
Slack IntegrationNEWSlack Block Kit APIInteractive messages with buttons
Comment AdditionNEWLinear MCPcreate_comment on existing tickets
Config TablesNEWSupabaseRouting rules, planner mappings

Data Model

Schema Changes to linear_ticket_generations (ADD columns):

ALTER TABLE linear_ticket_generations
  ADD COLUMN action_type TEXT DEFAULT 'create',          -- 'create', 'update', 'needs_review'
  ADD COLUMN linked_linear_issue_id TEXT,                -- existing ticket ID if UPDATE
  ADD COLUMN linked_linear_issue_identifier TEXT,        -- e.g., "ABC-123"
  ADD COLUMN similarity_score FLOAT,                     -- match confidence
  ADD COLUMN slack_message_ts TEXT,                      -- Slack message timestamp
  ADD COLUMN slack_channel_id TEXT,                      -- where Slack message was sent
  ADD COLUMN reviewed_by TEXT,                           -- who clicked approve/reject
  ADD COLUMN reviewed_at TIMESTAMPTZ;                    -- when review happened

Note: status column already exists with values: pending, approved, declined

New Config Tables:

-- Project to engagement planner mapping
CREATE TABLE project_planner_mapping (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  project_identifier TEXT NOT NULL,      -- folder name pattern or client name
  planner_slack_user_id TEXT NOT NULL,
  planner_name TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);
 
-- Team to Slack channel mapping (for standups)
CREATE TABLE team_slack_channels (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  linear_team_id TEXT NOT NULL,
  linear_team_name TEXT,
  slack_channel_id TEXT NOT NULL,
  slack_channel_name TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);
 
-- Meeting type classification patterns
CREATE TABLE meeting_type_patterns (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  pattern TEXT NOT NULL,           -- regex or contains pattern
  meeting_type TEXT NOT NULL,      -- 'internal' or 'external'
  description TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

Functional Requirements

Cross-Reference Logic

  1. For proposed assignee → fetch their Linear team memberships
  2. For all meeting participants → fetch their Linear team memberships (fallback scope)
  3. Fetch open tickets from Linear in those teams (status != Done, Canceled)
  4. Compare each action item against open tickets using similarity scoring
  5. Classify:
    • Similarity > 80% → UPDATE (link to matched ticket)
    • Similarity < 50% → CREATE (new ticket)
    • Similarity 50-80% → NEEDS_REVIEW (flag for human decision)

Slack Routing Logic

  1. Check meeting folder name against meeting_type_patterns table
  2. If matches “internal” pattern (e.g., contains “Standup”, “Sync”, “Daily”):
    • Route to per-team Slack channel (from team_slack_channels table)
    • Tag meeting participants
  3. Else:
    • Lookup project from meeting context
    • Route to designated engagement planner (from project_planner_mapping table)

Slack Message Actions

  • Approve (CREATE): Create new Linear ticket (existing behavior)
  • Approve (UPDATE): Add comment to existing Linear ticket with meeting context
  • Reject: Mark status = declined, no Linear action
  • Reassign: Update assignee, then approve

Assumptions

  1. Linear team memberships are accurate and up-to-date.

    • Risk if wrong: Cross-reference scope will miss relevant tickets.
  2. Meeting folder names follow consistent patterns.

    • Risk if wrong: Routing logic will misclassify meetings.
  3. Slack users can be mapped to Linear users reliably.

    • Risk if wrong: Reassign action won’t work correctly.
  4. 80%/50% similarity thresholds are reasonable starting points.

    • Risk if wrong: Too many false positives or missed duplicates.
  5. Langfuse is the source of truth for prompts.

    • Risk if wrong: Prompt changes won’t be tracked properly.

Open Questions

QuestionOwnerNeeded ByStatus
Which Slack channels exist for each team?OpsV1 startOpen
What folder name patterns indicate internal meetings?OpsV1 startOpen
How to handle meetings with no clear project association?ProductV1 startOpen
Should there be a timeout for pending reviews?ProductV1Open
What happens if a participant is not in Linear?EngineeringV1Open

Success Metrics

MetricTargetHow Measured
Duplicate tickets prevented50%+ reductionCompare pre/post ticket counts
Review completion time< 30 seconds per itemSlack sent → action clicked
Routing accuracy90%+ correctManual audit of 50 meetings
Pending ticket backlog< 500 at any timeCount of status=‘pending’
Pipeline reliability< 5% error rateError logs / retry counts

Timeline Summary

PhaseScopeDurationStatus
V0Extraction + Platform UICompleteDONE
POCCross-reference engine validation[TBD]Not started
V1Cross-reference + Slack approval[TBD]Not started
V2Analytics + threshold tuning[TBD]Not started

References

Existing Infrastructure (V0):

  • Supabase project: internal-zoom (viqeppmsqvwpslpvttkk)
  • Meeting data: zoom_meeting_recording_files (3,894 records)
  • Pending tickets: linear_ticket_generations (2,585 records, 2,557 pending)
  • Prompt management: Langfuse (document in playbook)
  • Platform review UI: [URL TBD - ask team for location]

External APIs: