# bito-lint
[](https://github.com/claylo/bito-lint/actions/workflows/ci.yml)
[](https://crates.io/crates/bito-lint)
[](https://docs.rs/bito-lint)
[](https://github.com/claylo/bito-lint)
**bito** = **b**uilding **i**n **t**he **o**pen.
AI coding agents generate documentation as they work — ADRs, design docs, changelogs, handoff notes. The quality varies between sessions. Sometimes you get crisp, well-structured prose. Sometimes you get bloated walls of text that no one wants to review.
bito-lint catches the problems before you commit. It runs 18 deterministic writing checks — readability scoring, token budgets, section completeness, grammar, dialect enforcement, and style analysis. No LLM, no API calls, no network. Same input, same result, every time.
The goal: agent-generated documents that are clean enough to ship.
```
$ bito-lint analyze docs/architecture.md
docs/architecture.md
Readability: Grade 12.4, 24 sentences, 390 words
Grammar: 8 issues, 3 passive (12.5%)
Sticky: Glue index 21.5%, 2 sticky sentences
Pacing: Fast 62% / Medium 29% / Slow 8%
Length: Avg 15.8 words, variety 10.0/10
Transitions: 0% of sentences, 0 unique
Overused: "template" (1.3%), "skill" (1.1%), "design" (1.1%)
Diction: 2 vague words
Style: Score 92/100, 2 adverbs, 0 hidden verbs
```
## What it checks
**`analyze`** runs 18 checks in one pass:
| Readability | Flesch-Kincaid grade level — flag documents that demand too much of the reader |
| Grammar | Passive voice, double negatives, subject-verb disagreement, missing punctuation |
| Sticky sentences | High "glue word" density — sentences stuffed with *is*, *the*, *of*, *in* |
| Pacing | Monotonous sentence rhythm — all short punches or all long slogs |
| Sentence variety | Length distribution — a score of 1/10 means every sentence is the same length |
| Transitions | Percentage of sentences using connective phrases — low means choppy reading |
| Overused words | Repeated non-trivial words that make the text feel circular |
| Repeated phrases | Bigrams and trigrams that recur too often |
| Echoes | Same word appearing in adjacent sentences (unintentional repetition) |
| Complex paragraphs | Paragraphs with too many ideas competing for attention |
| Conjunction starts | Sentences opening with *But*, *And*, *So* — fine in moderation, a tic in excess |
| Cliches | "At the end of the day," "move the needle," "low-hanging fruit" |
| Diction | Vague words (*things*, *stuff*, *very*) that add length without meaning |
| Sensory language | Percentage of concrete, sensory words — useful for judging descriptive writing |
| Consistency | Mixed US/UK spelling (*color* and *colour* in the same document) |
| Dialect enforcement | Flag spellings that violate your project's chosen dialect (en-us, en-gb, en-ca, en-au) |
| Acronyms | Tracks acronym usage for consistency |
| Style score | Combined metric: adverb density, hidden verbs (nominalizations), overall polish |
Every check is deterministic. No API calls, no LLM, no network. The same input produces the same output every time.
**Focused checks** run individually when you need a specific gate:
```bash
# Does this handoff fit in 2,000 tokens?
$ bito-lint tokens handoff.md --budget 2000
PASS: handoff.md is 546 tokens (budget: 2000)
# Is this user guide accessible to a general audience?
$ bito-lint readability getting-started.md --max-grade 8
Error: getting-started.md scores 14.7 (max: 8). Simplify sentences or reduce jargon.
# Does this ADR have all the sections it needs?
$ bito-lint completeness docs/decisions/0001-my-decision.md --template adr
PASS: docs/decisions/0001-my-decision.md (adr completeness check)
# How's the grammar?
$ bito-lint grammar changelog.md
changelog.md: 16 sentences analyzed
Passive voice: 2 instances (12.5%)
Grammar issues: 3
[MEDIUM] Sentence 3: Possible comma splice
[LOW] Sentence 9: Multiple consecutive spaces found
[MEDIUM] Sentence 16: Sentence missing terminal punctuation
```
## Installation
### Homebrew (macOS and Linux)
```bash
brew install claylo/brew/bito-lint
```
### From source
```bash
cargo install bito-lint
```
### Pre-built binaries
Download from the [releases page](https://github.com/claylo/bito-lint/releases). Binaries are available for macOS (Apple Silicon and Intel), Linux (x86_64 and ARM64), and Windows.
## Usage
### Full analysis
```bash
bito-lint analyze my-document.md
```
Add `--json` for machine-readable output. Add `--dialect en-gb` to enforce British spelling. Add `--checks readability,consistency` to run only specific checks.
### Quality gates
Quality gates are pass/fail checks designed for CI, pre-commit hooks, and automation:
```bash
# Token counting with budget enforcement
bito-lint tokens <file> --budget <max>
# Readability with grade ceiling
bito-lint readability <file> --max-grade <max>
# Section completeness against a template
bito-lint completeness <file> --template <name>
# Grammar and passive voice analysis
bito-lint grammar <file>
```
Built-in completeness templates: `adr`, `handoff`, `design-doc`. Define your own in a bito-lint config file.
Every command exits non-zero on failure, writes structured JSON with `--json`, and works in pipes.
### Dialect enforcement
Set a project dialect and bito-lint flags wrong-dialect spellings alongside mixed-spelling inconsistencies:
```bash
# Via flag
bito-lint analyze README.md --dialect en-us
# Via environment variable
export BITO_LINT_DIALECT=en-gb
# Via config file (.bito-lint.toml)
dialect = "en-ca"
```
Supported dialects: `en-us`, `en-gb`, `en-ca` (Canadian hybrid: US *-ize/-ise*, UK for the rest), `en-au`.
### MCP server
bito-lint includes a built-in [MCP](https://modelcontextprotocol.io/) server, so AI coding assistants can call quality gates directly during writing sessions:
```json
{
"mcpServers": {
"bito-lint": {
"command": "bito-lint",
"args": ["serve"]
}
}
}
```
This exposes six tools: `analyze_writing`, `count_tokens`, `check_readability`, `check_completeness`, `check_grammar`, and `get_info`. Total schema cost: ~1,283 tokens. See [docs/mcp-development.md](docs/mcp-development.md) for context budget details.
## Configuration
Drop a config file in your project and it takes effect automatically:
1. `.bito-lint.toml` (or `.yaml`, `.json`) in the current directory or any parent
2. `bito-lint.toml` (without dot prefix) in the current directory or any parent
3. `~/.config/bito-lint/config.toml` (user-wide defaults)
Closer files win. All formats (TOML, YAML, JSON) work interchangeably.
```toml
# .bito-lint.toml
dialect = "en-us"
token_budget = 2000
max_grade = 12.0
log_level = "warn"
```
## Shell completions
Included in Homebrew installs and release archives. For manual setup:
```bash
# Bash
bito-lint completions bash > ~/.local/share/bash-completion/completions/bito-lint
# Zsh
bito-lint completions zsh > ~/.zfunc/_bito-lint
# Fish
bito-lint completions fish > ~/.config/fish/completions/bito-lint.fish
```
## Development
```
crates/
├── bito-lint/ # CLI binary
└── bito-lint-core/ # Core library
```
Prerequisites: Rust 1.88.0+, [just](https://github.com/casey/just), [cargo-nextest](https://nexte.st/).
```bash
just check # fmt + clippy + test
just test # tests only (nextest)
just cov # coverage report
```
Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/). The project enforces safe Rust (`#![deny(unsafe_code)]`), clippy nursery lints, and `cargo deny` for dependency auditing.
## License
MIT ([LICENSE-MIT](LICENSE-MIT))