Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Feature ID: PF-60
Version: 1.0
Last Updated: 2026-01-30
Status: πŸ“‹ Specification

Overview

This document describes how PF-60 (RAG Infrastructure) integrates with other platform components and cores. RAG (Retrieval-Augmented Generation) provides semantic search capabilities that enable AI features to reference organization-specific documents and knowledge.

Integration Pattern

Pattern Type: Event-Based Integration + Platform Layer PF-60 acts as both:
  1. Event Consumer: Subscribes to document lifecycle events from PF-11
  2. Platform Layer: Provides semantic search API consumed by all AI features

Publisher Dependencies

PF-11: Document Management

PF-60 subscribes to document lifecycle events to maintain embedding synchronization. Events are emitted with the DomainEvent envelope (see EVENT_CONTRACTS.md): top-level event_type, payload, and metadata. The payload contains only identifiers and timestamps; consumers must fetch document content from pf_documents under RLS.
EventActionPayload (wire β€” payload only)
document_publishedGenerate embeddings{organization_id, document_id, timestamp, user_id} β€” fetch content from pf_documents
document_updatedRegenerate embeddings{organization_id, document_id, timestamp, user_id} β€” fetch content from pf_documents
document_deletedDelete embeddings{organization_id, document_id, timestamp, user_id}
Payload-only interfaces (align with EVENT_CONTRACTS and migration 20260226140000_pf_rag_document_knowledge_events.sql):
/** Payload only β€” event_type is at envelope level. */
interface DocumentPublishedPayload {
  organization_id: string;
  document_id: string;
  timestamp: string;
  user_id: string;
}

interface DocumentUpdatedPayload {
  organization_id: string;
  document_id: string;
  timestamp: string;
  user_id: string;
}

interface DocumentDeletedPayload {
  organization_id: string;
  document_id: string;
  timestamp: string;
  user_id: string;
}
Consumers use these types to type the payload field of the envelope. For embedding generation, the generate-embeddings edge function fetches title, extracted_content, category, tags from pf_documents by document_id; the event does not carry full content on the wire.

Consumer Cores

PF-60 provides semantic search capabilities to all modules with AI features.

Core Consumers

CoreUsageSource Type Preferences
GR (Governance)Policy search for compliance questionssource_type = 'policy'
HR (Workforce)Handbook search for HR queriessource_type = 'document', category = 'handbook'
FA (Finance)Procedure search for accounting queriessource_type = 'document', category = 'procedure'
All ModulesGeneral AI enhancementAll source types

Integration Flow

User Query β†’ ai-assistant Edge Function
    ↓
Generate Query Embedding (OpenAI API)
    ↓
pf_search_embeddings(query_embedding, org_id, ...)
    ↓
Inject matched chunks into AI prompt
    ↓
AI Response with Source Citations

API Contracts

Database Functions

pf_search_embeddings Performs semantic similarity search against document embeddings.
FUNCTION pf_search_embeddings(
  query_embedding extensions.halfvec(1536),  -- halfvec for 50% storage savings
  org_id UUID,
  match_count INT DEFAULT 5,
  match_threshold FLOAT DEFAULT 0.7,
  source_types TEXT[] DEFAULT NULL
) RETURNS TABLE (
  id UUID,
  source_type TEXT,
  source_id UUID,
  source_table TEXT,
  content TEXT,
  metadata JSONB,
  similarity FLOAT
)
Security: SECURITY DEFINER with SET search_path = public

Edge Functions

generate-embeddings Generates embeddings for a document and stores in database.
// Request
interface GenerateEmbeddingsRequest {
  sourceType: 'document' | 'policy' | 'knowledge_article';
  sourceId: string;
  content: string;
  organizationId: string;
  metadata?: Record<string, unknown>;
}

// Response
interface GenerateEmbeddingsResponse {
  success: boolean;
  chunksProcessed: number;
  embeddingsCreated: number;
}
ai-assistant (Updated) Enhanced to support RAG when useRAG: true.
// Request (extended)
interface AIAssistantRequest {
  messages: AIMessage[];
  moduleContext?: AIModuleContext;
  useRAG?: boolean; // Default: true
  ragConfig?: {
    sourceTypes?: string[];
    matchCount?: number;
    matchThreshold?: number;
  };
}

