enola/Docs/Change control

Documentation

Change control

Compare the architecture before and after a change. Nothing fails until you name a rule: the check reports the delta and exits 0 until --fail-on says what should break the build.

01 · Workflow

Pin, change, compare

Manual loopshell
enola baseline pin
# make the change
enola check

baseline pin creates the “before” snapshot. check builds the current snapshot, verifies that the two snapshots are comparable, and reports findings introduced by the change.

A changed Enola version, repository, or ignore configuration makes two snapshots non-comparable. Enola stops instead of reporting extraction noise as a code change.

If only the producer set differs, Enola grades facts from extractors and providers present in both snapshots. The result is marked PASS (partial verdict) or FAIL (partial verdict) and names every excluded producer and ungraded fact.

02 · Policy

Exit codes

CodeMeaningAction
0No configured regression was introduced.Continue.
1The change introduced a finding covered by --fail-on.Block the commit or job.
2The check could not run, for example because no baseline exists.Fix the invocation or repository state.
3The snapshots are not comparable — for example, the Enola version, repository identity, or ignore configuration differs.Review the receipts, then re-pin with the intended configuration.
Default: nothing fails. Every finding is reported, the run exits 0, and the output states that no policy was in effect — a gate that enforces nothing must not be mistaken for one that found nothing. Naming a category in --fail-on is what makes a build breakable.
Policy controlsshell
enola check --fail-on=layers
enola check --fail-on=layers,cycles,intent
enola check --fail-on=god-class --min-confidence=0.8
enola check --fail-on=layers --warn-only
enola check --json
enola check --detail
enola check --focus=internal/auth
enola check --target=internal/auth --max-spillover=0

--fail-on takes a comma-separated list of finding categories — layers, cycles, intent, god-class, hotspots, and the other categories defined in EXPLAINERS.md. There is no default: unset means nothing can fail. Only categories in the active list can produce exit code 1, and a name that matches no explainer matches nothing at all — enola check --json prints the policy that actually ran.

Two categories describe rather than complain: the finding that names which architecture pattern was matched, and the notice that a cluster config overrode a repo's own declaration. Both are exact, both are reported under Descriptive (never graded), and neither can fail a build — otherwise declaring a layer order would fail the very change that declared it.

--min-confidence filters findings by confidence before --fail-on is evaluated. Raise it to exclude lower-certainty estimates; proven load-order cycles carry confidence 1.0.

--warn-only downgrades a policy you set, so findings and spillover breaches report without producing exit code 1. Invocation errors and incomparable snapshots still return codes 2 and 3.

--focus narrows the reported delta. --target is different: it declares the area the change was meant to affect, computes the predicted reverse-dependency radius from the baseline, and reports touched packages outside it as spillover. Spillover remains advisory unless --max-spillover is set; 0 fails on any spillover.

03 · Automation

Automate the loop

enola baseline pin and enola check work independently of an agent. Run them from any client workflow, a pre-commit hook, or CI.

GitHub Actions

Add the Enola Architecture Check to .github/workflows/architecture.yml. It installs Enola, compares each pull request with its base commit, shows findings on affected lines, and summarizes the architectural change.

.github/workflows/architecture.ymlyaml
name: Architecture
on:
  pull_request:

permissions:
  contents: read

jobs:
  enola:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: enola-labs/enola-action@v2
        with:
          fail-on: layers
The fail-on input is the gate. Without it the job reports every finding on the pull request and stays green — a report rather than a check, which the job summary states in as many words. Name the categories this repository should fail on.

Using another CI system? Run enola check --fail-on=… directly and use its exit code to pass or fail the job.

Claude Code or Codex hooks: enola install --hooks adds SessionStart and Stop hooks. SessionStart pins a baseline unless you pinned one explicitly; Stop runs the check and returns output when your policy fails — or, when no policy is set, when the change introduced a finding Enola measures exactly, handed back with the decision left to you. Codex users must approve a newly installed hook once via /hooks. Use enola doctor to verify that the hooks fired.

04 · Findings

Deterministic and heuristic checks

Cycle detection runs over the extracted import graph with Tarjan’s strongly connected components algorithm. Other findings—such as god classes, hotspots, dependency depth, and complexity outliers—depend on documented thresholds.

The result is bounded by extractor coverage. Dynamic imports, generated code, runtime registration, and unsupported framework behavior can leave edges unresolved. Treat the receipt and coverage report as part of the result.

Read the full explainer guide for all eighteen explainers, their evidence, confidence, and default gate behavior. Snapshot comparability and provenance are described by the receipt returned through snapshot_receipt.