Source intelligence

How Horus understands code context and turns it into investigation evidence.

Source intelligence is Horus's understanding of your code. It lets Horus resolve incident hints into concrete symbols, trace impact across call paths, detect recent changes, and connect async boundaries such as queues. It is not a separate product: it is the code-analysis layer that runs behind the Horus CLI.

Local-first

The source-intelligence backend runs on your own machine. Horus talks to it over local HTTP and never uploads your source code to a remote service.

Supported languages

Python, TypeScript, JavaScript, Go, Java, and Rust are all first-class — Horus parses .py, .ts/.tsx, .js/.jsx/.mjs/.cjs, .go, .java, and .rs into the same code graph. The async-boundary stitcher covers JS/TS queues (BullMQ) and Python queue frameworks (Celery, Dramatiq, huey, and procrastinate); Go/Java/Rust are parsed into the graph but have no queue stitching yet.

What source intelligence is

When you investigate an incident, you usually ask questions like: What code handles checkout? Who changed it recently? What calls the payment service? What else breaks if it fails? Source intelligence gives Horus the structured code context it needs to answer those questions deterministically.

It is built from three pieces:

  1. A parsed representation of your repository: functions, classes, files, imports, and relationships.
  2. A graph that connects those symbols through calls, imports, async messages, and shared data.
  3. A local host that answers Horus queries over HTTP so evidence stays fast and private.

Why Horus uses a source-intelligence host

Parsing a codebase is slow. Querying it should be fast. The host parses your repository once, stores the graph, and serves queries on demand. This separation means:

  • horus explain can resolve a symbol in milliseconds.
  • horus investigate can ask many graph questions without re-parsing.
  • Multiple Horus commands share the same indexed view of the code.

The host is tied to a repository on disk. horus init --source <url> records an external host URL in .horus/config.json; otherwise horus init is what analyzes the repo, hosts it, and records the host URL. When you run horus hosts, you see every registered host and whether it is currently running.

Indexing with horus init

horus init is the command that refreshes source intelligence for a project. Beyond writing and registering config on first run, it does three things:

  1. It makes sure the source-intelligence host for the repository is running, reusing a healthy one.
  2. It runs the stitcher to build the queue map, connecting queue producers to workers across async boundaries.
  3. It builds a local project-knowledge snapshot of the repository into .horus/index/ (an offline, code-context index you can query with horus knowledge or expose to agents via horus mcp).
bash
cd /path/to/your-repo
horus init
horus init --env production

If the host is not running, horus init attempts to start it. If that fails, see Troubleshooting.

Code graph concepts

The graph is the mental model Horus uses. Every node is a symbol, file, or external system. Edges describe relationships.

ConceptWhat it meansExample query
SymbolA named entity in code: function, class, method, variable, type.horus explain AuthService.login
Call edgeOne symbol invokes another.Shown in horus explain --depth 2.
Import edgeA file depends on another file or module.Used during architecture analysis.
Async boundaryA producer sends work to a consumer through a queue or event bus.Connected by horus init queue stitching.
External systemA database, API, broker, or third party referenced in code.Surfaced by horus architecture.

These concepts show up as evidence in investigations. For example, if Horus suspects PaymentGateway caused a spike, it can show callers, callees, recent changes, and downstream queue consumers as supporting evidence.

Source-intelligence commands

horus explain

Explain a symbol: where it lives, what calls it, what it calls, and how important it is to the system.

bash
horus explain AuthService.login
horus explain AuthService.login --depth 2 --json

Use --depth to control how many hops of the call graph to include. Use --json when you want structured output for scripts.

Search symbols across all configured repositories. Useful when you know a keyword but not the exact symbol name.

bash
horus search "checkout"
horus search "checkout" --limit 10 --json

horus architecture

Discover the living architecture of the project: subsystems, async boundaries, external systems, and fragility points. This is not a hand-drawn diagram; it is derived from the current code.

bash
horus architecture
horus architecture --json

horus blast-radius

Given a symbol, show what could break if it fails. Horus walks upstream and downstream dependencies, including async boundaries, and returns a scoped impact view.

bash
horus blast-radius PaymentGateway
horus blast-radius PaymentGateway --depth 2 --json

horus owner

Estimate ownership for a symbol or component from git history, with confidence and evidence. It is a heuristic, not org-chart truth.

bash
horus owner PaymentGateway --json

horus repos and horus hosts

horus repos lists configured repositories and their host health. horus hosts lists source-intelligence host processes and whether they are running.

bash
horus repos
horus hosts

horus status

Show the health of source intelligence alongside connectors and project configuration.

bash
horus status

horus knowledge and horus mcp

Alongside source intelligence, horus init writes a local project-knowledge snapshot into .horus/index. horus knowledge queries that offline snapshot — no Cloud — with subcommands status, search, contracts, trace, ask, validate, push, and pull. horus mcp runs the Horus MCP server over stdio, exposing the same local project-knowledge index to agents.

bash
horus knowledge status
horus knowledge search "checkout"
horus mcp

How source evidence appears in investigations

When you run horus investigate, Horus combines runtime evidence with source evidence. Source evidence can include:

  • Symbols matching the incident hint.
  • Call paths from a suspected cause to runtime entry points.
  • Recent commits touching a suspected symbol.
  • Downstream queue consumers or upstream callers that explain blast radius.
  • Architecture context such as subsystems and external dependencies.

Source evidence is always labeled as such. It never overrides runtime evidence in scoring; it enriches it.

