Generated banner for OpenLore
Generated logo for OpenLore

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.
— the description by Clay Good

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.

Folders
FolderRoleFiles
.claudeagent-config1
.githubagent-config12
docsdocs62
examplesexamples95
scriptsscripts27
skillsagent-instructions25
srcsource-code1284
benchfolder15
benchmarksfolder1
openspecfolder1261
packagingfolder2
schemasfolder2
stubsfolder1

The agent reads

The agent writes

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

  1. 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
  2. Not scanned by AutoGineerAutoGineer could not scan everything it runs. https://www.npmjs.com/package/openlore
  3. 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 install

That 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 — install wires 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 review on 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 features to see every opt-in capability (embeddings, the commit gate, the spec store…), whether it's on, and the one command to enable it. openlore doctor verifies 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_surface classifies every changed export breaking / non-breaking / potentially-breaking and names the consumers each break hits. Never silently "safe."

  • Sensitive-boundary check — change_impact_certificate flags when a diff opens a new path into a boundary you declared (reachable after the change, not before).

  • Grounded claims — verify_claim returns confirmed / refuted / unverifiable with a citation, before an agent asserts "X is dead" or "Y is safe to change."

  • One commit gate — openlore enforce blocks on findings you mark blocking. 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.

ScenarioCost Δ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 --estimate on 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 fitA 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, measureMid-size repos and mixed workloads. Run openlore prove --estimate (seconds, no key) before you commit.
❌ Probably notA 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 taskorient(task) — functions, callers, specs, insertion points in one call
Find which file/function handles Xsearch_code
Know the blast radius of a changeanalyze_impact — risk + up/downstream chain + governing decisions
Trace how request X reaches function Ytrace_execution_path
Pick the tests a change should runselect_tests — backward reachability to the reaching tests
Find dead code / what dies if X is deletedfind_dead_code — cross-language reachability
Check a whole diff before commitblast_radius — callers, tests, specs that drift
Tell if a diff opens a sensitive boundarychange_impact_certificate
Tell if a change breaks a consumer's APIcertify_public_surface — verdict, consumers named
Verify a fact before asserting itverify_claim — deterministic verdict + citation
Record an architectural choicerecord_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-insLSP toolkitsGraph MCPSearch platformsOpenLore
Structural context instead of file reads❌ grep✓ symbols✓ graph✓ index✓ call graph + IaC + decisions on one graph
Local, no API key, deterministicPartial✓✓❌ 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 costsOn ripgrep (232 files)
One-time index build13.6 s, entirely local — no API key, no network
Disk27 MB under .openlore/ (gitignorable; rebuildable from source)
Per-query latency~430 µs p50 in-process via the MCP server
Your source codenever leaves the machine — no account, no telemetry (opt-in only)
Lock-innone — 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=1 records tool calls, agent identity, latency, error messages, decision titles, and lease events to the gitignored .openlore/telemetry/ directory, and OPENLORE_LLM_LOGS=1 stores 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_code work 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 helpsagent-setup.md
See all 83 MCP tools + parametersmcp-tools.md
Run the full CLI referencecli-reference.md
Configure .openlore/config.json (incl. enforcement.policy)configuration.md
Choose / configure an LLM provider (optional)providers.md
Fix a setup problemTROUBLESHOOTING.md
Read the benchmark methodology + per-task numbersAGENT-BENCHMARKS.md
Search code by meaning (semantic / GraphRAG)semantic-search.md
Pick the tests a change should runtest-impact-selection.md
Find dead code / coverage gapsreachability-dead-code.md · coverage-gaps.md
Detect spec ↔ code driftdrift-detection.md
Enforce architecture / import rulesarchitecture-invariants.md
Gate commits / wire CI & PR reviewci-cd.md · preflight.md
Understand IaC & cross-domain impactiac.md · cross-domain-impact.md
See declared API contracts in the graphcontracts.md
Query across repos (federation)federation.md
Share the index as a bundleshareable-bundle.md
Export to Sourcegraph / SCIP toolsscip-export.md
Read the internalsARCHITECTURE.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 typecheck

New 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.


  • OpenSpec — spec-driven development framework

  • AGENTS.md — system prompt for direct LLM prompting

  • Examples — BMAD, Vibe, GSD, drift-demo, spec-kit integrations

docs/configuration.md

Configuration

This page documents .openlore/config.json. For the LLM provider table (keys, env vars, default models), see providers.md. To list opt-in features and how to enable each, run openlore features.

