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.
-
Initialize in the directory that holds your
pyproject.toml:
-
See the drift:
-
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.
-
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.