MDX Limo
Rowboat Feature Adoption Plan

Rowboat Feature Adoption Plan

Document Version: 1.0 Created: February 2026 Source Repository: github.com/rowboatlabs/rowboat Status: Proposed


Executive Summary

This document outlines strategic feature adoptions from the Rowboat AI assistant platform that would significantly enhance Consul Agent's value proposition. After comprehensive analysis of both codebases, we've identified 10 high-impact opportunities that leverage Consul's existing infrastructure while addressing current gaps in intelligence amplification.

The recommended adoptions focus on making Consul smarter about user context rather than adding new integrations. The existing tool ecosystem (100+ tools), workflow infrastructure, and three-tier memory system provide a strong foundation—the opportunity is using data we already capture more intelligently.

Key Themes:

  • Transform passive data collection into active relationship intelligence
  • Surface the "why" behind agent decisions to build user trust
  • Enable cross-conversation learning that compounds over time
  • Prepare users for meetings with contextual briefings

Table of Contents

  1. Analysis Methodology
  2. Current State Assessment
  3. Feature Recommendations
  4. Implementation Roadmap
  5. Technical Dependencies
  6. Success Metrics
  7. Risk Assessment
  8. Appendix: Rowboat Architecture Overview

Analysis Methodology

Repositories Analyzed

RepositoryDescriptionKey Strengths
rowboatDesktop AI coworker with persistent memoryKnowledge graph, entity extraction, event-sourced execution
consul-agentExecutive AI assistant with Google Workspace integrationMature tool ecosystem, multi-channel delivery, workflow automation

Evaluation Criteria

Each feature was evaluated on:

  1. User Value — Direct impact on user productivity/experience
  2. Technical Fit — Compatibility with existing architecture
  3. Implementation Effort — Engineering resources required
  4. Strategic Alignment — Fit with Consul's product vision

Current State Assessment

Consul Agent Strengths

CategoryStatusDetails
Tool Ecosystem✅ Strong100+ tools across Gmail, Calendar, Drive, Docs, Slack, Contacts
Workflow Automation✅ StrongEmail triage, daily briefs, scheduling, sales processing
Multi-Channel✅ StrongWeb chat, iMessage/SMS, Email (AgentMail)
Memory System✅ StrongWorking + Semantic + Observational memory tiers
Safety Controls✅ Strong14-stage processor pipeline, human-in-the-loop confirmation

Identified Gaps

GapCurrent StateImpact
Entity ExtractionManual relationship entry onlyUsers must explicitly tell Consul about contacts
Meeting PreparationDaily brief lists meetings, no attendee contextMissed opportunity for high-value briefings
Decision TransparencyShows what action, not whyReduces user trust and adoption
Relationship Utilizationrelationships table exists but unused in toolsDrafts lack personalization context
Cross-Tool LearningTools operate independentlyPreferences not shared across tool executions
Skill AnalyticsOn/off toggle onlyNo visibility into automation effectiveness

Feature Recommendations

Tier 1: Highest Impact

These features address critical gaps with immediate, visible user value.


1. Knowledge Graph & Entity Extraction

Priority: P0 — Critical Effort: Medium (3-4 weeks) User Value: High

What Rowboat Has

Rowboat automatically extracts entities (people, organizations, projects, topics) from:

  • Emails and attachments
  • Meeting transcripts
  • Voice memos
  • Notes

Entities are linked in a knowledge graph with relationship types and interaction history.

Current Gap in Consul

The relationships table exists but requires manual population. The agent processes thousands of emails but doesn't learn who matters from communication patterns.

Proposed Implementation
1┌─────────────────────────────────────────────────────────────┐ 2│ Entity Extraction Pipeline │ 3├─────────────────────────────────────────────────────────────┤ 4│ │ 5│ emailTriageWorkflow ──► extractEntitiesStep ──► Supabase │ 6│ │ │ 7│ dailyBriefWorkflow ──► extractEntitiesStep ──► Supabase │ 8│ │ │ 9│ (future) meetingNotes ──► extractEntitiesStep ──► Supabase│ 10│ │ 11└─────────────────────────────────────────────────────────────┘

New Database Tables:

