enola/Examples

Examples

Real questions.
Graph-backed answers.

Watch Enola catch a regression, interpret Rails routes, trace change impact across repositories, replay architecture history, suggest reviewers and check compliance constraints. Eight examples include unedited recordings from Discourse, Mastodon, Chatwoot and Enola itself. Hand-built terminal output is labelled as illustrative.

Example 01 · The enola loop

Does the agent catch its own regression?

Tests passing and a green build don't mean the architecture is still sound. With enola install --hooks, a Stop hook grades every session against the baseline it pinned at the start, and hands the verdict back—only when something actually regressed.

promptclaude "add recentOrders(customerId) to domain, expose via API"
without enola.
3 / 3 runs shipped the cycle
 edit src/domain/orders.ts
  + import { listOrders } from '../store'
 edit src/api/orders.ts
 tsc: no errors
 tests: 14 passed
 PR merged
 domain ↔ store cycle shipped — nothing caught it
with enola. loop
0 / 3 runs shipped the cycle
 enola.set_baseline()          pinned at SessionStart
 edit src/domain/orders.ts
  + import { listOrders } from '../store'
 edit src/api/orders.ts
 enola.diff_snapshot()        Stop hook · 1 regression
 FAIL — cycle: src/domain ↔ src/store
 edit src/domain/orders.ts
  - import { listOrders } from '../store'
 enola.diff_snapshot() — 0 regressions, calls it done
3 → 0agents shipping the bug No prompt neededthe Stop hook asks, not the agent 0rules Enola brings with it — the build fails on what you named

Measured mechanism · 9 Claude Code headless trials with the gate set to --fail-on=cycles. Enola fails nothing unless a policy names it. Small sample: evidence that the mechanism works, not an effect size. Full methodology.

Recorded Baseline and check functions

Recorded terminal session showing the Enola baseline and check functions around a code change that crosses a declared layer
The Enola feedback loop: pin the baseline before the agent edits, then check the resulting tree against it. The same change is reported without a policy and failed with one.

Recorded · Discourse · 3:04 The same loop on a real repository

Unedited on discourse/discourse. Enola catches a new dependency from app/jobs into app/controllers; the agent reroutes the change and finishes with no regression.
Recording notes and limitations

Claude Code changes EnqueueDigestEmails and checks it against the baseline. Enola reports layers: domain -> controller; the agent routes through SiteSetting instead and lands on zero regressions and no new module-level coupling. bin/rspec and bin/lint both fail on this machine because of a Ruby version mismatch, so the specs are unrun.

Example 02 · Day one

The agent says it improved the architecture. Did it?

Start with a read-only pass. enola --explain shows where coupling is concentrated; those numbers are leads, not findings. The agent investigates one edge, changes the code and checks the result against a pinned baseline. Then the same verdict is reproduced from a clean shell, without trusting the agent’s session.

shellenola --explain .

Recorded · Enola · 2:21 Find one edge, change it, verify the result twice

Unedited on a clone of enola-labs/enola. --explain puts pkg/command near the top for coupling, with 86 outgoing dependencies. The agent investigates those edges, finds one that reaches past internal/providers into a specific provider implementation, and moves that knowledge behind the provider boundary.
Recording notes and limitations

Recorded on a throwaway clone at 0ab4d24, with no baseline pinned—the agent pins its own. pkg/command imported internal/providers/rubydex directly and named that provider in two string literals. The agent moved that knowledge into internal/providers behind BuiltInInfo and FetchBuiltIn.

Enola reports PASS, dependencies -1, imports -1 and no new module-level coupling. A scope check finds both touched packages with no spillover, and compare_receipts confirms that the two snapshots used equivalent inputs. Cyclomatic complexity rises by 1 in each touched function (9→10 and 3→4). Behaviour is checked against the real binary on every path, including the error path for an unknown provider. One pre-existing internal/providers test failure reproduces on a clean tree and is left alone.

Finally, the same working tree is graded outside the agent session. baseline clear discards the agent’s baseline, git stash -u rebuilds it from git, and enola check returns the same verdict.

1 of 86outgoing dependencies identified as misplaced −1 dependencyremoved from the command layer Same verdictfrom the agent session and a clean shell

Nothing forbade the import. Enola’s declared layer order allows this downward dependency, so go build, go vet and the layer gate remain silent. The import is visible in source; the graph reveals why it matters: the command layer reaches past the provider boundary into one specific implementation.

Example 03 · Ruby on Rails

Does it actually know the framework?

Ruby has no compiler, import graph or sound find-usages. The recording starts with a falsifiable check: whether Enola expands Rails only: and except: routes correctly. It then shows what those framework-aware facts reveal about Mastodon’s layer boundaries.

