grounded-lint 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. grounded_lint-0.7.1/CHANGELOG.md +114 -0
  2. grounded_lint-0.7.1/LICENSE +21 -0
  3. grounded_lint-0.7.1/MANIFEST.in +7 -0
  4. grounded_lint-0.7.1/PKG-INFO +302 -0
  5. grounded_lint-0.7.1/README.md +263 -0
  6. grounded_lint-0.7.1/examples/v2demo/src/app.js +16 -0
  7. grounded_lint-0.7.1/examples/v2demo/src/app.py +21 -0
  8. grounded_lint-0.7.1/examples/v2demo/src/real.js +3 -0
  9. grounded_lint-0.7.1/examples/v2demo/src/real_module.py +19 -0
  10. grounded_lint-0.7.1/pyproject.toml +35 -0
  11. grounded_lint-0.7.1/setup.cfg +4 -0
  12. grounded_lint-0.7.1/src/grounded/__init__.py +5 -0
  13. grounded_lint-0.7.1/src/grounded/checkers.py +799 -0
  14. grounded_lint-0.7.1/src/grounded/cli.py +286 -0
  15. grounded_lint-0.7.1/src/grounded/config.py +88 -0
  16. grounded_lint-0.7.1/src/grounded/delta.py +165 -0
  17. grounded_lint-0.7.1/src/grounded/fix.py +195 -0
  18. grounded_lint-0.7.1/src/grounded/mcp.py +207 -0
  19. grounded_lint-0.7.1/src/grounded/models.py +67 -0
  20. grounded_lint-0.7.1/src/grounded/parsers.py +693 -0
  21. grounded_lint-0.7.1/src/grounded/py.typed +1 -0
  22. grounded_lint-0.7.1/src/grounded/repo_index.py +198 -0
  23. grounded_lint-0.7.1/src/grounded/reporters.py +184 -0
  24. grounded_lint-0.7.1/src/grounded/scanner.py +157 -0
  25. grounded_lint-0.7.1/src/grounded_lint.egg-info/PKG-INFO +302 -0
  26. grounded_lint-0.7.1/src/grounded_lint.egg-info/SOURCES.txt +28 -0
  27. grounded_lint-0.7.1/src/grounded_lint.egg-info/dependency_links.txt +1 -0
  28. grounded_lint-0.7.1/src/grounded_lint.egg-info/entry_points.txt +2 -0
  29. grounded_lint-0.7.1/src/grounded_lint.egg-info/top_level.txt +1 -0
  30. grounded_lint-0.7.1/tests/test_grounded.py +895 -0