What is local vs remote

Everything in source intelligence is local. The backend runs on your machine, the graph is stored on your machine, and queries are answered on your machine. Horus does not send your code to a remote API for source analysis.

The only remote communication is optional: if you pass --ai, Horus may send a synthesized evidence summary to an AI provider after the deterministic investigation is complete. That summary does not include raw source code.

Storage backend (SQLite)

As of horus-source 2.0.0, the code graph and its embeddings are stored in SQLite. Each repository keeps a single .horus/source/horus.db file (WAL mode) that combines three things: the graph (nodes and edges), vector search via the sqlite-vec extension (vec0 brute-force cosine — the same algorithm the previous backend used), and keyword search via SQLite's built-in FTS5 (BM25). This replaces the previous KùzuDB backend, retiring an end-of-life dependency and dropping its native library for a lighter install. The backend ships inside the Horus release bundle — one bundle, one version — so the CLI always installs and validates the backend version paired with its own release.

Nothing changes in how you use Horus

The storage swap is behind the scenes. The same horus init, horus search, and horus explain commands work exactly as before — only the on-disk store changed.

Upgrading from a KùzuDB store

Update the backend, then re-index. The graph is rebuildable from source, so there is no manual data migration — the next index auto-detects a legacy .horus/source/kuzu store, prunes it, and rebuilds on SQLite.

bash
# Update the source-intelligence backend (ships inside the Horus bundle)
horus update
# (or re-run the installer, which installs the backend from the bundled wheel)
curl -fsSL https://horus.sh/install.sh | bash

# Re-index — auto-prunes the old kuzu store and rebuilds on SQLite
horus init

Platform requirement: glibc

Alpine / musl is not supported

The SQLite backend needs the sqlite-vec (vec0) extension for vector search, and sqlite-vec ships no musl/Alpine (musllinux) wheel and no source distribution. It therefore requires a glibc-based Python: Linux glibc on x86_64 or aarch64, or macOS. On Alpine the backend raises a clear error at startup.

If you run the backend in a container, use a glibc base image (for example a Debian- or Ubuntu-based image) rather than Alpine. If you must stay on musl, the legacy KùzuDB backend remains available through the 2.x line (removed in horus-source 3.0.0) — see the escape hatch below.

Escape hatch: the legacy KùzuDB backend

Through the 2.x line (until horus-source 3.0.0) you can opt back into KùzuDB. Install a legacy 2.x horus-source from PyPI with the optional kuzu extra and set the backend environment variable; the next index then writes a kuzu store instead of SQLite. (Current backends ship inside the Horus bundle — only the legacy 2.x line remains on PyPI.)

bash
uv tool install 'horus-source[kuzu]<3'
export HORUS_SOURCE_STORAGE_BACKEND=kuzu
horus init

Temporary

The kuzu backend is deprecated and kept only as a transition aid. Plan to move to the default SQLite backend on a glibc runtime.

Prerequisites and limitations

  • Source intelligence is optional. You can run runtime-only investigations, but impact analysis, queue stitching, and symbol resolution will be weaker.
  • Indexed languages are Python, TypeScript, JavaScript, Go, Java, and Rust.
  • The backend itself runs on Python 3.11+ and uv (independent of the languages it analyzes) and ships inside the Horus bundle — the installer and horus update install it from the bundled wheel, so Python 3.11+ with uv is the only prerequisite. The curl installer sets this up; npm and Homebrew installs do not.
  • The SQLite storage backend requires a glibc-based Python (Linux glibc x86_64/aarch64 or macOS); Alpine/musl is not supported. See Storage backend.
  • Very large monorepos may take longer to index. Run horus init after large refactors to refresh the graph.
  • Dynamic language features (runtime monkey-patching, string-based imports) may not appear in the graph.

Common failure modes

SymptomLikely causeFix
horus init cannot find a hostThe backend is not installed or not running.Re-run the curl installer, or start the host manually with uv.
horus explain returns no resultsThe repo has not been indexed, or the symbol name does not match.Run horus init, then try a broader horus search.
horus hosts shows the host as stoppedThe process crashed or was killed.Run horus init to restart it, or start the host manually.
Queue map is empty or incompletehorus init could not stitch producers to consumers.Check that queue names and worker entry points are visible to static analysis.
Architecture output misses dynamic boundariesThe graph is built from static analysis.Expect static edges. Dynamic dispatch and plugin systems may need manual verification.
Backend errors that sqlite-vec cannot be loadedRunning on Alpine/musl, where sqlite-vec has no wheel.Use a glibc-based Python (Debian/Ubuntu image or macOS), or fall back to the kuzu backend through the 2.x line (until horus-source 3.0.0). See Storage backend.

Shipped vs planned

Shipped today:

  • Multi-language indexing — Python, TypeScript, JavaScript, Go, Java, and Rust in one code graph.
  • Symbol search and explanation.
  • Call-graph and ownership heuristics.
  • Architecture and blast-radius analysis.
  • Queue-boundary stitching via horus init — BullMQ (JS/TS) and Celery, Dramatiq, huey, and procrastinate (Python).
  • Local-only operation.

Planned or under development:

  • Incremental indexing for very large repositories.
  • Cross-language graph edges for polyglot systems.
  • Richer type-aware impact analysis.

Next steps

If you have not installed source intelligence yet, start with Getting started. For the exact commands and options, see the CLI reference. For runtime evidence sources, see Connectors.