Skip to main content
Fensu’s defaults describe a coherent target architecture. How you turn them on depends on where you are starting. New / small repos are where Fensu pays off fastest; big legacy repos(e.g. 100k+ lines) need more judgment.

New repositories

The defaults are calibrated for a fresh repo.
fensu init scaffolds a src/ package, a tests/ directory, and a fensu.toml with the full ruleset selected. This is where Fensu is easiest to live with, because you never accumulate drift in the first place.

Small existing repositories

This is the strongest first experience. Whether the repo is tidy or very inconsistent, adoption is mostly a single pass that leaves it on a coherent architecture.
  1. Initialize in the directory that holds your pyproject.toml:
  2. See the drift:
  3. Drive the faults to zero. Hand the output to a coding agent and let it work through them, since each diagnostic already states the contract and the fix:
    Most faults are pretty mechanical to fix, but open enough that they can’t be auto fixed. The few that would require a genuine structural decision are worth pausing on rather than rushing.
  4. Defer the handful you want to think about. Record them as explicit rule exceptions or ignore entries so the run is green and the deferral is visible, then come back to them deliberately.
The result is a repo that conforms to a coherent architecture and stays that way, for very little up-front effort.

Large existing repositories

Pointing the full default set at a large, established codebase surfaces a lot at once. That is real drift against the target architecture, not the tool overreacting. But a big-bang refactor to zero faults is usually the wrong response, and it is rarely safe. Here the goal is not to bend the codebase to Fensu’s defaults. It is to encode the architecture you actually have and want.
Enforce as aggressively as you can refactor safely, and no more. If your test suite would not catch a bad structural move, do not let the linter pressure you into one.
Custom rules are the main lever. Where a default rule does not fit how part of the repo is legitimately built, do not twist the code to pass it. Write a custom rule that states the invariant you genuinely care about. You capture real architectural intent as an executable check instead of paying for a disruptive migration, and the rule flows into your generated agent guidance like any core rule. Supporting configuration keeps everything else visible while you decide:
  • ignore for a default that is wrong for this repo globally.
  • warn for a policy you want measured but not blocking yet.
  • rule_exceptions for isolated, justified findings.
  • Evaluation targeting to enforce the regions you trust while keeping the rest as project context.
Every deviation lives in configuration or a custom rule, where a reviewer can see it, rather than scattered through the source. See Philosophy for why that matters.