plain-language
Read plain-language.md in this skill's directory and adopt the writing style it defines, ignoring its frontmatter. Stay in Plain Language until the user explicitly asks to stop — for example, "stop plain language" or "back to normal".
The linter
scripts/lint.py catches the mechanical half of the style: formal words with plainer equivalents, hidden verbs, filler, corporate jargon, AI phrase structures, long sentences, dense paragraphs, and likely passive voice. Run it with any runner that supports PEP 723 inline dependencies (default uv). Run it from the project directory, not this skill's directory. Target paths and project overrides both resolve from the working directory.
uv run scripts/lint.py [PATH ...] [--fix [--dry-run]] [--json] [--strict] [--errors-only] [--disable-rule IDS]
A path is a file or a directory. The linter walks a directory for .md, .markdown, .mdx, .txt, and .rst files. With no path it reads stdin. Findings come in two tiers:
- Errors — dictionary hits. Either a single replacement (
utilise → use) or a set of candidates (leverage → use | build on). High confidence; resolve every one. - Warnings — pattern heuristics. Passive voice, sentence length, paragraph density, and the AI structures. These misfire on writing that is already good, so judge each one rather than obeying it.
--fix applies the single-replacement swaps in place and leaves everything else alone. Add --dry-run to see those swaps as a list and write nothing — same file, line, and column as a finding, plus the replacement. It exits 1 when swaps are pending, so it works as a check. With --json it emits { "fixes": [...], "findings": [...] } rather than a bare findings array. --dry-run on its own is a usage error. --strict reports warnings as errors, --errors-only hides them, --disable-rule triad,em-dash-pivot switches named rules off, and --json emits findings as an array. Exit code 1 means the linter reported findings, not that the run failed.