user@elrise.io:~/articles/$ ← elrise.io
· 18 min code-intelligencestatic-analysisobservabilityaideveloper-tools

Code intelligence stack 2026: building a map of the code, not a collection of AI toys

Six evidence layers, four evidence-loop stages, three deployment profiles, and a four-week rollout — a practical code intelligence stack for large polyglot codebases.

In a large codebase, the question "where is this function defined?" quickly turns into an investigation. You need to find every implementation and every caller, understand dependencies, check static violations, correlate code with real production behaviour, and then verify that the change didn't break a neighbouring service. In a monorepo or a polyglot system this is no longer a job for plain grep, and no longer a job you can safely hand to a single chatbot.

By code intelligence I mean not a specific AI product, but a closed loop of six kinds of facts:

  1. Textual and symbolic facts — search across files, branches, commits, and definitions.
  2. Static facts — AST, types, data-flow, dependencies, and rule violations.
  3. Dynamic facts — traces, profiles, latency, errors, and behaviour under load.
  4. Operational facts — logs, metrics, release-to-incident correlation, and retention.
  5. Relational / knowledge-graph facts — code-as-data queries, type-aware recipes, symbol links between repositories, and multi-hop questions.
  6. Generative interpretation — an LLM that answers questions only on top of the sources above and shows where the answer came from.

The first five are evidence layers around a single CODEBASE; the LLM is the actor that interprets them, not a sixth source of evidence. The illustration at the top of this section visualises this contract.

I compared tools along six axes: code search, static analysis, runtime tracing, log aggregation, LLM-assisted investigation, and knowledge-graph code models. Primary sources were verified on 20 July 2026. Where data changes quickly, that is flagged in place.

TL;DR

If you don't want a marketing checklist but a practical starter, I'd begin here:

This list does not mean "install everything." First decide which question you want to make cheap: find a symbol, catch a vulnerability, explain latency, delete data on user request, or validate a change through an LLM.

How to choose: maturity beats star count

For every tool I applied four filters:

"Mature" here means the tool has a stable production use case and is not in beta or maintenance mode (frozen project). It is not a promise of bug-free behaviour. Conversely, a beta tool can be fast and pleasant to use, but you cannot put it in a blocking gate (CI merge blocker) blindly.

1. Code search: find the facts first

Code search is the most under-rated layer. Before you build a graph and wire in an LLM, you must be able to answer "where is it declared", "who calls it", "which branch changed it", and "does the same problem exist in neighbouring repositories" — quickly.

Sourcegraph and Zoekt

Sourcegraph Code Search is the practical choice for an enterprise setup where multiple hosts, branches, commits, symbol search, batch changes, and Cody on top of the index all matter. Its strength is not just string search but a single interface for cross-repo investigations. The cost of that depth is a commercial model, opaque pricing, and the need for a separate privacy review for SaaS or AI features.

Zoekt is Apache-2.0 and a sound base for an OSS-only setup. It is the trigram-based engine that sits under Sourcegraph Code Search. It searches large code volumes quickly, supports regexp, boolean queries, and symbol ranking. But Zoekt on its own is not a drop-in replacement for the full Sourcegraph platform: UI, repo sync, access control, and operational processes are still on you.

The choice is simple: if you want a finished enterprise product and the licence works for you, choose Sourcegraph; if data control matters and you have a team to build the platform, choose Zoekt.

OpenGrok and livegrep

OpenGrok remains a reasonable option for Java-heavy and legacy environments. It has long offered cross-reference, broad language support, a web UI, and an API. The trade-offs are the JVM stack, the cost of full reindex, and tuning required for very large repositories. Also verify the actual licence mix: the project is CDDL-1.0 with mixed components.

livegrep is a narrower but convenient single-tenant scenario. It is a fast regex search across gigabytes of source on top of re2 and mmap indices. It fits an internal "Google Code Search" use case, where you don't need a complex permission model or multi-repo semantics.

Hound only makes sense if you need a very small deployment footprint and can tolerate maintenance mode. For a new strategic layer I would not make it the default.

What not to do

Don't start with semantic search if you don't already have solid text and symbol search. Otherwise the LLM will confidently retell an incomplete index, and your team won't be able to verify the answer with a simple repeated query.

2. Static analysis: separate fast feedback from deep investigation

Instead of one "magical" analyzer, it helps to split the work by cost.

The practical layout looks like this: Ruff and local Semgrep rules give fast feedback; CodeQL and deep taint analysis (tracking untrusted data) run in CI; SonarQube collects the cross-repository quality picture. Each finding must have an owner, severity, suppression reason, and review date. Otherwise the tool just produces backlog.

3. Runtime tracing and profiling: code explains intent, production shows fact

Static analysis does not show which branch actually runs or where the time goes. For Linux-native systems the baseline remains perf events, perf, ftrace, and the Brendan Gregg toolkit. They give hardware counters, kernel tracepoints, kprobes, uprobes, and USDT with low overhead.

bpftrace is convenient when you want a quick diagnostic query without writing a separate C program: system calls, lock latency, network events, or process behaviour. It is mature, but it requires Linux with BPF support and does not replace a full continuous profiling system.

For the JVM you want async-profiler. It captures CPU and heap profiles, works with native frames, JIT, and GC threads, and can export to JFR and flame graphs. In a Java service this is usually a better starting point than trying to apply a universal agent to every language.

For continuous profiling you can choose Pyroscope or Parca:

A profile without context is useless. Every measurement must be tied to build revision, service, environment, and time window. Otherwise the flame graph becomes a picture without causation.

4. Logs and observability: data standard first, backend second

The main observability decision is not "Loki or Elastic" but whether you preserve the ability to swap the backend without rewriting instrumentation.

OpenTelemetry belongs first in this layer. It is a vendor-neutral data model, SDK, and Collector for traces, metrics, and logs. OTel does not store data and is not a search engine, but it defines common semantic conventions, routing, and the boundary between application and backend.

Then the choice depends on the shape of your queries:

AGPL may be acceptable for self-hosted SaaS, but embedding a component into a closed commercial product requires a legal review. Also decide retention, data residency, erasure workflow, and log access up front. You can't promise user data deletion if the chosen storage cannot reliably find and delete all copies.

5. LLM-assisted investigation: the model is not a source of truth

An LLM is useful when it shortens the path from question to verifiable fact. It is dangerous when it delivers confident explanations on top of an incomplete index.

Aider is the strong OSS option for terminal-based work. It can build a repository map, work with different models, run lint and tests automatically, and commit changes to git. Its natural role is a managed CLI assistant, not an autonomous production deployer.

Cursor is convenient as an enterprise IDE, and Sourcegraph Cody makes sense for a team already using Sourcegraph that wants to feed the model its code graph. Both have a cost: commercial dependency, vendor-specific indexing, and the need to verify where source, prompts, snippets, and search results actually go.

Continue.dev can no longer be recommended as a base for new installations: according to its official documentation, the repository is no longer maintained and has been left read-only after the final 2.0 release. It can still be studied as a historical reference for prompt patterns, but it is not a current deployment target.

The minimum guardrail for any LLM tool:

  1. the model receives only allowed repositories and branches;
  2. every answer carries links to files, symbols, commits, or runtime traces;
  3. changes land in a diff first, not straight in production;
  4. lint, tests, SAST, and secret scanning run after generation;
  5. access to sensitive code, logs, and personal data goes through a separate review.

If the model can't show evidence, that's a hypothesis, not a finding.

6. Knowledge graph: different graphs answer different questions

The phrase "knowledge graph (relational model of code) of code" gets used for three different things.

OpenRewrite builds a Lossless Semantic Tree and applies type-aware recipes. It is a strong choice for mass refactoring and framework migrations: instead of regex replacement, the tool understands program structure and can re-apply a recipe across multiple repositories. Parser maturity varies by language: Java is usually better covered than newer directions.

CodeQL stores code in a relational model that can be used in practice as a knowledge model: queries express relationships between data sources, calls, types, and sinks. This is especially useful for security and cross-repo search for vulnerable patterns.