shellenola --generate .  ·  enola --explain .

Recorded · Mastodon · 2:13 Rails semantics and layer boundaries

Unedited on mastodon/mastodon. Enola expands the declared Rails routes exactly, finds seven layer violations and raises their confidence from inferred to declared.
Recording notes and limitations

Recorded at 348a6689 with Enola 0.4.4. resources :invites, only: [:index, :create, :destroy] yields three routes; resources :filters, except: [:show] yields six without filters#show. Enola recognises rails-mvc at 86% and reports seven controller-layer concerns outside the controller layer. After the layer order is declared in eight lines, the same seven findings return at confidence 1.00.

0.80 → 1.00inferred, then declared — “who says that’s a violation?” answered before it is asked No compilerand no find-usages Ruby could have given you Moreeverything enola does for Rails →
Example 04 · Onboarding

Give me the shape of this service.

A new engineer — or a fresh agent session — needs orientation, not a file dump. A top-level snapshot returns the module map and entry points in one pass.

promptcopilot "Explain the structure of src/billing"
with enola.
illustrative output
 enola.explore(target="src/billing")
 src/billing — 9 modules, 41 symbols
  entry        BillingService.charge()
  depends on   money · invoices · payments-api
  exposes      4 routes · 2 queue handlers
  patterns     idempotency keys · retry w/ backoff
Map firstthen read only what matters Same installevery agent

Illustrative output showing the shape of an answer, not a measured result.

Example 05 · Tracing auth

Where is authentication applied?

A common onboarding question. Without a map the agent crawls middleware, servers, and routes one file at a time. With enola. it reads the answer from a single scoped snapshot.

promptclaude "Where is auth applied?"
without enola.
illustrative path
 list_files src/
 read src/middleware/auth.ts
 read src/server/index.ts
 grep -r "requireAuth" .
 read src/routes/api/users.ts
 read src/routes/api/billing.ts
 continue following references file by file
with enola.
illustrative output
 enola.explore(target="middleware/auth")
 Auth applied at src/middleware/auth.ts
  mounted by src/server/index.ts:42
  wraps 47 routes across 6 modules
  bypassed by 3 public endpoints
 one scoped lookup — served from the map
File by filewithout a map One scoped lookupfrom the graph Same questionnarrower context

Illustrative comparison of the two exploration paths, not a measured retrieval-cost result.

Example 06 · Change impact

What could this change affect?

Before editing a shared symbol, an agent needs its structural blast radius. Grepping for call sites is noisy and misses transitive paths. impact_analysis returns the dependent graph directly, grouped by depth.

promptcursor "What depends on formatCurrency()?"
with enola.
illustrative output
 enola.impact_analysis(target="formatCurrency")
 formatCurrency defined in src/lib/money.ts:18
  direct dependents  12 symbols · 5 modules
  transitive reach   38 call sites
  crosses into      billing · invoices · reports
  ⚠ used in 2 public API responses — review before edit
1tool call replaces a recursive grep Transitivereach, not just direct hits

Illustrative output showing the shape of an answer, not a measured result.

Recorded Impact of pkg/history.Read

Recorded MCP session showing the impact of changing pkg/history.Read
Impact analysis for pkg/history.Read, run before the agent touches the symbol.

Recorded · Mastodon · 0:29 The same question on a real repository

Unedited on mastodon/mastodon. Enola finds 59 direct dependents and 205 within two hops, then isolates the ten that cross a layer boundary.
Recording notes and limitations

The agent calls Enola ten times. Of the 59 direct dependents, 49 are controllers that raise no layer question and ten cross a layer. Three matches are unrelated. Ruby’s implicit autoloading also means specs that exercise the code indirectly do not appear as edges.

Example 07 · Cross-repo reasoning

Which services call the payments API?

File-by-file exploration does not automatically connect callers and endpoints across repository boundaries. Enola. links repositories into one graph: generate the first snapshot, then add each additional repository with append: true. A reverse traversal can then follow the connection across all of them.

promptclaude "Who calls payments-api /charge?"
with enola. · linked graph
illustrative output
 enola.traverse(node="POST /charge", direction="reverse")
 POST /charge in payments-api/src/routes/charge.ts
  called by
    checkout-web   src/api/pay.ts:64
    mobile-bff     src/payments.ts:121
    billing-worker jobs/retry.ts:48
  3 repos · 4 call sites · 1 deprecated path
3 reposresolved in one call Noper-repo re-exploration

Illustrative output showing the shape of an answer, not a measured result.

Recorded · 0:44 What linked—and the call Enola could not match

