OpenLore
Memory server
Created by Clay Good
Published in clay-good/OpenLore. Publisher page
362 GitHub stars
What it is
Persistent architectural memory and structural cognition for AI coding agents.
AutoGineer overview, from the brain’s own files
OpenLore is a memory system designed to solve the amnesia and lack of governance in AI coding agents. By performing a one-time static analysis of a repository, it builds a persistent knowledge graph that encompasses application code, infrastructure-as-code, and architectural decisions. Unlike standard RAG systems, OpenLore operates deterministically without an LLM in the hot path, ensuring consistent answers and providing agents with an 'Epistemic Lease' to warn them when facts have become stale. It serves as both a memory layer for agent orientation and a governance engine that certifies changes, flags breaking API surface modifications, and validates sensitive boundary crossings before they are committed.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
OpenLore functions as an MCP server that indexes your repository into a local knowledge graph. Upon installation, it maps code structures, dependencies, and architectural specs. During agent sessions, it injects a compact architecture digest into the agent's context. The agent then uses MCP tools to query this graph for tasks like orienting to a codebase, tracing execution paths, or verifying claims. Governance tools analyze diffs against the graph to provide deterministic verdicts on breaking changes or boundary violations without requiring an LLM.
| Folder | Role | Files |
|---|---|---|
| .claude | agent-config | 1 |
| .github | agent-config | 12 |
| docs | docs | 62 |
| examples | examples | 95 |
| scripts | scripts | 27 |
| skills | agent-instructions | 25 |
| src | source-code | 1284 |
| bench | folder | 15 |
| benchmarks | folder | 1 |
| openspec | folder | 1261 |
| packaging | folder | 2 |
| schemas | folder | 2 |
| stubs | folder | 1 |
The agent reads
- get_style_fingerprint evidence: CLAUDE.md
- get_map evidence: CLAUDE.md
- find_clones evidence: CLAUDE.md
- get_duplicate_report evidence: CLAUDE.md
- get_env_vars evidence: CLAUDE.md
- get_language_support evidence: CLAUDE.md
- search_code evidence: README.md
The agent writes
- record_decision evidence: AGENTS.md
Requirements
Runtimes: Node.js ^22.22.0 || >=23.5.0
Databases: LanceDB
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 1 script. Review package.json before opening the folder in Claude Code. No step below turns a hook on for you.
package.json:node scripts/postinstall.mjs
- Not scanned by AutoGineerAutoGineer could not scan everything it runs. https://www.npmjs.com/package/openlore
Created by Clay Good. Published in clay-good/OpenLore. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Orienting an agent to a new codebase at the start of a task.
- Validating that a proposed code change does not break public API contracts.
- Checking if a diff introduces a path into a sensitive architectural boundary.
- Verifying claims about code safety or dead code before refactoring.
- Maintaining architectural specifications that stay synchronized with code changes.
- Selecting relevant tests to run based on the specific impact of a code modification.
- “Orient me to the user authentication flow in this repository.”
- The agent calls orient() and receives a summary of relevant functions, callers, and specs, allowing it to start the task immediately without manual file exploration.
- “Review my current changes for breaking API surface modifications.”
- The agent uses certify_public_surface to identify changed exports and lists the specific consumers that would be affected by the proposed changes.
- “Verify if the function 'deleteUser' is safe to remove.”
- The agent uses find_dead_code or verify_claim to determine if the function has any remaining callers or dependencies, providing a deterministic verdict.
- “Check if this diff opens a path into the sensitive 'payment-gateway' module.”
- The agent uses change_impact_certificate to confirm whether the new code creates a reachable path into the protected boundary.
Documentation by Clay Good
<h1 align="center">OpenLore</h1>
<p align="center"> <strong>Deterministic, local-first memory and guardrails for AI coding agents — no LLM in the hot path.</strong><br> Install once. From then on it runs in the background, keeping your agent oriented and its changes safe.<br> No API key. Same answer every time. </p>
<p align="center"> <a href="https://www.npmjs.com/package/openlore"><img src="https://img.shields.io/npm/v/openlore?color=2563eb&label=npm&logo=npm&logoColor=white" alt="npm version"></a> <a href="https://github.com/clay-good/OpenLore/actions/workflows/ci.yml"><img src="https://github.com/clay-good/OpenLore/actions/workflows/ci.yml/badge.svg" alt="CI status"></a> <a href="LICENSE"><img src="https://img.shields.io/npm/l/openlore?color=22c55e" alt="MIT License"></a> <img src="https://img.shields.io/node/v/openlore?color=339933&logo=node.js&logoColor=white" alt="Node >=22.22"> <br> <img src="https://img.shields.io/badge/MCP-ready-7c3aed?logo=anthropic&logoColor=white" alt="MCP ready"> <img src="https://img.shields.io/badge/languages-21%20%2B%2013%20IaC-f97316" alt="21 languages + 13 IaC ecosystems"> <img src="https://img.shields.io/badge/tests-5500%2B-success" alt="5500+ tests"> <img src="https://img.shields.io/badge/API_key-not_required-0ea5e9" alt="No API key required"> <a href="https://github.com/clay-good/OpenLore/stargazers"><img src="https://img.shields.io/github/stars/clay-good/OpenLore?style=social" alt="GitHub stars"></a> </p>
<p align="center"> <code>install</code> wires your agent and indexes the repo → <code>orient</code> returns the code a task touches → <code>review</code> catches the change that breaks a contract. All local, no API key. </p>
<p align="center"> <strong><a href="#install-once-then-forget-it">Install</a> · <a href="#what-you-get">What you get</a> · <a href="#value-scorecard--does-it-pay-for-itself">Benchmarks</a> · <a href="#openlore-vs-alternatives">vs. Alternatives</a> · <a href="#documentation">Docs</a></strong> </p>
AI coding agents are amnesiac and ungoverned. Every task restarts by re-reading the same files, long sessions drift onto stale assumptions, and nothing warns the agent when a change is about to break a contract or cross a boundary.
OpenLore fixes both halves, and then gets out of your way. A one-time static analysis builds a live knowledge graph of your repo — call structure, types, tests, decisions, IaC. From then on your agent is already oriented at the start of every task and its changes are certified before they land — automatically, deterministically, with no LLM in the hot path, so the same question returns the same grounded answer and the agent is told when a fact goes stale instead of served a confident guess.
Install once, then forget it
npm install -g openlore && openlore installThat is the only command most people ever run. It auto-detects your agent (Claude Code, Cursor, Cline, Continue, Pi, AGENTS.md), wires it, registers the MCP server, and builds the index — no API key, no config, no prompts. After that, it's on in the background and you don't think about it:
🔄 Every task starts oriented, automatically — a compact architecture digest is injected into your agent's context at the start of each session, and your agent calls
orient()and the other tools itself over MCP. You don't type anything.🌱 Every repo, not just this one —
installwires your user account too, so each new git repo you open indexes itself in the background on first touch. "Install once" is literal.🩹 Always fresh — a file watcher re-indexes as you edit and converges to a full analysis; anything it can't recompute in time is marked explicitly stale, never silently wrong.
🛡️ Changes get checked before they land — the governance tools (and
openlore reviewon a PR) run deterministically with no API key.
The CLI below exists for humans and CI — prove, review, doctor, features. The everyday path is: install, then let your agent use it.
Zero config. Run
openlore featuresto see every opt-in capability (embeddings, the commit gate, the spec store…), whether it's on, and the one command to enable it.openlore doctorverifies the wiring.
What you get
Two things, both deterministic and local:
🧠 Memory — your agent starts every task already oriented
Orient in one call —
orient(task)returns the relevant functions, callers, specs, tests, and insertion points (~430µs p50 on a 15k-node graph) instead of a dozen exploratory file reads.Survives refactors — anchored notes and decisions carry forward when a symbol is renamed or moved, instead of orphaning.
One graph for everything — application code, Infrastructure-as-Code, and architectural decisions share one graph, so a single query spans all three.
Told when a fact is stale — every response carries a brief, factual freshness note (the Epistemic Lease) once a cached fact has aged or the repo moved, so a long session can't drift onto a confident guess.
🛡️ Governance — guardrails on what the agent changes
Breaking-change verdict —
certify_public_surfaceclassifies every changed exportbreaking / non-breaking / potentially-breakingand names the consumers each break hits. Never silently "safe."Sensitive-boundary check —
change_impact_certificateflags when a diff opens a new path into a boundary you declared (reachable after the change, not before).Grounded claims —
verify_claimreturnsconfirmed / refuted / unverifiablewith a citation, before an agent asserts "X is dead" or "Y is safe to change."One commit gate —
openlore enforceblocks on findings you markblocking. Advisory by default, no API key.
The one line to remember: an agent's expensive failure mode isn't ignorance — it's confidence. A model that doesn't know a function exists will go look. A model that "knows" a stale fact builds on it, and you pay at review time. OpenLore is built so the agent can be told "that fact is stale" and "this change opens a path you said was sensitive" — deterministically, with no second model guessing about the first.
Value Scorecard — does it pay for itself?
OpenLore only earns its place if an agent with it reaches a correct answer for less total cost than the same agent without it. We measure that and publish it — wins and losses. Numbers from the Spec 14 benchmark (claude -p, sonnet, N=4 medians, pinned SHAs), measured 2026-06-01.
| Scenario | Cost Δ | Round-trips Δ | Verdict |
|---|---|---|---|
| Large/unfamiliar repo · deep "how does X flow through Y" (its target) | −7% to −21% | −26% | ✅ helps — and the win grows with repo size |
| Small/familiar repo · shallow "who calls X" | task-dependent (Round 1: +43%) | +38% | ❌ often adds overhead — measure first |
The win scales with codebase size (round-trips without → with):
| Repo (size) | Cost Δ | Round-trips |
|---|---|---|
| excalidraw (~640 files) | −21% | 25 → 16 |
| tokio (~790 files) | −21% | 17 → 13 |
| okhttp | −13% | 13 → 11 |
| django (~3k files) | −7% | 21 → 15 |
| gin (110 files, smallest) | +4% (≈even) | 10 → 9 |
Re-confirmed live 2026-06-03: the deep-task win reproduces (okhttp −13%); the small/familiar case is task-dependent, not a flat loss (chalk −32% win vs. express +59% loss). Don't guess from our repos — run
openlore prove --estimateon yours (seconds, no API key).
Honesty contract. We never publish a savings number the benchmark didn't produce, we always show the losses next to the wins, and every claim traces to a command you can run. Methodology: docs/AGENT-BENCHMARKS.md.
Is OpenLore for you?
| ✅ Strong fit | A codebase too big to hold in your head — and the model's. Private or niche code the model never memorized. Long sessions where stale assumptions compound. Polyglot repos, or code plus the IaC that deploys it. |
| 🤔 Try it, measure | Mid-size repos and mixed workloads. Run openlore prove --estimate (seconds, no key) before you commit. |
| ❌ Probably not | A small repo the model already knows, answering shallow questions — your agent's built-in search is cheaper, and we publish the measurement that says so. Also: OpenLore locates and certifies, it never edits your code. |
What your agent reaches for (you rarely type these)
Once wired, your agent calls these over MCP on its own. The default surface is the substrate preset — 15 tools: the navigation core, the highest-value governance reads (recall, verify_claim, blast_radius), and the spec composites. The lean navigation preset (10 tools) and the full 83 tools (--preset full) are one flag away.
| When the agent needs to… | Tool |
|---|---|
| Start any task | orient(task) — functions, callers, specs, insertion points in one call |
| Find which file/function handles X | search_code |
| Know the blast radius of a change | analyze_impact — risk + up/downstream chain + governing decisions |
| Trace how request X reaches function Y | trace_execution_path |
| Pick the tests a change should run | select_tests — backward reachability to the reaching tests |
| Find dead code / what dies if X is deleted | find_dead_code — cross-language reachability |
| Check a whole diff before commit | blast_radius — callers, tests, specs that drift |
| Tell if a diff opens a sensitive boundary | change_impact_certificate |
| Tell if a change breaks a consumer's API | certify_public_surface — verdict, consumers named |
| Verify a fact before asserting it | verify_claim — deterministic verdict + citation |
| Record an architectural choice | record_decision before writing the code |
Full reference — all 83 tools: docs/mcp-tools.md. Ships as a Claude Code Skill at skills/openlore-orient/.
OpenLore vs. alternatives
Everyone in this category answers the same first question: how does the agent see the codebase without reading it file by file? LSP toolkits answer with symbols, graph MCP servers with a parsed graph, search platforms with an index. OpenLore answers it too — then keeps going into the second question almost nobody answers: what happens when the agent starts writing? A retrieval layer makes an agent informed; it doesn't make it safe. That second half — governance on the same graph, no LLM in the loop — is what OpenLore is for.
| Agent built-ins | LSP toolkits | Graph MCP | Search platforms | OpenLore | |
|---|---|---|---|---|---|
| Structural context instead of file reads | ❌ grep | ✓ symbols | ✓ graph | ✓ index | ✓ call graph + IaC + decisions on one graph |
| Local, no API key, deterministic | Partial | ✓ | ✓ | ❌ hosted | ✓ no LLM in the hot path |
| Cross-session memory anchored to code | ❌ | Partial | ✓ notes | ❌ | ✓ carried across renames |
| Told when a cached fact goes stale | ❌ | ❌ | ❌ | ❌ | ✓ Epistemic Lease |
| Breaking-change verdict over a diff | ❌ | ❌ | Partial | ❌ | ✓ per export, consumers named |
| "Did this diff open a sensitive path?" | ❌ | ❌ | ❌ | ❌ | ✓ differential, pre-commit |
| Cost effect published with the losses | ❌ | ❌ | ❌ | ❌ | ✓ −26% round-trips on deep tasks |
Use the other tool when it's the right one: symbol-level edits (rename across files) are an LSP toolkit's home turf — OpenLore is deliberately read-only, and the two compose. Org-wide search across hundreds of repos is a search platform. Just-fast-graph-retrieval is a smaller graph MCP server. And a small, familiar repo with shallow questions is cheaper with your agent's built-in search. OpenLore also exports SCIP, so it sits alongside these tools, not against them.
Comparisons reflect each project's publicly documented capabilities as of July 2026; a correction PR is always welcome.
What it costs
Measured on a fresh clone of ripgrep with published [email protected]:
| What it costs | On ripgrep (232 files) |
|---|---|
| One-time index build | 13.6 s, entirely local — no API key, no network |
| Disk | 27 MB under .openlore/ (gitignorable; rebuildable from source) |
| Per-query latency | ~430 µs p50 in-process via the MCP server |
| Your source code | never leaves the machine — no account, no telemetry (opt-in only) |
| Lock-in | none — delete .openlore/ and nothing about your repo has changed |
Large monorepos take minutes rather than seconds, stated plainly in Known limitations. Platform: Linux and Windows are exercised in CI; macOS is supported.
Fully local — nothing phones home. No account, no network call; your source, the index, and every query stay on your machine. The only diagnostics that exist are opt-in and local-only, off by default and never transmitted:
OPENLORE_TELEMETRY=1records tool calls, agent identity, latency, error messages, decision titles, and lease events to the gitignored.openlore/telemetry/directory, andOPENLORE_LLM_LOGS=1stores prompts and responses (after secret redaction) in the gitignored.openlore/logs/directory. → docs/configuration.md
Languages, Infrastructure-as-Code & contracts
Languages: TypeScript · JavaScript · Python · Go · Rust · Ruby · Java · C++ · Swift · C# · Kotlin · PHP · C · Scala · Dart · Lua · Elixir · Bash — call graphs ride the same primitives for every language. → docs/language-support.md
Infrastructure-as-Code: Terraform/HCL · Kubernetes · Helm · CloudFormation · Ansible · Pulumi · AWS CDK · CDKTF · Dockerfile · Docker Compose · GitHub Actions · Azure Bicep · Serverless Framework — IaC resources project onto the same graph as application code, so orient, search_code, and analyze_impact answer "what's the blast radius of changing this security group / IAM role / base image / CI job?" with zero new tooling. → docs/iac.md
Interface contracts: OpenAPI 3.x · Swagger 2.0 — each declared operation projects onto the same graph, bound to the route handler that serves it and the function that calls it, so orient and analyze_impact cross the API boundary. Matching is literal, and everything unbound is disclosed. → docs/contracts.md
Known limitations
We'd rather you know these up front.
Static analysis only. Polymorphic dispatch, event channels, and route→handler bindings are recovered (provenance-labeled
synthesized). What isn't: reflective invocation with a non-literal target (getattr(o, name)()),eval, and DI/plugin registries with no visible binding — silently absent from the graph.LLM spec quality varies. Generated spec prose reflects the model's understanding — review complex business logic. Structure, format, coverage, and drift are checked deterministically.
Keyword (BM25) search answers first; local semantic follows in the background.
orient/search_codework immediately with no key. Background builds then add on-device vectors (CPU-only, ~23 MB model) when the optional package is installed; opt out with"embedding": { "provider": "none" }.Large monorepos analyze one package at a time after the first full build (
openlore analyze --shard <name>); the initial index is still a full analysis.Incremental updates converge or flag, never silently diverge. When a change exceeds the per-save budget, the rest is marked explicitly stale and self-heals on later edits or a background re-analyze.
Documentation
Start here: the documentation index maps every task to the one canonical page that answers it. The essentials:
| I want to… | Doc |
|---|---|
| Install & wire my agent (one command) | install.md |
| Understand why wiring an agent helps | agent-setup.md |
| See all 83 MCP tools + parameters | mcp-tools.md |
| Run the full CLI reference | cli-reference.md |
Configure .openlore/config.json (incl. enforcement.policy) | configuration.md |
| Choose / configure an LLM provider (optional) | providers.md |
| Fix a setup problem | TROUBLESHOOTING.md |
| Read the benchmark methodology + per-task numbers | AGENT-BENCHMARKS.md |
| Search code by meaning (semantic / GraphRAG) | semantic-search.md |
| Pick the tests a change should run | test-impact-selection.md |
| Find dead code / coverage gaps | reachability-dead-code.md · coverage-gaps.md |
| Detect spec ↔ code drift | drift-detection.md |
| Enforce architecture / import rules | architecture-invariants.md |
| Gate commits / wire CI & PR review | ci-cd.md · preflight.md |
| Understand IaC & cross-domain impact | iac.md · cross-domain-impact.md |
| See declared API contracts in the graph | contracts.md |
| Query across repos (federation) | federation.md |
| Share the index as a bundle | shareable-bundle.md |
| Export to Sourcegraph / SCIP tools | scip-export.md |
| Read the internals | ARCHITECTURE.md · ALGORITHMS.md · PHILOSOPHY.md |
Development
npm install
npm run build
npm run test:run # 5500+ unit tests, one-shot (npm test is watch mode)
npm run typecheckNew contributor? See CONTRIBUTING.md for setup, MCP wiring, and the commit gate. Please also read our Code of Conduct; to report a vulnerability, see SECURITY.md.
Community
If OpenLore saves your agents from re-reading the same files — or catches one risky change before it lands — star the repo. It's the signal that tells us to keep building, and it helps other engineers find it.
⭐ Star to follow along: github.com/clay-good/OpenLore
🐛 Bug or idea? Open an issue.
🤝 Contribute? Start with CONTRIBUTING.md.
Links
docs/mcp-tools.md
MCP Server
openlore mcp starts openlore as a Model Context Protocol server over stdio, exposing static analysis as tools that any MCP-compatible AI agent (Cline, Roo Code, Kilocode, Claude Code, Cursor...) can call directly -- no API key required.
Reading a response
A tool result is a list of text content blocks, and the payload is one block among them. OpenLore's own notes — the freshness (Epistemic Lease) signal, a background-change note from the session ledger, an index self-heal or auto-init disclosure, a panic signal — are each their own block, never concatenated into the payload, so a structured result (JSON, a patch) is never corrupted by them.
A note's position is not fixed: an urgent one is placed before the payload so the agent reads
it first, an informational one after. So do not read content[0] and assume it is the answer.
Either hand every block to the model (what an agent host does, and why this shape exists), or, if
you parse the payload yourself, pick the block that parses:
const payload = result.content
.map(b => b.text)
.find(t => { try { JSON.parse(t); return true; } catch { return false; } });Notes are also identifiable by prefix, but there are two prefix shapes: the disclosures begin
with a bracketed source tag ([openlore freshness], [openlore index]), while a panic signal
begins [PANIC: and its level ([PANIC:ELEVATED], [PANIC:PLANNING], [PANIC:SCOPE]). A host
that filters on [openlore alone will read a panic block as the answer.
When a whole-repository answer exceeds the response byte budget, the payload keeps its shape and
carries a responseBudget receipt instead of being replaced: { trimmed, omitted: { <field>: n }, note }, where each omitted count is exact and counts items dropped from the END of that list
(the tool ranked them least significant). Short lists are served whole and the dominant list is
the one bounded hardest. The receipt never overwrites a field the tool already defines — a tool
with its own truncated or omitted disclosure keeps it unchanged.
One caveat on "pick the block that parses": a few tools return plain text rather than JSON —
get_signatures is the one you are most likely to hit. For those, no block parses, and the
payload is the block that carries no note prefix.
confidenceBoundary.complete — what the answer claims about itself
A conclusion carries a confidenceBoundary saying what it does not know. Its complete flag is
derived, never asserted by the tool: complete: true is impossible in the same response as a
disclosed refusal, cap, fallback, degradation or discarded input. Concretely, complete is false
whenever the boundary itself crossed something (a synthesized-edge reliance, a dynamic-dispatch blind
spot, a stale or degraded index, a repair in flight) or the response carries any registered
disclosure channel — an unverifiable verdict, notAssessed, truncated, baseRefFallback,
changeGranularity.reasons, filePatternMatch with matchedFiles: 0, noPath,
ambiguousCallSites, partialIndex, and the rest of the set in DISCLOSURE_CHANNELS.
So you can read complete as a single gate: true means "this is everything, and nothing was
refused, capped or dropped" — safe to act on, and safe to stop looking.
When it is false, incompleteBecause tells you which part is incomplete: one entry per cause,
each naming the response field that holds the detail.
{ "confidenceBoundary": {
"complete": false,
"incompleteBecause": [
{ "channel": "changeGranularity.reasons",
"detail": "Per-symbol change detection degraded to whole-file granularity for some files (time-cap: 29) — read `changeGranularity`; the changed set is coarser than it looks." }
] } }Two things complete: false does not mean. It is not a quality score, and it is not a reason to
discard the answer — a lower bound is still a sound lower bound. Read the named channel and decide
whether that gap touches the question you asked.
A standing methodology caveat does not flip it. caveats and note mix permanent methodology with
live disclosure, so they are never read as completeness signals; a tool whose live disclosure is prose
declares it separately. That is deliberate: a flag that was always false would carry no information.
Setup
Claude Code -- add a .mcp.json at your project root:
{
"mcpServers": {
"openlore": {
"command": "openlore",
"args": ["mcp"]
}
}
}or for local development:
{
"mcpServers": {
"openlore": {
"command": "node",
"args": ["/absolute/path/to/openlore/dist/cli/index.js", "mcp"]
}
}
}Cline / Roo Code / Kilocode -- add the same block under mcpServers in the MCP settings JSON of your editor.
Recommended lean surface (cost, Spec 25 P1 · Spec 28)
MCP clients send every tool's JSON Schema on every request, so tools the agent never calls are pure per-request overhead. The full surface is 83 tools / ~106 KB / ~27k tokens (estimated) of tools/list. The Spec 14 benchmark showed this prefix is what made openlore lose on small repos — and that a lean, navigation-focused surface flips it to a win (see the Value Scorecard).
The default surface is the substrate preset (the navigation core plus governance and spec-workflow reads), not an extra step: openlore install (and a bare openlore mcp) wires the substrate preset — 15 tools: the navigation graph-traversal core, the three highest-value governance reads (recall, verify_claim, blast_radius), and prepare_spec_generation / prepare_spec_repair. An out-of-box capable MCP agent can therefore obtain a bounded evidence bundle and author specs with its native editor; OpenLore performs no internal LLM call in these composites. The lean navigate-only navigation preset (10 tools) stays a one-flag escape (--preset navigation); the full surface is one explicit opt-in away (--preset full / --all-tools). When the default surface is active, the server advertises breadth once via its instructions channel (no extra tool schemas) so an agent never concludes a capability is absent. To restore the prior all-tools default: openlore install --preset full.
Spec 28 measured how far the server can shrink that prefix, honestly: MCP has no server-driven lazy-schema mechanism (tools/list always returns full schemas), and the lossless server-side byte-lever is only ~2% — the payload is dominated by irreducible per-tool schema structure plus the selection text an agent needs to pick a tool. So the real lever is the client (deferred schemas, below) and tool count (--preset), not byte-shaving. The surface has been trimmed losslessly anyway (shared param descriptions, no boilerplate) and is now bounded by a regression guard so it can't silently bloat. Two ways to get the lean surface, in order of preference:
Deferred schemas (best — keeps every tool available). If your client supports it (Claude Code:
alwaysLoad: false), advertise tool names cheaply and load a tool's schema only when it's used. See the two-server setup — you keep all 83 tools without paying their schema cost up front.--preset navigation(server-side, navigation-only — the lean escape below the default). A bareopenlore mcp/openlore installwires the widersubstratedefault (see below);--preset navigationis the one-flag way down to the navigate-only core: a graph-traversal surface of 10 tools (orient, search_code, get_subgraph, trace_execution_path, analyze_impact, suggest_insertion_points, get_function_skeleton, get_landmarks, get_map, find_path). It is exactly the configuration the benchmark measured (−7%→−21% cost, −26% round-trips on deep traces). Note it omits the governance tools (record_decision,check_architecture, inventories, and thesubstratedefault's governance reads), so if you use the decision gate or architecture checks during a session, prefer option 1 (deferred schemas) or wire a governance-bearing preset (--minimal, or the full surface with--preset full).
The tool list and schemas are emitted in a fixed, deterministic order with no per-request variation, so the provider KV-cache holds the surface and its cost drops sharply after the first call (guarded by a regression test).
Measured standing context cost
OpenLore measures the exact live tools/list result that each preset places in context before the
first call: names, descriptions, input/output schemas, annotations, and any future wire fields. The
offline utf8-bytes-div-4-v1 approximation is
ceil(UTF-8 bytes / 4): it is a stable regression unit, not a model-specific billing claim.
CI fails when a measured value exceeds its reviewed budget, and this table is checked against the
live registry.
<!-- standing-context-cost:start -->
| Preset | Tools | Measured tokens | Budget |
|---|---|---|---|
minimal | 6 | 2,854 | 2,950 |
navigation | 10 | 3,616 | 3,800 |
memory | 3 | 1,510 | 1,610 |
verify | 5 | 2,089 | 2,220 |
federation | 10 | 3,912 | 4,100 |
coordination | 8 | 3,562 | 3,720 |
substrate | 15 | 5,248 | 5,500 |
full | 83 | 27,338 | 28,400 |
<!-- standing-context-cost:end -->
Choose MCP or the command line
MCP and the command line are both first-class, supported delivery paths; neither supersedes or
deprecates the other. Use MCP when an agent should decide mid-conversation when to retrieve a
conclusion. Use openlore CLI commands for scripts, CI, or shell-capable agents that can retrieve
on demand and want zero standing context cost before invocation. Paired capabilities route through
the same conclusion implementation. Successful semantic conclusions agree before transport;
protocol error envelopes, human rendering, and MCP's final byte cap may differ.
Rejected arguments are a tool result, not a protocol error. A call with a missing, unknown, or
wrongly typed parameter returns isError: true with text that names the parameter, the expected
shape, and a corrected example call, so the model can retry. Nothing runs, and nothing is written.
The shared input projection is guarded. MCP additionally exposes orient.rankBy,
search_code.mode, blast_radius.depth / maxSymbols, and
report_coverage_gaps.directResolvedOnly. The CLI alone exposes --allow-base-fallback for
impact-certificate and certify-public-surface; these controls are declared asymmetries, not
silent parity claims.
Capability families (one substrate, two faces)
OpenLore is one structural substrate with two faces — a read face that navigates the graph and a write/check face that anchors facts and weighs changes — not two products (architecture spec: UnifiedStructuralSubstrate). To keep a wide surface selectable rather than overwhelming, every tool declares exactly one of six closed capability families (mcp-quality: CapabilityFamilyTaxonomy), the way it already declares conclusion-vs-topology. The family is emitted in each tool's MCP annotations.family, so a client can present the full surface grouped by family — an agent chooses among ~6 families and a handful of tools per family, never the flat registry:
| Family | What it answers | Examples |
|---|---|---|
navigate | read the structural/spec graph, return a conclusion | orient, find_path, analyze_impact, select_tests, find_dead_code, get_map, the inventories/specs |
change | reason about a specific diff or change set | structural_diff, blast_radius, change_impact_certificate, certify_public_surface, certify_service_contract, briefing_since |
remember | record & recall durable, code-anchored facts | remember, recall, record_decision + its lifecycle |
verify | settle a claim before it reaches a human | verify_claim |
coordinate | schedule & deconflict parallel work | plan_parallel_work, map_in_flight_conflicts, declare_footprint |
federate | cross-repo / spec-store conclusions | federation_status, spec_store_status, working_set_context |
Adjacent tools within a family are not merged when each returns a separately-useful conclusion (NoRedundantConclusions); instead each states its distinct question and names its near-sibling in its own description (e.g. find_clones ↔ get_duplicate_report, select_tests ↔ report_coverage_gaps, blast_radius ↔ structural_diff ↔ change_impact_certificate, plan_parallel_work ↔ map_in_flight_conflicts). A CI guard (tool-contract.test.ts) fails if a tool forgets a family or an adjacent tool fails to cross-reference its sibling.
--preset substrate — navigation, spec preparation, and governance reads; now the default. It combines the navigation graph-traversal core, the bounded read-only prepare_spec_generation and prepare_spec_repair composites, and the three highest-value governance reads — recall (what is known about the code I'm touching), verify_claim (settle an assertion before it reaches a human), and blast_radius (weigh a diff). It contains reads only: no internal LLM or file writes, no remember/record_decision write, and no commit gate. Those write capabilities stay opt-in via --preset memory/minimal/full. The active out-of-box default is substrate because it exposes the core workflows while staying below the 21,000-byte schema budget. The lean navigate-only navigation preset remains a one-flag escape (--preset navigation).
Watch mode (keep search_code and orient fresh)
By default the MCP server reads llm-context.json from the last analyze run. With --watch-auto, it also watches source files for changes and incrementally re-indexes signatures and call-graph edges so search_code, orient, and graph queries reflect your latest edits without waiting for the next commit.
Add --watch-auto to your MCP config args:
{
"mcpServers": {
"openlore": {
"command": "openlore",
"args": ["mcp", "--watch-auto"]
}
}
}The watcher is on by default — it starts automatically on the first tool call
(no hardcoded path needed) and keeps the analysis fresh as you edit. To disable it,
start the server with openlore mcp --no-watch-auto.
Freshness is O(change), not O(repo) (Spec 13.1): per-file save events are coalesced
into a single batched flush, the patched signatures are handed directly to the MCP read
cache (so the next tool call is a cache hit, not a cold re-parse of llm-context.json),
and the vector index is updated with row-level ops rather than a full-table rewrite.
A bulk event above the watcher threshold (branch switch / rebase / formatter) marks the
affected region explicitly stale and hands it to one background full rebuild instead of
reloading the node table and re-parsing caller closures once per changed file. Cold-start
analysis runs in a child process, and watcher startup does not gate the first tool call. On large
repos (> 5000 source files) live embedding auto-degrades to signatures-only (logged once);
embeddings then refresh at commit. Set OPENLORE_WATCH_DEBUG=1 for per-file stderr detail
(default is one summary line per batch).
The call graph is kept incrementally fresh: each save re-resolves the changed file's
reverse-dependency closure — its direct callers plus any prior non-callers whose
previously-unresolved calls a newly-added symbol should now bind — so the affected region
matches what analyze --force would produce. A bounded per-save work budget
(INCREMENTAL_CLOSURE_BUDGET, default 40 files) keeps a hub edit light; when a change's
closure exceeds it, the un-recomputed files are marked explicitly stale in the graph
metadata (freshness verdicts over their symbols report non-authoritative, never silently
wrong) and self-heal as later edits touch them. A full openlore analyze --force (e.g. the
post-commit hook) recomputes everything and clears the stale region.
| Option | Default | Description |
|---|---|---|
--watch-auto | on | Auto-detect project root from first tool call |
--no-watch-auto | — | Disable the auto-watcher (one-shot tool calls) |
--watch <dir> | — | Watch a fixed directory (alternative to --watch-auto) |
--watch-debounce <ms> | 400 | Idle delay before a coalesced flush after a change |
--watch-no-embed | off | Signatures-only: skip live re-embedding (refresh at commit) |
Cline / Roo Code / Kilocode
For editors with MCP support, after adding the mcpServers block to your settings, download the slash command workflows:
mkdir -p .clinerules/workflows
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-analyze-codebase.md -o .clinerules/workflows/openlore-analyze-codebase.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-check-spec-drift.md -o .clinerules/workflows/openlore-check-spec-drift.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-plan-refactor.md -o .clinerules/workflows/openlore-plan-refactor.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-execute-refactor.md -o .clinerules/workflows/openlore-execute-refactor.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-implement-feature.md -o .clinerules/workflows/openlore-implement-feature.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/examples/cline-workflows/openlore-refactor-codebase.md -o .clinerules/workflows/openlore-refactor-codebase.mdAvailable commands:
| Command | What it does |
|---|---|
/openlore-analyze-codebase | Runs analyze_codebase, summarises the results (project type, file count, top 3 refactor issues, detected domains), shows the call graph highlights, and suggests next steps. |
/openlore-check-spec-drift | Runs check_spec_drift, presents issues by severity (gap / stale / uncovered / orphaned-spec), shows per-kind remediation commands, and optionally drills into affected file signatures. |
/openlore-plan-refactor | Runs static analysis, picks the highest-priority target with coverage gate, assesses impact and call graph, then writes a detailed plan to .openlore/refactor-plan.md. No code changes. |
/openlore-execute-refactor | Reads .openlore/refactor-plan.md, establishes a green baseline, and applies each planned change one at a time -- with diff verification and test run after every step. Optional final step covers dead-code detection and naming alignment (requires openlore generate). |
/openlore-implement-feature | Plans and implements a new feature with full architectural context: architecture overview, OpenSpec requirements, insertion points, implementation, and drift check. |
/openlore-refactor-codebase | Convenience redirect that runs /openlore-plan-refactor followed by /openlore-execute-refactor. |
All six commands ask which directory to use, call the MCP tools directly, and guide you through the results without leaving the editor. They work in any editor that supports the .clinerules/workflows/ convention.
Claude Skills
For Claude Code, copy the skill files to .claude/skills/ in your project:
mkdir -p .claude/skills
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/skills/claude-openlore.md -o .claude/skills/claude-openlore.md
curl -sL https://raw.githubusercontent.com/clay-good/openlore/main/skills/openspec-skill.md -o .claude/skills/openspec-skill.mdOpenLore Skill (claude-openlore.md) — Code archaeology skill that guides Claude through:
Project type detection and domain identification
Entity extraction, service analysis, API extraction
Architecture synthesis and OpenSpec spec generation
OpenSpec Skill (openspec-skill.md) — Skill for working with OpenSpec specifications:
Semantic spec search with
search_specsList domains with
list_spec_domainsNavigate requirements and scenarios
Tools
Most tools run on pure static analysis — no LLM quota consumed. Exceptions: record_decision consolidation (LLM optional, falls back to diff extraction) and sync_decisions (writes to files).
Run analysis
| Tool | Description | Requires prior analysis |
|---|---|---|
analyze_codebase | Run full static analysis: repo structure, dependency graph, call graph (hub functions, entry points, layer violations), and top refactoring priorities. Results cached for 1 hour (force: true to bypass). | No |
get_call_graph | Hub functions (high fan-in), entry points (no internal callers), and architectural layer violations. Supports TypeScript, JavaScript, Python, Go, Rust, Ruby, Java, C++, Swift. | Yes |
get_signatures | Compact function/class signatures per file. Filter by path substring with filePattern. Useful for understanding a module's public API without reading full source. | Yes |
get_duplicate_report | Detect duplicate code: Type 1 (exact clones), Type 2 (structural -- renamed variables), Type 3 (near-clones with Jaccard similarity >= 0.7). Groups sorted by impact. | Yes |
find_clones | Find existing clones of ONE query -- a symbol (a function in the index) or a snippet (raw code, even before you write it) -- ranked exact > structural > near. The edit-time "does this already exist? reuse it" question, scoped, where get_duplicate_report is the whole-repo audit. Reuses the same detector; one-vs-all so it finds near-clones even where the whole-repo O(n²) pass is skipped. Opt-in (--preset full). | Yes |
locate_symbol_span | The read-only, staleness-checked edit LOCATION for a known symbol. Resolves a symbol (name or name::path) and returns its span (startByte/endByte UTF-16 offsets + 1-based startLine/endLine) plus a freshness verdict: fresh (index still matches the file -- offsets are safe, with a contentHash integrity token), stale (file changed since analysis -- a re-analyze hint and no offset, refusing to serve a location it can't vouch for), ambiguous/not-found (the name::path candidate list, never a fuzzy guess). Where suggest_insertion_points ranks where to ADD code, this pinpoints an existing symbol's current bytes to modify. Read-only -- the host applies the edit with its own tool; no write face, no shell. Computed live from the cached graph + a re-read of the one file the symbol spans (no new artifact). Opt-in (--preset full). | Yes |
analyze_error_propagation | Error-flow conclusion for TS/JS/Python/Java/C# exceptions and Go returned errors plus panic/recover. Go emits errorModel: go-value and value-shaped escapes/handledInternally; checked and discarded results are correlated to the resolved callee's error-result position, and recovery is claimed only for a provable unconditional earlier defer with no replacement panic. Deferred-literal panics execute during unwind; goroutine-literal panics are disclosed as asynchronous boundaries, not caller-stack propagation. Typed handlers are exact-name lower bounds. Unanalyzable callees, discarded/ambiguous Go results, complex unwind ordering, finally/resource cleanup (including C# using), and traversal limits are disclosed in boundaries. Opt-in (--preset full). CLI: openlore error-propagation. | Yes |
Explore & Navigate
| Tool | Description | Requires prior analysis |
|---|---|---|
orient | Single entry point for any new task. Given a natural-language task description, returns relevant functions with stored declaration startLine, source files, spec domains, call neighbourhoods, insertion-point candidates, matching spec sections, and ranked suggestedTools. Files in scope that are generated, vendored, or lockfiles are marked in generatedFiles with their literal source and regenerate command (generated files). Start here. When a file in scope, or a route file that names a function in scope, has an indexed route that an OpenAPI operation declares, contracts names the operation, its spec file:line, and its required parameters and body properties. A route matches by method and full path; without the servers base path only when the path has a literal segment and is unique across specifications (matchedWithoutBasePath). When a resource in the graph deploys a function in scope, infrastructure names that resource and, for the deployed function only, each environment variable it reads with the infrastructure sites that set it (undeclared when nothing the scan read sets it, with scanBoundaries naming what it could not read). Nothing is read for this field when no resource runs a function in scope. | Yes (+ embedding) |
search_code | Natural-language semantic search over indexed functions. Returns the closest matches by meaning with a self-describing scoreKind, declaration startLine when stored, call-graph neighbourhood enrichment, and spec-linked peer functions. Falls back to BM25 keyword search when no embedding server is configured. | Yes (+ embedding) |
explain_retrieval_miss | Full-preset, read-only diagnostic for one exact symbol, file, or canonical requirement ID. Reuses the ordinary requested-limit candidate window and reports a surfaced rank/evidence or one closed miss cause. It never enumerates all misses. | Yes |
suggest_insertion_points | Semantic search over the vector index to find the best existing functions to extend or hook into when implementing a new feature. Returns ranked candidates with role and strategy. Falls back to BM25 keyword search when no embedding server is configured. | Yes (+ embedding) |
get_subgraph | Depth-limited subgraph centred on a function. Direction: downstream (what it calls), upstream (who calls it), or both. Output as JSON or Mermaid diagram. | Yes |
trace_execution_path | Find all call-graph paths between two functions (DFS, configurable depth/max-paths). Use this when debugging: "how does request X reach function Y?" Returns the shortest path (named shortestPathFound, with a truncated receipt, when enumeration stopped at maxPaths), all paths sorted by hops, and a step-by-step chain whose callsNext entries preserve caller identity and every stored call-site line for parallel edges. | Yes |
get_function_body | Return the exact source code of a named function in a file. Pass focus with required focusKind to return only stored variable def/use or callee call-site lines. Variable evidence carries data-flow precision; call evidence carries resolution confidence. Omit both for the unchanged full-body response. | No (focus requires analysis) |
get_function_skeleton | Noise-stripped view of a source file: logs, inline comments, and non-JSDoc block comments removed. Signatures, control flow, return/throw, and call expressions preserved. Returns reduction %. | No |
get_file_dependencies | Return the file-level import dependencies for a given source file (imports, imported-by, or both). | Yes |
get_architecture_overview | High-level cluster map: roles (entry layer, orchestrator, core utilities, API layer, internal), inter-cluster dependencies, global entry points, and critical hubs. No LLM required. | Yes |
get_minimal_context | The minimum context to safely modify a function: its signature + body, direct callers and callees (signatures only), and which test files cover it. Cheaper than reading whole files. | Yes |
get_cluster | All functions in the same community as a given function — label-propagation clusters of tightly-coupled code computed at analyze time. | Yes |
search_unified | Search code functions AND spec requirements in one call, cross-boosting results — "where is X implemented and what does the spec say about it?" | Yes |
Stack inventory
| Tool | Description | Requires prior analysis |
|---|---|---|
get_route_inventory | All detected HTTP routes with method, path, handler, and framework. Supports Express, NestJS, Next.js, FastAPI, Flask, and more. | Yes |
get_schema_inventory | ORM schema tables with field names and types. Supports Prisma, TypeORM, Drizzle, and SQLAlchemy. | Yes |
get_ui_component_inventory | Detected UI components with framework, props, and source file. Supports React, Vue, Svelte, and Angular. (Alias: get_ui_components — the prior name, still accepted.) | Yes |
get_env_vars | Env vars referenced in source code with required (no fallback) and hasDefault flags. Supports JS/TS, Python, Go, and Ruby. | Yes |
analyze_env_impact | The configuration analogue of analyze_impact: "what breaks if I remove this env var?". Given an env var name, the line-precise readSites (file/line/enclosing function; a read outside any function is module-level, disclosed), the affectedFunctions (upstream callers that transitively reach a read -- the blast radius), the reachingTests to run, declaredInEnvFile, the infrastructure files that set it (declaredBy: Kubernetes, compose, Dockerfile, Terraform/OpenTofu, CloudFormation/SAM, GitHub Actions, Serverless; key and location only, never the value; undeclared-in-corpus when none does, sources it cannot list in opaqueEnvSources; see IaC), and per-site required (no site-local fallback ??/` | |
get_middleware_inventory | Detected middleware with type (auth/cors/rate-limit/validation/logging/error-handler) and framework. | Yes |
get_external_packages | All direct external dependencies from package manifests (npm package.json, pypi pyproject.toml/requirements.txt, cargo Cargo.toml, go go.mod) — each with name, version, and ecosystem. | Yes |
Code quality
| Tool | Description | Requires prior analysis |
|---|---|---|
get_refactor_report | Prioritized list of functions with structural issues: unreachable code, hub overload (high fan-in), god functions (high fan-out), SRP violations, cyclic dependencies. | Yes |
get_critical_hubs | Highest-impact hub functions ranked by criticality. Each hub gets a stability score (0-100) and a recommended approach: extract, split, facade, or delegate. | Yes |
get_god_functions | Detect god functions (high fan-out, likely orchestrators) in the project or in a specific file, and return their call-graph neighborhood. Use this to identify which functions need to be refactored and understand what logical blocks to extract. | Yes |
analyze_impact | Deep impact analysis for a function: fan-in/fan-out, upstream/downstream chains with bounded stored callSites receipts, risk score (0-100), blast radius, and recommended strategy. | Yes |
blast_radius | Pre-flight structural blast-radius briefing for the current staged/working diff (advisory). Pure orchestration of existing analyses — no LLM: affected callers/layers and hubs (analyze_impact) of the symbols the diff actually changed (normalized per-symbol hashes; formatting and comments are not changes, and any file kept whole is named with its reason in changeGranularity), tests to run (select_tests), and the anchored memories/decisions the diff will drift/orphan plus specs it will make stale (check_spec_drift), changed files that are generated or vendored (generated, see generated files), references the diff adds that resolve to nothing (phantomReferences, see phantom references), and env vars the diff stops reading that infrastructure files still set (envDeclarations, see IaC). One conclusion-shaped briefing, never a graph. CLI: openlore blast-radius (+ --install-hook for an advisory pre-commit hook). contracts names the OpenAPI operations served by routes in the changed files. | Yes |
get_low_risk_refactor_candidates | Safest functions to refactor first: low fan-in, low fan-out, not a hub, no cyclic involvement. Best starting point for incremental, low-risk sessions. | Yes |
get_leaf_functions | Functions that make no internal calls (leaves of the call graph). Zero downstream blast radius. Sorted by fan-in by default -- most-called leaves have the best unit-test ROI. | Yes |
| (all) | A response may carry followUp: at most two receipts { tool, trigger: { field, value }, message } naming the next tool a field in this response warrants — search_code with a hub top hit → analyze_impact, find_dead_code with low-confidence candidates → verify_claim, blast_radius with specs that may go stale → check_spec_drift. Advisory, never on an error. | — |
verify_change | The pre-commit action receipt: flattens the diff-based signals into one severity-ranked checklist — each item names its subject, the producing check, a severity, and the single next action — plus the tests to run. Composes blast_radius (which already folds in select_tests + spec/memory/decision drift), structural_diff (removed/re-signed functions, new calls into deprecated code), the generated-file guard (generated-file-edited: a generated file or lockfile edited without its source, naming the source and regenerate command), and the phantom-reference check (unresolved-internal-import, unresolved-internal-symbol, undeclared-dependency, unpinned-dependency: imports, named exports, and packages the diff adds that resolve to nothing, with no network request), and structural_diff's check-weakening findings (a weakened test, suppression, discarded error, or check config, with the code the test reached); no LLM; beyond the composed conclusions it reads file headers, manifests, lockfiles, and the base revision of changed files. Advisory and grader-not-author: it names what to fix and run, but runs and edits nothing. Its sibling blast_radius returns the full structured briefing; this is the flattened next-action list for a propose-verify-correct loop. Opt-in --preset verify. CLI dispatch via the MCP tool. Also request bodies at call sites on lines the diff adds or changes (and in files not yet added to git) that lack a property their OpenAPI operation requires (contract-payload-missing-required). | Yes |
structural_diff | A graph diff (complement to git diff) between two states (working tree vs a ref, or two refs): what changed structurally and whose callers are now stale. Calls the diff adds into a symbol marked deprecated (JSDoc @deprecated, Go Deprecated:, Python @deprecated) are listed in deprecatedCalls with the target's replacement hint and how the target was resolved (changed-files, index-edge, or unique-name; nothing is guessed), each an advisory deprecated-symbol-use finding. checkWeakening reports, against the merge-base with the base or default branch, a test removed, skipped, or stripped of assertions, an expected value edited, a suppression or a discarded error added, or a check config relaxed (check weakening), each an advisory finding naming the code the test reached. | Yes |
detect_changes | Detect recently changed functions (git diff vs a base ref) and rank them by blast radius (fan-in + transitive reach). | Yes |
get_change_coupling | Co-change coupling mined from git history (not the call graph): what changes together with a file, and the most volatile code. | Yes |
get_health_map | One-call structural health dashboard: hubs, god functions, layer violations, and volatile files, ranked by severity. A good starting point on an unfamiliar repo. Surfaces an indexIntegrity block when the on-disk index did not reconcile against its build-time attestation (degraded / mismatched), so the health signals are not presented as complete over a broken index. complexityTrend re-parses each hotspot (complexity at or above 10, in a file with churn; at most 10 files) at its last 4 non-merge, non-bulk commits and labels the samples rising / falling / flat / mixed (no score, no size threshold); fewer than 3 samples withhold the label. A rising function at or above the threshold is an advisory declining-health finding. | Yes |
get_surprising_connections | Unexpected structural coupling — cross-community edges, peripheral-to-hub calls, cross-test-boundary dependencies. Spot accidental coupling before a refactor. | Yes |
report_coverage_gaps | Important code with no reaching test, ranked by hub/chokepoint significance — the structural inverse of select_tests over the whole graph, no runtime/coverage tool. SOUND DIRECTION ONLY: reports "no reaching test", never claims a symbol is "tested" (reachable-from-a-test ≠ behavior-verified). A gap with no caller at all is labeled also-dead (distinct from find_dead_code); an untested entry point is reported as untested-not-dead. Scope to a diff (changedSymbols/diffRef) or region (filePattern). Distinct from get_test_coverage (spec-tag based). Full surface only (opt-in --preset full); not in the lean default. CLI: openlore coverage-gaps. | Yes |
certify_public_surface | With no base ref, returns the package's public surface (exported symbols + signatures); with a base ref, a deterministic breaking-change verdict for the working-tree diff — each changed export classified breaking / non-breaking / potentially-breaking (removed/renamed export, added required param, narrowed param/return type, reduced visibility) with stable rule codes on every breaking or potentially-breaking change and every added export (export-removed, param-type-narrowed, …, signature-unprovable, export-added), a suggestedBump (major when anything breaks; withheld as null with a reason when compatibility is unproven; otherwise minor for an added export, else patch — an added optional parameter or widened return type alone suggests patch), and a registered governance finding per breaking rule code (error) and per signature-unprovable (warning) so the caller that runs the tool can gate individual rules with enforcement.policy (openlore enforce does not run it), each breaking one paired with the consumers it breaks and split into breaking-consumed or breaking-unconsumed-in-index (never "safe"; pass federation to also count indexed sibling repos), plus an overall summary. Breakages accepted with a justification in the checked-in .openlore/public-surface-baseline.jsonl (written by openlore certify-public-surface --accept) are listed under baseline.accepted instead of findings[]; an acceptance tied to a superseded decision is stale and reports again. Conservative by construction: a change it cannot prove compatible is potentially-breaking, never silently safe (no type checker, no build). A renamed export is reported as a rename (via symbol-identity continuity), not remove+add; external/unindexed consumers are disclosed as a known-unknowable boundary. Signature classification: TypeScript/JavaScript/Python (others fail-soft, surface membership only). Distinct from change_impact_certificate (paths into a surface) — this certifies the exported contract's shape. Full surface only (opt-in --preset full); not in the lean default. CLI: openlore certify-public-surface. | Yes |
certify_service_contract | Certifies OpenAPI 3.x / Swagger 2.0, protobuf v3 and GraphQL SDL contracts against the code. With no base ref: the operations each specification declares and two-way parity with the indexed route handlers — declared but not served (contract-declared-unimplemented), and served under a path the specification covers but not declared (contract-implemented-undeclared); parity is assessed: false with a reason when no route handler is indexed. With a base ref: a closed-table verdict for each changed operation, parameter, request property, or success-response property against the merge-base — breaking (removed operation, added required parameter or request property, made required, changed type, response property removed or made optional), dangerous (deprecated operation, widened response type), non-breaking (additions, widened request type), or potentially-breaking (any other schema difference: constraints, nested schemas, oneOf/anyOf, external $ref, status codes — found by hashing what the rules do not compare) — each breaking or dangerous one joined to the client call sites in this repository whose method and literal path match (contract-breaking), plus a suggestedBump (withheld when compatibility is unproven). A specification it cannot read is listed under notAssessed, never as unchanged; callers in other repositories are a disclosed boundary. Protobuf v3 (.proto) is read too, with its own rows in the table: fields are matched by NUMBER (a rename is dangerous, a new number breaking), a removed field is breaking unless its number is reserved (dangerous), reusing a reserved number is breaking, and RPCs removed, retyped or with changed streaming are breaking; gRPC client call sites are not read, so a protobuf finding names no consumer. GraphQL SDL is read too, as one schema merged across files, with variance-aware rows: an output may only become non-null and an input only optional; removed operations, fields, arguments, enum values and union members, a required argument (or one that lost its default) and an output made nullable are breaking; an added enum value, union member or implemented interface is dangerous; a changed directive is potentially-breaking; GraphQL client operations are not read, so a GraphQL finding names no consumer. Advisory; gate a code with enforcement.policy. Full surface only (--preset full). CLI: openlore certify-service-contract. payload: at each in-repo call site of an operation whose body requires properties, a literal body (an object, or JSON.stringify of one, in fetch or axios post/put/patch) missing one, or a required body not sent, is a contract-payload-missing-required finding; any other body (a variable, a spread, a comment or regular expression inside the call, a fetch wrapper, another client) is listed as not assessed. With a base ref, each consumer of a breaking or dangerous change lists the tests that reach the function holding the call (tests, testsTotal), or why they were not computed (testsNotComputed). | Yes |
get_style_fingerprint | A descriptive, deterministic idiom profile measured during the AST walk (no second parse, no LLM): per language, the dominant choice for a fixed counter set — function form (arrow vs. declaration vs. method), binding (const vs. let), conditional (ternary vs. if), async (await vs. .then), string (template vs. concatenation), function-naming case — as { dominant, ratio, samples }. Repository profile by default; communityId for a region, filePath for one file. Honest by construction: a counter below a fixed evidence floor, or one the language/formatter enforces (e.g. Go's visibility-by-case → functionNaming reports an enforced null), withholds its ratio rather than reporting a misleading or tautological value. Descriptive, not prescriptive — it measures what the code is, emits no lint judgment, and blends nothing into a composite style score. Languages: TypeScript / JavaScript / Python / Go (others fail-soft, no counters). orient also carries a compact regionStyle summary for the area in scope. Full surface only (opt-in --preset full); not in the lean default. CLI: openlore style-fingerprint. | Yes |
briefing_since | A catch-up briefing: given a base ref, the changed production symbols since it, ranked into a fixed tier order — surprising-change (a high-fan-in hub whose file rarely changed before) > hub-change (a broad high-fan-in/high-fan-out hub) > chokepoint-change (a high-fan-in funnel) > ordinary-change. Unlike blast_radius / change_impact_certificate (which brief your own pending diff), this briefs everything that moved since the ref — the reviewer / returning-engineer / onboarding lens. Tiers come entirely from existing classifiers (landmark-signals hub/orchestrator/chokepoint + the volatilityLevel churn classifier) plus raw evidence (fan-in, fan-out, prior churn) — no weighted score, no new tuning constant. Honest by construction: changed symbols are exact where both revisions hash cleanly — a formatting- or comment-only edit is not a change, and a rename is listed under carried — while a file kept whole (module-level change, parse errors, no native parse tree, …) is named with its reason in changeGranularity; the surprising-change label is withheld when history is too shallow (< 2 non-bulk commits) to say "rarely changed before", and withheld PER FILE for a file added (or renamed into its path) in the briefed range with no pre-base churn there — a brand-new file's zero churn is not stability, so its symbols are still briefed one tier lower with the withholding stated per entry and counted in withholding; the hub-derived tiers are likewise withheld from a function-local helper (a function nested inside another with every caller inside it — its fan-in is internal to one body, so the significance belongs to the enclosing symbol), which ranks ordinary-change with its hub label and fan-in kept as evidence; a bounded briefing carries a truncation receipt (omitted count + lowest tier) and never drops a higher tier for a lower one; a silent base-ref fallback is disclosed (an unresolvable baseRef reports baseRefFallback instead of silently briefing against main); and the file-path-exact churn join (git does not follow renames) is caveated when it could over-flag a just-renamed file as surprising; and the scope is hand-authored source code — IaC resources and generated/vendored files are excluded (their change-impact has its own lens), the same candidate set report_coverage_gaps ranks. Grouped by region, with the tests to run for the whole change set (via select_tests). The cursor is the base ref, never wall-clock time. Full surface only (opt-in --preset full); not in the lean default. CLI: openlore briefing-since. | Yes |
get_handoff_briefing | The succession briefing for a fresh context (after compaction, a cleared session, another machine): the in-flight change computed from the repository, never a transcript. Touched symbols (working tree, plus those this session committed when a session ledger is live) with callers; open openspec/changes naming them with unchecked tasks quoted; tests that reach them; anchored memories and decisions in scope (orphaned withheld, drifted flagged); specs that may go stale; uncommitted files and the index lease. Every element carries expand (the call that returns its detail); a budget trims the least central sections first, with receipts. Deterministic: the same state gives the same bytes; a clean tree says nothing is in flight. Unlike blast_radius (pending diff for review), briefing_since (others' landed changes) and orient (session start). Opt-in --preset full; CLI openlore handoff [--json]; pushed after compaction by the after-compact hook. | Yes |
Specs
| Tool | Description | Requires prior analysis |
|---|---|---|
get_spec | Read the full content of an OpenSpec domain spec by domain name. | Yes (generate) |
get_mapping | Requirement->function mapping produced by openlore generate. Shows which functions implement which spec requirements, confidence level, and orphan functions with no spec coverage. | Yes (generate) |
check_spec_drift | Detect code changes not reflected in OpenSpec specs. Compares git-changed files against spec coverage maps. Issues: gap / stale / uncovered / orphaned-spec / adr-gap. | Yes (generate) |
search_specs | Semantic search over OpenSpec specifications to find requirements, design notes, and architecture decisions by meaning. Also searches ADR files (decisions/adr-*.md under the configured OpenSpec root) indexed under domain decisions. Returns linked source files, a self-describing scoreKind, and index freshness (builtAt plus changed authoritative files) for graph highlighting and staleness checks. Use this when asked "which spec covers X?" or "where should we implement Z?" or "what decisions were made about Y?". Requires a spec index built with openlore analyze or --reindex-specs. | Yes (generate) |
list_spec_domains | List all OpenSpec domains available in this project. Use this to discover what domains exist before doing a targeted search_specs call. | Yes (generate) |
audit_spec_coverage | Parity audit: uncovered functions (in call graph, no spec), hub gaps (high fan-in + no spec), orphan requirements (spec with no implementation found), and stale domains (source changed after spec). Run before starting a feature to understand coverage health. No LLM required. | Yes (analyze) |
generate_tests | Generate spec-driven test files from OpenSpec scenarios — vitest, playwright (JS/TS), pytest (Python), gtest/catch2 (C++), junit (Java/Kotlin), gotest (Go). | Yes (generate) |
get_test_coverage | Which OpenSpec scenarios have test coverage — scans test files for // openlore: / # openlore: tags (added automatically by generate_tests). | Yes (generate) |
get_language_support | The deterministic per-language capability matrix (signatures, callGraph, testDetection, complexity, imports, cfgOverlay, typeInference, receiverResolution, styleFingerprint, iacProjection, iacCodeBinding, contractSchemas, crossServiceHttp, errorPropagation, dynamicBoundary, literalReflection, messageTopology) for the repo's detected languages — or, with a language name, that one language (a pure registry lookup; an unknown language returns an honest all-unsupported record). Vue, Svelte, and Astro names or extensions return recognized script-container records with their JS/TS extraction scope and remaining framework boundaries. Tells you whether a quiet structural result means "nothing found" or "this language is only partly supported". Fail-soft: an unsupported capability yields nothing, never a guess. Full surface only (opt-in --preset full); not in the lean default. | Repo mode: yes; named mode: no |
Decisions
| Tool | Description | Requires prior analysis |
|---|---|---|
record_decision | Record an architectural decision before writing code. Triggers background consolidation immediately — by commit time, decisions are already verified and the gate adds no LLM latency. | No |
list_decisions | List decisions in the store, optionally filtered by status (draft, consolidated, verified, approved, synced, phantom). | No |
approve_decision | Approve one or more decisions by ID, marking them ready to sync into specs and ADRs. | No |
reject_decision | Reject a decision by ID with a reason. Rejected decisions are excluded from sync. | No |
sync_decisions | Write approved decisions into OpenSpec spec.md files (as requirements) and create ADR files in openspec/decisions/. Append-only — never rewrites existing content. After sync, inactive decisions (synced/rejected/phantom) are purged from the store — their content lives in ADRs and git. Pass dryRun: true to preview. | No |
Memory (opt-in, --preset memory)
Durable, code-anchored notes that self-invalidate when the code they describe moves. Registered only under openlore mcp --preset memory.
| Tool | Description | Requires prior analysis |
|---|---|---|
remember | Persist a durable, code-anchored memory (invariant / gotcha / rationale). Anchor it to a symbol and/or file so it self-invalidates when that code changes. An anchor's optional span (exact text inside the symbol, at most 2,000 characters) narrows it to that text: while the index is current for the file, only an edit to the span drifts the memory, the span is found again wherever it moves in the symbol (CRLF and LF line endings match each other), and a span that then occurs more than once orphans the memory with its candidate lines. A span that does not occur exactly once at record time is not stored, and the result says why (spanNotRecorded). To keep renames working, analyze records a span-anchored symbol's last-analyzed body on its anchors, so notes.json changes when such a symbol changes. Re-recording the same content+anchor updates in place; supersedes retires a prior memory. Optional trigger (one of fileGlob, symbolPattern — globs support * ? ** — specDomain, withinHops) pushes the note into orient / blast_radius briefings as injectedMemories, each with the predicate that fired and its freshness verdict; pinned pushes it into every full orient briefing. The prompt-hook and Pi context-injection blocks show pushed notes as short, budget-gated lines. At most 10 are pushed, most specific first; credentials are redacted and instruction-shaped content is withheld. Optional claims (at most 10, in verify_claim's grammar: { kind, subject, object? }) are the structural facts the memory rests on; each must be confirmed now, or nothing is stored and the result returns every claim's verdict (claimVerdicts). | Yes |
recall | Recall code-anchored memories (notes + decisions) for a task with a freshness verdict — fresh, drifted (verify), or orphaned (never served as authoritative). Each anchor carries an outcome: silently-carried (unchanged where it resolves), re-pointed-with-provenance (carried across a rename or move), or needs-human-reselection (lost or ambiguous, with a reselectReason); a drifted anchor that was not carried has none. Each returned note that needs reselection is also a memory-anchor-lost finding in findings. A note's stored claims are checked again against the current graph (evidence-holds / evidence-refuted / evidence-unverifiable, each with the verify_claim reason and receipt); a note with a refuted claim moves to evidenceRefuted, and one with a claim that can no longer be checked to evidenceUnverifiable, so an unchanged anchor no longer hides a fact that stopped being true. Claims are not checked under asOf/changedSince. Optional asOf/changedSince for history and a type filter. | Yes |
Memory survives refactors (symbol identity continuity). A pure rename or a file move changes a symbol's identity and would otherwise orphan every memory and decision anchored to it. At each openlore analyze, OpenLore detects the rename/move between the prior and new graph and carries the anchors forward to the new symbol, recording carriedAcross: { from, reason, basis, atCommit } provenance that recall surfaces on the anchor — so the note recalls as fresh/drifted (carried) instead of orphaned. The match is deterministic and conservative: exact-body (byte-identical span — a move) or exact-signature (body identical modulo the symbol's own name — a rename, verified by name substitution against the recorded baseline hash), admitted only on a strict one-to-one match where the name-independent body is unique among new symbols. A deleted symbol is never re-anchored onto an unrelated newcomer that merely shares a parameter shape; an ambiguous move stays orphaned and discloses possiblyMovedTo: [...] candidates rather than guessing. No new tool, no LLM; the carry runs as part of analyze.
Claim verification (opt-in, --preset verify)
| Tool | Description | Requires prior analysis |
|---|---|---|
verify_claim | Verify a claim before asserting it to a human: a deterministic verdict (confirmed / refuted / unverifiable) plus a citation receipt. Structural kinds (calls, reaches, dead, impacts, safe-to-change) check the call graph ("X is dead", "Y calls Z", "this is safe to change"). The decision-current kind checks whether a recorded decision is still authoritative before you cite it — subject is an 8-char decision id, and the verdict is refuted (naming the live superseder to cite instead) if that decision was superseded or rejected. decision-governed (subject: a symbol) confirms when an authoritative decision or memory is anchored to it, listing ids and freshness; a draft, superseded, or orphaned record is listed as not governing. endpoint-implemented and endpoint-consumed (subject: an OpenAPI/Swagger operation, METHOD /path, base path and parameter names optional) confirm when an indexed route handler serves it, or a client call site in this repository calls it; a refuted endpoint-consumed is scoped to this repository and names callers elsewhere as not visible; an operation no readable specification declares is unverifiable. lease-current (subject: a leaseToken that orient and recall return) confirms when every symbol or file they served still hashes the same, and is refuted naming each one that changed; an unknown, pruned, or expired (12 hours) token is unverifiable. An unverifiable verdict means hedge or read the source. Registered only under openlore mcp --preset verify. | Yes (structural kinds) |
Federation (multi-repo, opt-in)
Registered only under openlore mcp --preset federation. Federation is an index-of-indexes: each repo keeps its own .openlore index, referenced by a project-local registry (openlore federation add). No merged graph is built.
| Tool | Description | Requires prior analysis |
|---|---|---|
federation_status | Report the federation registry and each registered repo's live index state (indexed / stale / unindexed / missing), with registered-vs-live fingerprints. Read-only. | No |
spec_store_status | Report the health of a spec-store binding (.openlore/config.json specStore): per-target resolution + live index state, reference presence, and store-path presence. Declared target/reference names resolve against the federation registry. Read-only; never throws, never blocks. | No |
working_set_context | Assemble the working-set structural briefing for an active change in a spec-store binding: orient, generalized from one repo to the change's targets. Reads the change's proposal under the bound store, orients each resolved+indexed target on that intent, and returns ONE deterministic, token-budgeted, per-target-attributed briefing (symbol, callers, spec domains, insertion points) plus fresh in-scope anchored intent (orphaned withheld, drifted flagged). Read-only; never throws, never blocks. | Targets indexed |
certify_provenance | A reproducible, content-addressed record of what a change does, for attachment to supply-chain provenance (SLSA / in-toto). Composes change_impact_certificate (blast radius, paths newly opened into a declared surface, drifted specs, tests to run) + structural_diff (added/removed/re-signed functions), serialized canonically and hashed (sha256) so a consumer can recompute and verify it — checkable, not merely signed. Emit as standalone JSON, or (format: "in-toto") wrapped in an unsigned in-toto Statement v1 envelope whose SHAPE is checked locally on every emission (no network, no schema fetch) and disclosed as the statementValidation receipt — a structural check of the envelope, not schema validation and not a signature. The envelope's subject digest is the content address of the predicate body, not of a built artifact, so an in-toto verifier resolving it against an artifact will not match: this is a semantic record to attach alongside identity/build provenance, not an artifact attestation. OpenLore emits but does not sign; bad base is fatal; boundaries disclosed (a lower bound, never "safe"). Sibling change_impact_certificate briefs your pending diff in-session; this is the portable attestation. Opt-in --preset verify. | Yes |
change_impact_certificate | Certify what the current diff touches before it lands: ONE conclusion-shaped certificate combining blast radius, the paths the change NEWLY OPENS into each declared covering surface (reachable after but not before — computed differentially over the call graph, no LLM), the specs it drifts, and the tests to run. Anchored to the touched symbols via the freshness lease, so it decays. Advisory; opt-in blocking only on a configured surface severity. CLI: openlore impact-certificate (+ --install-hook). | Yes |
map_in_flight_conflicts | Cross-actor interference map — also in the coordination preset (full description below). In the federation preset, passing federation: true matches in-flight changes (branches/PRs/agent tasks) across repository boundaries by content-addressed stable id, so a branch in repo A conflicts with a PR in repo B when they touch the same federated symbol. Read-only, stateless, advisory. | Yes |
When a registry exists, analyze_impact, find_dead_code, select_tests, and find_path accept opt-in federation (boolean) and federationRepos (name list) params: cross-repo consumers, live-via-federation exports, cross-repo test selection, and cross-repo producer/bridge location respectively. Each response names reposConsulted / reposSkipped — unindexed/stale repos are reported, never guessed.
A spec-store binding declares the code repositories an external spec repository targets/references; spec_store_status reports its health as a conclusion-shaped report whose findings[] carry stable codes (the --json agent contract):
| Code | Severity | Meaning |
|---|---|---|
no-binding | info | no specStore block configured (single-repo behavior unchanged) |
binding-invalid | error | malformed block: empty name/path, self-referential store path, a duplicate name, or a name in both targets and references |
registry-unreadable | error | .openlore/federation.json is present but corrupt/unparseable |
store-path-missing | error | the store's declared path does not exist on disk |
target-unresolved | error | a declared target name is not registered in the federation registry |
target-missing | error | a resolved target's registered path no longer exists |
index-missing | warn | a resolved target has no built .openlore index |
index-stale | warn | a resolved target's index changed since its registry baseline (re-baseline with openlore federation add) |
reference-missing | warn | a declared reference is unresolved or its path is gone |
The report is sound when it carries no error-severity finding. Every finding includes a pasteable remediation. Exposed only under openlore mcp --preset federation.
working_set_context builds on the binding: given --change <id>, it reads that change's proposal under the bound store, extracts a concise intent, and runs task-scoped orient against each resolved+indexed target. The merged briefing is ranked by structural relevance and bounded by a token budget (tokenBudget, default 8000); when truncated it carries an omissionNote. Every item is attributed to its target repository (target, name, callers, specDomains, expand). Fresh in-scope decisions appear under each target's anchoredIntent with verdict: "current"; drifted anchors appear as verdict: "drifted"; orphaned anchors are withheld entirely (orient never serves them as authoritative). Its findings[] carry stable codes (no-binding, binding-unsound, change-unspecified, change-not-found, no-briefable-targets, target-not-briefable, orient-unavailable); ready is true when the binding is sound and at least one target was briefed. Read-only, never blocks. Also exposed only under openlore mcp --preset federation.
change_impact_certificate is the third tool of the spec-store arc. Where blast_radius answers "what does this diff touch?", the certificate answers the more dangerous question "what can this diff now reach that it could not before?" — the cross-boundary case file-ownership misses. You declare covering surfaces (semantic/governance boundaries, not directory globs) under impactCertificate.surfaces; for the current diff, OpenLore computes reachability to each surface in the pre-change and post-change call graph and reports the paths that exist only after — the paths the change opened, with the shortest opening path named. This is differential and needs no full rebuild: a new call edge can only come from a changed file, so only the changed files are re-parsed (base-ref vs working tree), and the canonical adjacency is adjusted both ways (post = canonical + added − removed, pre = canonical − added + removed). The certificate also folds in blast radius, drifted specs, and tests-to-run (reused from blast_radius), and is anchored to the touched symbols via the freshness lease so it decays — when an anchored symbol later moves, spec_store_status re-fires it as a certificate-stale finding. Advisory by default; a repository MAY opt into blocking specific surface severities (e.g. impactCertificate.block: ["critical"]), exactly as blast_radius made blocking opt-in. That per-surface block is now thin sugar over the unified enforcement.policy ({ "surface-critical": "blocking" }), governed by the openlore enforce gate — one declarative source of truth across all governance findings, with a direct policy entry winning over inherited legacy sugar. See configuration.md and cli-reference.md. CLI: openlore impact-certificate [--base <ref>] [--change <id>] [--json] [--hook] [--save]. Exposed only under openlore mcp --preset federation.
Parallel-work coordination (opt-in, --preset coordination)
Registered only under openlore mcp --preset coordination.
| Tool | Description | Requires prior analysis |
|---|---|---|
certify_merge | Before landing two branches that merge cleanly, check whether one side breaks what the other calls. Builds the call graph at the merge-base and each side, then reports where one side ADDS a call/import edge into a symbol the other side changed incompatibly or removed — the "git merges cleanly, the combination is broken" failure textual merge cannot see. Both directions. Verdict per finding: incompatible (removed / breaking signature) or potentially-incompatible (unprovable), never silently safe; the overall verdict is a sound lower bound. Advisory finding merge-semantic-conflict. Completes the coordination arc after plan_parallel_work (dispatch) and map_in_flight_conflicts (in flight); distinct from the merge-tree oracle (will git textually conflict). Opt-in --preset coordination. | Yes |
fleet_status | Coordinating parallel branches off a moving base: re-checks each recorded coordination verdict (a clean blast radius, a stable public surface, a passed certify_merge) against the current graph via the freshness lease — still-valid / carried / invalidated / needs-reverification — so a verdict is never served fresh once its base moved without the check. Records are shared by every worktree of the clone (<git-common-dir>/openlore/verification-records.json; a legacy .openlore/coordination/ file is read and folded in on the next write; a record from another worktree is listed as other-worktree, not checked here). A record ends on the same rules as a peer-board entry — 30 minutes without being re-proven, its recorded directory removed, a deleted branch, or a branch merged into the default branch (a record carries only that directory, so it is not matched against the clone's worktree list) — and an ended record is reported as a count with its reason, never as a live verdict; fleet_status stays read-only and the next recordVerification prunes it (mirroring pruneEnded). Honest about what it cannot check: a missing or unusable field never means "ended". A record with no (or an unparseable) recordedAt is not expired, an unrecorded directory is not a removed worktree, a baseCommit that is not a commit id leaves the merged rule unknown instead of being handed to git, a git that cannot be asked about branches at all (not a work tree, no git) is not a deleted branch, and a branch that is not a branch of this clone is only branch-deleted when the record carries the evidence it once was one — a task id is unknown, never deleted. An unusable branch name, an empty one, and a repo with no main/master likewise leave those rules unapplied. Every skipped rule is named in unknownPredicates (always present, per record and in aggregate), so "checked and fine" never looks like "could not be checked". Nothing heartbeats a record the way declare_footprint refreshes an entry, so a verdict decays 30 minutes after it was recorded: re-run the producing tool to prove it again. No tool records a verdict yet (recordVerification is API-only), so the store is empty unless a caller writes to it directly — an empty record list means nothing was recorded, not that nothing holds. Two limits are disclosed in boundaries: a record whose recorded directory moved (a renamed monorepo package) ends as worktree-removed though the worktree is intact, and a squash/rebase merge — or a tip older than main's last 5,000 first-parent commits — is not detected as merged (such a record ends on a deleted branch or on idle, if it carries the evidence those rules need). Composes the coordination arc (plan_parallel_work → map_in_flight_conflicts → certify_merge), referencing each tool rather than re-deriving it. Advisory, read-only. Opt-in --preset coordination. | Yes |
declare_footprint | Publishes this agent's intended write-set and read-set (symbols or files; names that do not exist yet are intended creations) to the peer board shared by every worktree of the clone (<git-common-dir>/openlore/board/, no server), and returns the hazards against every live peer in the same response: the plan_parallel_work classes (WAW / shared-append / RAW / WAR / soft-coupling) plus duplicate-intent when two agents will create the same symbol name or file. action: release removes the entry, list reads the board (movedSinceDeclared names declared symbols whose text changed). When a live peer in another worktree changes a symbol in this worktree's declared read-set, or a function orient/recall served here in the last 30 minutes, and the peer's base still had the declared text, the after-tools hook names the symbol, the peer, and when it was declared, once per session. An entry ends on release, a merged or deleted branch, a removed worktree, or 30 minutes without a refresh — but never on a check git could not answer: when the clone's branches cannot be listed, neither the deleted nor the merged rule is applied (a branch whose short name git disambiguates to heads/<name>, because a tag shares it, is matched to its branch rather than read as deleted). Live entries also join map_in_flight_conflicts as agent tasks and appear in fleet_status. Advisory: nothing is locked; titles are redacted and withheld when instruction-shaped; peer fields are local-unreviewed. Findings parallel-work-conflict and duplicate-intent can be gated with enforcement.policy. Opt-in --preset coordination. CLI: `openlore footprint declare | release |
plan_parallel_work | Before fanning N tasks out across agents/worktrees, decide which are safe to run concurrently. Given a caller-supplied task list (each with seed symbols/files and an optional writeMode), returns the computed plan: a hazard-typed conflict graph (WAW / shared-append / RAW / WAR / soft-coupling) with witnessing symbols, a wave schedule (wave 1 = dispatch now; later waves name the predecessors they wait on), and a critical path (the minimum sequential rounds even with unlimited agents). Stateless and advisory — re-invoke with the remaining tasks to re-plan; there is no lease, no task assignment, no memory between calls. includeBoard: true also plans the live peer-board agents of other worktrees (declare_footprint) as tasks board:<actorId>. | Yes |
map_in_flight_conflicts | The team version of plan_parallel_work. Instead of a caller-supplied task list it harvests every change already in flight — local branches, open PRs (via gh), and any supplied agent task descriptors — and runs the same hazard classifier across all of them. Each footprint is derived from the change's ACTUAL diff, so it works without any writeMode declaration. Returns per conflict: the two actors, hazard class, shared symbols, a suggested landing order, and a textualMerge verdict — textual-conflict (git will not auto-merge; the conflicted files are named), clean-automerge (the hazard is behavioral only), or not-assessed with a reason. A change whose diff can't be fetched or whose symbols don't resolve is labeled "not assessed", never "no conflict". Diffs over the 400-file assessment budget remain visible with reason: "assessment-capped"; they are never partially cleared. Read-only, stateless (no watcher/poll/store), advisory; also in the federation preset, where it matches across repo boundaries by stable id. | Yes |
plan_parallel_work is the agent-facing surface of the parallel-work-coordination set: it composes a deterministic per-task footprint (write-set / read-set / affected-set, with ambient high-fan-in symbols excluded) and a pairwise hazard classifier into the schedule. The conflict model is a borrow checker lifted from variables to repository regions — two tasks may not hold overlapping mutable borrows of the same region concurrently (WAW → different waves), a read-after-write is an ordering edge (RAW → later wave), and concurrent appends to a shared registration site (a dispatcher case, a tool-registry array) are low-risk (shared-append → same wave, advisory). Declare registration-site touches writeMode: "append" so they are not falsely serialized — otherwise the conservative modify default will (correctly, but unhelpfully) split them across waves. OpenLore schedules; it never invents or decomposes the task list, never holds a lock, and never dispatches — the harness owns state and dispatch. WAW conflicts surface as the parallel-work-conflict governance finding (and unorderable RAW cycles as parallel-work-cycle), emitted in the unified GovernanceFinding shape so the caller that invoked plan_parallel_work can classify them with resolveEnforcementClass(code, policy) and choose to block in its own orchestration/CI. Note: the bundled openlore enforce commit gate is diff-based and does not run the planner, so it never blocks on these codes — they are policy-governable by the caller, not by the bundled gate. The supporting-evidence lists (conflicts, advisories, findings, and the per-task footprint regions) are capped with authoritative uncapped counts and a truncationNote for a very large plan, so the response stays well within the MCP byte budget; the schedule (waves + critical path) is always complete. Every plan carries the standing disclosure that footprints are predicted and integration tests remain the ground truth.
map_in_flight_conflicts generalizes that conflict graph from "N tasks I am about to dispatch" to "every change in flight right now." A team's costliest collision is not "two of my agents collided," it is "my agent spent an hour rewriting resolveCallSite, and so did a teammate's open PR, and we find out at merge." Worktrees and branch isolation cannot prevent that — they cause it, then surface it late. This tool surfaces it early, structurally: it enumerates local branches (diffed against the base), open PRs (changed files via gh), and any supplied agent task descriptors as actor-attributed nodes { actor, ref, repo }, derives each footprint from its actual diff rather than declared seeds, and runs the same pairwise hazard classifier across all of them. Because the write-set is observed, the per-symbol writeMode is read straight off the hunks — a symbol touched only by pure-insertion hunks is an append, one touched by any deletion/modification is a modify — so two PRs that each append a disjoint entry to the same dispatcher (or to the same module-scope registry array/object literal, which carries no function node — those module-scope appends fall back to a file-scope member) resolve to shared-append (merges trivially), not a false WAW, with no writeMode declaration needed. The base snapshot is parsed under each file's base path, so a symbol in a renamed-and-edited file keeps its base identity and still conflicts with an in-place edit of the same function (a rename does not hide a real merge conflict). Honesty is structural: a PR whose diff cannot be fetched, a federated target whose index is stale, a change whose symbols do not resolve, or a changed file whose base content could not be read (its symbols are omitted, disclosed in a caveat) is handled without ever producing a false "no conflict." (One deliberate limit: a module-scope modify of a non-function declaration is not assessed at symbol granularity — at file granularity it would over-couple disjoint top-level edits into a spurious WAW, and the tool prefers a rare missed module-scope-modify over a noisy false "must serialize.") It is read-only and stateless — no watcher, no polling, no persisted conflict store, no new graph schema; re-invoke to refresh. With federation: true it extends across repository boundaries, matching changes by content-addressed stable id (qualified name + parameter shape — the same identity model federation uses, with no file path or body) so a branch in repo A conflicts with a PR in repo B when they touch the same federated symbol, and degrading cleanly to single-repo when no federation is configured. Cross-repo matches carry a caveat that two genuinely different symbols sharing a name and arity across repos could collide, so confirm a cross-repo witness names the same logical symbol before acting (file paths are namespaced per repo, so a coincidental shared relative path never raises a false same-file overlap). Each conflict pair also carries a textual merge verdict. The tool runs git merge-tree --write-tree (git 2.40 or later) between the two tip commits over the merge base that the real repository resolves. The merge runs in a scratch bare repository in the OS temp directory, which reads the real objects through an alternates file. So the analyzed repository gets no new objects, and no merge driver of that repository runs. Settings the scratch repository cannot see are read in the real repository with value-only commands (git config, git check-attr): rename and diff settings (merge.renames, diff.renames, rename limits, merge.directoryRenames, diff.indentHeuristic, merge.conflictStyle, and git's default diff.algorithm; a setting that can hide a conflict a fresh clone or hosted merge would report — renames off, a rename limit, merge.directoryRenames other than conflict, or a non-default diff.algorithm — is not-assessed) are forwarded, keys git merge parses strictly (merge.stat, merge.log, merge.ff, commit.cleanup, core.bigFileThreshold, …) must hold a value git parses (checked untrimmed, with git's k/m/g units and 32-bit ranges), a tip or merged tree that git's own path protection (read-tree with core.protectNTFS and core.protectHFS) refuses is not-assessed (.git., GIT~1, .git::$DATA, a .gitmodules symlink), any other merge.* key from any scope outside a short allowlist of output and tooling keys makes the pair not-assessed (global includeIf "gitdir:" can reach only the real repository), a pull.twohead other than exactly ort/recursive (case- and space-sensitive, as git reads it) is not-assessed, and a changed path that carries a non-default merge attribute (-merge, binary, merge=union, a custom driver) or any attribute outside an allowlist of text, eol, crlf, whitespace, export-*, and linguist-* (for example diff, which changes rename detection, or filter), checked in the working tree, the base, both tips, and the merged tree (tree reads run in the scratch repository, so a local .git/info/attributes cannot hide a rule a fresh clone applies) (a merge that places a path neither change touched, as a directory rename can, is not-assessed), merge.default, any merge.<name>.* driver section named text/set/unspecified (indistinguishable from the default merge in check-attr output), merge.renormalize, branch.<name>.mergeOptions, replace refs or grafts, a path that changes between a submodule and a regular entry (vendoring collides with the checked-out submodule's files), a changed path longer than a checkout filesystem allows (a name over 255 bytes or a path over 1,000 bytes) or a changed symlink whose target is 1,000 bytes or longer, or a submodule conflict makes the pair not-assessed. Attributes are checked by top-level path and exact path bytes (decomposed Unicode included), so a subdirectory analysis root does not hide them; a .gitattributes that is not a regular file (a symlink or gitlink a real merge ignores but check-attr would read) or that has a UTF-8 byte-order mark, a NUL byte, a line near git's 2,048-byte attribute line limit, or a checkout attribute of its own such as ident (each read differently from a blob than from disk), or an attributes file, ancestor directory, or file that differs from a changed path (or another changed path) only by letter case is not-assessed on every platform, because a real merge on a case-insensitive filesystem reads it whatever core.ignorecase says (a non-ASCII name in those directories is not-assessed, since filesystems fold Unicode case in ways the check cannot reproduce), and so is a core.worktree that resolves to another repository. The simulation's reads of the analyzed repository disable git's lazy fetch (git 2.45 or later; on older git a partial clone is not-assessed), so a partial clone cannot run a repository-chosen uploadpack command. Your global and system git config still apply, and the verdict compares the two tips with each other, not with the current base. A pair is not-assessed, never clean, in these cases: no merge base (shallow clone, unrelated histories), several merge bases (criss-cross history), a PR head commit that is not present locally, an agent task (it has no commit), a cross-repository pair, more than 60 simulations in one call, or a spent 20-second simulation budget. A textual-conflict pair makes the landing suggestion say that whichever change lands second must resolve the conflict by hand. WAW pairs surface as the cross-actor-conflict governance finding, so a CI check can resolveEnforcementClass(code, policy) and warn when a new PR's footprint collides with an open one. Advisory by default; the standing disclosure holds — structural overlap predicts conflict probability, not certainty, and merge/integration remains the ground truth.
Story Management
| Tool | Description | Requires prior analysis |
|---|---|---|
generate_change_proposal | Generate a structured change proposal for a feature: affected functions, risk score, insertion points, spec impact, and a ready-to-use story file. Use during sprint planning or before implementing a non-trivial change. | Yes |
annotate_story | Annotate an existing story file with structural context: risk score, affected functions, recommended insertion point, and spec domain links. Prepares a story for the dev agent so it can skip the orientation step. | Yes |
Parameters
orient
directory string Absolute path to the project directory
task string Natural-language description of the task, e.g. "add rate limiting to the API"
limit number Max relevant functions to return (default: 5, max: 20)
tokenBudget number Optional: fit the whole response to ~this many tokens. When the default answer
fits, functions ranked past `limit` (with their call paths) are added while
they fit; otherwise the lowest-ranked entries are dropped, peripheral sections
first. Decisions, memories, and matching specs are never dropped. The `budget`
receipt gives estimated tokens (as sent), `fits`, and per-section counts.
lean boolean Optional: return only the navigation core (relevantFunctions + callPaths +
specDomains + suggestedTools), dropping enrichment (Spec 27). See below.Response includes suggestedTools: string[] — a ranked list of openlore tool names relevant to the task, derived from hub presence, spec domains, and task keywords. No extra I/O. Use this on clients without Tool Search (Cline, Cursor, OpenCode) to know which tools to call next without enumerating all 69.
When no repository function matches, the response includes emptyResult with the unmatched
identifier-shaped task tokens and bounded nearTokens receipts. In that case suggestedTools
and nextSteps point to search_code and get_map; they do not prescribe implementation or
decision-recording work without a concrete result.
Lean mode (Spec 27). lean: true (CLI: orient --lean) returns only the navigation core for shallow "who calls X / where is Y" lookups — ~40% smaller than the rich default on this repo. Everything dropped (insertion points, provenance, change-coupling, inline specs, matching specs, decisions, architecture violations) is one expand handle or one dedicated tool call away, so it trims bytes per turn without forcing a follow-up round-trip. Lean is also compute-lean (Spec 27 P5): it skips the work behind those blocks — the extra spec-embedding search, manifest/spec-file reads, the decision-store load, and the git-derived joins — so the shallow path is faster, not only smaller. The rich default is unchanged; omit lean when you need specs, decisions, or insertion points.
working_set_context
directory string Absolute path to the home project directory (holds the specStore binding)
change string The change id to brief; its proposal.md lives under the bound store at
<store>/openspec/changes/<change>/. Confined to the store (traversal is rejected).
tokenBudget number Optional: cap the merged briefing to ~this many tokens (default: 8000)Response (WorkingSetContextReport) — the stable JSON shape an orchestrator can rely on:
bound boolean whether a specStore binding is configured
store { name, path } present when bound
change { id, intent, declaredScope? } intent = the ≤1000-char task oriented on; declaredScope = the change's spec-delta domains
targets [ { target, briefed, reason?, insertionPoints[], specDomains[],
anchoredIntent[ { id, title, status, verdict: "current"|"drifted" } ] } ]
items [ { target, name, filePath, score, expand, signature?, callers[], specDomains[] } ] merged, ranked, budgeted
omissionNote string present only when the budget dropped items
findings [ { code, severity, subject, message, remediation } ] stable codes (see below)
ready boolean true when the binding is sound AND ≥1 target was briefed
summary string conclusion-shaped headlineFinding codes: no-binding, binding-unsound, change-unspecified, change-not-found, no-briefable-targets, target-not-briefable, orient-unavailable. Read-only; always succeeds (every problem is a finding), never blocks.
change_impact_certificate
directory string Absolute path to the project directory (must have a built index)
baseRef string Optional: git ref to diff the working tree against (default: HEAD)
change string Optional: change id recorded on the certificate (default: "working-tree")
persist boolean Optional: write the certificate under .openlore/impact-certificates/ so the
spec-store health check can re-fire it when its lease decaysResponse (ImpactCertificate) — the stable JSON shape an orchestrator can rely on:
change string the change id (or "working-tree")
baseRef, resolvedBaseRef string requested vs the ref git actually diffed against
changed { files, symbols }
surfaces [ { name, severity, resolvedSymbols, unresolvedMembers[] } ]
newlyOpenedPaths [ { surface, surfaceSeverity, openingEdge: { from, to }, path[], pathIds[], reaches } ]
pathIds is the uncapped canonical graph-id path used for stable identity
impact / tests / specs reused verbatim from blast_radius (or { unavailable })
lease { anchors[] } the touched-symbol anchors that drive decay
findings [ { code, severity, subject, message, remediation, surfaceSeverity? } ]
highestSurfaceSeverity "info" | "warn" | "critical" | "none" the block signal
posture "advisory"
caveats string[]
headline string conclusion-shaped one-linerFinding codes: surface-newly-reached, surface-critical, surface-unresolved-member, surface-empty, spec-drift, unresolved-added-call, no-surfaces-declared (and certificate-stale, emitted by spec_store_status when a persisted certificate's anchored symbols have moved). Declare covering surfaces under impactCertificate.surfaces in .openlore/config.json (a surface is a set of { symbol } / { file } members with an optional severity); opt into blocking with impactCertificate.block: ["critical"] — now thin sugar over the unified enforcement.policy, governed by openlore enforce. (Note: the certificate's own finding codes above are what --json emits; the enforcement gate governs the per-severity codes surface-info / surface-warn / surface-critical, so a enforcement.policy entry should name surface-critical, not surface-newly-reached.) Newly-opened-path detection is differential and bounded — only the changed files are re-parsed; renamed files read their base-ref content, untracked files are folded in, and an ambiguous added callee is reported (unresolved-added-call), never guessed. Read-only; always succeeds (every problem is a finding/caveat), advisory — never blocks. Exposed only under openlore mcp --preset federation.
analyze_codebase
directory string Absolute path to the project directory
force boolean Force re-analysis even if cache is fresh (default: false)get_refactor_report, get_call_graph
directory string Absolute path to the project directoryget_signatures
directory string Absolute path to the project directory
filePattern string Optional path substring filter (e.g. "services", ".py")get_subgraph
directory string Absolute path to the project directory
functionName string Function name to centre on (case-insensitive partial match)
direction string "downstream" | "upstream" | "both" (default: "downstream")
maxDepth number BFS traversal depth limit (default: 3)
format string "json" | "mermaid" (default: "json")Note: If no exact name match is found, get_subgraph falls back to semantic search (when a vector index is available) to find the most similar function.
get_mapping
directory string Absolute path to the project directory
domain string Optional domain filter (e.g. "auth", "crawler")
orphansOnly boolean Return only orphan functions (default: false)get_duplicate_report
directory string Absolute path to the project directorycheck_spec_drift
directory string Absolute path to the project directory
base string Git ref to compare against (default: auto-detect main/master)
files string[] Specific files to check (default: all changed files)
domains string[] Only check these spec domains (default: all)
failOn string Minimum severity to report: "error" | "warning" | "info" (default: "warning")
maxFiles number Max changed files to analyze (default: 100)list_spec_domains
directory string Absolute path to the project directoryanalyze_impact
directory string Absolute path to the project directory
symbol string Function or method name (exact or partial match)
depth number Traversal depth for upstream/downstream chains (default: 2)Note: If no exact name match is found, analyze_impact falls back to semantic search (when a vector index is available) to find the most similar function.
Canonically selected affected entries include bounded callSites with caller identity, file,
stored line, and confidence. callSitesReceipt reports per-entry totals; the top-level
callSiteEvidenceReceipt discloses when the global 128-entry evidence envelope omits entries.
get_low_risk_refactor_candidates
directory string Absolute path to the project directory
limit number Max candidates to return (default: 5)
filePattern string Optional path substring filter (e.g. "services", ".py")get_leaf_functions
directory string Absolute path to the project directory
limit number Max results to return (default: 20)
filePattern string Optional path substring filter
sortBy string "fanIn" (default) | "name" | "file"get_critical_hubs
directory string Absolute path to the project directory
limit number Max hubs to return (default: 10)
minFanIn number Minimum fan-in threshold to be considered a hub (default: 3)get_architecture_overview
directory string Absolute path to the project directoryget_function_skeleton
directory string Absolute path to the project directory
filePath string Path to the file, relative to the project directoryget_function_body
directory string Absolute path to the project directory
filePath string Path to the file, relative to the project directory
functionName string Name of the function to extract
focus string Optional variable or callee name; returns stored structural evidence (max 200 chars)
focusKind string Required with focus: "variable" | "callee"A successful focused response omits body, returns bounded source lines in slice, and includes
evidenceReceipt. Variable slices expose dataFlowPrecision and the same-spelling scope boundary;
callee slices expose stored callConfidence without inventing data-flow precision. Stale, ambiguous,
unsupported, malformed, or out-of-span evidence returns a machine-readable sliceUnavailable
boundary instead of guessed line evidence. Calls that omit focus and focusKind retain the legacy
full-body response.
get_file_dependencies
directory string Absolute path to the project directory
filePath string Path to the file, relative to the project directory
direction string "imports" | "importedBy" | "both" (default: "both")trace_execution_path
directory string Absolute path to the project directory
entryFunction string Name of the starting function (case-insensitive partial match)
targetFunction string Name of the target function (case-insensitive partial match)
maxDepth number Maximum path length in hops (default: 6)
maxPaths number Maximum number of paths to return (default: 10, max: 50)get_spec
directory string Absolute path to the project directory
domain string Domain name (e.g. "auth", "user", "api")get_god_functions
directory string Absolute path to the project directory
filePath string Optional: restrict search to this file (relative path)
fanOutThreshold number Minimum fan-out to be considered a god function (default: 8)suggest_insertion_points
directory string Absolute path to the project directory
description string Natural-language description of the feature to implement
limit number Max candidates to return (default: 5)
language string Filter by language: "TypeScript" | "Python" | "Go" | ...search_code
directory string Absolute path to the project directory
query string Natural-language query, e.g. "authenticate user with JWT"
limit number Max results (default: 10)
language string Filter by language: "TypeScript" | "Python" | "Go" | ...
minFanIn number Only return functions with at least this many callerssearch_specs
directory string Absolute path to the project directory
query string Natural language query, e.g. "email validation workflow"
limit number Maximum number of results to return (default: 10)
domain string Filter by domain name (e.g. "auth", "analyzer")
section string Filter by section type: "requirements" | "purpose" | "design" | "architecture" | "entities"Search hits carry scoreKind: rrf and bm25 are higher-is-better, while
cosine_distance is lower-is-better. search_specs.indexFreshness reports the
index builtAt timestamp, tracking status, and the count/list of indexed spec or ADR
files changed under the configured OpenSpec root since that build; run openlore analyze --reindex-specs when the
count is nonzero. An unavailable receipt reports a null count, never a false zero.
explain_retrieval_miss (full preset only)
directory string Absolute project directory
query string The original search query
surface string "code" | "spec"
target.kind string "symbol" | "file" | "requirement"
target.value string Exact name, repo-relative file, or canonical requirement ID
target.filePath string Optional symbol disambiguation path
limit integer Ordinary result cutoff (default: 10)
language string Code-only language filter
minFanIn integer Code-only minimum-caller filter
domain string Spec-only domain filter
section string Spec-only section filterIncompatible target/filter combinations return a usage error. budget-truncated names the
ordinary bounded candidate window; presentation token budgets and the transport cap are outside
this retrieval trace.
generate_change_proposal
directory string Absolute path to the project directory
description string Natural-language description of the change (story, intent, or spec delta)
slug string URL-safe identifier for the proposal (e.g. "add-payment-retry")
storyContent string Optional full story markdown to embed in the proposalannotate_story
directory string Absolute path to the project directory
storyFilePath string Path to the story file (relative to project root or absolute)
description string Natural-language summary of the story for structural analysisrecord_decision
directory string Absolute path to the project directory
title string Short decision title (e.g. "Use Redis for session cache")
rationale string Why this approach was chosen
consequences string Trade-offs and impacts of this decision
affectedFiles string[] Source files involved (relative paths)
proposedRequirement string Optional: "The system SHALL …" requirement to add to specs
supersedes string Optional: ID of a prior decision this replaceslist_decisions
directory string Absolute path to the project directory
status string Optional filter: draft | consolidated | verified | approved | synced | phantomapprove_decision
directory string Absolute path to the project directory
ids string[] Decision IDs to approvereject_decision
directory string Absolute path to the project directory
id string Decision ID to reject
reason string Reason for rejectionsync_decisions
directory string Absolute path to the project directory
dryRun boolean Preview changes without writing files (default: false)Typical workflow
Scenario A -- Initial exploration
1. analyze_codebase({ directory }) # repo structure + call graph + top issues
2. get_call_graph({ directory }) # hub functions + layer violations
3. get_duplicate_report({ directory }) # clone groups to consolidate
4. get_refactor_report({ directory }) # prioritized refactoring candidatesScenario B -- Targeted refactoring
1. analyze_impact({ directory, symbol: "myFunction" }) # risk score + blast radius + strategy
2. get_subgraph({ directory, functionName: "myFunction", # Mermaid call neighbourhood
direction: "both", format: "mermaid" })
3. get_low_risk_refactor_candidates({ directory, # safe entry points to extract first
filePattern: "myFile" })
4. get_leaf_functions({ directory, filePattern: "myFile" }) # zero-risk extraction targetsScenario C -- Spec maintenance
1. check_spec_drift({ directory }) # code changes not reflected in specs
2. get_mapping({ directory, orphansOnly: true }) # functions with no spec coverageScenario D -- Starting a new task (fastest orientation)
1. orient({ directory, task: "add rate limiting to the API" })
# Returns in one call:
# - relevant functions (keyword/BM25 by default, or hybrid semantic when enabled)
# - source files and spec domains that cover them
# - call-graph neighbourhood for each top function
# - best insertion-point candidates
# - spec-linked peer functions (cross-graph traversal)
# - matching spec sections AND matching ADRs (domain "decisions")
# - active decisions touching the task's domains (pendingDecisions)
# - approved decisions always surfaced — must sync before committing
# - suggestedTools: ranked list of next tools to call based on task context
# (hub presence, spec domains, task keywords) — portable discovery for
# clients without Tool Search (Cline, Cursor, OpenCode)
2. get_spec({ directory, domain: "..." }) # read full spec before writing code
3. check_spec_drift({ directory }) # verify after implementationScenario E -- Coverage audit before implementing
1. audit_spec_coverage({ directory })
# Before writing code: surfaces stale domains, uncovered hub functions,
# orphan requirements. 0 LLM calls, ~200ms.
2. If staleDomains includes your target: run the `openlore-repair` host skill, which exhausts
`prepare_spec_repair` evidence and edits the existing spec with the host agent. Use
`openlore generate --domains $DOMAIN` only when explicitly choosing the optional paid
standalone-provider path.
3. If hubGaps includes a function you'll touch: flag it in your risk checkScenario E.1 -- Agent-authored specification generation and repair
Use prepare_spec_generation({ directory, domain }) for a new domain spec and
prepare_spec_repair({ directory, domain, baseRef? }) for an existing spec. Both
are read-only, deterministic MCP compositions: OpenLore prepares evidence while
the host agent interprets it, authors prose, and edits files. They are present in
the default and full surfaces; the explicit navigation-only preset omits them.
Each response includes analysis provenance and a receipt. A partial receipt
names omitted evidence and either supplies an opaque continuation cursor or a
prefilled atomic-tool follow-up. Exhaust cursors in order; use get_spec,
get_mapping, audit_spec_coverage, structural_diff, and other atomic tools
only when the receipt requests deeper evidence. Repair scopes structural changes
over current domain files plus historical paths from the spec and mapping, so a
deleted/moved file and a fully orphaned spec remain observable. Unavailable
mapping provenance never masquerades as zero uncovered code.
Scenario F -- Decisions workflow
1. record_decision({ directory, title, rationale, consequences, affectedFiles })
# Call this before writing code — captures the design choice
2. [implement the feature / refactor]
3. git commit # decisions hook consolidates drafts, cross-checks against diff,
# blocks commit if unreviewed decisions remain
# If blocked, check "reason":
# "verified" → present decisions to user, approve/reject, then sync
# "approved_not_synced" → run sync_decisions, then retry commit
# "drafts_pending_consolidation" → run openlore decisions --consolidate --gate
# "no_decisions_recorded" → run openlore decisions --consolidate --gate
4. list_decisions({ directory, status: "verified" })
# Review the consolidated + verified decisions
5. approve_decision({ directory, ids: ["<id>"] })
6. sync_decisions({ directory, dryRun: true }) # preview
7. sync_decisions({ directory }) # write to specs and ADRsSemantic Search & GraphRAG
openlore analyze builds a search index over repository-defined call-graph functions plus
signature-only symbols. Synthetic external call targets are excluded. When test functions or
signature-only symbols make the indexed population larger than the production call graph, the
analyze output reports each population separately. The index enables natural-language search via
the search_code, orient, and suggest_insertion_points MCP tools, and the search bar in the viewer.
GraphRAG retrieval expansion
Semantic search is only the starting point. openlore combines three retrieval layers into every search result — this is what makes it genuinely useful for AI agents navigating unfamiliar codebases:
Semantic seed — keyword (BM25) search by default, or dense+BM25 hybrid ranking when embeddings are enabled, finds the top-N functions closest in meaning to the query.
Call-graph expansion — BFS up to depth 2 follows callee edges from every seed function, pulling in the files those functions depend on. During
generate, this ensures the LLM sees the full call neighbourhood, not just the most obvious files.Spec-linked peer functions — each seed function's spec domain is looked up in the requirement→function mapping. Functions from the same spec domain that live in different files are surfaced as
specLinkedFunctions. This crosses the call-graph boundary: implementations that share a spec requirement but are not directly connected by calls are retrieved automatically.
The result: a single orient or search_code call returns not just "functions that mention this concept" but the interconnected cluster of code and specs that collectively implement it. Agents spend less time chasing cross-file references manually and more time making changes with confidence.
Embedding configuration
Keyword (BM25) search is the first-class default and needs no configuration. To enable semantic ranking you have two options:
Local, zero-config (recommended):
openlore embed --local # on-device, no API key; revert with: openlore embed --offRemote OpenAI-compatible endpoint — via environment variables or .openlore/config.json:
EMBED_BASE_URL=https://api.openai.com/v1
EMBED_MODEL=text-embedding-3-small
EMBED_API_KEY=sk-... # optional for local servers
openlore analyze # embedding is automatic when configured{
"embedding": {
"provider": "remote",
"baseUrl": "http://localhost:11434/v1",
"model": "nomic-embed-text",
"batchSize": 64
}
}provider:"local"(on-device),"remote"(default whenbaseUrl/modelare set), or"none"(keyword only: no background vectors, and wins overEMBED_*)batchSize: Number of texts to embed per API call (default: 64)
See docs/semantic-search.md for the full retrieval-mode reference. The index is stored in .openlore/analysis/vector-index/ and is automatically used by the viewer's search bar and the search_code / suggest_insertion_points MCP tools.
512 files · 450 not served here
- .claude/commands/first-run-hardening.md (not served here)
- .gitattributes (not served here)
- .github/CODEOWNERS (not served here)
- .github/ISSUE_TEMPLATE/bug_report.md (not served here)
- .github/PULL_REQUEST_TEMPLATE.md (not served here)
- .github/actions/openlore-review/action.yml (not served here)
- .github/codeql/codeql-config.yml (not served here)
- .github/dependabot.yml (not served here)
- .github/windows-unit-exclusions.json (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/codeql.yml (not served here)
- .github/workflows/openlore-review.yml.example (not served here)
- .github/workflows/release.yml (not served here)
- .github/workflows/scorecard.yml (not served here)
- .gitignore (not served here)
- .npmrc (not served here)
- .nvmrc (not served here)
- .prettierrc (not served here)
- AGENTS.md
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- CLAUDE.md
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- LICENSE
- README.md
- ROADMAP.md
- SECURITY.md
- bench/Dockerfile (not served here)
- bench/PROTOCOL.md (not served here)
- bench/container-entrypoint.sh (not served here)
- bench/container/package-lock.json (not served here)
- bench/container/package.json (not served here)
- bench/corpora/default-surface.json (not served here)
- bench/results/adr-0023-default-surface.json (not served here)
- bench/retrieval/queries/gridprims.json (not served here)
- bench/retrieval/queries/openlore.json (not served here)
- bench/retrieval/queries/roughlogic.json (not served here)
- bench/retrieval/results/2026-10-31.json (not served here)
- bench/retrieval/results/2026-11-01.json (not served here)
- bench/retrieval/run.ts (not served here)
- bench/rules/adr-0023.json (not served here)
- bench/run.ts (not served here)
- benchmarks/certified-scale-v1.json (not served here)
- docs/AGENT-ADOPTION.md
- docs/AGENT-BENCHMARKS.md
- docs/ALGORITHMS.md
- docs/ARCHITECTURE.md
- docs/OPENSPEC-FORMAT.md
- docs/OPENSPEC-INTEGRATION.md
- docs/PHILOSOPHY.md
- docs/README.md
- docs/REFACTORING-WORKFLOW.md
- docs/TROUBLESHOOTING.md
- docs/agent-setup.md
- docs/agentic-workflows.md
- docs/agentic-workflows/BMAD.md (not served here)
- docs/agentic-workflows/README.md (not served here)
- docs/agents/domain.md (not served here)
- docs/agents/issue-tracker.md (not served here)
- docs/agents/triage-labels.md (not served here)
- docs/api.md
- docs/architecture-invariants.md
- docs/change-coupling.md
- docs/check-weakening.md
- docs/ci-cd.md
- docs/cli-reference.md
- docs/configuration.md
- docs/contracts.md
- docs/coverage-gaps.md
- docs/cross-domain-impact.md
- docs/cross-service-topology.md
- docs/drift-detection.md
- docs/federation.md
- docs/generated-files.md
- docs/governance-dogfooding.md
- docs/iac.md
- docs/install.md
- docs/language-support.md
- docs/languages.md
- docs/mcp-tools.md
- docs/openlore-gallery-source.svg (not served here)
- docs/openlore-gallery.png (not served here)
- docs/output.md
- docs/performance-envelope.md
- docs/phantom-references.md
- docs/pipeline.md
- docs/preflight.md
- docs/provenance.md
- docs/providers.md
- docs/publishing.md
- docs/reachability-dead-code.md
- docs/scip-export.md
- docs/semantic-search.md
- docs/session-ledger.md
- docs/shareable-bundle.md
- docs/spec-link-index.md
- docs/spec-tests.md
- docs/specs/generation-repair/openlore-capability-audit.md (not served here)
- docs/specs/generation-repair/openlore-generation-repair-hlspec.md (not served here)
- docs/specs/generation-repair/openlore-resume-point.md (not served here)
- docs/specs/generation-repair/openlore-unified-hlspec-v2.md (not served here)
- docs/structural-diff.md
- docs/test-impact-selection.md
- docs/viewer.md
- docs/windows-support.md
- eslint.config.js (not served here)
- examples/bmad/README.md (not served here)
- examples/bmad/agents/architect.md (not served here)
- examples/bmad/agents/dev-brownfield.md (not served here)
- examples/bmad/setup/architect.customize.yaml (not served here)
- examples/bmad/tasks/implement-story.md (not served here)
- examples/bmad/tasks/onboarding.md (not served here)
- examples/bmad/tasks/refactor.md (not served here)
- examples/bmad/tasks/sprint-planning.md (not served here)
- examples/bmad/templates/story.md (not served here)
- examples/ci/openlore-preflight.gitlab.yml (not served here)
- examples/ci/openlore-preflight.sh (not served here)
- examples/ci/openlore-preflight.yml (not served here)
- examples/cline-workflows/openlore-analyze-codebase.md (not served here)
- examples/cline-workflows/openlore-check-spec-drift.md (not served here)
- examples/cline-workflows/openlore-execute-refactor.md (not served here)
- examples/cline-workflows/openlore-implement-feature.md (not served here)
- examples/cline-workflows/openlore-plan-refactor.md (not served here)
- examples/cline-workflows/openlore-refactor-codebase.md (not served here)
- examples/cline-workflows/openlore-write-tests.md (not served here)
- examples/drift-demo/openspec/config.yaml (not served here)
- examples/drift-demo/openspec/specs/architecture/spec.md (not served here)
- examples/drift-demo/openspec/specs/auth/spec.md (not served here)
- examples/drift-demo/openspec/specs/database/spec.md (not served here)
- examples/drift-demo/openspec/specs/overview/spec.md (not served here)
- examples/drift-demo/openspec/specs/projects/spec.md (not served here)
- examples/drift-demo/openspec/specs/tasks/spec.md (not served here)
- examples/drift-demo/package.json (not served here)
- examples/drift-demo/src/auth/auth-middleware.ts (not served here)
- examples/drift-demo/src/auth/auth-routes.ts (not served here)
- examples/drift-demo/src/auth/auth-service.ts (not served here)
- examples/drift-demo/src/database/connection.ts (not served here)
- examples/drift-demo/src/index.ts (not served here)
- examples/drift-demo/src/projects/project-model.ts (not served here)
- examples/drift-demo/src/projects/project-service.ts (not served here)
- examples/drift-demo/src/tasks/task-model.ts (not served here)
- examples/drift-demo/src/tasks/task-routes.ts (not served here)
- examples/drift-demo/src/tasks/task-service.ts (not served here)
- examples/drift-demo/src/utils/validation.ts (not served here)
- examples/drift-demo/tests/auth.test.ts (not served here)
- examples/drift-demo/tests/tasks.test.ts (not served here)
- examples/drift-demo/tsconfig.json (not served here)
- examples/drift-test/run-drift-test.sh (not served here)
- examples/gsd/README.md (not served here)
- examples/gsd/commands/gsd/openlore-drift.md (not served here)
- examples/gsd/commands/gsd/openlore-orient.md (not served here)
- examples/mistral-vibe/README.md (not served here)
- examples/mistral-vibe/antipatterns-template.md (not served here)
- examples/mistral-vibe/skills/openlore-analyze-codebase/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-brainstorm/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-debug/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-generate/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-implement-story/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-review-changes/SKILL.md (not served here)
- examples/mistral-vibe/skills/openlore-write-tests/SKILL.md (not served here)
- examples/opencode-skills/openlore-analyze-codebase/SKILL.md (not served here)
- examples/opencode-skills/openlore-brainstorm/SKILL.md (not served here)
- examples/opencode-skills/openlore-debug/SKILL.md (not served here)
- examples/opencode-skills/openlore-execute-refactor/SKILL.md (not served here)
- examples/opencode-skills/openlore-generate/SKILL.md (not served here)
- examples/opencode-skills/openlore-implement-story/SKILL.md (not served here)
- examples/opencode-skills/openlore-plan-refactor/SKILL.md (not served here)
- examples/opencode-skills/openlore-review-changes/SKILL.md (not served here)
- examples/opencode-skills/openlore-write-tests/SKILL.md (not served here)
- examples/opencode/agent-guard.ts (not served here)
- examples/opencode/plugins/anti-laziness.ts (not served here)
- examples/opencode/plugins/lib/openlore-context-injector-helpers.ts (not served here)
- examples/opencode/plugins/lib/openlore-decision-extractor-helpers.ts (not served here)
- examples/opencode/plugins/openlore-context-injector.test.ts (not served here)
- examples/opencode/plugins/openlore-context-injector.ts (not served here)
- examples/opencode/plugins/openlore-decision-extractor.test.ts (not served here)
- examples/opencode/plugins/openlore-decision-extractor.ts (not served here)
- examples/opencode/plugins/openlore-enforcer.ts (not served here)
- examples/opencode/prompts/sisyphus-sdd.md (not served here)
- examples/openspec-analysis/README.md (not served here)
- examples/openspec-analysis/SUMMARY.md (not served here)
- examples/openspec-analysis/config.json (not served here)
- examples/openspec-analysis/dependencies.mermaid (not served here)
- examples/openspec-analysis/dependency-graph.json (not served here)
- examples/openspec-analysis/llm-context.json (not served here)
- examples/openspec-analysis/repo-structure.json (not served here)
- examples/openspec-cli/README.md (not served here)
- examples/openspec-cli/openspec/config.yaml (not served here)
- examples/openspec-cli/openspec/specs/architecture/spec.md (not served here)
- examples/openspec-cli/openspec/specs/artifact-graph/spec.md (not served here)
- examples/openspec-cli/openspec/specs/cli/spec.md (not served here)
- examples/openspec-cli/openspec/specs/overview/spec.md (not served here)
- examples/openspec-cli/openspec/specs/parsing/spec.md (not served here)
- examples/openspec-cli/openspec/specs/validation/spec.md (not served here)
- examples/pi/README.md (not served here)
- examples/spec-kit/README.md (not served here)
- examples/spec-kit/commands/drift.md (not served here)
- examples/spec-kit/commands/orient.md (not served here)
- examples/spec-kit/extension.yml (not served here)
- flake.lock (not served here)
- flake.nix (not served here)
- openspec/changes/BACKGROUND-SUBSTRATE-2026-10.md (not served here)
- openspec/changes/COMPETITIVE-SUBSTRATE-2026-07.md (not served here)
- openspec/changes/CONTRACT-GRAPH-AND-AGENT-LOOP-2026-10.md (not served here)
- openspec/changes/DOGFOOD-call-resolution-recall.md (not served here)
- openspec/changes/DOGFOOD-change-impact-certificate.md (not served here)
- openspec/changes/DOGFOOD-v2.0.19.md (not served here)
- openspec/changes/DOGFOOD-v2.1.1-tool-count-drift.md (not served here)
- openspec/changes/DOGFOOD-widen-js.md (not served here)
- openspec/changes/E2E-AUDIT-2026-07.md (not served here)
- openspec/changes/E2E-FIRSTRUN-2026-07-27.md (not served here)
- openspec/changes/ECOSYSTEM-RESEARCH-2026-07-27.md (not served here)
- openspec/changes/FEATURE-UPDATES.md (not served here)
- openspec/changes/FIELD-RESEARCH-2026-07.md (not served here)
- openspec/changes/GOVERNANCE-SUBSTRATE-2026-07-31.md (not served here)
- openspec/changes/HARDEN-DISTRIBUTION-AND-SUBSTRATE.md (not served here)
- openspec/changes/KNOWN-LIMITATIONS-2026-07.md (not served here)
- openspec/changes/KOTLIN-TOTAL-SUPPORT-2026-10.md (not served here)
- openspec/changes/PARALLEL-WORK-COORDINATION.md (not served here)
- openspec/changes/README.md (not served here)
- openspec/changes/RELEASE-v2.1.0.md (not served here)
- openspec/changes/RELEASE-v2.1.1.md (not served here)
- openspec/changes/RELEASE-v2.1.2.md (not served here)
- openspec/changes/RELEASE-v2.1.4.md (not served here)
- openspec/changes/RELEASE-v2.1.5.md (not served here)
- openspec/changes/SPEC-STORE-INTEGRATION.md (not served here)
- openspec/changes/STATUS.md (not served here)
- openspec/changes/STRUCTURAL-CONTEXT-PATTERNS.md (not served here)
- openspec/changes/SUBSTRATE-WHITESPACE-2026-07-27.md (not served here)
- openspec/changes/add-agent-loop-hooks-task-created/proposal.md (not served here)
- openspec/changes/add-agent-loop-hooks-task-created/specs/cli/spec.md (not served here)
- openspec/changes/add-agent-loop-hooks-task-created/tasks.md (not served here)
- openspec/changes/add-assumption-anchored-resolutions/proposal.md (not served here)
- openspec/changes/add-assumption-anchored-resolutions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-assumption-anchored-resolutions/tasks.md (not served here)
- openspec/changes/add-behavior-neutral-change-verdict/proposal.md (not served here)
- openspec/changes/add-behavior-neutral-change-verdict/specs/analyzer/spec.md (not served here)
- openspec/changes/add-behavior-neutral-change-verdict/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-behavior-neutral-change-verdict/tasks.md (not served here)
- openspec/changes/add-build-graph-ingest/proposal.md (not served here)
- openspec/changes/add-build-graph-ingest/specs/analyzer/spec.md (not served here)
- openspec/changes/add-build-graph-ingest/specs/architecture/spec.md (not served here)
- openspec/changes/add-build-graph-ingest/tasks.md (not served here)
- openspec/changes/add-call-site-usage-profile/proposal.md (not served here)
- openspec/changes/add-call-site-usage-profile/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-call-site-usage-profile/tasks.md (not served here)
- openspec/changes/add-callgraph-soundness-calibration/proposal.md (not served here)
- openspec/changes/add-callgraph-soundness-calibration/specs/analyzer/spec.md (not served here)
- openspec/changes/add-callgraph-soundness-calibration/tasks.md (not served here)
- openspec/changes/add-change-provenance-certificate/proposal.md (not served here)
- openspec/changes/add-change-provenance-certificate/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-change-provenance-certificate/tasks.md (not served here)
- openspec/changes/add-codeowners-ownership-evidence/proposal.md (not served here)
- openspec/changes/add-codeowners-ownership-evidence/specs/analyzer/spec.md (not served here)
- openspec/changes/add-codeowners-ownership-evidence/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-codeowners-ownership-evidence/tasks.md (not served here)
- openspec/changes/add-coverage-map-test-selection/proposal.md (not served here)
- openspec/changes/add-coverage-map-test-selection/specs/analyzer/spec.md (not served here)
- openspec/changes/add-coverage-map-test-selection/tasks.md (not served here)
- openspec/changes/add-data-flow-conclusions/proposal.md (not served here)
- openspec/changes/add-data-flow-conclusions/specs/analyzer/spec.md (not served here)
- openspec/changes/add-data-flow-conclusions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-data-flow-conclusions/tasks.md (not served here)
- openspec/changes/add-datastore-access-graph/proposal.md (not served here)
- openspec/changes/add-datastore-access-graph/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-datastore-access-graph/tasks.md (not served here)
- openspec/changes/add-dependency-impact-analysis/proposal.md (not served here)
- openspec/changes/add-dependency-impact-analysis/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-dependency-impact-analysis/tasks.md (not served here)
- openspec/changes/add-doc-claim-certification/proposal.md (not served here)
- openspec/changes/add-doc-claim-certification/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-doc-claim-certification/tasks.md (not served here)
- openspec/changes/add-effect-purity-inference/proposal.md (not served here)
- openspec/changes/add-effect-purity-inference/specs/analyzer/spec.md (not served here)
- openspec/changes/add-effect-purity-inference/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-effect-purity-inference/tasks.md (not served here)
- openspec/changes/add-ffi-boundary-edges/proposal.md (not served here)
- openspec/changes/add-ffi-boundary-edges/specs/analyzer/spec.md (not served here)
- openspec/changes/add-ffi-boundary-edges/tasks.md (not served here)
- openspec/changes/add-flag-impact-analysis/proposal.md (not served here)
- openspec/changes/add-flag-impact-analysis/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-flag-impact-analysis/tasks.md (not served here)
- openspec/changes/add-fleet-coordination-arc/proposal.md (not served here)
- openspec/changes/add-fleet-coordination-arc/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-fleet-coordination-arc/tasks.md (not served here)
- openspec/changes/add-iac-deploy-binding-commands/proposal.md (not served here)
- openspec/changes/add-iac-deploy-binding-commands/specs/analyzer/spec.md (not served here)
- openspec/changes/add-iac-deploy-binding-commands/tasks.md (not served here)
- openspec/changes/add-incremental-early-cutoff/proposal.md (not served here)
- openspec/changes/add-incremental-early-cutoff/specs/analyzer/spec.md (not served here)
- openspec/changes/add-incremental-early-cutoff/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-incremental-early-cutoff/tasks.md (not served here)
- openspec/changes/add-invalidation-receipts/proposal.md (not served here)
- openspec/changes/add-invalidation-receipts/specs/drift/spec.md (not served here)
- openspec/changes/add-invalidation-receipts/tasks.md (not served here)
- openspec/changes/add-knowledge-map-and-coupling-upgrades/proposal.md (not served here)
- openspec/changes/add-knowledge-map-and-coupling-upgrades/specs/analyzer/spec.md (not served here)
- openspec/changes/add-knowledge-map-and-coupling-upgrades/tasks.md (not served here)
- openspec/changes/add-log-anchor-conclusions/proposal.md (not served here)
- openspec/changes/add-log-anchor-conclusions/specs/analyzer/spec.md (not served here)
- openspec/changes/add-log-anchor-conclusions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-log-anchor-conclusions/tasks.md (not served here)
- openspec/changes/add-lsp-evidence-tier/proposal.md (not served here)
- openspec/changes/add-lsp-evidence-tier/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-lsp-evidence-tier/tasks.md (not served here)
- openspec/changes/add-merge-semantic-certificate/proposal.md (not served here)
- openspec/changes/add-merge-semantic-certificate/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-merge-semantic-certificate/tasks.md (not served here)
- openspec/changes/add-migration-impact-certificate/proposal.md (not served here)
- openspec/changes/add-migration-impact-certificate/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-migration-impact-certificate/tasks.md (not served here)
- openspec/changes/add-openspec-proposal-orientation/design.md (not served here)
- openspec/changes/add-openspec-proposal-orientation/proposal.md (not served here)
- openspec/changes/add-openspec-proposal-orientation/specs/cli/spec.md (not served here)
- openspec/changes/add-openspec-proposal-orientation/specs/openspec/spec.md (not served here)
- openspec/changes/add-openspec-proposal-orientation/tasks.md (not served here)
- openspec/changes/add-ownership-tagged-conclusions/proposal.md (not served here)
- openspec/changes/add-ownership-tagged-conclusions/specs/architecture/spec.md (not served here)
- openspec/changes/add-ownership-tagged-conclusions/tasks.md (not served here)
- openspec/changes/add-refactoring-aware-churn/proposal.md (not served here)
- openspec/changes/add-refactoring-aware-churn/specs/analyzer/spec.md (not served here)
- openspec/changes/add-refactoring-aware-churn/tasks.md (not served here)
- openspec/changes/add-resource-lifecycle-conclusions/proposal.md (not served here)
- openspec/changes/add-resource-lifecycle-conclusions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-resource-lifecycle-conclusions/tasks.md (not served here)
- openspec/changes/add-scip-index-interchange/proposal.md (not served here)
- openspec/changes/add-scip-index-interchange/specs/analyzer/spec.md (not served here)
- openspec/changes/add-scip-index-interchange/specs/cli/spec.md (not served here)
- openspec/changes/add-scip-index-interchange/tasks.md (not served here)
- openspec/changes/add-shared-state-hazard-conclusions/proposal.md (not served here)
- openspec/changes/add-shared-state-hazard-conclusions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-shared-state-hazard-conclusions/tasks.md (not served here)
- openspec/changes/add-store-origin-provenance/proposal.md (not served here)
- openspec/changes/add-store-origin-provenance/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-store-origin-provenance/tasks.md (not served here)
- openspec/changes/add-structural-search-tool/proposal.md (not served here)
- openspec/changes/add-structural-search-tool/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-structural-search-tool/tasks.md (not served here)
- openspec/changes/add-symbol-provenance-conclusions/proposal.md (not served here)
- openspec/changes/add-symbol-provenance-conclusions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-symbol-provenance-conclusions/tasks.md (not served here)
- openspec/changes/add-team-memory-promotion/proposal.md (not served here)
- openspec/changes/add-team-memory-promotion/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-team-memory-promotion/tasks.md (not served here)
- openspec/changes/add-test-evidence-claims/.openspec.yaml (not served here)
- openspec/changes/add-test-evidence-claims/design.md (not served here)
- openspec/changes/add-test-evidence-claims/proposal.md (not served here)
- openspec/changes/add-test-evidence-claims/specs/analyzer/spec.md (not served here)
- openspec/changes/add-test-evidence-claims/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-test-evidence-claims/tasks.md (not served here)
- openspec/changes/add-verification-feedback-loop/proposal.md (not served here)
- openspec/changes/add-verification-feedback-loop/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-verification-feedback-loop/tasks.md (not served here)
- openspec/changes/add-vuln-reachability-triage/proposal.md (not served here)
- openspec/changes/add-vuln-reachability-triage/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/add-vuln-reachability-triage/tasks.md (not served here)
- openspec/changes/adopt-agent-context-interop/proposal.md (not served here)
- openspec/changes/adopt-agent-context-interop/specs/cli/spec.md (not served here)
- openspec/changes/adopt-agent-context-interop/specs/generator/spec.md (not served here)
- openspec/changes/adopt-agent-context-interop/tasks.md (not served here)
- openspec/changes/adopt-mcp-tasks-and-cache-hints/proposal.md (not served here)
- openspec/changes/adopt-mcp-tasks-and-cache-hints/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/adopt-mcp-tasks-and-cache-hints/specs/mcp-quality/spec.md (not served here)
- openspec/changes/adopt-mcp-tasks-and-cache-hints/tasks.md (not served here)
- openspec/changes/adopt-spec-link-status-vocabulary/proposal.md (not served here)
- openspec/changes/adopt-spec-link-status-vocabulary/specs/drift/spec.md (not served here)
- openspec/changes/adopt-spec-link-status-vocabulary/specs/verifier/spec.md (not served here)
- openspec/changes/adopt-spec-link-status-vocabulary/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-add-doc-claim-sync-guards/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-add-doc-claim-sync-guards/specs/mcp-quality/spec.md (not served here)
- openspec/changes/archive/2026-07-25-add-doc-claim-sync-guards/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-add-language-capability-conformance/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-add-language-capability-conformance/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-add-language-capability-conformance/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-add-stable-nested-function-identity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-add-stable-nested-function-identity/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-add-stable-nested-function-identity/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-enforce-conclusion-contract-runtime/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-enforce-conclusion-contract-runtime/specs/mcp-quality/spec.md (not served here)
- openspec/changes/archive/2026-07-25-enforce-conclusion-contract-runtime/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-artifact-output-determinism/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-artifact-output-determinism/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-artifact-output-determinism/specs/architecture/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-artifact-output-determinism/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-cli-conclusion-honesty/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-cli-conclusion-honesty/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-cli-conclusion-honesty/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-clone-string-normalization/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-clone-string-normalization/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-clone-string-normalization/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-export-parser-fidelity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-export-parser-fidelity/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-export-parser-fidelity/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-language-detection-single-source/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-language-detection-single-source/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-language-detection-single-source/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-node-sqlite-engine-floor/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-node-sqlite-engine-floor/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-node-sqlite-engine-floor/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-route-anchor-fidelity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-route-anchor-fidelity/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-route-anchor-fidelity/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-fix-test-suite-hygiene/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-fix-test-suite-hygiene/specs/project/spec.md (not served here)
- openspec/changes/archive/2026-07-25-fix-test-suite-hygiene/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-artifact-write-atomicity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-artifact-write-atomicity/specs/architecture/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-artifact-write-atomicity/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-call-resolution-ambiguity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-call-resolution-ambiguity/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-call-resolution-ambiguity/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-index-store-lifecycle/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-index-store-lifecycle/specs/architecture/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-index-store-lifecycle/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-local-http-surfaces/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-local-http-surfaces/specs/mcp-security/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-local-http-surfaces/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-runtime-event-resilience/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-runtime-event-resilience/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-runtime-event-resilience/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-runtime-event-resilience/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-harden-serve-descriptor-trust/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-harden-serve-descriptor-trust/specs/mcp-security/spec.md (not served here)
- openspec/changes/archive/2026-07-25-harden-serve-descriptor-trust/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-modularize-call-graph-builder/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-modularize-call-graph-builder/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-modularize-call-graph-builder/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-optimize-hash-keyed-analyze/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-optimize-hash-keyed-analyze/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-25-optimize-hash-keyed-analyze/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-reconcile-substrate-write-face/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-reconcile-substrate-write-face/specs/mcp-quality/spec.md (not served here)
- openspec/changes/archive/2026-07-25-reconcile-substrate-write-face/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-refine-happy-path-and-defaults/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-refine-happy-path-and-defaults/tasks.md (not served here)
- openspec/changes/archive/2026-07-25-restore-spec-corpus-integrity/proposal.md (not served here)
- openspec/changes/archive/2026-07-25-restore-spec-corpus-integrity/specs/openspec/spec.md (not served here)
- openspec/changes/archive/2026-07-25-restore-spec-corpus-integrity/tasks.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-parallel-extraction-pool/proposal.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-parallel-extraction-pool/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-parallel-extraction-pool/tasks.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-reachability-precompute/proposal.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-reachability-precompute/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-reachability-precompute/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-26-optimize-reachability-precompute/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-add-config-schema-validation/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-add-config-schema-validation/specs/config/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-config-schema-validation/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-add-decision-autopilot/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-add-decision-autopilot/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-decision-autopilot/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-decision-autopilot/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-add-parse-health-boundary-disclosure/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-add-parse-health-boundary-disclosure/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-parse-health-boundary-disclosure/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-parse-health-boundary-disclosure/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-add-symbol-span-locator/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-add-symbol-span-locator/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-symbol-span-locator/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-add-zero-interaction-onboarding/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-add-zero-interaction-onboarding/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-add-zero-interaction-onboarding/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-defer-gryph-runtime-observability/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-defer-panic-blocking-enforcement/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-defer-panic-setup-hooks/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-delegate-lifecycle-scope-decision-sync/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-delegate-lifecycle-scope-decision-sync/specs/architecture/spec.md (not served here)
- openspec/changes/archive/2026-07-27-delegate-lifecycle-scope-decision-sync/specs/openspec/spec.md (not served here)
- openspec/changes/archive/2026-07-27-delegate-lifecycle-scope-decision-sync/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-analyze-native-abort-and-file-cost-budget/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-analyze-native-abort-and-file-cost-budget/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-analyze-native-abort-and-file-cost-budget/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-analyze-native-abort-and-file-cost-budget/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-bm25-identifier-tokenization/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-bm25-identifier-tokenization/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-bm25-identifier-tokenization/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-cli-output-hygiene/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-cli-output-hygiene/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-cli-output-hygiene/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-decision-status-transitions/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-decision-status-transitions/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-decision-status-transitions/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-default-preset-claims/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-default-preset-claims/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-default-preset-claims/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-drift-gate-blindness/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-drift-gate-blindness/specs/drift/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-drift-gate-blindness/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-epistemic-lease-weights/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-epistemic-lease-weights/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-epistemic-lease-weights/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-git-path-quoting/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-git-path-quoting/specs/analyzer/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-git-path-quoting/specs/drift/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-git-path-quoting/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-pi-parity-drift/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-pi-parity-drift/specs/mcp-quality/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-pi-parity-drift/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-redaction-module-gaps/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-redaction-module-gaps/specs/mcp-security/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-redaction-module-gaps/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-structural-diff-merge-base/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-structural-diff-merge-base/specs/mcp-handlers/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-structural-diff-merge-base/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-fix-update-install-detection/proposal.md (not served here)
- openspec/changes/archive/2026-07-27-fix-update-install-detection/specs/cli/spec.md (not served here)
- openspec/changes/archive/2026-07-27-fix-update-install-detection/tasks.md (not served here)
- openspec/changes/archive/2026-07-27-harden-decision-consolidation/proposal.md (not served here)
Advantages
- Deterministic, local-first operation with no LLM in the hot path ensures consistent, grounded answers. evidence: README.md
- Provides governance guardrails that flag breaking changes and sensitive boundary violations before code is committed. evidence: README.md
- Maintains persistent memory across sessions that survives code renames and refactors. evidence: README.md
- Reduces agent round-trips and costs by providing structural context instead of relying on exploratory file reads. evidence: README.md
Limitations
- Static analysis cannot recover reflective invocations, eval, or dynamic DI/plugin registries with no visible bindings. evidence: README.md
- Small, familiar repositories may experience overhead compared to native agent search. evidence: README.md
- Large monorepos require incremental analysis strategies after the initial full build. evidence: README.md
Security
Risk level: Low risk
This brain runs
Agent instructions that run or fetch something (169)
.claude/commands/first-run-hardening.md:Your job: find and fix the bugs that break a NEW USER's first-run experience — the way earlier passes found "unknown command 'orient'", "--no-embed kills BM25", "watcher EMFILE on target/", and "install never builds the index"..claude/commands/first-run-hardening.md:BUILD FIRST so you test current code, not the published version: `npm run build` → drive `node dist/cli/index.js`, never bare `openlore`/`npx openlore` (those resolve the OLD published version)..claude/commands/first-run-hardening.md:When comparing to published behavior, do it explicitly with `npx --yes openlore@latest` and label it..claude/commands/first-run-hardening.md:Run the REAL first-run flow as a user would, end to end, checking exit codes AND actual output of each step: openlore install # the one-command path.claude/commands/first-run-hardening.md:Also exercise: init → analyze → analyze --no-embed → analyze --force → orient (no task / with task / bad --limit) → install --no-analyze → install --dry-run → install --uninstall → mcp server over stdio (initialize → tools/call orient)..claude/commands/first-run-hardening.md:Idempotency / re-runs: running install or analyze twice must be a clean no-op, not a duplicate or a clobber..claude/commands/first-run-hardening.md:Treat other people's repos as READ-ONLY fixtures: after each dogfood run, remove ALL openlore artifacts (.openlore, openspec/, CLAUDE.md, ARCHITECTURE.md) and `git checkout` any modified .gitignore / settings.json..claude/commands/first-run-hardening.md:Verify the repo is clean (`git status`) before moving on..claude/commands/first-run-hardening.md:Verify honestly: run `npm run typecheck` and `npm run test:run` and report the REAL counts..claude/commands/first-run-hardening.md:confirm with `git rev-list --left-right --count origin/main...main` (want `0 0`) before and after..claude/commands/first-run-hardening.md:Branch pruning: only delete branches already merged into origin/main (verify with `git branch -r --merged origin/main`);AGENTS.md:Before committing code (pre-commit hook via `openlore drift --install-hook`)AGENTS.md:openlore drift --install-hook # Install as git pre-commit hookAGENTS.md:[ ] No spec drift — run `openlore drift` to verify specs match codeAGENTS.md:- Run `openspec validate --all` to verify structureAGENTS.md:- Run `openlore drift --install-hook` to catch future driftAGENTS.md:Always run `openlore analyze` first.AGENTS.md:Or install the Vibe skill (creates `.vibe/skills/openlore.md` as a `/openlore` slash command):AGENTS.md:Because the output limit is 4 096 tokens (vs 16 000 for Claude), generation produces **shorter specs per run**.AGENTS.md:**One domain at a time** — run `openlore generate` with `--domain <name>` so each invocation focuses on a single domain and stays within the output budget.AGENTS.md:**Use the analysis artifacts** — always run `openlore analyze` first;AGENTS.md:**Expect multi-pass generation** — large codebases may require multiple `generate` runs (one per domain) rather than a single all-domains run.AGENTS.md:Then run `openlore decisions --sync` and retry `git commit`.AGENTS.md:**`reason: "approved_not_synced"` — decisions approved but not written to specs:** Run `openlore decisions --sync` then retry `git commit`.AGENTS.md:If yes: run `openlore decisions --consolidate --gate` and handle the result.AGENTS.md:If no: retry with `git commit --no-verify` to skip the gate.AGENTS.md:If yes: run `openlore decisions --consolidate --gate` and handle the result.AGENTS.md:If no: retry with `git commit --no-verify` to skip the gate.CLAUDE.md:CLI: `openlore coverage-gaps` | | "What's the blast radius of my diff before I commit?" | `blast_radius` — one advisory briefing: callers/layers, tests to run, anchored memories/decisions that will drift, stale specs | | "Post a deterministic structural review on a PR" (CLI, no MCP/agen …[+99 chars]CLAUDE.md:Call `orient "<task description>"` (via the openlore MCP server, or `npx openlore orient --json`) **before touching a module you have not yet read in this session**, and when a task spans several modules.CLAUDE.md:re-run `openlore install --preset <name>` to change it and regenerate these instructions.examples/mistral-vibe/skills/openlore-analyze-codebase/SKILL.md:Suggest running `/openlore-plan-refactor` once the user has enough context to act, then `/openlore-execute-refactor` to apply the planexamples/mistral-vibe/skills/openlore-analyze-codebase/SKILL.md:To activate `search_specs`, run `openlore analyze --embed` or `openlore analyze --reindex-specs`.examples/mistral-vibe/skills/openlore-brainstorm/SKILL.md:Using Domain Sketch — structural analysis will be available after `openlore analyze` is run on the first implementation."examples/mistral-vibe/skills/openlore-brainstorm/SKILL.md:- First implementation — run `openlore analyze && openlore generate` afterexamples/mistral-vibe/skills/openlore-debug/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/mistral-vibe/skills/openlore-debug/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.examples/mistral-vibe/skills/openlore-debug/SKILL.md:Run it.examples/mistral-vibe/skills/openlore-debug/SKILL.md:**Apply the fix**, then run the test again.examples/mistral-vibe/skills/openlore-debug/SKILL.md:Run the full test suite.examples/mistral-vibe/skills/openlore-debug/SKILL.md:If the domain spec does not exist yet (`uncovered` from Step 8), note the invariant in the story/issue instead and flag it for the next `openlore generate` run.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:"execute the planned refactoring"examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:explicit command `/openlore-execute-refactor`examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:**Prerequisite**: the `openlore-plan-refactor` skill must have been run and the plan confirmed.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:If a coverage tool is available, run it on the target file and compare against the coverage baseline in the plan.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:git status # must show: nothing to commit, working tree cleanexamples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:git log --oneline -1 # note this commit hash — your restore pointexamples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:For **each change** in the plan, execute the full mini-development cycle below.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:**4 — TEST** Run the test gate from the plan entry.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:Run the full test suite one final time to confirm the refactored state is clean.examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:Apply renames one file at a time, run tests after each, and respect the ≤ 50-line edit constraint.**examples/mistral-vibe/skills/openlore-generate/SKILL.md:OpenLore does not validate OpenSpec structure, so run the `openspec validate` follow-up the receipt names.examples/mistral-vibe/skills/openlore-generate/SKILL.md:**If validation cannot run — the CLI is missing, broken, or fails for any reason — say so explicitly and report the spec as NOT validated.** Never present an unvalidated spec as complete;examples/mistral-vibe/skills/openlore-generate/SKILL.md:Finalize: after validation, run `openlore mapping refresh` when shell access is available so the persisted link index matches the spec you wrote.examples/mistral-vibe/skills/openlore-generate/SKILL.md:If you cannot run it, say so explicitly — correctness is unaffected, because audit and Repair re-derive the index in memory, and only the cache is stale.examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:| Situation | Approach | |---|---| | `risk_context` present, risk 🟢 < 40 | Skip to Step 3 — use insertion point from context | | `risk_context` present, risk 🟡 40–69 | Run Step 2 impact check, then proceed | | `risk_context` present, risk 🔴 ≥ 70 | Stop — a blocking refactor story mus …[+81 chars]examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:Run `/openlore-execute-refactor` on the blocking function first, or create a blocking refactor task and return to this story once the risk is resolved.examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:Run the `openlore-repair` host skill before implementing.examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:Only run once tests are green.examples/mistral-vibe/skills/openlore-implement-story/SKILL.md:| Drift type | Resolution | |---|---| | `uncovered` on new files | Note it — propose `openlore generate` post-sprint | | `gap` on existing domain | Run the `openlore-repair` host skill | | `stale` | Fix the reference | | No drift | Done |examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:To apply the plan, use the `openlore-execute-refactor` skill.examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:Each change = one atomic edit → one diff verification → one full test run → ✅ or rollback.examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:If a recent analysis already exists, skip unless the user explicitly requests a fresh run.examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:| Ecosystem | Command | |---|---| | Node.js | `npm test -- --coverage --collectCoverageFrom="<files>"` | | Python | `pytest --cov=<module> --cov-report=term-missing` | | Rust | `cargo tarpaulin --include-files <files>` | | Go | `go test -cover ./...` |examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:**Test gate**: exact test command to run after this changeexamples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:Workflow: /openlore-plan-refactor → /openlore-execute-refactorexamples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:- `git diff --stat` shows only the expected filesexamples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md:Hash: <to be filled by the execute workflow>examples/mistral-vibe/skills/openlore-write-tests/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/mistral-vibe/skills/openlore-write-tests/SKILL.md:If `orient` returns `"error": "no cache"` → run `openlore analyze` first, then retry.examples/mistral-vibe/skills/openlore-write-tests/SKILL.md:| File found | Framework | |---|---| | `vitest.config.*`, `vitest.config.ts` | Vitest — runner: `npx vitest run <file>` | | `jest.config.*` | Jest — runner: `npx jest <file>` | | `pytest.ini`, `pyproject.toml` (with `[tool.pytest]`), `setup.cfg` | pytest — runner: `pytest <file> -v` | …[+147 chars]examples/mistral-vibe/skills/openlore-write-tests/SKILL.md:Run the test file with `$TEST_RUNNER`.examples/opencode-skills/openlore-analyze-codebase/SKILL.md:Suggest running `/openlore-plan-refactor` once the user has enough context to act, then `/openlore-execute-refactor` to apply the planexamples/opencode-skills/openlore-analyze-codebase/SKILL.md:To activate `search_specs`, run `openlore analyze --embed` or `openlore analyze --reindex-specs`.examples/opencode-skills/openlore-brainstorm/SKILL.md:Using Domain Sketch — structural analysis will be available after `openlore analyze` is run on the first implementation."examples/opencode-skills/openlore-brainstorm/SKILL.md:- First implementation — run `openlore analyze && openlore generate` afterexamples/opencode-skills/openlore-debug/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/opencode-skills/openlore-debug/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.examples/opencode-skills/openlore-debug/SKILL.md:Run it.examples/opencode-skills/openlore-debug/SKILL.md:**Apply the fix**, then run the test again.examples/opencode-skills/openlore-debug/SKILL.md:Run the full test suite.examples/opencode-skills/openlore-debug/SKILL.md:If the domain spec does not exist yet (`uncovered` from Step 8), note the invariant in the story/issue instead and flag it for the next `openlore generate` run.examples/opencode-skills/openlore-execute-refactor/SKILL.md:"execute the planned refactoring"examples/opencode-skills/openlore-execute-refactor/SKILL.md:explicit command `/openlore-execute-refactor`examples/opencode-skills/openlore-execute-refactor/SKILL.md:**Prerequisite**: the `openlore-plan-refactor` skill must have been run and the plan confirmed.examples/opencode-skills/openlore-execute-refactor/SKILL.md:If a coverage tool is available, run it on the target file and compare against the coverage baseline in the plan.examples/opencode-skills/openlore-execute-refactor/SKILL.md:git status # must show: nothing to commit, working tree cleanexamples/opencode-skills/openlore-execute-refactor/SKILL.md:git log --oneline -1 # note this commit hash — your restore pointexamples/opencode-skills/openlore-execute-refactor/SKILL.md:For **each change** in the plan, execute the full mini-development cycle below.examples/opencode-skills/openlore-execute-refactor/SKILL.md:**4 — TEST** Run the test gate from the plan entry.examples/opencode-skills/openlore-execute-refactor/SKILL.md:Run the full test suite one final time to confirm the refactored state is clean.examples/opencode-skills/openlore-execute-refactor/SKILL.md:Apply renames one file at a time, run tests after each, and respect the ≤ 50-line edit constraint.**examples/opencode-skills/openlore-generate/SKILL.md:OpenLore does not validate OpenSpec structure, so run the `openspec validate` follow-up the receipt names.examples/opencode-skills/openlore-generate/SKILL.md:**If validation cannot run — the CLI is missing, broken, or fails for any reason — say so explicitly and report the spec as NOT validated.** Never present an unvalidated spec as complete;examples/opencode-skills/openlore-generate/SKILL.md:Finalize: after validation, run `openlore mapping refresh` when shell access is available so the persisted link index matches the spec you wrote.examples/opencode-skills/openlore-generate/SKILL.md:If you cannot run it, say so explicitly — correctness is unaffected, because audit and Repair re-derive the index in memory, and only the cache is stale.examples/opencode-skills/openlore-implement-story/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/opencode-skills/openlore-implement-story/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.examples/opencode-skills/openlore-implement-story/SKILL.md:| Situation | Approach | |---|---| | `risk_context` present, risk 🟢 < 40 | Skip to Step 3 — use insertion point from context | | `risk_context` present, risk 🟡 40–69 | Run Step 2 impact check, then proceed | | `risk_context` present, risk 🔴 ≥ 70 | Stop — a blocking refactor story mus …[+81 chars]examples/opencode-skills/openlore-implement-story/SKILL.md:Run `/openlore-execute-refactor` on the blocking function first, or create a blocking refactor task and return to this story once the risk is resolved.examples/opencode-skills/openlore-implement-story/SKILL.md:Run the `openlore-repair` host skill before implementing.examples/opencode-skills/openlore-implement-story/SKILL.md:Only run once tests are green.examples/opencode-skills/openlore-implement-story/SKILL.md:| Drift type | Resolution | |---|---| | `uncovered` on new files | Note it — propose `openlore generate` post-sprint | | `gap` on existing domain | Run the `openlore-repair` host skill | | `stale` | Fix the reference | | No drift | Done |examples/opencode-skills/openlore-plan-refactor/SKILL.md:To apply the plan, use the `openlore-execute-refactor` skill.examples/opencode-skills/openlore-plan-refactor/SKILL.md:Each change = one atomic edit → one diff verification → one full test run → ✅ or rollback.examples/opencode-skills/openlore-plan-refactor/SKILL.md:If a recent analysis already exists, skip unless the user explicitly requests a fresh run.examples/opencode-skills/openlore-plan-refactor/SKILL.md:| Ecosystem | Command | |---|---| | Node.js | `npm test -- --coverage --collectCoverageFrom="<files>"` | | Python | `pytest --cov=<module> --cov-report=term-missing` | | Rust | `cargo tarpaulin --include-files <files>` | | Go | `go test -cover ./...` |examples/opencode-skills/openlore-plan-refactor/SKILL.md:**Test gate**: exact test command to run after this changeexamples/opencode-skills/openlore-plan-refactor/SKILL.md:Workflow: /openlore-plan-refactor → /openlore-execute-refactorexamples/opencode-skills/openlore-plan-refactor/SKILL.md:- `git diff --stat` shows only the expected filesexamples/opencode-skills/openlore-plan-refactor/SKILL.md:Hash: <to be filled by the execute workflow>examples/opencode-skills/openlore-write-tests/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).examples/opencode-skills/openlore-write-tests/SKILL.md:If `orient` returns `"error": "no cache"` → run `openlore analyze` first, then retry.examples/opencode-skills/openlore-write-tests/SKILL.md:| File found | Framework | |---|---| | `vitest.config.*`, `vitest.config.ts` | Vitest — runner: `npx vitest run <file>` | | `jest.config.*` | Jest — runner: `npx jest <file>` | | `pytest.ini`, `pyproject.toml` (with `[tool.pytest]`), `setup.cfg` | pytest — runner: `pytest <file> -v` | …[+147 chars]examples/opencode-skills/openlore-write-tests/SKILL.md:Run the test file with `$TEST_RUNNER`.skills/openlore-analyze-codebase/SKILL.md:Suggest running `/openlore-plan-refactor` once the user has enough context to act, then `/openlore-execute-refactor` to apply the planskills/openlore-analyze-codebase/SKILL.md:To activate `search_specs`, run `openlore analyze --embed` or `openlore analyze --reindex-specs`.skills/openlore-brainstorm/SKILL.md:Using Domain Sketch — structural analysis will be available after `openlore analyze` is run on the first implementation."skills/openlore-brainstorm/SKILL.md:- First implementation — run `openlore analyze && openlore generate` afterskills/openlore-debug/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).skills/openlore-debug/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.skills/openlore-debug/SKILL.md:Run it.skills/openlore-debug/SKILL.md:**Apply the fix**, then run the test again.skills/openlore-debug/SKILL.md:Run the full test suite.skills/openlore-debug/SKILL.md:If the domain spec does not exist yet (`uncovered` from Step 8), note the invariant in the story/issue instead and flag it for the next `openlore generate` run.skills/openlore-execute-refactor/SKILL.md:"execute the planned refactoring"skills/openlore-execute-refactor/SKILL.md:explicit command `/openlore-execute-refactor`skills/openlore-execute-refactor/SKILL.md:**Prerequisite**: the `openlore-plan-refactor` skill must have been run and the plan confirmed.skills/openlore-execute-refactor/SKILL.md:If a coverage tool is available, run it on the target file and compare against the coverage baseline in the plan.skills/openlore-execute-refactor/SKILL.md:git status # must show: nothing to commit, working tree cleanskills/openlore-execute-refactor/SKILL.md:git log --oneline -1 # note this commit hash — your restore pointskills/openlore-execute-refactor/SKILL.md:For **each change** in the plan, execute the full mini-development cycle below.skills/openlore-execute-refactor/SKILL.md:**4 — TEST** Run the test gate from the plan entry.skills/openlore-execute-refactor/SKILL.md:Run the full test suite one final time to confirm the refactored state is clean.skills/openlore-execute-refactor/SKILL.md:Apply renames one file at a time, run tests after each, and respect the ≤ 50-line edit constraint.**skills/openlore-generate/SKILL.md:OpenLore does not validate OpenSpec structure, so run the `openspec validate` follow-up the receipt names.skills/openlore-generate/SKILL.md:**If validation cannot run — the CLI is missing, broken, or fails for any reason — say so explicitly and report the spec as NOT validated.** Never present an unvalidated spec as complete;skills/openlore-generate/SKILL.md:Finalize: after validation, run `openlore mapping refresh` when shell access is available so the persisted link index matches the spec you wrote.skills/openlore-generate/SKILL.md:If you cannot run it, say so explicitly — correctness is unaffected, because audit and Repair re-derive the index in memory, and only the cache is stale.skills/openlore-implement-story/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).skills/openlore-implement-story/SKILL.md:If `orient` returns `"error": "no cache"` → run `analyze_codebase` first, then retry.skills/openlore-implement-story/SKILL.md:| Situation | Approach | |---|---| | `risk_context` present, risk 🟢 < 40 | Skip to Step 3 — use insertion point from context | | `risk_context` present, risk 🟡 40–69 | Run Step 2 impact check, then proceed | | `risk_context` present, risk 🔴 ≥ 70 | Stop — a blocking refactor story mus …[+81 chars]skills/openlore-implement-story/SKILL.md:Run `/openlore-execute-refactor` on the blocking function first, or create a blocking refactor task and return to this story once the risk is resolved.skills/openlore-implement-story/SKILL.md:Run the `openlore-repair` host skill before implementing.skills/openlore-implement-story/SKILL.md:Only run once tests are green.skills/openlore-implement-story/SKILL.md:| Drift type | Resolution | |---|---| | `uncovered` on new files | Note it — propose `openlore generate` post-sprint | | `gap` on existing domain | Run the `openlore-repair` host skill | | `stale` | Fix the reference | | No drift | Done |skills/openlore-orient/SKILL.md:This is the lowest-latency path and gives the model access to whatever tool surface the server was wired with — the lean 10-tool `navigation` preset by default (`openlore install --preset full` wires all 62), not just `orient`.skills/openlore-orient/SKILL.md:bash scripts/orient.sh "<task description>"skills/openlore-orient/SKILL.md:The wrapper tries the direct CLI subcommand first (`npx --yes openlore orient --json --task "<task>"`) and falls back to driving the `openlore mcp` server over stdio JSON-RPC via the sibling `orient-via-mcp.mjs` helper on older openlore versions that predate the CLI subcommand.skills/openlore-orient/SKILL.md:Run `npx openlore analyze` once to seed the graph, then retry.skills/openlore-orient/SKILL.md:Re-run `npx openlore analyze` to rebuild.skills/openlore-plan-refactor/SKILL.md:To apply the plan, use the `openlore-execute-refactor` skill.skills/openlore-plan-refactor/SKILL.md:Each change = one atomic edit → one diff verification → one full test run → ✅ or rollback.skills/openlore-plan-refactor/SKILL.md:If a recent analysis already exists, skip unless the user explicitly requests a fresh run.skills/openlore-plan-refactor/SKILL.md:| Ecosystem | Command | |---|---| | Node.js | `npm test -- --coverage --collectCoverageFrom="<files>"` | | Python | `pytest --cov=<module> --cov-report=term-missing` | | Rust | `cargo tarpaulin --include-files <files>` | | Go | `go test -cover ./...` |skills/openlore-plan-refactor/SKILL.md:**Test gate**: exact test command to run after this changeskills/openlore-plan-refactor/SKILL.md:Workflow: /openlore-plan-refactor → /openlore-execute-refactorskills/openlore-plan-refactor/SKILL.md:- `git diff --stat` shows only the expected filesskills/openlore-plan-refactor/SKILL.md:Hash: <to be filled by the execute workflow>skills/openlore-repair/SKILL.md:OpenLore does not validate OpenSpec structure, so run the `openspec validate` follow-up the receipt names.skills/openlore-repair/SKILL.md:**If validation cannot run — the CLI is missing, broken, or fails for any reason — say so explicitly and report the spec as NOT validated.** Never present an unvalidated edit as complete;skills/openlore-repair/SKILL.md:Finalize: after validation, run `openlore mapping refresh` when shell access is available so the persisted link index matches the spec you edited.skills/openlore-repair/SKILL.md:If you cannot run it, say so explicitly — correctness is unaffected, because audit and Repair re-derive the index in memory, and only the cache is stale.skills/openlore-write-tests/SKILL.md:**Prerequisite**: openlore analysis must exist (`openlore analyze` has been run).skills/openlore-write-tests/SKILL.md:If `orient` returns `"error": "no cache"` → run `openlore analyze` first, then retry.skills/openlore-write-tests/SKILL.md:| File found | Framework | |---|---| | `vitest.config.*`, `vitest.config.ts` | Vitest — runner: `npx vitest run <file>` | | `jest.config.*` | Jest — runner: `npx jest <file>` | | `pytest.ini`, `pyproject.toml` (with `[tool.pytest]`), `setup.cfg` | pytest — runner: `pytest <file> -v` | …[+147 chars]skills/openlore-write-tests/SKILL.md:Run the test file with `$TEST_RUNNER`.
Package scripts (1)
package.json(postinstall):node scripts/postinstall.mjs
- Low risk: network-instructions (.claude/commands/first-run-hardening.md:21)
- Low risk: scripts-present (bench/retrieval/run.ts)
- Low risk: scripts-present (bench/run.ts)
- Low risk: autonomy-phrase (examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md:240)
- Low risk: autonomy-phrase (examples/opencode-skills/openlore-execute-refactor/SKILL.md:240)
- Low risk: scripts-present (scripts/api-consumer-smoke.mjs)
- Low risk: scripts-present (scripts/copy-assets.mjs)
- Low risk: scripts-present (scripts/postinstall.mjs)
- Low risk: autonomy-phrase (skills/openlore-execute-refactor/SKILL.md:240)
- Low risk: network-instructions (skills/openlore-orient/SKILL.md:37)
- Low risk: scripts-present (skills/openlore-orient/scripts/orient.sh)
Attribution and licence
- Created by
- Clay Good
- Declared authors
- Clay Good (declared in package.json)
- Publisher
- Clay Good (Community)
- Source
- clay-good/OpenLore · commit c45c2ca
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Clay Good.
Install from source
450 of its files are not served here, so there is no ZIP. clay-good/OpenLore at c45c2ca