Skip to content

Primitives

Prose is built from a small set of shared primitives that each carry a single responsibility. A rule reads source through Source, walks the AST through one of the shared walkers, emits Edit lists, and surfaces diagnostics through the Pipeline. Every rule in the catalog composes from the named pieces below, so a new rule lands as a thin walker plus the per-rule decision rather than a from-scratch implementation. The padding math, the comment-attachment, and the conflict discipline live once and downstream rules consume them.

The graph below traces how a source flows through the primitive set, with each node marking one primitive and each edge marking a consumer relationship (A → B reads as "A is consumed by B"). The graph nodes match the registries below, and hovering a node previews the primitive's one-line role.

Hover a tile to see what it draws from and what it feeds into.

The Surface

Public Primitives

Reachable from a downstream Rust consumer today:

PrimitiveRole
PipelineRuns registered rules in deterministic order, reparses between rules, returns the final source.
RuleIdCanonical kebab-case slug identifying each rule across CLI, config, suppressions, and diagnostics.
SourceOwned wrapper bundling the original text, AST, tokens, line index, and supporting tables. Every rule reads through this value.

Crate-Internal Primitives

pub(crate) today and stabilizing toward 1.0, where consumer-implemented rules become reachable:

PrimitiveRole
AlignerComputes padding widths and emits the alignment edits every alignment rule consumes.
BindingAnalysisPer-source table indexing every write and read of every name in every lexical scope.
CacheUser-level on-disk cache keyed on (source ++ config ++ rules ++ version), collapsing repeat runs to a stat plus a hash plus a deserialize.
ColonTargetsWalks the five : contexts in Python and emits alignment members for each.
DocstringPEP 257 walker reaching every module, class, and function docstring in source order.
EditThe Edit { range, content } unit every rule emits and the pipeline applies.
OrdererReorders sibling AST nodes by a classifier while preserving attached comments.
SuppressionMapPer-source index of # fmt: off / # fmt: skip / # prose: ignore[...] directives.
WalkerIgnore-aware filesystem walker yielding every .py / .pyi / .pyw source and .ipynb notebook under given paths.

Reading Order

For a downstream Rust consumer integrating Prose through the public surface, the load-bearing reads are Source (input), Pipeline (runner), and RuleId (slug type). The three together cover construction, execution, and the slug shape that flows through every CLI flag and config table.

For a rule author working inside the Prose crate, the reading path starts at Edit (the unit every rule emits) and walks through Pipeline (the runner the rule registers with). From there, the right walker primitive depends on what the rule does:

Source is the input every walker reads against, and SuppressionMap is the filter every emission passes through.

The Rules page walks every rule each primitive shows up under, the Configuration reference covers the [tool.prose] table that drives the Pipeline's rule selection, and the Pipeline Order reference covers the deterministic order rules fire in.