fensu init sets up Fensu in a repository. It detects your layout, writes a
fensu.toml with the complete default ruleset, runs an initial check to show the
current drift, and offers to install agent skill files.
It never guesses silently: every detected path shows where it came from, and
nothing is written until you confirm (or pass --yes).
What it does
- Detects your layout. Package roots come from
pyproject.tomlmetadata (hatch, setuptools, poetry, flit, uv workspaces, the project name), ruff’ssrcsetting, and a directory scan. Test paths come from pytesttestpathsandtests/testdirectories; tooling fromscripts,tools,bin, andtasksdirectories with Python files. If package metadata also names one of those conventional tooling directories, tooling classification wins so a path is never proposed in both scopes; an explicit--rootoverrides detection. - Enables the complete ruleset. Every repository gets
select = ["FF"]. An empty repository also gets a scaffoldedsrc/<name>/package plustests/. - Writes
fensu.tomland updates your.gitignoreto cover Fensu’s cache directory. - Measures current drift by running the starting ruleset once and printing per-family fault counts.
- Installs project-specific agent skill files (
.claude/,.opencode/,.agents/) at the Git root unless you decline; seefensu skills.
Options
--skills and --no-skills are mutually exclusive. --root, --tests, and
--tooling only apply when a codebase is detected; --name only applies when
none is.
An existing repository
On a repository with code,fensu init shows what it detected and why, then
confirms before writing:
e at the confirmation lets you edit the paths; n aborts without
writing anything. When several package roots are detected, you pick which to
include by number.
No rule family is silently held back. For an existing repository, keep the target
visible and roll it out with evaluation targeting or explicit rule exceptions; see
Adopting Fensu.
An empty repository
With no Python code detected,fensu init scaffolds a fresh layout instead. In an
interactive terminal it asks for a package name and offers the directory name as a
default. Non-interactive --yes cannot confirm that derived name, so it requires
--name:
Gitignore handling
Fensu’s generated result cache lives under.fensu/cache/, which should not be
committed. The rest of the .fensu/ namespace is not ignored automatically.
- If a root
.gitignoreexists and does not already cover the cache path,fensu initappends a.fensu/cache/entry to it. - An empty repository with no
.gitignoregets one created from the standard GitHub Python template, plus the.fensu/cache/entry. - An existing repository with no
.gitignoregets one containing just the.fensu/cache/entry.
Rerunning is safe
If the directory already has afensu.toml or a [tool.fensu] table,
fensu init changes nothing and exits 0:
fensu skills.
Non-interactive use
Prompts require a terminal. In CI or scripts, pass--yes (or make every choice
explicit with flags); otherwise init fails:
Exit codes
Related
Quickstart
The manual version of what init automates.
Adopting Fensu
Rolling out full enforcement with explicit boundaries and exceptions.
Configuration
Every key in the file init writes.
fensu skills
The agent guidance init offers to install.

