MasteryMade · Infrastructure PRD
Close the archive gap keeping Claude.ai as primary. Every Forge interaction gets a session ID, full transcript to Supabase, entities/topics extracted, optionally published to NowPage. Once this exists, Forge becomes primary for everything.
CREATE TABLE sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_type TEXT NOT NULL CHECK (session_type IN (
'forge_interactive','forge_autonomous','claude_code','telegram_bot','voice_agent','api_consumer'
)),
initiated_by TEXT NOT NULL,
runtime TEXT NOT NULL,
title TEXT,
transcript TEXT NOT NULL,
summary TEXT,
entities_mentioned UUID[],
topics TEXT[],
decisions_made JSONB, -- [{decision,rationale,reversible}]
action_items JSONB, -- [{item,owner,deadline}]
gate INT,
related_sessions UUID[],
skills_used TEXT[],
published_url TEXT,
published_at TIMESTAMPTZ,
started_at TIMESTAMPTZ NOT NULL,
ended_at TIMESTAMPTZ,
duration_seconds INT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_sessions_started ON sessions(started_at DESC);
CREATE INDEX idx_sessions_topics ON sessions USING gin(topics);
CREATE INDEX idx_sessions_entities ON sessions USING gin(entities_mentioned);
CREATE INDEX idx_sessions_transcript ON sessions
USING gin(to_tsvector('english', coalesce(title,'') || ' ' || transcript));
ALTER TABLE sessions ADD COLUMN summary_embedding vector(1536);
Session Starts → generate session_id → begin transcript capture
During → append to buffer → track skills invoked
Session Ends (idle timeout / explicit /end / cron)
→ Webhook to n8n:
1. Store raw transcript
2. AI summary (Claude Haiku — cheap, fast)
3. Entity extraction (match against entities table)
4. Topic extraction (keyword + embedding classification)
5. Decision/action item extraction
6. Gate classification
7. Register in org registry changelog
8. OPTIONAL: Publish to NowPage if marked publishable
9. Telegram: "Session logged. N decisions, N action items."
CREATE FUNCTION search_sessions(p_query TEXT, p_limit INT DEFAULT 20, p_after TIMESTAMPTZ DEFAULT NULL)
RETURNS SETOF sessions AS $$
SELECT * FROM sessions
WHERE to_tsvector('english', coalesce(title,'') || ' ' || transcript)
@@ plainto_tsquery('english', p_query)
AND (p_after IS NULL OR started_at >= p_after)
ORDER BY ts_rank(...) DESC LIMIT p_limit;
$$ LANGUAGE sql;
CREATE FUNCTION semantic_search_sessions(p_embedding vector(1536), p_limit INT DEFAULT 10)
RETURNS SETOF sessions AS $$
SELECT * FROM sessions WHERE summary_embedding IS NOT NULL
ORDER BY summary_embedding <=> p_embedding LIMIT p_limit;
$$ LANGUAGE sql;
| Function | Current | Target |
|---|---|---|
| Daily briefs | Manual in Claude.ai | Autonomous on Forge (PRD 6) |
| NowPage publishing | Claude.ai MCP | Forge direct + n8n |
| Session archival | Claude.ai native | Forge → Supabase sessions |
| Skill execution | Claude.ai skill loading | Forge MANUAL.md loading |
| Meeting processing | Manual upload | Fireflies webhook → Forge |
What stays on Claude.ai: Interactive brainstorming (conversation UX better for exploration). Past chat search for pre-migration history. File creation/editing (compute sandbox).
Now: Session logger built. All new Forge sessions archived. Week 2: Daily briefs + NowPage publishing move to Forge. Week 4: Meeting processing automated via Fireflies webhook. Ongoing: Claude.ai for interactive work. Forge is system of record.
MASTERYMADE — PRD 10 of 12
Dominia Facta. Build what compounds.