Skip to content

Selvedge vs. OpenLore

OpenLore is the closest thing to Selvedge in the category, and the most useful comparison because of it: both are local-first, both are deterministic, and neither puts an LLM in the retrieval path. The difference is where the memory comes from, and what survives in it.

SelvedgeOpenLore
Reasoning sourceCaptured live, by the agent in the same context that produced the changeDerived — tree-sitter static analysis of code state, plus commit-gated decision notes
GranularityEntity — DB column, table, env var, dep, API route, functionAST node (18 languages + 12 IaC)
MechanismMCP server — the agent calls it as work happensMCP server — one-time index + commit-time certificates
GroupingChangesets — named feature/task slugs across many entitiesCall-graph edges
Prior attemptsYesprior_attempts surfaces tried-and-rejected pathsPurged — rejected is an inactive status, dropped from the queryable store after each decision sync
StorageSQLite, zero depsSQLite graph in .openlore/
  • Determinism is shared ground here, not a differentiator. Against most of this category Selvedge leads on having no model in the storage or retrieval path. OpenLore is deterministic-native too — its own description is “no LLM in the hot path” — so that argument doesn’t separate the two, and we won’t pretend it does.
  • Testimony vs. derivation. OpenLore derives what it knows from the code as it stands: a static analysis can always be recomputed, so it can only ever describe the state that survived. Selvedge stores what the agent said at the time. Testimony is not re-derivable from the repository, which is exactly why it’s worth keeping.
  • What happens to a rejected decision. This is the sharp one. In OpenLore, rejected is one of the inactive statuses, and purgeInactiveDecisions drops those from the store after every decision sync — the annotation survives in the synced spec markdown, but the queryable record does not. In Selvedge the store is append-only: a rejection is a first-class, permanent, queryable fact, and prior_attempts is built to return it. Nothing in a purged store can answer “has this been tried, and how did it turn out?”
  • Entity granularity vs. AST node. OpenLore’s node coverage is broader across languages. Selvedge’s entities are the things you search for six months later that have no AST node at all — users.email, env/STRIPE_SECRET_KEY, deps/stripe.

If what you want is a deterministic map of the code as it exists now — call graphs, AST-level structure, broad language coverage, decisions kept in step with the current spec — OpenLore is a strong and genuinely well-built fit, and its language coverage is wider than ours. Reach for Selvedge when the question you need answered is about the path not taken.