// Response (extended)
interface AIAssistantResponse {
  content: string;
  sources?: RAGSource[]; // Present when useRAG=true
  usage?: TokenUsage;
}

interface RAGSource {
  sourceType: string;
  sourceId: string;
  title?: string;
  excerpt: string;
  similarity: number;
}

Data Flow Diagrams

Document Indexing Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PF-11 Document │───────▢ β”‚ document_published β”‚
β”‚  Management     β”‚  Event  β”‚     Event          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                                      β–Ό
                            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                            β”‚ generate-embeddings β”‚
                            β”‚   Edge Function     β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β–Ό                 β–Ό                 β–Ό
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚ Text Chunkingβ”‚  β”‚ OpenAI API   β”‚  β”‚   Database   β”‚
           β”‚ (6000 chars) β”‚  β”‚ Embeddings   β”‚  β”‚    Insert    β”‚
           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RAG Query Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User   │─────▢│  ai-assistant    │─────▢│  OpenAI API     β”‚
β”‚  Query  β”‚      β”‚  Edge Function   β”‚      β”‚  (Query Embed)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚                         β”‚
                          β–Ό                         β”‚
                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
                 β”‚ pf_search_       β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚ embeddings       β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                          β–Ό
                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                 β”‚ Inject Context   │─────▢│  AI Response    β”‚
                 β”‚ into Prompt      β”‚      β”‚  with Citations β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Security Considerations

Multi-Tenancy

  • All embeddings include organization_id
  • RLS policies enforce tenant isolation on all operations
  • pf_search_embeddings uses SECURITY DEFINER but validates org_id
  • UPDATE policy includes WITH CHECK to prevent org_id modification

Access Control

Embeddings inherit access control from source documents:
  • Users can only search embeddings from their organization
  • Same permissions as source documents apply
  • No cross-organization embedding access

PHI/PII Handling

  • Embedding content field contains document text (may include PHI)
  • RLS provides the same protection as source documents
  • Embeddings are cascade deleted when source is deleted
  • No PHI stored in metadata field

Performance Considerations

Indexing Performance

MetricTargetNotes
Embedding generation<5s per documentOpenAI API latency
Bulk indexing100 docs/batchRate limit handling
Retry delaysExponential backoff1s, 2s, 4s

Search Performance

MetricTargetNotes
Semantic search<500msHNSW index
Top 5 results<500msCosine similarity
10,000+ embeddingsSupportedPer organization

Index Configuration

-- HNSW index for fast approximate nearest neighbor search (better than IVFFlat)
CREATE INDEX idx_pf_document_embeddings_vector_hnsw
ON pf_document_embeddings 
USING hnsw (embedding halfvec_cosine_ops);

Migration Guide

For Existing Documents

Use the bulk indexing job to index existing documents:
// Trigger via edge function
POST /functions/v1/bulk-index-documents
{
  "organizationId": "uuid",
  "sourceType": "document",
  "batchSize": 100
}

For New Integrations

  1. Emit document_published event when content is created
  2. Emit event with identifiers only (organization_id, document_id, timestamp, user_id). The consumer (generate-embeddings) fetches content from pf_documents by document_id under RLS.
  3. PF-60 handles embedding generation automatically

Troubleshooting

Common Issues

IssueCauseSolution
No search resultsEmbeddings not generatedCheck pf_document_embeddings for source_id
Low similarity scoresQuery mismatchAdjust matchThreshold parameter
Slow generationLarge documentsCheck chunking, reduce chunk size if needed
429 errorsRate limitingBulk indexing handles this automatically

Monitoring

Check embedding status:
SELECT source_type, COUNT(*) as count
FROM pf_document_embeddings
WHERE organization_id = 'your-org-id'
GROUP BY source_type;

Dependencies

DependencyTypeRequired For
PF-59 (AI Provider Migration)RequiredOpenAI/OpenRouter API access
PF-11 (Document Management)RequiredSource documents and events
PF-27 (Platform AI)RequiredAI infrastructure base
pgvector extensionRequiredVector similarity search

  • Spec: specs/pf/specs/PF-60-rag-infrastructure.md
  • Tasks: specs/pf/tasks/PF-60-TASKS.md
  • AI Strategy: docs/architecture/analysis/AI_INTEGRATION_STRATEGY_2026.md
  • Event Contracts: docs/architecture/integrations/EVENT_CONTRACTS.md

Last Updated: 2026-01-30