Architecture linting for Python repositories
Project description
Keeping Python repos from turning into spaghetti.
Most linters catch bad code inside files. Strata catches architectural drift: code crossing the wrong boundary, living in the wrong module, or growing into the wrong shape.
As a repository grows, code moves, lessons get forgotten, and the mental map decays. Tests preserve behavior and types preserve interfaces. Strata makes the repository's architectural expectations executable.
Strata enforces:
- which layers may import which;
- what each module or role file may contain;
- whether orchestrator functions stay small;
- whether dataflow and mutation are explicit;
- whether names such as
validate_*mean what they claim.
It ships a coherent default architecture rather than a blank rule framework, then lets projects disable, extend, or replace parts deliberately.
Strata is functional and self-hosting, but remains pre-release.
Installation
pip install stratalint
The distribution name is stratalint; the installed command is strata.
Strata requires Python 3.12+ and includes a compiled analysis core. Prebuilt
wheels cover Linux (x86_64, aarch64) and macOS (Intel, Apple silicon); on any
other platform, pip builds from source, which requires a Rust toolchain.
Native Windows is not yet verified — use WSL, where the Linux wheels work
as-is.
Quick Start
Detect the repository layout, choose a starting ruleset, and write a validated configuration:
strata init
For non-interactive setup, use strata init --yes. To configure manually instead,
add strata.toml at the repository root:
roots = ["src/my_package"]
tests = ["tests"]
tooling = ["scripts"]
[cache]
enabled = true
Then run:
strata check
All rule families are enabled by default. Product roots and tooling receive structural rules; tests receive test-convention and annotation rules.
Default Structure
Product code uses domain, subdomain, then role. Tests mirror the code they cover;
tooling uses one ownership level because scripts/ already establishes the outer
boundary.
src/my_package/
└── domain/
└── subdomain/
├── main/
│ └── run.py
├── _helpers/
├── classes/
├── models.py
├── types.py
├── constants.py
└── exceptions.py
tests/unit/src/my_package/domain/subdomain/
├── _test_types.py
└── test_run.py
scripts/
├── run_tool.py
└── tool_name/
├── main/
├── _helpers/
└── classes/
Direct scripts/*.py files are thin command adapters. Supporting logic belongs
under scripts/<tool>/<role>/.
Core Commands
strata init
strata check
strata rule SFS131
strata map run_plan --depth 3
strata init detects and validates an onboarding configuration, strata check
enforces the configured architecture, strata rule explains one rule and its
remediation, and strata map renders a conservative downstream call tree. Mapping
follows project functions and class methods when imports,
annotations, constructors, or return types prove the receiver. Calls through
protocols and untyped parameters remain visible as unresolved dispatch seams
rather than guessed implementations. Mapping does not require Strata
configuration or rule adoption.
strata check stores disposable evaluation results in a repository-local
SQLite database under .strata/cache/
and reuses them only after validating source, configuration, rule, implementation,
and project-query inputs. Caching is enabled by default; set cache.enabled = false
in configuration or pass --no-cache for an explicit uncached check. --cache
overrides a disabled project preference for one invocation.
Deleting .strata/cache/ is always safe; ignore that directory rather than the
complete .strata/ namespace, which is reserved for other Strata-owned state.
Enforce It, Then See It
Because Strata enforces the structure, it can also render it. strata map
produces a deterministic downstream call tree with clickable path:line
locations, class-qualified method names, and explicit protocol seams while
marking unresolved dynamic calls, depth limits, and cycles.
$ strata map run_map --depth 4
run_map(...) src/strata/cli/main/map.py:21
├── _parser(...) src/strata/cli/main/map.py:53
├── resolve_mapping_project(...) src/strata/mapping/main/resolve_project.py:11
│ └── resolve_mapping_project(...) src/strata/mapping/_helpers/project.py:15
│ ├── _find_project_root(...) src/strata/mapping/_helpers/project.py:73
│ ├── _explicit_source(...) src/strata/mapping/_helpers/project.py:65
│ ├── _optional_config_source(...) src/strata/mapping/_helpers/project.py:38
│ │ └── find_config_source(...) src/strata/config/main/find_config.py:12 (depth limit)
│ └── _configured_project(...) src/strata/mapping/_helpers/project.py:45
│ ├── load_config(...) src/strata/config/main/load_config.py:15 (depth limit)
│ └── _configured_source(...) src/strata/mapping/_helpers/project.py:57
└── build_call_map(...) src/strata/mapping/main/build.py:12
├── provider(...) src/strata/mapping/main/build.py:24 (unresolved parameter call)
└── render_tree(...) src/strata/mapping/_helpers/render.py:19
├── _child_lines(...) src/strata/mapping/_helpers/render.py:41
│ └── _child_lines(...) src/strata/mapping/_helpers/render.py:41 (cycle)
└── _label(...) src/strata/mapping/_helpers/render.py:88
The map is useful precisely because it is not guessing. strata check enforces
layers, roles, and public surfaces first, and strata map then renders the
structure the code is required to expose.
Philosophy
Strata is strict by default wherever it can make an honest deterministic claim. Following the rules should remove repeated architectural decisions from everyday work. Deliberate differences belong in selection, configuration, or custom rules, where they remain visible, rather than in scattered inline suppressions.
Unavoidable external calling conventions can use exact symbol-scoped exceptions:
[[rule_exceptions]]
rule = "SFS120"
path = "src/my_package/integrations/_helpers/callbacks.py"
symbols = ["ProgressCollector.update"]
reason = "The external API invokes this callback positionally."
Exceptions accept one exact rule code, repository-relative Python file, and one
or more qualified symbols. Globs, directories, line numbers, path-only entries,
and inline suppression comments are not supported. strata check rejects stale
exceptions that no longer suppress a fault.
Agent Skills
Generate repository-aware guidance from the active ruleset:
strata skills
strata skills --global
The generated skill includes Strata usage, rule-supported architecture examples,
navigation and work-handoff guidance, and every enabled core and custom rule.
Existing user-authored skill files are preserved unless --force is supplied.
Custom Rules
Custom checks use X... codes and the same RuleContext as core rules. Once
configured, they participate in strata check, strata rule, and generated agent
skills. Rules can use ctx.facts, ctx.project, ctx.text, ctx.syntax, and
ctx.relations; these are the same backend-neutral analysis zones used by Strata's
built-in rules. Project and filesystem reads made through ctx.project are tracked
for cache invalidation. Raw ast.Module access remains available for checks that need
unrestricted Python syntax traversal. See the
custom-rule guide
for the complete API and configuration.
Documentation
The quickstart, architecture model, configuration reference, adoption guide, and CLI reference live in the Strata documentation repository.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stratalint-0.15.1.tar.gz.
File metadata
- Download URL: stratalint-0.15.1.tar.gz
- Upload date:
- Size: 288.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77e241daf78b5767af61012e91560b34a0448b1e082cf7aa4ee72bc3aab3a407
|
|
| MD5 |
72e27a03ce30cfaea534a191a5176ced
|
|
| BLAKE2b-256 |
6ae491d9431e9ffca428c48de9c3925419bdf46a4aa5ed74d5ae99573fea6b6c
|
Provenance
The following attestation bundles were made for stratalint-0.15.1.tar.gz:
Publisher:
publish.yml on chio-labs/strata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stratalint-0.15.1.tar.gz -
Subject digest:
77e241daf78b5767af61012e91560b34a0448b1e082cf7aa4ee72bc3aab3a407 - Sigstore transparency entry: 2170724260
- Sigstore integration time:
-
Permalink:
chio-labs/strata@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chio-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file stratalint-0.15.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: stratalint-0.15.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93709fd4594a677fb3739f5e5731d3c52d552c93cd1d2e0f4fd791af5de8240f
|
|
| MD5 |
11ed2f044b8a515463a140799ddcfec8
|
|
| BLAKE2b-256 |
9756d4babbbe03c3a93f0a5cc9280a2090ac4a097d3563f71255faedae6cd1b3
|
Provenance
The following attestation bundles were made for stratalint-0.15.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish.yml on chio-labs/strata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stratalint-0.15.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
93709fd4594a677fb3739f5e5731d3c52d552c93cd1d2e0f4fd791af5de8240f - Sigstore transparency entry: 2170724340
- Sigstore integration time:
-
Permalink:
chio-labs/strata@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chio-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file stratalint-0.15.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: stratalint-0.15.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0845ba2c73204147d0578e19724e6798b4da023accf3ab7d327bc909b7fea9a8
|
|
| MD5 |
f21bcc1ab72bd85edd190be5fcacea8d
|
|
| BLAKE2b-256 |
97451c42488117408845c4d562fc2da20681e9445b57d9914f7b78d769e7432a
|
Provenance
The following attestation bundles were made for stratalint-0.15.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
publish.yml on chio-labs/strata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stratalint-0.15.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
0845ba2c73204147d0578e19724e6798b4da023accf3ab7d327bc909b7fea9a8 - Sigstore transparency entry: 2170724540
- Sigstore integration time:
-
Permalink:
chio-labs/strata@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chio-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file stratalint-0.15.1-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: stratalint-0.15.1-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30a985864d41f4dfb4170ef9b5da44ae47d3ee104995b3b300273e07a0e2f0c1
|
|
| MD5 |
d1655eeb959efec943d6fa20c0a0cfd6
|
|
| BLAKE2b-256 |
bf21c7b4bea9a895a09b524e73d3dca907b64498d80728e94ddd8934d7692246
|
Provenance
The following attestation bundles were made for stratalint-0.15.1-cp312-abi3-macosx_11_0_arm64.whl:
Publisher:
publish.yml on chio-labs/strata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stratalint-0.15.1-cp312-abi3-macosx_11_0_arm64.whl -
Subject digest:
30a985864d41f4dfb4170ef9b5da44ae47d3ee104995b3b300273e07a0e2f0c1 - Sigstore transparency entry: 2170724417
- Sigstore integration time:
-
Permalink:
chio-labs/strata@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chio-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file stratalint-0.15.1-cp312-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: stratalint-0.15.1-cp312-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
589b1dba04a4d6e9c00924723079bf5044785d7b0eb17e15082d477aaefeaa73
|
|
| MD5 |
0ac6eb2b34299262952a538855cd9dcd
|
|
| BLAKE2b-256 |
173bed872aecae4a1e0a5ac98c916d2c97c8d336bb8ad652cb15c41113e37e90
|
Provenance
The following attestation bundles were made for stratalint-0.15.1-cp312-abi3-macosx_10_12_x86_64.whl:
Publisher:
publish.yml on chio-labs/strata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stratalint-0.15.1-cp312-abi3-macosx_10_12_x86_64.whl -
Subject digest:
589b1dba04a4d6e9c00924723079bf5044785d7b0eb17e15082d477aaefeaa73 - Sigstore transparency entry: 2170724463
- Sigstore integration time:
-
Permalink:
chio-labs/strata@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/chio-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9341e6099ab81b6b4ae42c28f90f769304e151a8 -
Trigger Event:
workflow_dispatch
-
Statement type: