Free and Apache 2.0. Runs on your machine; no model, no embeddings, nothing uploaded.View on GitHub

Architectural regression testing for AI-assisted development

Catch architecture regressions before they merge.

Enola maps your codebase before a change, shows exactly what the change altered afterward, and fails only the structural rules you choose. Your agent can fix the regression before it reports done — or the same check can stop it in CI.

23 languages & formatsOne local binaryAgent hooks · CLI · CI

enola check
the build passed; the declared layer order did not
$ enola check --fail-on=layers

FAIL — 1 structural regression introduced.

Regressions (fail):
  - [layers] 1.00 — Layer violation: storage -> delivery
      import of notify

New coupling (4):
  storage           --imports--> notify
  storage.LoadPrice --calls--> notify.SendReceipt
  …and 2 more calls and declarations

$ echo $?
1

Your rule: storage must not depend on delivery. The change: a helper added that dependency. The verdict: one new regression, exit code 1.

A different kind of test

Builds test behavior. Enola tests structural change.

Enola runs alongside your compiler and test suite. After they confirm that the code still works, Enola compares the architecture before and after the change. It reports the new dependencies, cycles, boundary violations and unintended spread the change introduced — then fails only the rules you chose to enforce.

Compiler · tests · git diff

Does the code still work?

  • Does it compile?
  • Do the behaviors we tested still pass?
  • Which lines and files changed?
Enola

What did the change do to the system?

  • Which structural relationships changed?
  • Did it introduce a cycle or cross a declared boundary?
  • How far did it spread beyond its intended scope?
Up to 171pre-existing findings in a benchmark repository
1regression introduced by this change

Enola reports the one you introduced. Existing debt stays silent, so the gate can stay on.

Why a finding is not yet a verdict

One change in. One verdict out.

The architecture before. The actual delta after.

The verdict is not a fresh audit of the whole repository. It is a comparison between two deterministic structural maps, narrowed to what this change introduced or resolved.

  1. 01 · Before

    Map the real structure.

    Enola parses modules, symbols, routes, storage and dependencies into one deterministic graph, then pins it as the baseline.

    OutputAddressable architecture snapshot
  2. 02 · During

    Give the agent exact answers.

    Over MCP, the agent can ask what depends on a symbol, how two modules connect, and what a proposed edit can reach before it changes code.

    OutputDependency paths and impact
  3. 03 · After

    Grade only the delta.

    Enola rebuilds the graph, compares it with the baseline, and returns new findings, resolved findings, coupling changes and scope spillover.

    OutputReport — or exit 1
one deterministic verdictagent hooklocal shellpull-request CI
Recorded terminal session: a helper makes the storage layer import the delivery layer. Bare enola check reports the violation and exits 0; enola check --fail-on=layers fails the same change; after the fix the re-run passes and the chained echo fires.
Three runs on one change. The first reports without enforcing. The second fails on the declared layer policy. After the dependency is fixed, the third passes. The policy is yours; the structural measurement is Enola's.
What you can choose to enforce

Enola measures the whole structural delta. Your policy decides which parts are allowed to stop the change.

Layer boundariesDependencies that point against the order you declared.
Dependency cyclesNew groups of modules that can all reach each other.
Declared intentUnexpected service seams or mechanisms across repositories.
Change scopeEdits that spread beyond the target named for the work.
Baselines, exit codes, and what counts as a regression

See it on your code first

One read-only command. No setup commitment.

Try the same architecture engine directly from the CLI before connecting Enola's MCP server to an agent. --explain needs no baseline or configuration and writes nothing to the repository.

After installing the one binaryshell
enola --explain /path/to/your/repo
excerpt — gitea, 3,537 parsed files, 1.2 s
Architecture
  Pattern:             go-standard (38% confidence)
  cyclic dependencies         0
  layer violations            0