openlore init creates .openlore/config.json:

{
  "version": "1.2.0",
  "projectType": "nodejs",
  "openspecPath": "./openspec",
  "analysis": {
    "maxFiles": 500,
    "includePatterns": [],
    "excludePatterns": []
  },
  "generation": {
    "model": "claude-sonnet-4-20250514",
    "domains": "auto"
  }
}
Workspace shards

analyze detects monorepo package boundaries from existing manifests. Usually no configuration is needed. To replace detection with explicit repository-relative roots, add:

{
  "workspace": {
    "shards": [
      { "name": "payments", "root": "services/payments" },
      { "name": "web", "root": "apps/web" }
    ]
  }
}

After one full analysis, openlore analyze --shard payments recomputes that package and every outside call site whose resolution may change. Files matching no configured root belong to the nameable root shard. Boundaries partition the corpus after analysis.includePatterns and analysis.excludePatterns; they never widen it. The scoped receipt is .openlore/analysis/workspace-shards.json. See Analyze options. Configured names and roots must be non-empty and unique; root is reserved. OpenLore bounds workspace declarations to 2,000 manifest patterns and 5,000 resolved shards so repository-owned metadata cannot turn discovery into an unbounded scan.

Repository vocabulary expansion

Keyword search mines a deterministic abbreviation and co-occurrence vocabulary from the repository during openlore analyze. A verified vocabulary is applied only to queries: it does not add terms to the BM25 corpus or change index size. Results with an original query-term match always rank ahead of expansion-only results, and responses name only expansion terms that actually scored. The served mode is keyword+vocabulary; if the artifact is missing, stale, invalid, or disabled, OpenLore serves ordinary keyword mode.

Expansion is enabled by default. Disable it without rebuilding the index:

{
  "retrieval": {
    "vocabularyExpansion": false
  }
}

Disabling expansion restores ordinary keyword ranking. Semantic retrieval remains the higher-recall path; openlore status and openlore doctor name it in both keyword modes. Agent responses report retrievalMode only, with no advice to change it. openlore prove --estimate reports a separately labeled recall@10 comparison over up to 100 of the repository's own symbol/doc-comment pairs; it is not an agent-cost benchmark.