1-- Extracted entities from communications 2CREATE TABLE entities ( 3 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 4 user_id UUID NOT NULL REFERENCES profiles(id), 5 entity_type TEXT NOT NULL, -- 'person', 'organization', 'project', 'topic' 6 name TEXT NOT NULL, 7 aliases TEXT[], -- Alternative names/spellings 8 email TEXT, -- For person entities 9 metadata JSONB DEFAULT '{}', 10 first_seen TIMESTAMPTZ DEFAULT now(), 11 last_seen TIMESTAMPTZ DEFAULT now(), 12 mention_count INTEGER DEFAULT 1, 13 UNIQUE(user_id, entity_type, name) 14); 15 16-- Relationships between entities 17CREATE TABLE entity_relationships ( 18 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 19 user_id UUID NOT NULL REFERENCES profiles(id), 20 source_entity_id UUID NOT NULL REFERENCES entities(id), 21 target_entity_id UUID NOT NULL REFERENCES entities(id), 22 relationship_type TEXT NOT NULL, -- 'works_with', 'reports_to', 'collaborates_on' 23 strength REAL DEFAULT 0.5, -- 0-1 based on interaction frequency 24 last_interaction TIMESTAMPTZ, 25 context TEXT -- e.g., "Frequently CC'd together on legal emails" 26); 27 28-- Entity mentions in communications 29CREATE TABLE entity_mentions ( 30 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 31 entity_id UUID NOT NULL REFERENCES entities(id), 32 source_type TEXT NOT NULL, -- 'email', 'calendar', 'note' 33 source_id TEXT NOT NULL, -- Gmail message ID, calendar event ID, etc. 34 mentioned_at TIMESTAMPTZ DEFAULT now(), 35 context_snippet TEXT -- Surrounding text for context 36);

New Workflow Step:

1// apps/agents/src/mastra/workflows/steps/extract-entities.ts 2export const extractEntitiesStep = createStep({ 3 id: "extract-entities", 4 inputSchema: z.object({ 5 content: z.string(), 6 sourceType: z.enum(["email", "calendar", "note"]), 7 sourceId: z.string(), 8 userId: z.string(), 9 }), 10 outputSchema: z.object({ 11 entities: z.array(z.object({ 12 type: z.enum(["person", "organization", "project", "topic"]), 13 name: z.string(), 14 email: z.string().optional(), 15 confidence: z.number(), 16 })), 17 }), 18 execute: async ({ inputData, mastra }) => { 19 const model = mastra.getModel("openai/gpt-4.1-mini"); 20 21 const result = await model.generate({ 22 messages: [{ 23 role: "system", 24 content: ENTITY_EXTRACTION_PROMPT, 25 }, { 26 role: "user", 27 content: inputData.content, 28 }], 29 response_format: { type: "json_object" }, 30 }); 31 32 // Upsert entities to Supabase 33 // Link to source via entity_mentions 34 // Update relationship strengths based on co-occurrence 35 36 return { entities: result.entities }; 37 }, 38});
Success Metrics
  • Entities extracted per user per week
  • Relationship accuracy (user corrections)
  • Entity utilization rate in drafting/scheduling

2. Meeting Prep Agent

Priority: P0 — Critical Effort: Medium (2-3 weeks) User Value: Very High

What Rowboat Has

Pre-meeting briefings that include:

  • Attendee backgrounds and roles
  • Recent interaction history
  • Open threads/action items with each attendee
  • Suggested talking points
  • Relevant documents/emails
Current Gap in Consul

Daily brief lists upcoming meetings but provides no attendee context. Users enter meetings without knowing what was last discussed or what's pending with each participant.

Proposed Implementation

Option A: Extend Daily Brief Add a meetingPrepSection to dailyBriefWorkflow that generates per-meeting briefings.

Option B: Standalone Workflow (Recommended) Create meetingPrepWorkflow that runs 30 minutes before each meeting, delivering briefing via preferred channel.