Impact analysis (hotspots)
  coupled modules           319
    high criticality        244
  Top hotspots (by coupling):
    module               fan-in  fan-out crit  blast radius
    modules/setting         590       61 high  306
    modules/log             579        9 high  321
    routers/web/repo          6      676 high  5
    models/db               421       23 high  228

Code health
  god classes (high fan-in)     25
    models/db.GetEngine            922 dependents
    modules/log.Error              856 dependents
  complexity outliers        15
    services/gitdiff.ParsePatch       complexity 65

What you get

Architecture

The pattern Enola recognized or the layer order you declared, plus cycles and boundary violations.

Impact

The modules most other code depends on, how far a change can reach, and where coupling concentrates.

Code health

Structural outliers such as god classes, deep dependency chains and unusually complex functions.

If the map looks right, regression testing is the same measurement with a before to compare against.

Installshell
curl -fsSL https://raw.githubusercontent.com/enola-labs/enola/main/install.sh | sh

One graph for the whole repository

Your architecture does not stop at a language boundary.

Enola detects every supported language and format in the tree and puts them into one baseline and one verdict — because the boundary worth grading is often the one between them.

66,497Ruby facts in Discourse — the half a Rails-only checker sees.
69,562TypeScript and Ember facts in the same repository.
553dependents on the frontend module whose job is calling Rails.

One read-only run over Discourse measured 140,291 facts and 750,144 edges across both halves. A language-specific checker cannot see the boundary between them, but can still print a confident report about "the architecture."

Why language counts are the wrong comparison

Use it where you work

Local CLI, MCP clients, and CI.

Run Enola directly, add it to CI, or connect Claude Code, Cursor, GitHub Copilot, Codex, or Pi. No account and no hosted service, because there is nothing to sign up to.

01
Install the binary

One command, one file in ~/.local/bin. No Go toolchain and no C compiler needed. macOS and Linux run it as-is; on Windows use Git Bash or WSL, or download the archive.

02
Tell your agent it exists

Writes Enola's instructions into the files your agents already read, and adds the hooks that grade each session. It previews every change and asks before writing; enola uninstall reverses it byte-for-byte.

03
Connect your MCP client

One line for Claude Code and Codex, a small JSON block everywhere else. This is what lets the agent read the graph before it edits.

04
Check that it actually fired

A hook your agent silently ignores looks exactly like one it honours, so doctor reports when each hook last ran. It is a report, not a gate, and always exits 0.

1curl -fsSL https://raw.githubusercontent.com/enola-labs/enola/main/install.sh | sh
2enola install --hookspreviews every edit and asks before writing
3claude mcp add enola enolaClaude Code · Cursor · Copilot · Codex · Pi — see the guide for the rest
4enola doctorafter your next session, confirms the hooks fired

Full install guide, all MCP clients

Not using an agent?

The gate is a plain CLI. No MCP, no hooks, no config file: enola baseline pin, make your change, enola check --fail-on=layers. Same command and same exit code in CI. Drop the flag and it reports without failing anything.

Public benchmark

Does Enola catch the regression?

15 / 15injected dependency cycles caught, across repositories carrying up to 171 pre-existing findings; none of those repeated as new
3/3 → 0/3agents shipped the cycle without Enola versus with the automatic loop; nine controlled trials in total
72 / 72public repositories produced byte-identical snapshot IDs and fact hashes across cache states

Those runs enforced --fail-on=cycles: a policy has to be named for anything to fail, and that is the one the benchmark named. The cycle benchmark tests regression isolation, not every finding type. The agent result comes from nine controlled Claude Code trials: evidence that the mechanism works end to end, not a measured effect size. We have also published the three MCP server benchmarks that did not work, and what each of them was really measuring. Read the methodology and full results.

Try it on one change

Free, local, and open source.

Every language, all 19 MCP tools, all 19 explainers, baselines, receipts and the dashboard ship in the open-source repository. There is no license check anywhere in it.

Running Enola across many teams and repositories?

Roll out Enola across your organization