stilyagi df12 · deterministic prose analysis
§ Roadmap · six vertical slices

The plan,
by slice.

Each phase ships a thin strip through the whole system — extraction, IR, rule, output, cache, docs. We do not build the entire extractor and then the entire rule catalogue. We build one rule working end-to-end, then another, then another.

GROUNDED
The Vertical Slices — phases building upward from foundations to 1.0 00 · Foundations (shipped) 01 · Markdown pack (shipped) 02 · Capability planner (in flight) 03 · Grammar & spelling (planned) 04 · CI & packaging (planned) 05 · Editor & LSP (planned)
Figure 01 · Slice chart from the Stilyagi deck, plotting the climb from foundations to 1.0 one vertical slice at a time.
Shipped (0.1–0.2)In flight (0.4)Planned (0.6 – 1.0)

The goal of this slice

The Rust extractor emits a minimal Document IR. The Python runtime loads one rule, receives regions, and prints diagnostics. PyO3 wheels build on three platforms. CI runs green. The product exists in outline.

§   Shipped: a pipeline that runs one rule against one file and prints one diagnostic. Everything downstream is an embellishment.

Deliverables

  • PyO3 bindings with a narrow JSON-over-FFI boundary
  • Document IR v0 — regions, ranges, content_hash
  • One working rule: MD201 heading depth
  • Text formatter with stable ordering
  • stilyagi check reads paths and stdin
  • CI green on Linux, macOS, Windows

The goal of this slice

Heading hygiene, list consistency, link policy, inline code usage, punctuation within prose. Suppression comments arrive at line and block scope. SARIF output lands. Early adopters can replace Vale for most of their configuration.

§   Shipped: twenty-two Markdown rules with deterministic output, the first class of safe autofixes, and suppression comments at three scopes.

Deliverables

  • MD rule pack — 22 rules across headings, links, lists, code fences
  • Suppressions: disable-line, disable-next-line, disable-block
  • SARIF output, stable across invocations
  • Safe-fix class with dry-run and --diff
  • Cache v1 keyed by (content_hash, ruleset_id, capability_set)
  • stilyagi rule list / show / describe
02
§ Content slice II

Capability planner & docstrings

In flight
0.4.0 · eight weeks
Python / Rust docstrings
+

The goal of this slice

Extend Stilyagi's reach into source-embedded prose. Introduce the capability planner so linguistic providers are loaded on demand only, and ship docstring extraction for Python and Rust. The planner is what makes the rest affordable: it lets grammar and spelling join the catalogue without taxing every lint run.

§   In flight: the planner is the hinge the whole design turns on. It guarantees that the base install stays small and fast, no matter what the rule catalogue grows into.

Deliverables

  • Capability planner with explicit provider declarations
  • Python AST extractor for Module, Class, Function docstrings
  • Rust syn extractor for /// doc comments
  • PYDOC rule pack — 14 rules
  • RSDOC rule pack — 9 rules
  • stilyagi dump-ir with --include annotations
  • Owner metadata surfaced in diagnostics

The goal of this slice

Add the linguistic providers behind the capability planner without compromising the offline base install. Grammar ships as stilyagi[grammar]; spelling as stilyagi[spell]. Neither is required to use Stilyagi's core value — but when enabled, they unlock the GRAM, SPELL, and TERM families.

§   Planned: prose-level checks arrive as optional extras. The base install remains under thirty megabytes.

Deliverables

  • spaCy provider with model pinning and cache
  • symspell spellchecker with a bundled dictionary
  • GRAM rule pack — passive voice, sentence length, modal verbs
  • SPELL rule pack — common words, allowlists, per-region scoping
  • TERM rule pack — canonical term enforcement
  • Documented optional-extras install story

The goal of this slice

Make Stilyagi trivial to adopt in CI pipelines, editors, and agentic workflows. Polish every surface a machine will read and every surface a developer will first encounter. Cached runs should be indistinguishable from clean runs modulo timestamp.

§   Planned: Stilyagi becomes a line in a pre-commit config, a job in an Action, a format a reviewdog already speaks.

Deliverables

  • Pre-commit hook with a config template
  • GitHub Action with matrix-friendly defaults
  • Reviewdog format parity
  • SARIF v2.1.0 full schema conformance
  • stilyagi config print / validate / explain KEY / locate
  • Auto-discovery of stilyagi.toml and pyproject.toml

The goal of this slice

Land the editor story. A language server that speaks textDocument/diagnostic, supports codeAction for safe fixes, and respects the capability planner's cost model under interactive load. Incremental analysis keyed by content_hash and line_index. The 1.0 mark — Stilyagi is someone's daily driver.

§   Planned: version 1.0.0 ships under semver with editor integrations and a public rule stability policy.

Deliverables

  • stilyagi-lsp process with workspace symbols
  • Incremental re-analysis keyed by line_index
  • codeAction handlers for safe and unsafe fixes
  • Suppressions surfaced in hover & relatedInformation
  • VS Code extension (thin)
  • Neovim and Zed recipes
  • 1.0.0 release with semver guarantees
§ Cadence
Minor releases every six to ten weeks. Patches as needed. No sprint theatre.
§ Deprecations
One minor-version warning before removal. Renames ship with aliases that outlive two minors.
§ Stability
Rule IDs never change meaning. If a rule evolves, it gets a new ID; the old one is retired, never reassigned.
§ Governance
New rules require a one-page RFC. New providers require a two-page RFC and a performance budget.

What we will not do along the way

We will not ship a rule whose diagnostic we cannot justify in one sentence. We will not add a capability to the planner without naming who asked for it. We will not accept a dependency into the base install that pushes the wheel past thirty megabytes.

We will not invent a configuration key to paper over an ambiguous rule. If two users read a rule's description and expect different outcomes, that rule is not ready. It sits in the draft column until it is.

We will not write a linter that calls itself opinionated as a substitute for writing down the opinions. Each rule ships with a rationale paragraph and — where the rationale is contestable — a citation.