implementation.md

ctx0 Implementation Index

This document guides Claude Code (or any implementing agent) through the ctx0 implementation process. Read this first to understand what to build and in what order.


Documentation Map

Before implementing, read the documentation in this order:

OrderDocumentPurpose
1ctx0-supabase-data-architecture.mdDatabase schema, tables, RLS, functions
2ctx0-vault-structure.mdLocked folders, file organization
3ctx0-agents.mdAgent system (AGENT.md + config.json)
4ctx0-skills.mdDB-as-skill pattern for sync tables
5ctx0-sessions.mdSession/conversation storage

Implementation Phases

Phase 1: Database Schema

Goal: Set up Supabase tables, indexes, RLS, and functions.

Tasks:

  1. Create all ctx0_* tables (see ctx0-supabase-data-architecture.md)
  2. Create indexes for performance
  3. Create RLS policies for user isolation
  4. Create helper functions (ctx0_query, ctx0_semantic_search)
  5. Create storage bucket (ctx0-vault)

Files to create:

packages/ctx0/
├── migrations/
│   ├── 001_ctx0_schema.sql     # All tables, indexes, RLS
│   └── manifest.json           # Migration metadata
└── src/
    └── migrations.ts           # Export SQL as strings

Verification:

  • All 9 tables created
  • Indexes created
  • RLS enabled on all tables
  • User isolation policies work
  • Service role bypass works
  • ctx0_query function blocks mutations
  • Storage bucket created

Phase 2: Vault Structure

Goal: Initialize vault with locked folders and default content.

Tasks:

  1. Create initialization function that sets up vault structure
  2. Create locked folders (.ctx0/, agents/, skills/, tools/, mcp/)
  3. Create default agents (ctx0, curator)
  4. Create default tools documentation
  5. Create _index.md files

Files to modify:

packages/daemon/src/
├── ctx0/
│   ├── init.ts                 # Vault initialization
│   ├── entries.ts              # Entry CRUD operations
│   └── storage.ts              # Storage bucket operations

Default content to create:

  • /agents/ctx0/AGENT.md + config.json
  • /agents/curator/AGENT.md + config.json
  • /tools/ctx0_remember/TOOL.md
  • /tools/ctx0_retrieve/TOOL.md
  • /tools/ctx0_sql/TOOL.md
  • /agents/_index.md
  • /skills/_index.md
  • /tools/_index.md
  • /mcp/_index.md

Verification:

  • Locked folders created with is_locked=true
  • Default agents created with is_system=true
  • Default tools documented
  • User cannot delete locked folders
  • User can add custom agents/skills/tools

Phase 3: ctx0 Tools

Goal: Implement the core ctx0 tools for agents to use.

Tasks:

  1. Implement ctx0_remember tool
  2. Implement ctx0_retrieve tool (semantic search)
  3. Implement ctx0_sql tool (DB-as-skill queries)
  4. Implement ctx0_browse tool (list entries)
  5. Implement ctx0_read tool (read entry content)

Files to create:

packages/daemon/src/tools/
├── ctx0-remember.ts
├── ctx0-retrieve.ts
├── ctx0-sql.ts
├── ctx0-browse.ts
└── ctx0-read.ts

Verification:

  • ctx0_remember creates entries in vault
  • ctx0_retrieve returns semantically similar entries
  • ctx0_sql only allows SELECT queries
  • ctx0_sql blocks dangerous keywords
  • ctx0_browse lists entries in a path
  • ctx0_read returns full entry content

Phase 4: Session Storage

Goal: Store and retrieve conversation history.

Tasks:

  1. Implement session creation/update
  2. Implement message logging
  3. Implement compaction tracking
  4. Implement session resumption

Files to create:

packages/daemon/src/ctx0/
├── sessions.ts                 # Session CRUD
└── messages.ts                 # Message logging

Verification:

  • Sessions created with correct metadata
  • Messages stored with correct sequence
  • Tool calls logged with params and results
  • Compaction points marked correctly
  • Compaction summary stored in message
  • Sessions can be resumed from compaction point

Phase 5: Agent System

Goal: Load and invoke agents from vault.

Tasks:

  1. Parse AGENT.md files (frontmatter + markdown)
  2. Load config.json for structured config
  3. Build agent context with tools, skills, permissions
  4. Implement subagent invocation
  5. Implement skill preloading

Files to create:

packages/daemon/src/ctx0/
├── agents.ts                   # Agent loading and invocation
└── parser.ts                   # AGENT.md/SKILL.md parsing

Verification:

  • AGENT.md parsed correctly (frontmatter + body)
  • Agent tools filtered correctly
  • Subagent invocation works
  • Skills preloaded into agent context
  • Custom agents loadable from vault

Phase 6: Tracker Script

Goal: Import conversations from external AI tools.

Tasks:

  1. Watch Claude Code conversation files
  2. Parse .jsonl format
  3. Insert into ctx0_sessions + ctx0_session_messages
  4. Track compaction events
  5. Store source_path for linking back

