🏰 Self-documenting Identifier Name Analyser for Go
1# 🏰 Kivia
2
3> Self-documenting Name Analyser for Go
4
5Name things so your code explains itself.
6
7Kivia is a fast, local-only analyser that flags identifiers whose terms are absent from dictionary sources or resemble abbreviations of dictionary words. It is built for teams that want explicit, readable naming conventions without external AI calls.
8
9## Philosophy
10
11Identifier names should be fully self-documenting.
12
13Kivia enforces a strict readability standard:
14
15- Prefer full words over shorthand
16- Avoid ambiguous abbreviations
17- Keep the naming intent clear from the identifier itself
18
19Examples:
20
21- `userNum` → invalid (`num` is an abbreviation)
22- `ctx` → invalid (`ctx` is an abbreviation)
23- `userCount` → valid
24- `requestContext` → valid
25
26## Rules
27
281. **Dictionary words pass**: If a token is present in the loaded dictionary sources, it passes.
292. **Abbreviations are violations**: If a token expands to a dictionary word (for example, `ctx` -> `context`), it is flagged.
303. **Unknown terms are violations**: If a token is not in the dictionary and does not map to a known expansion, it is flagged.
314. **Minimum length is explicit**: `--min-eval-length` determines whether short identifiers are evaluated.
32
33Kivia also applies dictionary-backed spelling-variant matching for common British/American pairs (for example `normalise`/`normalize`, `colour`/`color`, `centre`/`center`).
34
35## How It Works
36
37Kivia parses Go source using the standard library's AST, extracts identifiers, tokenises names (camel, snake, or kebab), and evaluates each token against a local NLP dictionary pipeline.
38
39- No network requests
40- No LLM/API dependency
41- Deterministic local analysis
42
43## Installation
44
45```bash
46go install github.com/Fuwn/kivia@latest
47```
48
49Or build locally:
50
51```bash
52go build -o ./bin/kivia .
53```
54
55## Usage
56
57```bash
58# Analyse a package tree
59kivia --path ./...
60
61# Ignore single-letter names during evaluation
62kivia --path ./... --min-eval-length 2
63
64# Ignore specific violations
65kivia --path ./... --ignore name=ctx --ignore file=testdata
66
67# JSON output without context payload
68kivia --path ./... --format json --omit-context
69```
70
71### Flags
72
73| Flag | Description |
74|------|-------------|
75| `--path` | Path to analyse (`directory`, `file`, or `./...`). |
76| `--omit-context` | Hide usage context in output. |
77| `--min-eval-length` | Minimum identifier length in runes to evaluate (must be `>= 1`). |
78| `--format` | Output format: `text` or `json`. |
79| `--fail-on-violation` | Exit with code `1` when violations are found. |
80| `--ignore` | Ignore violations by matcher. Repeatable. Prefixes: `name=`, `kind=`, `file=`, `reason=`, `func=`. |
81
82## Ignore Matchers
83
84`--ignore` supports targeted filtering:
85
86- `name=<substring>`
87- `kind=<substring>`
88- `file=<substring>`
89- `reason=<substring>`
90- `func=<substring>`
91
92Without a prefix, the matcher is applied as a substring across all violation fields.
93
94Example:
95
96```bash
97kivia --path ./... \
98 --ignore name=ctx \
99 --ignore reason=abbreviation \
100 --ignore file=_test.go
101```
102
103## Output
104
105### Text (default)
106
107```text
108internal/example/sample.go:12:9 parameter "ctx": Contains abbreviation: ctx.
109 context: type=context.Context, function=Handle
110```
111
112### JSON
113
114```json
115{
116 "violations": [
117 {
118 "identifier": {
119 "name": "ctx",
120 "kind": "parameter",
121 "file": "internal/example/sample.go",
122 "line": 12,
123 "column": 9,
124 "context": {
125 "enclosingFunction": "Handle",
126 "type": "context.Context"
127 }
128 },
129 "reason": "Contains abbreviation: ctx."
130 }
131 ]
132}
133```
134
135## Identifier Scope (Go)
136
137Kivia currently extracts and evaluates:
138
139- Types
140- Functions and methods
141- Receivers
142- Parameters
143- Named results
144- Variables (`var`/`const` and `:=`)
145- Range keys and values
146- Struct fields
147- Interface methods
148
149## Dictionary and NLP Source
150
151Kivia loads dictionary data only from configured/system dictionary files.
152
1531. `KIVIA_DICTIONARY_PATH` (optional): one path or multiple paths separated by your OS path separator (`:` on macOS/Linux, `;` on Windows). Commas are also accepted.
1542. If `KIVIA_DICTIONARY_PATH` is not set, Kivia uses a default set of dictionary files (for example, `/usr/share/dict/words`, `/usr/share/dict/web2`, and Hunspell dictionaries when present).
1553. If no usable words are found, the analysis fails with an error.
156
157## License
158
159Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or
160[MIT license](LICENSE-MIT) at your option.
161
162Unless you explicitly state otherwise, any contribution intentionally submitted
163for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
164be dual licensed as above, without any additional terms or conditions.