The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Unswell listing page.
A linter for lean English, built to reduce AI-sounding prose.
Unswell's main motivation is to keep formulaic AI-style wording from leaking into source code and documentation. AI-assisted work often leaves behind conversational preambles, generic claims of importance, inflated modifiers and repeated setup. Unswell finds these patterns in prose and explains what to revise before the text reaches a commit or a published document.
The checks apply to text regardless of its author. They enforce a chosen editorial policy through concrete findings and explainable scores. Unswell runs locally as a Go library and CLI, without sending source text to an AI service.
Unswell is not an authorship detector. A clean scan of a generated text is a correct result, and a finding on a human-written text is a finding about the wording. No score is a probability that a tool wrote the text; see ADR 0037 for the goal and its non-goals.
Development alpha. The published release is v0.1.0-alpha.3. Stage 2 features
include custom rules, baselines, and checks of changed code. Go tools can train,
calibrate, and load models.
Rules and defaults remain experimental. No editorial model has met the criteria for use in the product. See the acceptance audit for features, release evidence, and work still open. Revision probability is unavailable until a labeled corpus and compatible calibration model meet the later acceptance criteria.
Build with the minimum Go version declared in go.mod:
Install the published alpha without Go through the Homebrew tap:
A separate GitHub Action runs pinned release archives and writes JSON/SARIF reports. See installation and release verification for availability and platform checks.
For example, this introduction:
produces filler.announced-importance. A direct version preserves the condition:
Use the strict profile to make the introductory phrase a hard policy violation:
One analysis can write all five reports:
Add --include-source to retain snippets and highlighted paragraphs in saved
reports. Source text is omitted by default. Reports can contain internal prose;
choose artifact access accordingly.
Exit codes: 0 for a complete pass, 1 for a complete policy failure, 2 for
operational errors or incomplete analysis, and 130 for cancellation. An empty
scan fails unless explicitly allowed. --no-gate permits advisory checks while
preserving operational errors. Display filtering never changes the gate. A rule
that exhausts its candidate budget abstains on that document with the reason
budget_exhausted; the report lists the abstention and the other rules' findings
stay.
The index uses points from 0 to 100. Every local score includes its contributing rules, activations, deduplication decisions and caps. A clean paragraph cannot reduce another paragraph's score. The tool makes no authorship or factuality claim.
Inputs include plain text, Markdown/GFM, MDX, and comments and string literals in Go,
JavaScript, TypeScript/TSX, Python, Rust, Java, C/C++, C#, YAML, Bash/POSIX sh, Zsh's common
shell syntax, Fish and PowerShell. Markdown uses block and inline grammars.
See formats and extraction limits for extensions and dialect details.
For stdin, provide --filename or a supported --format. Coordinates use original
UTF-8 byte ranges and one-based Unicode code point columns.
Recursive Git scans select tracked files. Explicit files may be untracked and bypass recursive include/exclude patterns. Outside Git, directories use a bounded filesystem walk. Inputs must remain within the current project root. Symlinks are not followed during discovery. Unsupported explicit formats fail.
The CLI reads the nearest .unswell.yaml up to the project root, or the exact file
named by --config. It reads no home configuration. Local inheritance, ordered file
overrides, and shared term dictionaries use one
configuration plan in the CLI, library, and MCP server.
Add team policies with custom rule packs, load them through
--ruleset or inline rule_sets, and execute their examples with unswell rules test.
Select checked contexts globally or per language with the
extraction policy. Use reasoned exceptions for intentional
examples, dictionaries and other text that should remain outside an editorial check.
Exceptions can select paths, languages, comments or strings, and named string owners.
AI assistants can call the same engine through the separate MCP server.
Its tools check supplied drafts and expose the fixed policy. make dogfood-mcp
verifies repository checks through a real MCP client and subprocess.
Separate CLI and MCP containers support Linux AMD64 and ARM64,
including repository checks through both interfaces in CI. Both images are public
in GHCR and mirrored to Docker Hub with matching digests and attestations.
Available profiles are technical, strict, minimal, business, reference
and custom; each also accepts a -v1 suffix. Unknown settings, duplicate keys,
unsupported rule parameters and unavailable model names fail before analysis.
The external consumer implements a custom rule using only public packages. See the API policy for supported imports and ownership contracts. Go rules are trusted code and must support concurrent calls.
Unswell checks its own README, documentation, Go code and Bash scripts with the committed
strict repository policy. Run make dogfood, or make check for
all checks. CI runs the same gate and uploads all five report formats. A negative
CLI probe must fail with exit code 1, proving the policy is active. Third-party
licenses and test-data documents are outside this editorial policy; inline code
and fenced examples use the normal extractor's protected boundaries.
The policy excludes deliberate fixture strings and catalog data with recorded reasons.
Comments and runtime strings remain checked. Bash also passes syntax, ShellCheck
and shfmt checks, including negative probes for each gate.
Reasoned source suppressions permit individual rule findings
while retaining raw evidence, scores, and an audit record across CLI and MCP.
Explicit baselines accept existing debt without removing findings
or changing scores. The new gate checks new findings and changed scored units.
Committed changed-unit checks compare merge-base to HEAD with
clean-source verification and retain whole-document repetition context.
Use trusted policy to apply merge-base rules and baseline
while auditing candidate policy changes and new source permissions.
The public Go analysis adapter and its prototype vet driver
check comments and strings through the same engine.
The contextual editorial catalog adds opt-in filler,
hype, and rhetorical-pattern checks with explicit evidence and technical counterexamples.
The repetition catalog adds bounded phrase, POS-template,
paragraph, heading, and summary comparisons with measured overlap evidence.
The surface catalog adds opt-in syntax, readability, and
formatting measurements with explicit counting protocols and protected boundaries.
The research pipeline that fits and evaluates those models is a separate
developer workflow; see training and evaluation.
The active roadmap improves contextual diagnostics and checks
them on real technical prose. Human qualification and calibrated revision
probabilities remain deferred under ADR 0037, with their original requirements
preserved. Neither capability is claimed by this alpha.
Code, URLs, front matter, directives and quoted Markdown blocks are excluded from ordinary prose checks. POS-based chunks are surface candidates, not grammatical dependencies. Lexical overlap is not a claim of semantic equivalence. Thresholds are initial editorial policy, not measured precision or confidence.
Code is MIT licensed. Runtime dependencies and the embedded English model have their own notices. No scan downloads rules, sends prose to a service or requires Python, Node.js, a server, an API key or cgo.