Files to create:

packages/daemon/src/tracker/
├── index.ts                    # Main tracker
├── claude-code.ts              # Claude Code parser
└── watchers.ts                 # File watching

Verification:

  • Tracker detects new Claude Code conversations
  • Messages parsed correctly
  • Tool calls extracted
  • Compaction events detected
  • Sessions linked to source files

Package Structure

packages/
├── ctx0/                       # Shared migrations and types
│   ├── package.json            # @bot0/ctx0
│   ├── migrations/
│   │   ├── 001_ctx0_schema.sql
│   │   └── manifest.json
│   └── src/
│       ├── index.ts
│       ├── migrations.ts
│       └── types.ts
│
└── daemon/                     # Core implementation
    └── src/
        ├── ctx0/
        │   ├── init.ts         # Vault initialization
        │   ├── entries.ts      # Entry operations
        │   ├── sessions.ts     # Session operations
        │   ├── agents.ts       # Agent system
        │   └── storage.ts      # Storage bucket
        ├── tools/
        │   ├── ctx0-remember.ts
        │   ├── ctx0-retrieve.ts
        │   ├── ctx0-sql.ts
        │   ├── ctx0-browse.ts
        │   └── ctx0-read.ts
        └── tracker/
            ├── index.ts
            └── claude-code.ts

Key Implementation Details

Entry Path Handling

Paths always start with / and use forward slashes:

typescript
// Good const path = '/contacts/sarah-chen.md'; const folder = '/agents/ctx0/'; // Bad const path = 'contacts/sarah-chen.md'; const folder = 'agents\\ctx0\\';

Locked Folder Enforcement

Before any entry modification:

typescript
const LOCKED_FOLDERS = ['.ctx0', 'agents', 'skills', 'tools', 'mcp']; function isLockedPath(path: string): boolean { const parts = path.split('/').filter(Boolean); return LOCKED_FOLDERS.includes(parts[0]); } function canModifyEntry(entry: Entry, operation: 'update' | 'delete'): boolean { if (entry.is_locked) return false; if (entry.is_system && operation === 'delete') return false; return true; }

AGENT.md Parsing

typescript
import matter from 'gray-matter'; interface AgentConfig { name: string; description: string; tools?: string[]; disallowedTools?: string[]; model?: string; skills?: string[]; subagents?: string[]; } function parseAgentMd(content: string): { config: AgentConfig; prompt: string } { const { data, content: body } = matter(content); return { config: data as AgentConfig, prompt: body.trim() }; }

ctx0_sql Security

typescript
const FORBIDDEN_PATTERNS = [ /\bDROP\b/i, /\bDELETE\b/i, /\bTRUNCATE\b/i, /\bINSERT\b/i, /\bUPDATE\b/i, /\bALTER\b/i, /\bCREATE\b/i, /\bGRANT\b/i, /\bREVOKE\b/i, ]; function validateQuery(sql: string): void { if (!/^\s*SELECT\b/i.test(sql)) { throw new Error('Only SELECT queries allowed'); } for (const pattern of FORBIDDEN_PATTERNS) { if (pattern.test(sql)) { throw new Error('Query contains forbidden keyword'); } } }

Compaction Tracking

When inserting a compaction marker:

typescript
await supabase.from('ctx0_session_messages').insert({ session_id: sessionId, user_id: userId, message_sequence: nextSequence(), role: 'system', content: '[Context compacted]', is_compaction_point: true, compaction_summary: summary, context_tokens_before: tokenCount }); await supabase.from('ctx0_sessions') .update({ compaction_count: sql`compaction_count + 1` }) .eq('id', sessionId);

Testing Checklist

Database

  • Tables create without errors
  • RLS blocks cross-user access
  • Service role bypasses RLS
  • ctx0_query rejects mutations
  • Indexes improve query performance

Vault

  • Initialization creates all folders
  • Default agents are loadable
  • Custom agents can be added
  • Locked folders protected
  • Entry CRUD works

Tools

  • ctx0_remember creates entries
  • ctx0_retrieve returns relevant results
  • ctx0_sql executes safe queries
  • ctx0_sql blocks unsafe queries
  • ctx0_browse lists correctly
  • ctx0_read returns content

Sessions

  • Sessions track all agents
  • Messages preserve order
  • Tool calls logged
  • Compaction tracked
  • Resumption works

Agents

  • AGENT.md parsing works
  • Tool filtering works
  • Subagent invocation works
  • Skill preloading works

Common Pitfalls

  1. UUID generation: Use gen_random_uuid() in SQL, not client-side
  2. Path normalization: Always use / prefix, no trailing slash for files
  3. RLS context: Ensure user_id is set correctly for RLS to work
  4. Compaction timing: Store summary BEFORE clearing context
  5. Locked folder checks: Check BEFORE the operation, not after