How Luci's knowledge persistence works: the vault architecture, directory structure, database schema, MCP server tools, indexer, and the two-DB split between vault.db and mc.db.
Markdown files are the source of truth. vault.db is a derived query index. mc.db is Luci's operational database.
The vault.db can be rebuilt from files at any time via python index.py --rebuild. Only the activity_log table is authoritative in the DB (append-only, not derived from files).
Implemented 2026-04-07. Two databases with clear ownership, one MCP server that queries both transparently.
PKA/Vault/vault.db (tracked in git).git/info/exclude)python index.py --rebuild (file index) + python session_indexer.py (session transcripts)~/workspace/mission-control/mc.db on Luci's servermc_pickup.py, scheduler.py, heartbeat.py, MC API (app.py), session_indexer.py100.118.207.3:3001 (never direct DB access)PKA/Vault/)Project-specific structured data:
Vault/
vault.db # SQLite query index (derived from files)
vault.db-wal # WAL journal
vault.db-shm # Shared memory
schema.sql # DDL for vault.db (v2, 2026-03-30)
memory/ # Memory files (durable reference knowledge)
MEMORY.md # Memory index -- lists all memories
auto/ # Auto-generated memories from Claude sessions
*.md # Individual memories (feedback, project, reference, user)
tasks/ # Task files with YAML frontmatter
projects/ # Project tracking files
notes/ # General notes
~/.claude/vault/)Cross-project personal data shared between PKA, CoWork, and other projects:
~/.claude/vault/
identity/ # KYC profiles (Elmar, Nicolette, children)
entities/ # Company profiles (ENCFT, Werda, YellowNickel), group financials
contacts/ # Master contact list (people + companies)
work/ # FlySafair role/team/tools, glossary
secrets/ # API keys, POPIA passwords, SSH keys
preferences/ # About me, communication style
infrastructure/ # Server profiles, network/SSH config, service inventory
references/ # Reference documents
scripts/ # Utility scripts
session_tracker.py # Session registration
sessions.json # Session log
next-session.md # Carry-forward notes
Schema v2 (2026-03-30). Key tables:
.md file. Columns: path, root (pka or personal), title, type, status, priority, due_date, assigned, project, frontmatter (JSON), content_hash, file_modifiedfrontmatter or wikilink). As of MC-462: 197 edges (up from 42) after auto-generation from shared projects, entities, and content similarity.Removed (MC-462, 2026-04-09):
vitals_logandtask_runswere dropped from vault.db. Both were always empty — all task runs go to mc.db, and vitals were never populated.vault_cleanup.pyhandles this cleanup.
session_indexer.py)Script: vault_mcp.py (runs as stdio MCP server, configured in .mcp.json)
Provides 8 tools for Claude Code sessions to query the knowledge graph:
| Tool | Source | Purpose |
|---|---|---|
memory_search |
vault.db (FTS5) | Full-text search across all indexed files |
memory_recall |
vault.db (FTS5 + edges) | FTS matches plus graph-connected neighbors |
graph_neighbors |
vault.db (edges) | All files connected to a given path |
file_lookup |
vault.db (files) | Query by type, status, project, assignee |
memory_health |
vault.db (files) | Memory lifecycle: stale, unreviewed, status |
session_search |
vault.db + Luci MC API | Search past session transcripts (merged) |
activity_log |
vault.db + Luci MC API | Recent activity entries (merged local + remote) |
luci_status |
Luci MC API only | Live Luci state: active tickets, inbox, activity |
The three cross-boundary tools (session_search, activity_log, luci_status) call the MC API at http://100.118.207.3:3001 over HTTP with bearer token auth (mc-lucienne-2026).
Circuit breaker (MC-462, 2026-04-09): HTTP fallback calls use a circuit breaker — after 3 consecutive failures, the breaker opens for 5 minutes and returns a clear error instead of hanging. This prevents silent degradation when Luci is down.
Ticket context auto-logging: When memory_recall or file_lookup is called during a worker session (detected via MC_TICKET_ID env var), the consulted vault files are automatically logged to mc.db's ticket_context table via the MC API. This creates a ticket↔vault bridge so tickets know which knowledge was consulted.
Connection: Read-only to vault.db (file:...?mode=ro). Never writes.
Script: index.py
Scans markdown files from two roots and populates vault.db:
pka) -- Team/.md, Vault/memory/.md, Vault/tasks/.md, Vault/projects/.md, Vault/notes/*.md, Lucienne.md, CLAUDE.md, SETUP.mdpersonal) -- identity, contacts, entities, preferences, work, infrastructure (excludes secrets/).md files matching glob patternsfiles tablerelated: field (relation: related_to)belongs_to, assigned -> assigned_to, depends_on, blocks, parent -> subtask_of[wikilinks](/wiki/wikilinks) in body text (relation: references)search_fts)activity_logpython index.py # Incremental (skip unchanged files)
python index.py --rebuild # Full rebuild (preserves activity_log, vitals_log, task_runs)
python index.py --stats # Show index statistics
Rebuild safety: --rebuild drops and recreates the DB from schema.sql, but first saves and restores activity_log, vitals_log, and task_runs rows.
Memory files use YAML frontmatter followed by markdown content:
---
name: Memory Title
description: One-line summary
type: project | feedback | reference | user
created: 2026-04-07
last_reviewed: 2026-04-07
status: active
owner: lucienne | luci | both
stale_after: 30d | never
---
## Content
Markdown body with details, decisions, and context.
Key frontmatter fields:
- type -- Categorizes the memory (project, feedback, reference, user)
- status -- Lifecycle state (active, archived, etc.)
- stale_after -- Duration before memory is considered stale (e.g., 30d, never). The v_memory_health view uses this to flag memories needing review.
- last_reviewed -- Date of last human/system review
- owner -- Who maintains this memory (lucienne, luci, both)
Memory index: Vault/memory/MEMORY.md is the manually curated index that lists all memories grouped by category (User, Project, Reference, Feedback).
session_indexer.py parses JSONL session transcripts from ~/.claude/projects/sessions_index + sessions_fts (FTS5) tablespython session_indexer.py (incremental) or --rebuild.git/info/exclude (read-only consumer).bak files are also excluded from gitstale_after + last_reviewed)index.py --rebuild is safe: preserves activity_logsession_indexer.py into FTS5 tablesvault_cleanup.py removes dead tables (vitals_log, task_runs) and can prune orphaned graph nodesticket_context tableMission Control is the board for your delegated work: requests come in, Luci coordinates the next step, and evidence stays visible for review.
Luci is your always-on assistant for routing, status updates, and follow-through. Operators can still open deeper evidence when needed.