@@ -0,0 +1,114 @@
1
+ # Changelog
2
+
3
+ All notable changes to `grounded` are documented here. Format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
+
6
+ ## [0.7.1] - 2026-09-21
7
+
8
+ ### Changed
9
+ - Distribution renamed to `grounded-lint` on PyPI (bare `grounded` was
10
+ claimed). Command (`grounded`), import package, and action behavior
11
+ unchanged.
12
+
13
+ ## [0.7.0] - 2026-09-21
14
+
15
+ ### Added
16
+ - `grounded mcp`: stdlib MCP server over stdio (initialize negotiation,
17
+ tools/list, tools/call, ping) with `check_path` and `explain_checker`
18
+ tools; paths confined to the server root. Verified with an independent
19
+ Node client against the spec.
20
+ - Symbol renames in `grounded fix`: exactly one similar (ratio 0.75+),
21
+ same-directory candidate, or nothing is touched. Proven on the case
22
+ that killed naive similarity autofix.
23
+ - Per-symbol defining files in the repo index (powers scope proximity).
24
+
25
+ ### Changed
26
+ - General Markdown verification declined after measurement (199 import
27
+ claims trivially valid, flag claims mostly external tools on axios
28
+ docs); overlaps readme-ci, doccident, doc-drift, and docverity.
29
+
30
+ ## [0.6.0] - 2026-09-17
31
+
32
+ ### Added
33
+ - C support (`.c`/`.h`): functions incl. split declarations and K&R style,
34
+ types, macros, function-pointer members, `#include` maps.
35
+ - Parallel scanning (`--jobs N`, auto by file count; identical output).
36
+ - VS Code task snippet using the bundled problem matcher.
37
+
38
+ ### Changed
39
+ - JS index covers default exports, `module.exports` members, TS
40
+ interfaces/types (no benchmark delta).
41
+
42
+ ## [0.5.0] - 2026-09-17
43
+
44
+ ### Added
45
+ - Go support: functions, types, and imports across all four checkers.
46
+ - `grounded fix [--dry-run]`: rewrites unambiguous stale file paths
47
+ (unique same-basename match, comment lines only).
48
+ - Inline suppressions: `# grounded-disable: <id>` (`//` form for JS/TS/Go).
49
+ - First-party GitHub Action with problem matchers (verified live on a
50
+ test PR); pre-commit hook definition.
51
+
52
+ ### Changed
53
+ - File references use exact-path semantics and list same-named candidates;
54
+ ticket-anchored history notes stay silent.
55
+ - Markdown files are not scanned: measured zero file-reference hits across
56
+ 160 documentation files, so no evidence of value (rejected).
57
+ - Symbol rename autofix rejected: string-similarity ranking picked the
58
+ wrong target on a real case; suggestions stay advisory-only.
59
+
60
+ ## [0.4.1] - 2026-09-17
61
+
62
+ ### Fixed
63
+ - CI demo-fixture count to match current fixtures. No product changes.
64
+
65
+ ## [0.4.0] - 2026-09-17
66
+
67
+ ### Added
68
+ - Inline suppressions: `# grounded-disable: <id>` (`//` form for JS/TS).
69
+ - First-party GitHub Action (`action.yml`) with problem matchers for inline
70
+ PR annotations; verified live on a test PR.
71
+ - Pre-commit hook definition (`.pre-commit-hooks.yaml`).
72
+
73
+ ### Changed
74
+ - Commented-code suppression gate tightened (prose with a few keywords no
75
+ longer qualifies).
76
+
77
+ ## [0.3.0] - 2026-09-17
78
+
79
+ ### Added
80
+ - `grounded baseline`: record current findings to `.grounded-baseline.json`.
81
+ `scan --baseline FILE` then reports only new findings. Fingerprints hash
82
+ checker, path, and claim text (never line numbers), so unrelated edits
83
+ that shift lines do not churn the file. `--show-baselined` lists
84
+ suppressed findings.
85
+ - `scan --changed [BASE]` (default: `HEAD`): report only findings on lines
86
+ changed relative to BASE, for PR gates and pre-commit use. The tree is
87
+ still fully scanned; reporting is filtered. Fails loudly outside git.
88
+ - `.gitignore`, contributor fixture guidelines in README.
89
+
90
+ ## [0.2.0] - 2026-09-17
91
+
92
+ ### Changed
93
+ - Deleted `param-mismatch`, `raises-mismatch`, `return-mismatch`,
94
+ `commented-code`: verified redundant with darglint/pydoclint,
95
+ eslint-plugin-jsdoc, and Ruff ERA001. `explain <id>` now routes to them.
96
+ - Rebuilt `stale-symbol-ref`: import-aware (stdlib/deps/relative), same-file
97
+ scope proxy, Sphinx/JSDoc-tag scrubbing, dunder-typo class, verb-gated
98
+ bare calls, acronym/negation/ticket gates, `difflib` rename suggestions.
99
+ - Hardened `stale-file-ref`: repo-scope rule, alphabetic extension list,
100
+ placeholder + illustrative-example handling.
101
+ - Tightened commented-code suppression gate (suppression-only use).
102
+ - Excluded TypeScript declaration files (`.d.ts`/`.d.cts`/`.d.mts`).
103
+ - Measured on requests/axios/django: 844 → 42 findings; the 1 remaining
104
+ lie is a confirmed true rename-rot.
105
+
106
+ ### Added
107
+ - `examples/v2demo`: 4-file fixture tree (8 intended findings, designed
108
+ silences for every suppression rule).
109
+ - MIT `LICENSE`, CI workflow (tests + self-scan gate), this file.
110
+
111
+ ## [0.1.0] - 2026-09-16
112
+
113
+ Initial release: 8 checkers. Superseded by 0.2.0, which narrowed scope to
114
+ reference checks and removed contract checks covered by other linters.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 gonisulaimann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include README.md CHANGELOG.md LICENSE
2
+ include src/grounded/py.typed
3
+ recursive-include examples *.py *.js
4
+ prune src/grounded.egg-info
5
+ prune build
6
+ prune dist
7
+ global-exclude __pycache__ *.py[cod]
@@ -0,0 +1,302 @@
1
+ Metadata-Version: 2.4
2
+ Name: grounded-lint
3
+ Version: 0.7.1
4
+ Summary: Find dangling references in code comments. Deterministic, offline, zero dependencies.
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 gonisulaimann
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Project-URL: Homepage, https://github.com/gonisulaimann/Grounded
28
+ Project-URL: Changelog, https://github.com/gonisulaimann/Grounded/blob/main/CHANGELOG.md
29
+ Keywords: lint,comments,documentation,static-analysis,tech-debt
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Developers
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Topic :: Software Development :: Quality Assurance
35
+ Requires-Python: >=3.10
36
+ Description-Content-Type: text/markdown
37
+ License-File: LICENSE
38
+ Dynamic: license-file
39
+
40
+ # grounded
41
+
42
+ [![CI](https://github.com/gonisulaimann/Grounded/actions/workflows/ci.yml/badge.svg)](https://github.com/gonisulaimann/Grounded/actions/workflows/ci.yml)
43
+ [![PyPI version](https://badge.fury.io/py/grounded-lint.svg)](https://pypi.org/project/grounded-lint/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
45
+ <a href="https://www.ko-fi.com/gonisulaiman"><img src="https://srv-cdn.himpfen.io/badges/kofi/kofi-flat.svg" alt="Ko-Fi" /></a>
46
+
47
+ Find dangling references in code comments. If a comment names a function
48
+ that no longer exists, or a file that is not there, `grounded` reports it
49
+ with the claim, the evidence, and a suggested fix.
50
+
51
+ ```console
52
+ $ grounded scan ./src
53
+ LIE src/app.py:9 [stale-symbol-ref] Comment references `ghost_service` which is not defined here
54
+ claim: `ghost_service()`
55
+ evidence: `ghost_service` is not defined, imported, or used in this file,
56
+ and no definition was found in 84 indexed source files.
57
+ fix: Update the comment to the current name, or remove the reference.
58
+ ```
59
+
60
+ Zero dependencies. No network access. Works on Python, JavaScript/TypeScript, Go, and C.
61
+
62
+ ## Install
63
+
64
+ Requires Python 3.10 or later.
65
+
66
+ ```console
67
+ pip install grounded-lint
68
+ ```
69
+
70
+ From source:
71
+
72
+ ```console
73
+ git clone https://github.com/gonisulaimann/Grounded.git
74
+ cd Grounded
75
+ pip install -e .
76
+ ```
77
+
78
+ ## Usage
79
+
80
+ ```console
81
+ grounded scan [PATH] [--format terminal|json|sarif|html] [--output FILE]
82
+ [--fail-on lie|drift|smell|never]
83
+ [--enable CHECKER,...] [--disable CHECKER,...]
84
+ [--baseline FILE] [--show-baselined]
85
+ [--changed [BASE]]
86
+ [--config grounded.toml] [--no-color] [--quiet]
87
+ [--jobs N]
88
+ grounded baseline [PATH] [--output FILE] # record findings for delta gating
89
+ grounded fix [PATH] [--dry-run] # rewrite unambiguous stale file paths
90
+ grounded list [PATH] # show files that would be scanned
91
+ grounded explain CHECKER # describe a checker (including removed ones)
92
+ grounded init [--force] # write a starter grounded.toml
93
+ ```
94
+
95
+ `grounded scan` exits with status `1` when any finding meets `--fail-on`
96
+ (default: `lie`), `0` otherwise. Point it at CI and gate on the default.
97
+
98
+ Example output formats for tooling: `--format json` for scripts,
99
+ `--format sarif` for GitHub code scanning, `--format html` for a
100
+ self-contained report page (no external assets, works opened from disk).
101
+
102
+ Large trees scan in parallel automatically (32+ files); `--jobs N`
103
+ overrides, `--jobs 1` forces serial. Output is identical either way.
104
+
105
+ In VS Code, wire the bundled problem matcher through a task
106
+ (`.vscode/tasks.json`, paths relative to the workspace):
107
+
108
+ ```json
109
+ {
110
+ "version": "2.0.0",
111
+ "tasks": [
112
+ {
113
+ "label": "grounded",
114
+ "type": "shell",
115
+ "command": "grounded scan . --no-color",
116
+ "problemMatcher": {
117
+ "owner": "grounded",
118
+ "pattern": [
119
+ {
120
+ "regexp": "^(LIE|DRIFT|SMELL)\\s+(.+?):(\\d+)\\s+\\[(.+?)\\]\\s+(.*)$",
121
+ "file": 2,
122
+ "line": 3,
123
+ "code": 4,
124
+ "message": 5
125
+ }
126
+ ]
127
+ }
128
+ }
129
+ ]
130
+ }
131
+ ```
132
+
133
+ ## Adopting on an existing codebase
134
+
135
+ Two mechanisms, composable. Both keep the full-tree scan and filter
136
+ reporting only.
137
+
138
+ Record a baseline once, commit it, gate on the delta:
139
+
140
+ ```console
141
+ grounded baseline . --output .grounded-baseline.json # record today
142
+ git add .grounded-baseline.json
143
+ grounded scan . --baseline .grounded-baseline.json # new findings only
144
+ ```
145
+
146
+ Fingerprints cover checker, path, and claim text, not line numbers, so
147
+ unrelated edits do not churn the file. Editing the offending line itself
148
+ re-triggers the gate. `--show-baselined` lists suppressed findings.
149
+
150
+ Gate pull requests on changed lines only:
151
+
152
+ ```console
153
+ grounded scan . --changed # uncommitted work vs HEAD
154
+ grounded scan . --changed origin/main # branch vs base (CI)
155
+ ```
156
+
157
+ Untracked files are fully reported. Outside a git repo, or with an
158
+ unresolvable base, `--changed` exits `2` with the git error instead of
159
+ silently scanning everything.
160
+
161
+ ## Rules
162
+
163
+ | ID | Default severity | What it reports |
164
+ |---|---|---|
165
+ | `stale-symbol-ref` | lie (error) | A comment names a call that resolves nowhere: not defined in the repo, not imported in the file, not used in the file, not a builtin or keyword. Prints rename suggestions when a close match exists. |
166
+ | `stale-file-ref` | lie (error) | A comment claims a path inside the repo tree that does not exist. References to other projects, frameworks, template namespaces, and placeholder paths are ignored. |
167
+ | `number-drift` | drift (warning) | A comment states a magic number (timeout, port, limit, threshold) that disagrees with adjacent code. |
168
+ | `fragile-anchor` | smell (note) | `line 42` anchors, `see above` / `see below` without a symbol, and workaround markers (`HACK`, `XXX`, `workaround`) with no ticket or expiry condition. |
169
+
170
+ A rule stays silent unless the contradiction is mechanical. Imported names,
171
+ standard library names, parameters, locals, attributes, docstring field
172
+ lists (`:param:`, `@param`), and illustrative examples ("For example …")
173
+ never produce findings.
174
+
175
+ ## Configuration
176
+
177
+ `grounded init` writes a starter file. Settings also load from
178
+ `pyproject.toml` under `[tool.grounded]`.
179
+
180
+ ```toml
181
+ # grounded.toml
182
+ disable = ["fragile-anchor"]
183
+ fail_on = "lie"
184
+ ignore_dirs = ["docs", "sandbox"]
185
+ ignore_files = ["generated.py"]
186
+ ```
187
+
188
+ Suppress a single accepted finding where it sits (reviewable, local):
189
+
190
+ ```python
191
+ # Calls `legacy_parse()` for old dumps. # grounded-disable: stale-symbol-ref
192
+ ```
193
+
194
+ ```js
195
+ // Calls `legacyParse()` for old dumps. // grounded-disable: stale-symbol-ref
196
+ ```
197
+
198
+ ## CI, pre-commit, and GitHub Action
199
+
200
+ Gate pull requests with the first-party Action (inline PR annotations
201
+ included via problem matchers):
202
+
203
+ ```yaml
204
+ - uses: gonisulaimann/Grounded@v0.7.0
205
+ with:
206
+ changed-base: origin/main # new findings on edited lines only
207
+ fail-on: lie
208
+ ```
209
+
210
+ Or with a baseline file for whole-tree delta gating:
211
+
212
+ ```yaml
213
+ - uses: gonisulaimann/Grounded@v0.7.0
214
+ with:
215
+ baseline: .grounded-baseline.json
216
+ ```
217
+
218
+ As a pre-commit hook (runs on uncommitted changes):
219
+
220
+ ```yaml
221
+ repos:
222
+ - repo: https://github.com/gonisulaimann/Grounded
223
+ rev: v0.7.0
224
+ hooks:
225
+ - id: grounded
226
+ ```
227
+
228
+ SARIF upload for code scanning: run with `--format sarif --output
229
+ results.sarif`, then upload with `github/codeql-action/upload-sarif`.
230
+
231
+ ## Coding agents (MCP)
232
+
233
+ `grounded` serves itself over stdio as a Model Context Protocol server,
234
+ so agents can verify references instead of trusting them:
235
+
236
+ ```json
237
+ {
238
+ "mcpServers": {
239
+ "grounded": { "command": "grounded", "args": ["mcp", "--root", "."] }
240
+ }
241
+ }
242
+ ```
243
+
244
+ Two tools: `check_path` (scan a path under the server root; paths cannot
245
+ escape it) and `explain_checker`. Protocol versions `2025-03-26` through
246
+ `2025-06-18` are negotiated per the spec; logs go to stderr, stdout
247
+ carries only MCP messages.
248
+
249
+ ## Non-goals
250
+
251
+ Docstring contracts (parameter lists, return sections, raised exceptions)
252
+ are covered precisely by [darglint](https://github.com/terrencepreilly/darglint)
253
+ and [pydoclint](https://github.com/jsh9/pydoclint) for Python and
254
+ [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) for
255
+ JavaScript/TypeScript. Commented-out code is covered by
256
+ [Ruff ERA001](https://docs.astral.sh/ruff/rules/commented-out-code/) and
257
+ equivalent ESLint rules. `grounded` intentionally does not duplicate them;
258
+ `grounded explain <id>` points at the right tool for each removed check.
259
+
260
+ ## Limitations
261
+
262
+ - Unformatted, unverbed name mentions are skipped. A rename noted without
263
+ backticks or a reference verb ("calls", "see", "uses") will be missed.
264
+ This trades recall for precision.
265
+ - Names imported from anywhere are treated as known elsewhere, including
266
+ cross-module renames.
267
+ - Framework namespaces (template paths, URL names) are out of scope; such
268
+ references stay silent instead of guessed.
269
+ - JavaScript/TypeScript, Go, and C analysis is syntactic (imports plus
270
+ identifiers), not a full type graph.
271
+ - External references stay silent only when recognized: stdlib and POSIX
272
+ names, imports, and same-file identifiers. References to vendored code,
273
+ kernel idioms, platform APIs, paper algorithms, and prose verbs in
274
+ parentheses (`forks()`) can still report; judge those on sight.
275
+ - Rename suggestions use string similarity only; the first guess can miss.
276
+ `grounded fix` applies a symbol rename only with exactly one similar,
277
+ same-directory candidate.
278
+ - `grounded fix` rewrites stale file paths only on unambiguous
279
+ same-basename matches in comments (never docstrings, never ties).
280
+
281
+ ## Development
282
+
283
+ ```console
284
+ python -m unittest discover -s tests # 80+ tests, stdlib only, no extras
285
+ grounded scan src # self-scan gate, must report clean
286
+ grounded scan examples/v2demo # fixture tree, expect 10 findings
287
+ ```
288
+
289
+ ## Contributing
290
+
291
+ Issues and pull requests are welcome. Please include:
292
+
293
+ - a minimal fixture (a few lines showing the comment and the code),
294
+ - current output vs expected output,
295
+ - the checker id in the issue title.
296
+
297
+ New checkers are accepted only with a fixture, tests, and no new runtime
298
+ dependencies (stdlib only is a project rule).
299
+
300
+ ## License
301
+
302
+ MIT. See [LICENSE](LICENSE).