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.
| Selvedge | OpenLore | |
|---|---|---|
| Reasoning source | Captured live, by the agent in the same context that produced the change | Derived — tree-sitter static analysis of code state, plus commit-gated decision notes |
| Granularity | Entity — DB column, table, env var, dep, API route, function | AST node (18 languages + 12 IaC) |
| Mechanism | MCP server — the agent calls it as work happens | MCP server — one-time index + commit-time certificates |
| Grouping | Changesets — named feature/task slugs across many entities | Call-graph edges |
| Prior attempts | Yes — prior_attempts surfaces tried-and-rejected paths | Purged — rejected is an inactive status, dropped from the queryable store after each decision sync |
| Storage | SQLite, zero deps | SQLite graph in .openlore/ |
Where Selvedge is different
Section titled “Where Selvedge is different”- 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,
rejectedis one of the inactive statuses, andpurgeInactiveDecisionsdrops 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, andprior_attemptsis 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.
When OpenLore might fit you better
Section titled “When OpenLore might fit you better”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.