SCIP (Sourcegraph's index format for symbols and links between them; lets different language indexers feed a common format.) (Sourcegraph index format) is the Sourcegraph Code Intelligence Protocol index format. It's useful as an interoperability layer: separate language indexers can emit symbols and relationships in a common format. The SCIP ecosystem, however, is still most closely tied to Sourcegraph.

Sourcegraph Code Graph is a commercial, production-grade graph for cross-repo symbol navigation and AI-grounded Q&A. It delivers the most value when you already have Sourcegraph-scale code search. For a small repository, a separate graph is almost always overkill.

The practical rule: a graph is for relations and multi-hop questions — "which services depend on this type?" or "which calls reach this sink?" — not for any string search. For local fact lookup, a plain index is faster, cheaper, and easier to verify.

Reference architecture

A minimal production layout looks like this:

Git repositories
-> Zoekt or Sourcegraph index
-> SCIP and symbol metadata
-> Semgrep, CodeQL, SonarQube, Ruff
-> OpenTelemetry Collector
-> logs, traces, profiles
-> Loki, Quickwit, OpenObserve, or Elastic
-> Aider, Cody, or another guarded LLM interface
-> diff, tests, SAST, reviewer

Sequence matters here. The LLM must not be the first link. First you build indices and telemetry contracts; then you add a model that can move from question to evidence. If you swap the order, you'll get an expensive chat with stale context instead of code intelligence.

Three practical deployment profiles

The diagram above shows the compliance-sensitive concerns as a horizontal overlay that crosses both main profiles, not as a third equal column. Compliance is orthogonal to the tool choice: you can run OSS or GitHub-centric, and you can run either in compliance-sensitive mode. The two questions — which vendor mix? and which compliance posture? — are independent.

OSS-only and self-hosted

Zoekt, Semgrep OSS, CodeQL CLI, Ruff, perf/bpftrace, OpenTelemetry (Open standard for telemetry data (traces, metrics, logs) with vendor-neutral SDK and Collector; it defines formats, not storage.), Loki or Quickwit, Aider, and OpenRewrite. This option gives control over code and data, but it puts auth, indexing, UI, retention, and upgrades on your team.

GitHub-centric enterprise

Sourcegraph or GitHub-native search, CodeQL (GitHub's code-as-data engine: code is converted into a relational model, queries are written in QL to find vulnerabilities and patterns.), Semgrep, SonarQube, OpenTelemetry, your chosen observability backend, Cody or Cursor. This is faster to start, but you have to fix the SaaS boundaries, indexing cost, and exit plan (vendor-migration plan) up front.

Compliance-sensitive production

Start with the data map, not the LLM: which repositories, logs, and profiles contain personal data, where they're stored, who has access, and how a deletion request (user data deletion) flows. Then choose self-hosted indexing, an OTel (Open standard for telemetry data (traces, metrics, logs) with vendor-neutral SDK and Collector; it defines formats, not storage.) Collector with filtering, a backend with clear retention, and only then an AI tool with a verified data-handling policy.

152-FZ (Russian personal-data law) and GDPR cannot be reduced to a single checkbox in a product. Quickwit's delete API or OpenObserve's claimed GDPR-ready status are useful technical elements, but compliance is determined by the whole system: collection, access, storage, backups, deletion, residency, and the organisational processes around them.

A four-week rollout plan

  1. Week 1 — inventory. Lock down languages, repositories, branches, owners, investigation questions, and data classification. Pick one pilot repository.
  2. Week 2 — static baseline. Wire up Ruff or a language-native linter, Semgrep, and one deep analyzer. Cut noise, assign owners, and seed a regression corpus.
  3. Week 3 — runtime loop. Turn on OpenTelemetry (Open standard for telemetry data (traces, metrics, logs) with vendor-neutral SDK and Collector; it defines formats, not storage.), collect minimum traces and logs, add perf or async-profiler for one critical service. Link every event to a build revision.
  4. Week 4 — guarded AI. Connect Aider, Cody, or Cursor only to the pilot scope. Require citations, diff, tests, and security checks. Compare model answers against a fixed set of investigations.

After the pilot, measure not the number of tools or the token spend, but time-to-find, time-to-explain, the share of findings with reproducible evidence, false-positive rate, and the time from a runtime signal to a fix.

Exit gates

Each week in the diagram ends with an explicit exit gate. The next week starts only when the gate is satisfied — this is a sequencing rule, not a calendar rule. A gate is a one-line verifiable criterion, not a goal:

If a gate fails, fix the gap before continuing. The pilot repository and the gates are the only durable artefacts that survive the rollout — everything else can be replaced.

Anti-patterns

What to re-check before publication

Code intelligence moves fast, so this article cannot be treated as a permanent catalogue:

A re-fetch every six months is reasonable for this space, and before any meaningful change for commercial AI tooling and compliance-sensitive deployments.

Sources

Static analysis

Runtime tracing and profiling

Logs and telemetry

LLM investigation and code models

Compliance references