1┌─────────────────────────────────────────────────────────────┐ 2│ Meeting Prep Workflow │ 3├─────────────────────────────────────────────────────────────┤ 4│ │ 5│ 1. fetchUpcomingMeetings (next 2 hours) │ 6│ │ │ 7│ ▼ │ 8│ 2. For each meeting: │ 9│ ├─ resolveAttendees (→ entities table) │ 10│ ├─ fetchRecentEmails (with each attendee) │ 11│ ├─ fetchPastMeetings (with same attendees) │ 12│ ├─ fetchOpenReminders (related to attendees) │ 13│ └─ fetchRelatedDocs (shared recently) │ 14│ │ │ 15│ ▼ │ 16│ 3. generateBriefing (structured summary) │ 17│ │ │ 18│ ▼ │ 19│ 4. deliverBriefing (iMessage/email/web notification) │ 20│ │ 21└─────────────────────────────────────────────────────────────┘

Briefing Output Schema:

1const meetingBriefingSchema = z.object({ 2 meetingTitle: z.string(), 3 startTime: z.string(), 4 attendees: z.array(z.object({ 5 name: z.string(), 6 email: z.string(), 7 role: z.string().optional(), 8 relationship: z.string().optional(), // From relationships table 9 lastInteraction: z.object({ 10 date: z.string(), 11 summary: z.string(), 12 }).optional(), 13 openItems: z.array(z.string()), // Pending actions/reminders 14 })), 15 suggestedAgenda: z.array(z.string()), 16 relevantContext: z.array(z.object({ 17 type: z.enum(["email", "document", "reminder"]), 18 title: z.string(), 19 summary: z.string(), 20 link: z.string().optional(), 21 })), 22 talkingPoints: z.array(z.string()), 23});
Success Metrics
  • Meeting prep delivery rate (% of meetings with briefing)
  • User engagement (opened, actioned)
  • Feedback rating (thumbs up/down on briefings)

3. Decision Reasoning Transparency

Priority: P0 — Critical Effort: Low (1-2 weeks) User Value: High

What Rowboat Has

Event-sourced execution with full audit trail. Users can see the chain of reasoning that led to any action.

Current Gap in Consul

The suspend/resume pattern shows what action the agent wants to take but not why it chose that action over alternatives.

Proposed Implementation

Schema Changes:

1-- Add reasoning to pending_approvals 2ALTER TABLE pending_approvals 3ADD COLUMN reasoning TEXT, 4ADD COLUMN alternatives_considered JSONB DEFAULT '[]', 5ADD COLUMN confidence REAL;

Tool Output Enhancement:

1// Extend tool output schema pattern 2const toolOutputWithReasoning = baseOutputSchema.extend({ 3 _reasoning: z.object({ 4 rationale: z.string(), 5 alternativesConsidered: z.array(z.object({ 6 action: z.string(), 7 whyNotChosen: z.string(), 8 })).optional(), 9 confidence: z.number().min(0).max(1), 10 dataSourcesUsed: z.array(z.string()), 11 }).optional(), 12});

Processor Enhancement:

Create ReasoningCaptureProcessor that extracts reasoning from tool calls and stores it:

1export class ReasoningCaptureProcessor extends InputProcessor { 2 async process(messages: Message[]): Promise<Message[]> { 3 // After tool execution, capture reasoning from assistant message 4 // Store in pending_approvals.reasoning for suspended tools 5 // Log to decision_audit_log for all tools 6 return messages; 7 } 8}

UI Enhancement:

Update confirmation modal to display:

  • "Why this action?" expandable section
  • Alternatives considered (if any)
  • Confidence indicator
  • Data sources referenced
Success Metrics
  • Confirmation acceptance rate (should increase with transparency)
  • Time-to-decision (should decrease as users trust reasoning)
  • User feedback on reasoning quality

Tier 2: High Impact

Significant value with moderate architectural work.


4. Cross-Conversation Learning

Priority: P1 — High Effort: Medium (2-3 weeks) User Value: High

What Rowboat Has

Knowledge index that refreshes between processing batches. Entities and patterns learned in one context are available in all future contexts.

Current Gap in Consul

ObservationalMemory exists but tools don't actively share learnings. Each tool operates with local context only.

Proposed Implementation

Observation Emission Pattern:

1// After successful tool execution, emit observation 2export async function emitObservation( 3 context: ToolContext, 4 observation: { 5 type: 'preference' | 'pattern' | 'correction' | 'feedback'; 6 category: string; // e.g., 'scheduling', 'email_tone', 'meeting_duration' 7 content: string; 8 confidence: number; 9 source: string; // Tool ID that generated observation 10 } 11) { 12 const userId = context.requestContext?.get("userId"); 13 if (!userId) return; 14 15 // Store in observations table 16 await supabase.from("user_observations").insert({ 17 user_id: userId, 18 ...observation, 19 observed_at: new Date().toISOString(), 20 }); 21 22 // Update working memory with high-confidence observations 23 if (observation.confidence > 0.8) { 24 // Merge into working memory schema 25 } 26}

Example Observations:

ToolObservation TypeExample
scheduleMeetingpreference"User prefers 30-minute meetings over 1-hour"
composeEmailpattern"User always includes greeting before business content"
triageEmailpattern"User archives all marketing emails from @promotions.com"
confirmSendEmailcorrection"User edited draft to add CC — remember to include Jane on legal emails"

Observation Retrieval:

Tools query relevant observations before execution:

1const relevantObservations = await getObservations({ 2 userId, 3 categories: ["email_tone", "recipient_preferences"], 4 minConfidence: 0.7, 5 limit: 5, 6}); 7 8// Include in tool context for LLM
Success Metrics
  • Observations generated per user per week
  • Observation accuracy (validated by user corrections)
  • Reduced user edits to agent-generated content

5. Relationship-Aware Drafting

Priority: P1 — High Effort: Low (1 week) User Value: High

What Rowboat Has

Wiki-style links to people entities. Drafting tools pull relationship context automatically.

Current Gap in Consul

The relationships table exists with contact tags and notes, but composeEmail and triage draft tools don't query it.

Proposed Implementation

Enhance composeEmail and Related Tools:

1// In composeEmail execute function 2const recipientContext = await getRelationshipContext(userId, recipientEmail); 3 4// recipientContext includes: 5// - relationship tags (e.g., "client", "team member", "executive") 6// - last interaction date and summary 7// - communication style notes 8// - preferred formality level 9// - any user notes about the relationship 10 11// Include in LLM prompt 12const systemPrompt = ` 13You are drafting an email to ${recipientContext.name}. 14 15Relationship context: 16- Type: ${recipientContext.tags.join(", ")} 17- Last interaction: ${recipientContext.lastInteraction} 18- Communication style: ${recipientContext.communicationStyle} 19- User notes: ${recipientContext.notes} 20 21Adjust tone and content appropriately. 22`;

Relationship Context Query:

1async function getRelationshipContext( 2 userId: string, 3 email: string 4): Promise<RelationshipContext | null> { 5 // Check relationships table 6 const relationship = await supabase 7 .from("relationships") 8 .select("*") 9 .eq("user_id", userId) 10 .eq("email", email) 11 .single(); 12 13 if (relationship) { 14 return { 15 name: relationship.name, 16 tags: relationship.tags, 17 notes: relationship.notes, 18 lastInteraction: relationship.last_interaction_at, 19 communicationStyle: relationship.communication_style, 20 }; 21 } 22 23 // Fall back to entities table if no explicit relationship 24 const entity = await supabase 25 .from("entities") 26 .select("*") 27 .eq("user_id", userId) 28 .eq("email", email) 29 .single(); 30 31 return entity ? mapEntityToContext(entity) : null; 32}
Success Metrics
  • Draft acceptance rate (should increase)
  • User edits per draft (should decrease)
  • Relationship data utilization rate

6. Skill Performance Analytics

Priority: P1 — High Effort: Medium (2-3 weeks) User Value: Medium-High

What Rowboat Has

PostHog integration with detailed event tracking. Users can see which features work well.

Current Gap in Consul

Skills (triage, drafting, scheduling, etc.) have on/off toggles but no metrics on effectiveness.

Proposed Implementation

New Analytics Tables:

1CREATE TABLE skill_events ( 2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 3 user_id UUID NOT NULL REFERENCES profiles(id), 4 skill_id TEXT NOT NULL, -- 'triage', 'drafting', 'scheduling', etc. 5 event_type TEXT NOT NULL, -- 'invoked', 'completed', 'failed', 'approved', 'rejected', 'edited' 6 metadata JSONB DEFAULT '{}', 7 created_at TIMESTAMPTZ DEFAULT now() 8); 9 10CREATE TABLE skill_metrics ( 11 user_id UUID NOT NULL REFERENCES profiles(id), 12 skill_id TEXT NOT NULL, 13 period_start DATE NOT NULL, 14 invocation_count INTEGER DEFAULT 0, 15 success_count INTEGER DEFAULT 0, 16 failure_count INTEGER DEFAULT 0, 17 approval_rate REAL, -- For skills with confirmation 18 avg_time_to_completion INTERVAL, 19 user_edit_rate REAL, -- How often user modified output 20 PRIMARY KEY (user_id, skill_id, period_start) 21);

Dashboard Component:

1// apps/web/app/(authenticated)/skills/[skillId]/analytics/page.tsx 2export default function SkillAnalyticsPage({ params }: { params: { skillId: string } }) { 3 return ( 4 <div className="space-y-6"> 5 <SkillMetricsSummary skillId={params.skillId} /> 6 <SkillTrendChart skillId={params.skillId} period="30d" /> 7 <SkillEventLog skillId={params.skillId} limit={50} /> 8 <SkillRecommendations skillId={params.skillId} /> 9 </div> 10 ); 11}

Metrics Displayed:

  • Invocations per day/week
  • Success rate trend
  • Approval vs. rejection rate (for confirmable actions)
  • Average time to user decision
  • Common failure reasons
  • Recommendations for improvement
Success Metrics
  • User engagement with analytics pages
  • Skill configuration changes after viewing analytics
  • Overall skill effectiveness improvements

Tier 3: Medium Impact

Valuable features with higher implementation effort.


7. Voice Memos with Transcription

Priority: P2 — Medium Effort: Medium-High (3-4 weeks) User Value: Medium-High

What Rowboat Has

Voice recording with Deepgram transcription. Voice notes become searchable knowledge.

Proposed Implementation

Frontend (Web):

1// apps/web/components/chat/voice-input.tsx 2export function VoiceInput({ onTranscription }: { onTranscription: (text: string) => void }) { 3 const [isRecording, setIsRecording] = useState(false); 4 const mediaRecorder = useRef<MediaRecorder | null>(null); 5 6 const startRecording = async () => { 7 const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); 8 mediaRecorder.current = new MediaRecorder(stream); 9 // ... capture audio chunks 10 }; 11 12 const stopAndTranscribe = async () => { 13 const audioBlob = new Blob(chunks, { type: "audio/webm" }); 14 const formData = new FormData(); 15 formData.append("audio", audioBlob); 16 17 const response = await fetch("/api/transcribe", { 18 method: "POST", 19 body: formData, 20 }); 21 22 const { text } = await response.json(); 23 onTranscription(text); 24 }; 25 26 return ( 27 <Button 28 variant={isRecording ? "destructive" : "outline"} 29 onClick={isRecording ? stopAndTranscribe : startRecording} 30 > 31 <Mic className="h-4 w-4" /> 32 </Button> 33 ); 34}

Backend Transcription:

1// apps/web/app/api/transcribe/route.ts 2export async function POST(request: Request) { 3 const formData = await request.formData(); 4 const audioFile = formData.get("audio") as File; 5 6 const transcription = await openai.audio.transcriptions.create({ 7 file: audioFile, 8 model: "whisper-1", 9 }); 10 11 return NextResponse.json({ text: transcription.text }); 12}
Success Metrics
  • Voice input usage rate
  • Transcription accuracy (user corrections)
  • Task completion rate via voice vs. text

8. Wiki-Style Knowledge Base

Priority: P2 — Medium Effort: High (4-6 weeks) User Value: Medium

What Rowboat Has

Local markdown files with [[wiki links]]. Graph visualization of knowledge relationships.

Proposed Implementation

Database Schema:

1CREATE TABLE notes ( 2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 3 user_id UUID NOT NULL REFERENCES profiles(id), 4 title TEXT NOT NULL, 5 content TEXT NOT NULL, -- Markdown with [[wiki links]] 6 tags TEXT[] DEFAULT '{}', 7 linked_entities UUID[] DEFAULT '{}', -- References to entities table 8 created_at TIMESTAMPTZ DEFAULT now(), 9 updated_at TIMESTAMPTZ DEFAULT now() 10); 11 12CREATE TABLE note_links ( 13 source_note_id UUID NOT NULL REFERENCES notes(id), 14 target_note_id UUID NOT NULL REFERENCES notes(id), 15 link_text TEXT, -- The [[text]] used 16 PRIMARY KEY (source_note_id, target_note_id) 17);

New Tools:

  • createNote — Create new knowledge note
  • updateNote — Edit existing note
  • searchNotes — Full-text search across notes
  • linkNote — Create wiki-style link between notes

UI Components:

  • Note editor with wiki-link autocomplete
  • Knowledge graph visualization
  • Note search and browse interface
Success Metrics
  • Notes created per user
  • Wiki links created
  • Note retrieval in agent conversations

9. MCP (Model Context Protocol) Integration

Priority: P2 — Medium Effort: High (4-6 weeks) User Value: Medium (power users)

What Rowboat Has

Extensible tool system via MCP servers. Users can add custom tool providers.

Proposed Implementation

MCP Client in Agents:

1// apps/agents/src/mastra/mcp/client.ts 2import { Client } from "@modelcontextprotocol/sdk/client"; 3 4export class MCPToolProvider { 5 private clients: Map<string, Client> = new Map(); 6 7 async connectServer(config: MCPServerConfig): Promise<void> { 8 const client = new Client({ 9 name: "consul-agent", 10 version: "1.0.0", 11 }); 12 13 await client.connect({ 14 command: config.command, 15 args: config.args, 16 }); 17 18 this.clients.set(config.id, client); 19 } 20 21 async getTools(serverId: string): Promise<Tool[]> { 22 const client = this.clients.get(serverId); 23 if (!client) throw new Error(`MCP server ${serverId} not connected`); 24 25 const { tools } = await client.listTools(); 26 return tools.map(mcpToolToMastraTool); 27 } 28 29 async invokeTool(serverId: string, toolName: string, args: unknown): Promise<unknown> { 30 const client = this.clients.get(serverId); 31 return client.callTool({ name: toolName, arguments: args }); 32 } 33}

User Configuration UI:

  • MCP server management page
  • Add/remove server configurations
  • Test connection functionality
  • Per-server tool visibility settings
Success Metrics
  • MCP servers configured per user
  • MCP tool invocations
  • Custom integration adoption

Tier 4: Lower Priority

Interesting capabilities for future consideration.


10. Composio Integration

Priority: P3 — Low Effort: Medium (2-3 weeks) User Value: Low-Medium

What Rowboat Has

Pre-built connections to 100+ apps via Composio platform.

Proposed Implementation

Integrate Composio SDK for simplified OAuth and third-party tool access. Useful for quickly adding integrations without building custom OAuth flows.

Considerations
  • Adds external dependency for auth management
  • May conflict with existing custom OAuth implementations
  • Best suited if rapidly expanding integration count

Implementation Roadmap

Phase 1: Quick Wins (Weeks 1-4)

FeatureEffortDependencies
Decision Reasoning Transparency (#3)1-2 weeksNone
Relationship-Aware Drafting (#5)1 weekNone
Basic Entity Extraction (#1 partial)1-2 weeksNone

Deliverables:

  • Reasoning displayed in confirmation modals
  • composeEmail queries relationships table
  • Entity extraction step added to emailTriageWorkflow

Phase 2: Core Intelligence (Weeks 5-12)

FeatureEffortDependencies
Meeting Prep Workflow (#2)2-3 weeksEntity extraction
Full Knowledge Graph (#1 complete)2-3 weeksPhase 1 entity work
Cross-Conversation Learning (#4)2-3 weeksNone

Deliverables:

  • meetingPrepWorkflow delivering briefings before meetings
  • Entities table fully populated from all communication sources
  • Observations system capturing and applying learnings

Phase 3: Polish & Analytics (Weeks 13-18)

FeatureEffortDependencies
Skill Performance Analytics (#6)2-3 weeksNone
Voice Memos (#7)3-4 weeksNone

Deliverables:

  • Analytics dashboard for each skill
  • Voice input in web chat

Phase 4: Expansion (Future)

FeatureEffortDependencies
Wiki-Style Knowledge Base (#8)4-6 weeksEntity extraction
MCP Integration (#9)4-6 weeksNone
Composio Integration (#10)2-3 weeksNone

Technical Dependencies

New Packages Required

1{ 2 "@modelcontextprotocol/sdk": "^1.0.0", // For MCP integration (Phase 4) 3 "deepgram-sdk": "^3.0.0" // Alternative to OpenAI Whisper (Phase 3) 4}

Database Migrations Required

PhaseTablesDescription
1pending_approvals (alter)Add reasoning columns
1-2entities, entity_relationships, entity_mentionsKnowledge graph
2user_observationsCross-conversation learning
3skill_events, skill_metricsAnalytics
4notes, note_linksWiki knowledge base

Infrastructure Considerations

  • No new services required for Phases 1-3
  • Vector database updates may be needed for semantic entity search
  • Background job capacity — Meeting prep workflow adds scheduled jobs

Success Metrics

User-Facing Metrics

MetricBaselineTargetMeasurement
Confirmation acceptance rate65%85%pending_approvals accept/reject ratio
Draft edit rate40%20%User modifications to agent drafts
Meeting prep engagementN/A70% open rateBriefing delivery and opens
Time to first action45s25sUser decision time on confirmations

System Metrics

MetricTargetMeasurement
Entities extracted/user/week50+entities table growth
Observations generated/user/week20+user_observations table
Cross-tool learning accuracy80%+Observation validation rate

Risk Assessment

Technical Risks

RiskLikelihoodImpactMitigation
Entity extraction accuracyMediumMediumUse confidence thresholds; allow user corrections
Meeting prep timing failuresLowHighFallback delivery windows; retry logic
Observation noiseMediumLowConfidence filtering; periodic cleanup

Product Risks

RiskLikelihoodImpactMitigation
Information overload (meeting prep)MediumMediumConfigurable briefing depth
Privacy concerns (entity tracking)LowHighClear data policies; user controls
Feature complexityMediumMediumPhased rollout; feature flags

Appendix: Rowboat Architecture Overview

Key Architectural Patterns

1. Event-Sourced Agent Execution

Rowboat reconstructs agent state from immutable event logs, enabling:

  • Resumable runs across sessions
  • Full audit trail
  • Time-travel debugging

2. Knowledge Graph Structure

1┌─────────────────────────────────────────────────────────────┐ 2│ Knowledge Graph │ 3├─────────────────────────────────────────────────────────────┤ 4│ │ 5│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 6│ │ Person │────────▶│ Project │◀────────│ Topic │ │ 7│ └──────────┘ └──────────┘ └──────────┘ │ 8│ │ │ │ │ 9│ │ ┌───────────────┼───────────────┐ │ │ 10│ │ │ │ │ │ │ 11│ ▼ ▼ ▼ ▼ ▼ │ 12│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 13│ │ Org │ │ Email │ │ Meeting │ │ 14│ └──────────┘ └──────────┘ └──────────┘ │ 15│ │ 16└─────────────────────────────────────────────────────────────┘

3. Tiered Note Creation

Rowboat uses complexity-based processing:

  • High complexity: Full multi-agent analysis
  • Medium complexity: Single-agent with context
  • Low complexity: Direct extraction

4. MCP Tool Architecture

1┌─────────────────────────────────────────────────────────────┐ 2│ Tool System │ 3├─────────────────────────────────────────────────────────────┤ 4│ │ 5│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 6│ │ Built-in │ │ MCP │ │ Sub-Agent │ │ 7│ │ Tools │ │ Tools │ │ Tools │ │ 8│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ 9│ │ │ │ │ 10│ └────────────────┼────────────────┘ │ 11│ │ │ 12│ ▼ │ 13│ ┌──────────────┐ │ 14│ │ Agent Runtime │ │ 15│ └──────────────┘ │ 16│ │ 17└─────────────────────────────────────────────────────────────┘

Document History

VersionDateAuthorChanges
1.0Feb 2026Claude CodeInitial analysis and recommendations

This document should be reviewed and updated as implementation progresses and priorities shift.