by SQLStack
Fensu checks repository architecture: import boundaries, module roles, and function shape for Python, Rust, TypeScript, JavaScript, and Svelte.
- Boundaries: stop one domain from importing another domain’s private helpers.
- Roles: keep entry points, helpers, models, and types in their owning modules.
- Function shape: keep orchestrators small, dataflow explicit, and signatures clear.
Requires Python 3.12+. Install in your project’s Python environment:
pip install fensuFrom an existing Python repository’s pyproject.toml directory:
fensu init --yes
fensu checkfensu init --yes detects your project, creates fensu.toml, runs an initial check,
and installs agent guidance. Existing configuration is preserved.
Run fensu check locally and in CI to enforce your policy. For established
repositories, adopt rules incrementally using explicit boundaries and exceptions.
See the quickstart for empty repositories, existing configuration, and language-specific setup.
An order entry point importing inventory’s private helper crosses a domain boundary:
# src/shop/orders/main/submit.py
from shop.inventory._helpers.reserve import reserveExcerpt from a real fensu check --no-color run with FFL102 selected:
FFL102 import 'shop.inventory._helpers.reserve' reaches into internal structure of 'shop.inventory'
--> src/shop/orders/main/submit.py:1:0
= help: Import from classes, models, types, constants, exceptions, or a thin main/ entry.
Publish the operation through inventory’s thin main/ entry, then import that
public surface instead:
from shop.inventory.main.reserve import reserveThat change clears this boundary finding; it does not disable the rule. Inspect a
diagnostic’s full contract and settings with fensu rule FFL102.
A Python domain owns its behavior and vocabulary:
src/shop/
└── inventory/
├── main/ # public entry points and orchestration
│ └── reserve.py
├── _helpers/ # private implementation phases
├── classes/ # one class per module
├── models.py # data models
├── types.py # type declarations
├── constants.py
└── exceptions.py
A leaf needs meaningful main/ behavior, not an empty placeholder. Domains can
split into named subdomains; tests mirror the code they cover. Tooling has its own
scope. See the architecture model
for complete role contracts, layouts, and defaults.
| Command | Purpose |
|---|---|
fensu rule FFL102 |
Explain a rule and its effective settings. |
fensu map submit --root src --depth 2 |
Show proven static Python calls, without running the program. |
fensu dupes --since origin/main --diff |
Review changed duplicated-code clusters; advisory, not a blocking check. |
fensu skills --check |
Verify installed guidance matches the current policy. |
Call mapping needs neither Fensu configuration nor rule adoption. It marks unresolved calls, cycles, and depth limits instead of guessing dynamic targets. See the map reference and duplicated-code guide.
fensu.io/docs is the full manual; the README is the starting point.
| Start here | Reference |
|---|---|
| Quickstart | Installation, initialization, and reading diagnostics. |
| Adoption | Roll out enforcement safely on existing code. |
| Configuration | Targets, ownership roots, selection, thresholds, exceptions, and ignores. |
| Architecture | Roles, domain boundaries, tooling, and test layout. |
| Rust · Web | Analyzer-specific setup and rule packs. |
| CLI · Agent guidance | Commands, execution, and skill update safety. |
| Caching | Cache identities, controls, and safe cleanup. |
| Custom rules · RuleContext API | Author, configure, and test project-specific policies. |
Python dead-code enforcement has a separate repository guide covering reachability, explicit dynamic roots, and adoption caveats.
