Skip to main content
How Relic stays cheap, deterministic, and resilient — from the contract that defines a skill to the partitioning that keeps each repo’s memory isolated and every fact cited.

1. Decoupled skill registry & MCP serving engine

Relic stores, validates, and serves standard team operating procedures (“skills”) to coding agents. Skills are validated against a strict contract, registered in SQLite, moved through a lifecycle (draft → verified → deprecated), and the verified ones are served as MCP tools and resources.

The contract

The SkillIR Pydantic model is the single source of truth for a skill’s metadata, inputs, outputs, preconditions, safety checks, and citations. The MCP tool input schema is built dynamically from SkillIR.inputs.

Lifecycle in SQLite

Skills live in SQLite. When a skill is verified, its last_verified_at updates and it becomes eligible to be served or written to disk.
The MCP server takes a RecallFn by injection, so the serving package never imports any graph or OpenAI dependency — it keeps serving skills even when FalkorDB is offline.
Reference: packages/relic-serve/src/relic/serve/mcp_server.py; contract in packages/relic-core/src/relic/ontology/skill_ir.py.

2. Deterministic ingestion, token budgeting & a checkpoint ledger

Relic collects issue and PR histories from GitHub and Linear, buffers them in a raw filesystem store, maps them to structured episode specs, and loads them into the graph sequentially — under strict budget control.
1

Deterministic mappers

Connectors and mappers.py run with zero LLM usage, structuring API responses into PrEpisodeBody and IssueEpisodeBody models.
2

Token & content bounding

Descriptions are clipped to 2,000 characters, commits to 1,000; bot reviews are dropped and human reviews are capped and filtered. The payload is then fitted to a strict token budget with _fit_budget.
3

Idempotent checkpoint ledger

A ledger tracks already-ingested episodes (e.g. PR owner/name#42) under ./data/ingest/<group_id>.log. Re-runs skip these entries, making ingestion resilient to interruptions and rate limits.
Reference: packages/relic-ingest/src/relic/ingest/mappers.py and .../ingest/checkpoint.py.

3. Per-repo graph partitioning & provenance recall

Knowledge graphs are partitioned by repository using FalkorDB’s multi-database support, and queries return facts with cited issue/PR URLs.

Per-repo partitioning

A repo name maps to a safe database name (buildrelic/relic-core → buildrelic__relic-core). Ingestion clones the Graphiti driver scoped to that database (driver.clone(database=group_id)); search passes the same database = group_id.

Fact provenance

Recall maps search hits back to their source episodes via _resolve_sources, extracting the canonical issue or PR URL (e.g. https://github.com/owner/name/pull/12) to build a fully cited response.
Reference: packages/relic-graph/src/relic/graph/recall.py.

The hardest problem

FalkorDB upstream integration and Graphiti patching. Migrating memory storage from embedded Kuzu to FalkorDB unlocked multi-database partitioning and RediSearch full-text support, but introduced two compatibility issues with graphiti-core 0.29.x:
Queries containing only stopwords or punctuation generated empty parentheses, crashing write operations.
Hyphens (e.g. relic-core) were treated as negation operators, breaking search queries.
Both were resolved in engram.py by monkeypatching the Graphiti query builders (_patch_falkordb_empty_query) to sanitize empty queries and escape hyphens dynamically before execution.

Performance & DX

Deterministic scorecard

Instead of an LLM-as-judge, the evaluation suite does exact URL matching against gold sets — normalizing trailing slashes and casing — and computes Hit Rate, MRR, and Coverage. Recall tuning stays fast, cheap, and deterministic.

Batched GraphQL fetching

GitHub ingestion moved from many REST calls per PR to a single batched GraphQL query (file changes, reviews, assignees, commits in one trip). Bulk loading routes through Graphiti’s add_episode_bulk for parallel extraction with deduping.

Primary entry points

Last modified on June 22, 2026