Unedited. enola coverage reports three detected calls, two resolved and one unresolved, then names the unmatched call site.
What an unresolved edge means

The target may live in a repository that was not snapshotted, belong to a third-party endpoint or expose a gap in Enola’s extraction. Enola reports the unresolved call instead of guessing which.

Example 08 · gRPC across languages

Which service implements this RPC, and who calls it?

Generated stubs make the path from a gRPC client call to its implementation difficult to follow, especially across languages. Enola. binds each proto RPC to its handler and resolves Go, Python and TypeScript client calls to the same route.

promptclaude "Which service implements UpdateInventory, and what calls it?"
with enola. · linked graph
illustrative output
 enola.explore(target="InventoryService/UpdateInventory")
 InventoryService/UpdateInventory in inventory-svc/internal/server/inventory.go:88
  bound via handled_by edge · proto inventory/v1/inventory.proto
  called by
    reporting-worker   jobs/sync_inventory.py:41   (grpc-python stub)
    admin-console      src/api/inventory.ts:19     (connect-es)
  2 repos · Go ← Python, TypeScript · 0 unresolved
Proto-levelbinding, not text search Cross-languagegRPC resolved in one call

Illustrative output showing the shape of an answer, not a measured result.

Example 09 · Architecture history

When did this get like it is?

Every other example asks what a change is about to do. This one asks what an earlier change did. Enola. records a graph per commit, so a structural violation can be traced to the revision that introduced it. The result is the same architecture delta the gate would have printed at the time.

shellenola blame notify  ·  enola show HEAD~2

Recorded · 0:42 Which commit introduced it, and what that commit did

Unedited. enola blame notify finds four events across six revisions; enola show HEAD~2 replays the introducing commit as an architecture diff.
Recording notes

The history includes the commit that introduced the finding, the one that resolved it and the dependency and symbol edges behind each. The replay reports one new storage -> delivery layer violation at confidence 1.00.

Per commitnot per file 1.00confidence — a cycle or a crossed layer is measured, not inferred
Example 10 · Review routing

Who should review this?

CODEOWNERS records declared ownership. Commit history shows who has worked in a module. Neither alone tells you whether the author owns the modules that depend on what they changed. Enola combines history with the import graph to suggest reviewers for that ownership gap.

shellenola check --reviewers

Recorded · Chatwoot · 1:27 Ownership and dependent-module routing

Unedited on a chatwoot/chatwoot clone. Enola identifies the touched module’s owner, the author’s ownership gap and six dependent modules that may need review.
Recording notes and privacy

Recorded at cf6ee136, built from main after v0.4.8. Contributor names are pseudonyms: an untracked .mailmap renames authors before Enola reads %aN; no commit or contribution count is changed. Without --reviewers, the check passes without reading an author name. With the flag, the verdict stays unchanged and a routing section reports 55% ownership of app/models/channel, 0% for the author and six dependent modules the author does own.

55% / 0%ownership gap 6dependent modules Advisory onlynever changes the verdict

The reviewer signal follows the major/minor ownership concept studied by Bird, Nagappan, Murphy, Gall and Devanbu in Don’t Touch My Code! (ESEC/FSE 2011). Their 5% threshold and reported correlation are evidence, not a rule declared by your repository—which is why reviewer routing cannot affect Enola’s verdict.

Example 11 · Policy as code

Which policies apply to this code?

This example defines a compliance boundary in the repository. A policy page lists the files in scope, and each constraint describes a prohibited change and cites the requirement behind it. When a change violates a strict constraint, the check fails and reports the relevant rule, reason and source line.

shellenola check --fail-on=constraints

Recorded · Enola example · 1:43 Three changes that violate compliance constraints

This is an unedited run of examples/policy-as-code from the Enola repository. Clone the repository and run ./run.sh with Enola installed to reproduce it.
Recording notes

The example applies seven constraints to a small Go module: six strict and one advisory. A policy page lists the files in the cardholder-data environment. The script then makes three changes: analytics gains an indirect path to card data, a new file is added without being linked from a policy page, and code that handles personal data logs a subject identifier. go build and go vet pass, but Enola reports three strict violations. The ledger also lists two existing exemptions, including the owner, reason and date for each one.

2 hopsindirect access from analytics to card data 3 violationsreachability, policy coverage and logging 2 exemptionseach has an owner, reason and date

This example checks reachability and policy coverage: which code can reach other code, and which files a policy page includes. It does not check runtime or data properties such as encryption at rest, retention periods, lawful basis or access logging. Enola checks code against a scope that someone has declared; it does not detect sensitive data.

Try it on your repository

Ask these questions about the code you are changing.

Install Enola, generate the graph and give your coding agent the same architecture context.