Skip to main content
TENET’s storage adapter pattern lets all modules work against different backends without changing their code. Locally, everything writes to .jfl/ files and SQLite. In production, the same operations go to Postgres with workspace isolation.

Interface

interface TenetStorage {
  read(key: string): Promise<any>
  write(key: string, value: any): Promise<void>
  append(key: string, value: any): Promise<void>
  list(prefix?: string): Promise<string[]>
  query(query: Record<string, any>): Promise<any[]>
  execute(operation: string, params?: any): Promise<any>
  vectorSearch(vector: number[], options?: { limit?: number }): Promise<any[]>
}

Implementations

LocalStorage (default)

File-based storage in .jfl/ directory. Uses SQLite for queries and cosine similarity for vector search. This is what runs when you use tenet on your machine.

CloudStorage

Postgres-backed storage for multi-user deployments. All operations scoped by workspaceId. Uses pgvector for similarity search.
const storage = new CloudStorage(workspaceId, connectionString)

Factory

import { createStorage } from '@tenet-ai/cli'

// Local (default)
const local = createStorage()

// Cloud
const cloud = createStorage({ 
  cloud: { workspaceId: 'ws_123', connectionString: process.env.DATABASE_URL } 
})

How Modules Use It

Memory, training buffer, and policy head all accept an optional storage parameter. When not provided, they use LocalStorage (backward compatible):
// Existing behavior — unchanged
const memory = new MemoryDB(projectRoot)

// Cloud behavior — same API, different backend
const memory = new MemoryDB(projectRoot, { storage: cloudStorage })