Environment Variables
VariableProviderDescription
ANTHROPIC_API_KEYanthropicAnthropic API key
ANTHROPIC_API_BASEanthropicCustom base URL (proxy / self-hosted)
OPENAI_API_KEYopenaiOpenAI API key
OPENAI_API_BASEopenaiCustom base URL (Azure, proxy...)
OPENAI_COMPAT_API_KEYopenai-compatAPI key for OpenAI-compatible server
OPENAI_COMPAT_BASE_URLopenai-compatBase URL, e.g. https://api.mistral.ai/v1
GEMINI_API_KEYgeminiGoogle Gemini API key
COPILOT_API_BASE_URLcopilotBase URL of the copilot-api proxy (default: http://localhost:4141/v1)
COPILOT_API_KEYcopilotAPI key if the proxy requires auth (default: copilot)
EMBED_BASE_URLembedding (remote)Base URL for a remote OpenAI-compatible embedding API (e.g. http://localhost:11434/v1)
EMBED_MODELembedding (remote)Remote embedding model name (e.g. nomic-embed-text)
EMBED_API_KEYembedding (remote)API key for the remote embedding service (defaults to OPENAI_API_KEY)
EMBED_SKIP_SSL_VERIFYembedding (remote)Set to 1/true to skip TLS certificate verification for embedding requests only (self-signed internal server). See Self-signed certificates
LLM_SKIP_SSL_VERIFYLLM providersSet to 1/true to skip TLS certificate verification for LLM requests only. Equivalent to --insecure, but reaches the paths that never see a command line (the openlore mcp daemon, the pre-commit decisions gate)
NODE_EXTRA_CA_CERTS--Path to a PEM CA certificate to trust in addition to the system roots. Preferred over either skip flag: it makes the certificate verify rather than disabling the check
DEBUG--Enable stack traces on errors
CI--Auto-detected; enables timestamps in output
OPENLORE_NO_AUTO_ANALYZE--Disable the MCP server's cold-start self-bootstrap (no background index build on first run)
OPENLORE_NO_UPDATE_NOTIFIER--Silence the passive "update available" banner (NO_UPDATE_NOTIFIER is also honored)
OPENLORE_SKIP_POSTINSTALL--Suppress the post-install next-step hint
OPENLORE_LLM_LOGSLLM commands/APISet to exactly 1 to persist redacted prompts and responses under .openlore/logs/; disabled by default, new opted-in logging is bounded to six files or 300 MB (older logs are pruned on the next opted-in save)
OPENLORE_NO_WORKERSanalyzeRun per-file extraction on a single thread instead of the worker pool. Both lanes produce byte-identical analysis output, so this only costs wall-clock — set it to isolate a worker-related problem, or in an environment where extra threads are unwelcome. A worker never gets the last word on a file: anything it reports as empty, or as a parse failure, is re-extracted on the main thread, so a parse-failure in parse-health.json always rests on the main thread's own attempt. If analyze ever prints a lane defect ("extraction worker reported a parse failure for N file(s) that the main thread extracted fine"), the facts are still whole — set this flag to skip the pool, and please report it
OPENLORE_NO_FACT_CACHEanalyzeRe-extract every file instead of reusing the per-file extraction cache, exactly as --force does (and, like --force, the cache is refilled afterwards). Both lanes produce byte-identical analysis output, so this only costs wall-clock — reach for it when a CLI flag is not available, e.g. from an embedded caller
OPENLORE_NO_AUTO_HEAPCLIDisable adaptive heap sizing — the CLI runs at Node's default heap (or whatever you set) with no re-exec, exactly as before this feature existed
OPENLORE_HEAP_MBCLIForce the analyzer's V8 old-space heap to this many MB (skips auto-detection). Equivalent to setting --max-old-space-size yourself, but as an env knob
OPENLORE_HEAP_FRACTIONCLIFraction of available memory used for the heap when sizing automatically (default 0.75)
OPENLORE_FORCE_MEMORY_TIERanalyzeForce the graceful-degradation tier: full, shed-overlay, or shed-overlay-and-deep-analysis. Overrides the pre-flight estimate — for a memory-constrained CI job that wants reduced fidelity deterministically, or to reproduce the degraded path
Self-signed certificates

An internal embedding server or LLM gateway with a self-signed certificate fails with UNABLE_TO_VERIFY_LEAF_SIGNATURE. There are two ways out, and they are not equivalent.

Preferred — trust the signing CA. Verification stays on; the certificate simply validates:

export NODE_EXTRA_CA_CERTS=/path/to/internal-ca.crt   # Windows: setx NODE_EXTRA_CA_CERTS "C:\certs\internal-ca.crt"

Point it at the CA that signed the certificate, not the server certificate itself, or the chain will not validate. It is read once at process start, so restart the daemon/IDE after setting it. It covers both surfaces, including the openlore mcp daemon and the pre-commit decisions gate.

Fallback — skip verification for one surface. Only when the CA is not available. The keys are scoped on purpose: an internal embedding server does not justify relaxing an LLM vendor's perfectly valid certificate, so there is no global switch.

export EMBED_SKIP_SSL_VERIFY=1   # embedding requests only
export LLM_SKIP_SSL_VERIFY=1     # LLM requests only  (or pass --insecure for one command)

Verification is relaxed per request rather than for the process lifetime, but it is still process-global while a request is in flight — use these only on a trusted network.

A repository's own .openlore/config.json can never disable verification: llm.sslVerify: false and embedding.skipSslVerify: true are refused with a warning, because a clone must not be able to turn off certificate checking on the machine analyzing it. Only the operator's flags and environment can.

Remote embeddings need both variables. EMBED_BASE_URL without EMBED_MODEL is a no-op that falls back to the keyword (BM25) index — openlore warns when it sees that combination.

The extraction cache costs disk. analyze memoizes each file's extracted facts inside call-graph.db, keyed by content hash, so a later run re-parses only what changed. It is the largest table in the store — roughly 10 MB per 800 source files (about +55% on the graph index). It is a pure cache: deleting .openlore/analysis/ reclaims it and costs only time, never correctness. (analyze --force re-extracts everything and then refills the cache, so it reclaims nothing — it is the correctness escape, not the disk one.) The cache is stripped from openlore export bundles, which carry the graph and not this machine's build cache.

Trusted bundle producers

Signed bundle import is opt-in. Each trusted signer is an inline Ed25519 public key in SPKI PEM form; an optional label is display-only, while OpenLore derives identity from the key fingerprint. Because this repository-controlled file defines the trust root, review changes to it like any other security-sensitive configuration.

{
  "bundle": {
    "trustedSigners": [
      { "label": "release", "publicKey": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" }
    ]
  }
}

The EMBED_* variables configure the remote embedding provider only. For on-device embeddings with no endpoint or key, run openlore embed --local (or set embedding.provider: "local" in .openlore/config.json). Keyword (BM25) search is the first-class default and needs none of these. See docs/semantic-search.md for the full embedding/retrieval-mode reference.

Repository secret redaction

OpenLore redacts credential-shaped repository content before source-carrying tool results reach an agent. Redacted results include a count and the matched credential kinds. Persisted LLM request logs use the same pattern set for both prompts and responses and record the redaction count per request.

The tool-output boundary is enabled by default. Repository config cannot disable it because cloned code is not trusted to choose whether source secrets are disclosed. A trusted solo operator who requires byte-exact tool output can opt out explicitly for one process:

OPENLORE_UNREDACT_TOOL_OUTPUT=1 openlore mcp

This opt-out does not disable redaction in LLM logs, errors, or telemetry.

Analyzing at any repository size

The promise: openlore analyze works to your machine's capacity, degrades gracefully and transparently beyond it, and never crashes — with no flags and no attention. Two mechanisms deliver that, both on by default:

  1. Adaptive heap sizing. A very large repository's call graph can outgrow Node's default V8 heap, and the old recourse was knowing to pass --max-old-space-size by hand. The CLI now sizes its own heap: the finite graph-building commands (analyze, install, prove, import, run) re-execute themselves once at startup with a heap set to a generous fraction (0.75) of the memory available to the process — the container/cgroup limit when there is one (walking the cgroup hierarchy for the tightest cap, so a CI or container job sizes to its own limit, not the host's, and is not OOM-killed), otherwise host RAM. It is quiet and safe: at most once (a marker prevents any loop), skipped when you already set the heap (--max-old-space-size / NODE_OPTIONS) or opted out (OPENLORE_NO_AUTO_HEAP), and the one-line disclosure goes to stderr, never stdout. The query hot paths (orient, search, …) and the long-lived daemons (mcp, serve) are not re-executed — the hot paths read bounded data and must not pay an extra process spawn, and a daemon must not run behind a blocking supervisor that could orphan it on a directed signal; give a daemon on a huge repo a heap the ordinary way (--max-old-space-size or OPENLORE_HEAP_MB, both honored). Turn sizing off with OPENLORE_NO_AUTO_HEAP=1; pin an exact size with OPENLORE_HEAP_MB; change the fraction with OPENLORE_HEAP_FRACTION.

  2. Graceful degradation, disclosed. Before the heavy passes, the analyzer estimates the memory the graph will need from the repository's own size (file count + bytes). If even the largest sane heap will not hold full-fidelity analysis, it sheds the most expensive, least-essential work first — the CFG/def-use overlay, then LLM deep-analysis breadth — and still produces a usable index (call graph + search intact), rather than aborting with a raw out-of-memory fatal. Whatever it reduced is disclosed in parse-health.json (a memoryDegradation record) and in one CLI line, so a downstream conclusion reads reduced coverage as reduced, never as genuine structural absence.

Determinism is preserved. Heap size and buffer-versus-spill choices never change the produced artifact: two full-fidelity runs of the same repository are byte-identical regardless of how much RAM each machine had. Only the degradation ladder reduces content, and only as a function of declared constraints (available memory, repository size) — disclosed and reproducible, never a silent machine-dependent difference between two "full" runs.

Embeddable API path. The in-process API (import { analyze } from 'openlore') cannot re-execute the host process, so it does not resize the heap — the host owns that. The degradation ladder still applies within whatever heap the host provides, so an over-capacity repository degrades gracefully there too instead of crashing. Because the pre-flight estimate is deliberately conservative (it over-estimates so degradation triggers before a crash), an embedding host running at Node's default heap may shed the overlay on a large-but-manageable repository. If you want full fidelity there, give the host process a real heap (--max-old-space-size, or OPENLORE_HEAP_MB), or force the tier with OPENLORE_FORCE_MEMORY_TIER=full when you know it fits.

Not yet in scope: an out-of-core (streaming) graph — a graph larger than RAM, persisted and never held whole. Adaptive heap plus graceful degradation cover the practical need; a genuine RAM-ceiling case at normal function density would earn its own proposal.

Spec-store binding

An optional specStore block in .openlore/config.json binds this repository to an external spec store — a standalone repository that holds specs/changes — and declares the code repositories its plans are about. It is configuration only: OpenLore reads the declared relationships and never clones, writes to, syncs, or fences the store or any target. Omit the block entirely for unchanged single-repository behavior.

{
  "specStore": {
    "name": "team-plans",
    "path": "../team-plans",
    "targets": ["api", "web"],
    "references": ["design-system"]
  }
}
FieldRequiredMeaning
nameyesa stable, user-facing name for the store
pathyesabsolute or repo-relative path to the external spec repository
targetsyesfederation-registered names of the code repositories the store's work is about
referencesnofederation-registered names of repositories the store draws on for context

targets and references are names, not paths: each must match a repository registered with openlore federation add … --name <name> (see Federation). Check the binding's health with openlore spec-store status (CLI reference); it reports per-target resolution, index freshness, reference presence, and store-path presence as findings with stable codes, and never blocks.

Covering surfaces (change-impact certificate)

An optional impactCertificate block declares the covering surfaces the change-impact certificate assesses a diff against — semantic or governance boundaries (a client surface, a data-handling surface, a regulated interface), not directory globs. Omit it entirely and the certificate still reports blast radius, drifted specs, and tests; declaring surfaces additionally reports the paths a change newly opens into each. See openlore impact-certificate and the change_impact_certificate MCP tool.

{
  "impactCertificate": {
    "surfaces": [
      {
        "name": "client",
        "severity": "critical",
        "members": [
          { "symbol": "renderResponse" },
          { "file": "src/api/public.ts" }
        ]
      }
    ],
    "block": ["critical"]
  }
}
FieldRequiredMeaning
surfaces[].nameyesa stable, user-facing surface name (must be unique; empty names and duplicates are dropped)
surfaces[].membersyesthe boundary's members: each is a { "symbol": "<name>" } (resolved to exactly one indexed symbol — ambiguous/unknown becomes a finding, never guessed) and/or a { "file": "<repo-relative path>" } (all of the file's symbols). A member may set both.
surfaces[].severitynoinfo | warn | critical (default warn); any other value is coerced to warn
blocknoseverities the advisory git hook should fail a commit on (e.g. ["critical"]). Empty/absent = advisory-only (the default). Infrastructure failure never blocks. Now thin legacy sugar that lowers onto enforcement.policy (["critical"] ≡ { "surface-critical": "blocking" }); a direct policy entry wins.

A surface is resolved against the indexed graph (plus any symbol the same diff just added). The certificate is advisory by default and decays via the code-anchored freshness lease; when an anchored symbol later moves, openlore spec-store status re-fires a persisted certificate as a certificate-stale finding.

Enforcement policy

An optional enforcement.policy block is the single source of truth for what blocks a commit, freezes existing debt, merely advises, or is deliberately silenced. It maps a stable governance finding code to one enforcement class — blocking, frozen, advisory, or off — decoupling a finding's intrinsic severity (owned by the source that computes it) from this repository's risk posture (owned here). It is consumed by openlore enforce, the unified gate.

{
  "enforcement": {
    "policy": {
      "stale-decision-reference": "blocking",
      "surface-critical": "frozen",
      "orphans-anchored-memory": "off"
    }
  }
}
  • Additive and optional. An absent or empty policy preserves today's behavior exactly — every finding stays advisory by default, so nothing newly blocks.

  • Brownfield ratchet. frozen records the code's current finding identities in .openlore/enforcement-baseline.jsonl; later findings absent from that committed baseline block, and fixed identities are removed. Run openlore enforce outside hook mode to initialize or shrink the baseline. Review the result, then run git add .gitignore and git add .openlore/config.json .openlore/enforcement-baseline.jsonl before enabling the hook. Hooks and PR review never initialize debt from the candidate change, and PR review never shrinks the baseline.

  • Stable identity. Baseline matching uses code + subject + a source-owned discriminator where needed. It never uses message wording or file:line, so moving a violation does not un-freeze it.

  • Reviewable progress. A hook that ratchets the baseline keeps the commit blocked until the changed baseline is staged. Read-only PR review reports identities that would retire and directs the operator to run openlore enforce locally. An invalid candidate config cannot silently disable a frozen policy from the trusted base. Downgrading frozen to advisory through a valid config leaves its baseline bytes untouched; re-upgrading resumes from them.

  • Deterministic precedence. A finding's class is a pure function of (code, policy): a direct enforcement.policy value (blocking, frozen, advisory, or off) wins over legacy sugar, and legacy sugar wins over the source-declared default. Each code has one effective class; there is no priority ordering among explicit class values.

  • Severity is never changed. The policy decides enforcement class only; the emitting source remains the sole authority on a finding's intrinsic severity.

  • off is visible, not invisible. A silenced finding is still listed in the gate output (marked off), so a deliberate silence is auditable.

  • Legacy block sugar lowers onto it. blastRadius.block: ["orphans-anchored-decision"] and impactCertificate.block: ["critical"] are thin equivalents of enforcement.policy: { "orphans-anchored-decision": "blocking" } and { "surface-critical": "blocking" }. A direct enforcement.policy entry always wins over inherited legacy sugar.

  • Unknown codes are retained. Naming a code no installed source emits yet is not an error — the entry is kept and surfaced as an informational note, so a policy may name a code before its source ships.

The governable finding codes (the finding-code catalogue — every code defaults to advisory; blocking is always opt-in):

CodeSourceDefaultMeaning
stale-decision-referencestale-decision-referenceadvisoryA live, authoritative artifact (approved decision, non-orphaned anchored memory, or spec requirement) references a decision that has since been superseded.
orphans-anchored-memoryblast-radiusadvisoryThe change orphans one or more code-anchored memories.
memory-anchor-lostmemory-freshnessadvisoryA recorded memory has an anchor that is lost or ambiguous (needs-human-reselection), so recall withholds it. One finding per memory, with the memory id as subject; openlore enforce always collects it, and recall also returns it in findings. Set to blocking or frozen, it also fails the gate when the check is incomplete: no analysis, an unreadable memory store, or an anchored file whose content differs from what the analysis recorded (a file the index has no content key for, such as one from an imported bundle, is disclosed but does not fail it). openlore enforce never renames a torn notes.json or decisions/pending.json; it stays in place and is reported until repaired, and the corpus-integrity codes (blocking by default) fail on it, so a commit is blocked until it is fixed.
declining-healthhealth-mapadvisoryA high-complexity function in a churned file never got simpler and ended more complex over its sampled recent commits (rising in get_health_map's complexityTrend).
deprecated-symbol-usestructural-diffadvisoryA diff adds a call into a symbol marked deprecated by its language's standard marker (see deprecationMarkers in language support). Calls that were already there do not fire it. structural_diff returns these findings in deprecatedCalls, classified by this policy.
unresolved-internal-importphantom-referencesadvisoryA diff adds a relative import whose target is not a file in this repository. A path alias the resolver cannot follow is disclosed instead. verify_change returns these in findings, classified by this policy; openlore enforce does not collect them. See phantom references.
unresolved-internal-symbolphantom-referencesadvisoryA diff adds a named import the target module does not export, read from the target's current content. A target that re-exports from somewhere unfollowable is disclosed instead.
undeclared-dependencyphantom-referencesadvisoryA diff adds an import of an external package no manifest in scope declares, and that is not the standard library. An ecosystem with no readable manifest is disclosed instead.
unpinned-dependencyphantom-referencesadvisoryA diff adds an import of a package its changed manifest declares but the lockfile beside it does not pin. An absent or unparseable lockfile yields no finding.
generated-file-editedgenerated-file-guardadvisoryA diff edits a generated or vendored file without its source or the config entry that regenerates it, or changes a lockfile without its manifest. A newly added generated file does not fire it. verify_change returns these in findings, classified by this policy; openlore enforce does not collect it. See generated files.
test-removedcheck-weakeningadvisoryA test case or test file present at the baseline (the merge-base) is gone; a case renamed with the same body does not fire it. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
test-disabledcheck-weakeningadvisoryA skip marker (it.skip, xit, @pytest.mark.skip, t.Skip, @Disabled) or a focus marker (.only, fit) was added to a test. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
assertions-reducedcheck-weakeningadvisoryA test has fewer assertion calls than at the baseline. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
expected-value-changedcheck-weakeningadvisoryA literal argument of a test's assertions changed while no production symbol the test file reaches changed. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
suppression-addedcheck-weakeningadvisoryA suppression comment or annotation was added (@ts-ignore, eslint-disable, # noqa, # type: ignore, //nolint, @SuppressWarnings, …). structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
error-swallowedcheck-weakeningadvisoryA new catch/except (or Go if err != nil) block that is empty, or only logs and returns at most a constant, around a call. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
check-config-relaxedcheck-weakeningadvisoryA test-runner, coverage, lint, or CI config was relaxed (exclude added, rule off, threshold lowered or removed, continue-on-error or if: false added, test step removed or changed, config deleted), or .openlore/config.json lowered the enforcement class of a check-weakening code. structural_diff and verify_change return it, classified by this policy; openlore enforce does not collect it. See check weakening.
orphans-anchored-decisionblast-radiusadvisoryThe change orphans one or more anchored architectural decisions.
surface-infoimpact-certificateadvisoryThe change opens a new path into a declared covering surface marked info.
surface-warnimpact-certificateadvisoryThe change opens a new path into a declared covering surface marked warn.
surface-criticalimpact-certificateadvisoryThe change opens a new path into a declared covering surface marked critical.
parallel-work-conflictplan-parallel-workadvisoryTwo tasks proposed for concurrent work have a write-write (WAW) conflict; plan_parallel_work schedules them into different waves.
parallel-work-cycleplan-parallel-workadvisoryA set of proposed tasks forms an unorderable read-after-write cycle; plan_parallel_work schedules the members mutually exclusive and the circular dependency should be resolved.
cross-actor-conflictinterference-mapadvisoryTwo in-flight changes (branches/PRs/agent tasks, within or across a federation) have a write-write (WAW) conflict on a shared symbol; map_in_flight_conflicts reports them as must-not-land-concurrently. A CI check can name this code to warn when a new PR collides with an open one.
duplicate-intentdeclare-footprintadvisoryTwo live agents on the peer board intend to create the same symbol name or file.
export-removedpublic-surfaceadvisoryAn exported symbol was removed from the public surface.
export-renamedpublic-surfaceadvisoryAn exported symbol was renamed; consumers binding the old name break.
export-visibility-reducedpublic-surfaceadvisoryAn exported symbol is still defined but no longer exported.
param-removedpublic-surfaceadvisoryA parameter was removed from an exported signature.
param-required-addedpublic-surfaceadvisoryA required parameter was added to an exported signature.
param-became-requiredpublic-surfaceadvisoryAn optional parameter of an exported signature became required.
param-type-narrowedpublic-surfaceadvisoryA parameter type of an exported signature was narrowed.
return-type-narrowedpublic-surfaceadvisoryThe return type of an exported signature was narrowed.
signature-unprovablepublic-surfaceadvisoryAn exported signature changed and its compatibility cannot be proven from the available types; emitted at severity warning, never breaking-classed.
contract-breakingservice-contractadvisoryAn API schema element changed in a way existing clients may not handle (a breaking or dangerous rule of certify_service_contract).
contract-declared-unimplementedservice-contractadvisoryAn API operation is declared in a specification but no indexed route handler serves it.
contract-implemented-undeclaredservice-contractadvisoryA route handler serves a path under one the specification covers, but the specification does not declare it.

Note on the surface codes. The change-impact certificate's own --json finding codes are surface-newly-reached / surface-critical (see mcp-tools.md); the enforcement gate governs the per-severity codes surface-info / surface-warn / surface-critical (one per declared surface severity). To block a surface via enforcement.policy, name the per-severity code (e.g. "surface-critical": "blocking"), not surface-newly-reached — an unrecognized code is retained but governs nothing.

Note on the public-surface codes. The nine public-surface codes are the finding-bearing rule codes of certify_public_surface (one finding per rule per changed export, in its findings[]): the eight breaking-classed codes at severity error, and signature-unprovable at severity warning. Like the parallel-work codes, they are emitted only by that tool, which needs a base ref; openlore enforce does not run it. export-added is a rule code on the verdict but not a finding.

Note on the parallel-work / cross-actor codes. parallel-work-conflict / parallel-work-cycle (from plan_parallel_work) and cross-actor-conflict (from map_in_flight_conflicts) are emitted only by those MCP tools, which openlore enforce never runs (the gate is diff-based; these tools need a caller-supplied task list or live git/PR state). Naming them in enforcement.policy lets the caller that invokes the tool classify its findings[] with resolveEnforcementClass and block in its own CI — e.g. a CI check that warns when a new PR's footprint collides with an open one; the bundled commit gate never produces or blocks on them.

Agent-loop hooks

openlore install wires four agent-loop moments in a repository's Claude Code settings (see install). Each is on unless turned off here:

{ "hooks": { "before-edit": true, "after-tools": true, "before-stop": false } }
KeyMoment
before-editbefore an edit tool runs: generated, vendored, or lockfile target; unresolved references in the pending text
after-toolsafter an edit: session-ledger record and facts, check weakening, phantom references, peer changes to declared or served symbols
before-stopbefore the agent stops: the verify_change receipt (blocks only on policy-blocking findings)
after-compactafter the conversation is compacted: the handoff briefing of the in-flight change
before-subagentbefore an Agent/Task call: queues the sub-agent's task (prints nothing)
subagent-startwhen a sub-agent starts: its task-scoped briefing and the live peers on the board
Task-scoped context injection

An optional contextInjection block controls the per-task orientation that openlore install wires as a Claude Code UserPromptSubmit hook (openlore orient --inject). It runs orient against your submitted prompt and places a bounded, ignorable orientation block in context before the agent's first turn, so the common task begins already oriented without a manual orient call — amortizing the per-task round-trip the Value Scorecard attributes the small/familiar loss case to. Omit the block entirely for the defaults below (injection enabled). See openlore install.

{
  "contextInjection": {
    "mode": "task-scoped",
    "tokenBudget": 600,
    "relevanceMinMatches": 2,
    "relevanceMinFanIn": 2,
    "relevanceMinScore": 0.3
  }
}
FieldDefaultMeaning
modetask-scopedtask-scoped enables injection; off makes orient --inject a no-op (exit 0). Disabling does not affect the MCP server or the SessionStart primer.
tokenBudget600Hard cap on the injected block, in estimated tokens, with a 68-token minimum for the mandatory framed task and stale-index disclosure. Lower positive values are clamped to 68; lower-priority detail (functions → files → call neighbours → specs → tools) is dropped to stay within budget.
relevanceMinMatches2Relevance gate: minimum matched-function count unless the prompt names a matched identifier exactly (below it → a one-line pointer).
relevanceMinFanIn2Relevance gate: a match with at least this fan-in (or a hub) clears the gate structurally. Exact identifier mentions and scale-free top-match identifier overlap can also clear the gate.
relevanceMinScore0.3Relevance gate: minimum top match score — used only on the bounded semantic/hybrid score scale (BM25-fallback scores are corpus-relative and the score path is disabled there).

The relevance gate is deterministic and never learned: when a task's graph match is weak (the small/familiar/shallow case), injection degrades to a single pointer line rather than taxing a task that needs no orientation. Injection is fail-open — any failure (no graph, parse error, empty/weak match) emits the pointer line and exits 0, so the hook can never break the agent's turn. Set OPENLORE_INJECT_DEBUG=1 to write the gate verdict and applicable failed criteria to stderr; stdout remains injection-only.

Without embeddings (the default keyword/BM25 index) the gate never compares the unbounded, corpus-relative BM25 score to a fixed threshold. It uses matched-function count plus scale-free evidence: an exact identifier mention, top-match identifier-token overlap, or fan-in/hub centrality. Running openlore embed --local (one command, on-device, no API key) — or configuring a remote EMBED_* endpoint — additionally enables the bounded semantic-score path (relevanceMinScore). The injected block is always explicitly ignorable, so a false positive costs only a few tokens.

512 files · 450 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 hook
  • AGENTS.md: [ ] No spec drift — run `openlore drift` to verify specs match code
  • AGENTS.md: - Run `openspec validate --all` to verify structure
  • AGENTS.md: - Run `openlore drift --install-hook` to catch future drift
  • AGENTS.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 plan
  • examples/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` after
  • examples/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 clean
  • examples/mistral-vibe/skills/openlore-execute-refactor/SKILL.md: git log --oneline -1 # note this commit hash — your restore point
  • examples/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 change
  • examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md: Workflow: /openlore-plan-refactor → /openlore-execute-refactor
  • examples/mistral-vibe/skills/openlore-plan-refactor/SKILL.md: - `git diff --stat` shows only the expected files
  • examples/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 plan
  • examples/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` after
  • examples/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 clean
  • examples/opencode-skills/openlore-execute-refactor/SKILL.md: git log --oneline -1 # note this commit hash — your restore point
  • examples/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 change
  • examples/opencode-skills/openlore-plan-refactor/SKILL.md: Workflow: /openlore-plan-refactor → /openlore-execute-refactor
  • examples/opencode-skills/openlore-plan-refactor/SKILL.md: - `git diff --stat` shows only the expected files
  • examples/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 plan
  • skills/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` after
  • skills/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 clean
  • skills/openlore-execute-refactor/SKILL.md: git log --oneline -1 # note this commit hash — your restore point
  • skills/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 change
  • skills/openlore-plan-refactor/SKILL.md: Workflow: /openlore-plan-refactor → /openlore-execute-refactor
  • skills/openlore-plan-refactor/SKILL.md: - `git diff --stat` shows only the expected files
  • skills/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