aigate-lite 0.5.0__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.
- aigate_lite-0.5.0/LICENSE +201 -0
- aigate_lite-0.5.0/NOTICE +5 -0
- aigate_lite-0.5.0/PKG-INFO +371 -0
- aigate_lite-0.5.0/README.md +356 -0
- aigate_lite-0.5.0/aigate_lite.egg-info/PKG-INFO +371 -0
- aigate_lite-0.5.0/aigate_lite.egg-info/SOURCES.txt +50 -0
- aigate_lite-0.5.0/aigate_lite.egg-info/dependency_links.txt +1 -0
- aigate_lite-0.5.0/aigate_lite.egg-info/entry_points.txt +3 -0
- aigate_lite-0.5.0/aigate_lite.egg-info/top_level.txt +1 -0
- aigate_lite-0.5.0/aigate_lite.py +9667 -0
- aigate_lite-0.5.0/pyproject.toml +32 -0
- aigate_lite-0.5.0/setup.cfg +4 -0
- aigate_lite-0.5.0/tests/test_agent_format.py +82 -0
- aigate_lite-0.5.0/tests/test_all_mode.py +70 -0
- aigate_lite-0.5.0/tests/test_atlas_batch.py +300 -0
- aigate_lite-0.5.0/tests/test_attribution.py +174 -0
- aigate_lite-0.5.0/tests/test_audit_ux.py +87 -0
- aigate_lite-0.5.0/tests/test_baseline.py +283 -0
- aigate_lite-0.5.0/tests/test_bytecode_cache.py +389 -0
- aigate_lite-0.5.0/tests/test_cache.py +167 -0
- aigate_lite-0.5.0/tests/test_cache_optin.py +68 -0
- aigate_lite-0.5.0/tests/test_checkers.py +56 -0
- aigate_lite-0.5.0/tests/test_ci.py +96 -0
- aigate_lite-0.5.0/tests/test_code_tests.py +258 -0
- aigate_lite-0.5.0/tests/test_credit.py +225 -0
- aigate_lite-0.5.0/tests/test_doctor.py +176 -0
- aigate_lite-0.5.0/tests/test_easy_commands.py +97 -0
- aigate_lite-0.5.0/tests/test_errors.py +237 -0
- aigate_lite-0.5.0/tests/test_fix.py +231 -0
- aigate_lite-0.5.0/tests/test_full_scan.py +65 -0
- aigate_lite-0.5.0/tests/test_gate.py +226 -0
- aigate_lite-0.5.0/tests/test_harness.py +43 -0
- aigate_lite-0.5.0/tests/test_hooks.py +143 -0
- aigate_lite-0.5.0/tests/test_housekeeping.py +70 -0
- aigate_lite-0.5.0/tests/test_init.py +163 -0
- aigate_lite-0.5.0/tests/test_installed_mode.py +609 -0
- aigate_lite-0.5.0/tests/test_lang_go.py +296 -0
- aigate_lite-0.5.0/tests/test_lang_go_deps.py +533 -0
- aigate_lite-0.5.0/tests/test_lang_js.py +183 -0
- aigate_lite-0.5.0/tests/test_lexer.py +254 -0
- aigate_lite-0.5.0/tests/test_output.py +128 -0
- aigate_lite-0.5.0/tests/test_perf.py +180 -0
- aigate_lite-0.5.0/tests/test_perf_hotspots.py +69 -0
- aigate_lite-0.5.0/tests/test_precision.py +312 -0
- aigate_lite-0.5.0/tests/test_python_discovery.py +286 -0
- aigate_lite-0.5.0/tests/test_release_workflow.py +172 -0
- aigate_lite-0.5.0/tests/test_repo_hygiene.py +68 -0
- aigate_lite-0.5.0/tests/test_review_api.py +556 -0
- aigate_lite-0.5.0/tests/test_review_precision.py +45 -0
- aigate_lite-0.5.0/tests/test_review_rest.py +453 -0
- aigate_lite-0.5.0/tests/test_secrets_deps.py +188 -0
- aigate_lite-0.5.0/tests/test_trust.py +164 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 Hitarth Khatiwala
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
aigate_lite-0.5.0/NOTICE
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aigate-lite
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Free, local commit-time gate that checks AI-written code before it is committed or pushed
|
|
5
|
+
Author-email: Hitarth Khatiwala <hitarthkhatiwala@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/hitarth1812/AI-Gate
|
|
8
|
+
Project-URL: Repository, https://github.com/hitarth1812/AI-Gate
|
|
9
|
+
Keywords: git-hooks,pre-commit,ai,code-review,security,supply-chain
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
License-File: NOTICE
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# aigate-lite
|
|
17
|
+
|
|
18
|
+
A free, local "CI gate" that runs when you commit. It checks only what the commit adds, looking for
|
|
19
|
+
the mistakes AI coding tools make most often, and stops the commit if it finds a serious one.
|
|
20
|
+
|
|
21
|
+
- **Cost:** none. One Python file, standard library only. No account, server, API key or LLM.
|
|
22
|
+
- **Network:** only free public lookups (PyPI, npm, OSV), cached on disk. `--offline` skips them.
|
|
23
|
+
- **Speed:** measured, not estimated: see [docs/PERF.md](docs/PERF.md) (generated by `bench/bench.py`).
|
|
24
|
+
- **Needs:** Python 3.11+ and git.
|
|
25
|
+
- **Tested on:** by hand (the full test suite) on Windows 11 and on Ubuntu under WSL2, each with Python 3.11, 3.12, 3.13
|
|
26
|
+
and 3.14. macOS is covered only by CI (`.github/workflows/ci.yml`: Ubuntu, macOS and Windows on 3.11-3.14, on every push to
|
|
27
|
+
main and every pull request; the results are in the repository's Actions tab). The runs done by hand are listed in
|
|
28
|
+
[PROGRESS.md](PROGRESS.md).
|
|
29
|
+
|
|
30
|
+
It is the lightweight, local version of the AI Code Trust Gate plan. It uses the same rule names,
|
|
31
|
+
actions and risk score.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
After the first release (not published to PyPI yet: until then use the file itself, as in the next section):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install aigate-lite # adds the commands `aigate-lite` and `aigate`
|
|
39
|
+
pipx install aigate-lite # the same, in its own environment (recommended for a command-line tool)
|
|
40
|
+
uvx aigate-lite review # run once without installing
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Maintainers: how a release is published (PyPI Trusted Publishing, no token) is in [docs/RELEASING.md](docs/RELEASING.md).
|
|
44
|
+
|
|
45
|
+
## First success in a few commands
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cd your-project # any git repo; needs Python 3.11+ and git
|
|
49
|
+
python3 /path/to/aigate_lite.py setup # hooks + a copy of the gate in .aigate/ + a starter config
|
|
50
|
+
python3 .aigate/aigate_lite.py audit # see what is already in the repo
|
|
51
|
+
python3 -c "print('KEY = \"AKIA' + 'QWERTYUIOPASDFGH\"')" > leak.py # a fake key, to see a block
|
|
52
|
+
git add leak.py && git commit -m "try it" # stopped: secrets.hardcoded
|
|
53
|
+
git rm --cached -q leak.py && rm leak.py # clean up
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`setup` is `install` plus `init`; it never overwrites an existing `.aigate/lite.toml`. Run from a loose `aigate_lite.py` (as
|
|
57
|
+
above) it vendors the gate into `.aigate/`, because a loose file cannot be found again by name; run from an installed package
|
|
58
|
+
(`pipx install aigate-lite`) the hooks run the installed tool instead (`--mode installed|vendored` chooses explicitly). A
|
|
59
|
+
repository that already has `.aigate/aigate_lite.py` stays vendored. `audit` is `check --all`.
|
|
60
|
+
After `pip install .` the command is also available as `aigate` (same as `aigate-lite`).
|
|
61
|
+
|
|
62
|
+
On Windows use `py -3` instead of `python3`; the installed hooks use the interpreter that ran `install` (pinned in `.git/hooks`, never committed) and, if
|
|
63
|
+
that is gone, look for `python3`, `python`, `python3.14`..`python3.11`, `py -3.14`..`py -3.11`, then `py -3`.
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# inside your project
|
|
69
|
+
python3 /path/to/aigate_lite.py setup # copies itself to .aigate/, adds both hooks, writes lite.toml
|
|
70
|
+
python3 .aigate/aigate_lite.py audit # see what is already in the repo
|
|
71
|
+
python3 .aigate/aigate_lite.py baseline # optional: accept today's findings so only new ones block
|
|
72
|
+
git add .aigate && git commit -m "add aigate-lite"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Manual setup** (what `setup` does, step by step):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 /path/to/aigate_lite.py install --vendor # copies itself to .aigate/ and adds both hooks
|
|
79
|
+
python3 .aigate/aigate_lite.py init # optional: starter .aigate/lite.toml
|
|
80
|
+
git add .aigate && git commit -m "add aigate-lite"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
From then on:
|
|
84
|
+
|
|
85
|
+
| When | What runs | Checks |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `git commit` | `pre-commit` hook | The staged changes |
|
|
88
|
+
| `git push` | `pre-push` hook | Every commit being pushed, one by one for secrets. This catches commits made with `--no-verify`. |
|
|
89
|
+
| Any time | `aigate-lite check` | Staged changes, or `--range origin/main..HEAD` |
|
|
90
|
+
| Audit | `aigate-lite audit` (same as `check --all`) | Every tracked file in HEAD, including the root commit (not used by hooks) |
|
|
91
|
+
|
|
92
|
+
`--vendor` makes the hooks portable: they run `.aigate/aigate_lite.py` with whatever `python3` is on
|
|
93
|
+
the PATH, so teammates only need to run `python3 .aigate/aigate_lite.py install --vendor`.
|
|
94
|
+
Without `--vendor`, the hooks point at the script's current location.
|
|
95
|
+
|
|
96
|
+
**Existing hooks.** If you already use husky or the pre-commit framework, `install` prints the line or
|
|
97
|
+
YAML snippet to add instead. `--force` installs anyway; your old hook is kept as `<hook>.local` and
|
|
98
|
+
still runs first.
|
|
99
|
+
|
|
100
|
+
## What it catches
|
|
101
|
+
|
|
102
|
+
**Actions:** `block` and `fix` stop the commit; `warn` only reports.
|
|
103
|
+
|
|
104
|
+
| Mistake | Rules (default action) |
|
|
105
|
+
|---|---|
|
|
106
|
+
| Exposed secrets | `secrets.hardcoded`: provider keys and private keys (block). `secrets.env_file`: `.env`, key and credential files (block). `secrets.generic`: credential-like literals and JWTs (fix). `secrets.env_not_ignored` (warn). |
|
|
107
|
+
| Hallucinated or risky packages | `deps.hallucinated`: package or version not on PyPI/npm, in a manifest or an import (block). `deps.untrusted_source`: git/URL deps, custom indexes, odd lockfile URLs (block). `deps.new_package`: first release under 30 days (fix). `deps.version_cooldown`: version under 5 days (fix), with security bumps exempt. `deps.vulnerable`: OSV advisories for the pinned version (fix). `deps.undeclared` (fix). `deps.removed_stdlib`, e.g. `distutils` or `cgi` (fix). `deps.typosquat`, `deps.outdated` and `deps.deprecated` (warn). |
|
|
108
|
+
| Weakened tests | Assertions or cases removed, skip/xfail added, tests deleted (renames are detected), `.only` focus, trivial asserts, test-config narrowing (all fix). `sitecustomize.py`, `.pth` files and `pytest11` entry points (block). Result-changing pytest hooks (fix). Expected values changed alongside source (warn). |
|
|
109
|
+
| Placeholder or unsafe code | `... rest of the code` comments, `...` bodies, swallowed exceptions, debugger leftovers, syntax errors (fix). `eval`/`exec`, `shell=True`, pickle and unsafe YAML, SQL built with f-strings, `verify=False` (fix). Debug mode, wildcard CORS, weak crypto, raw HTML (warn). |
|
|
110
|
+
| Silenced checkers | `# nosec`, `# type: ignore`, `@ts-ignore`, `# pragma: no cover`, whole-file disables (fix). `# noqa`, `eslint-disable-line` (warn). In `[paths] sensitive` these are one step stricter. |
|
|
111
|
+
| Bloat and time complexity | Long or complex functions, long files, big diffs, duplicated blocks, unused imports (warn). Loops nested 3 or more deep, nested loops over the same list, `x in list` / `.pop(0)` / sorting inside loops, network or DB calls inside loops, branching recursion without a cache (warn). |
|
|
112
|
+
| Scope creep | `scope.forbidden_path` (block). `scope.out_of_scope` against a declared task scope (fix). `gate.config_changed` (warn). |
|
|
113
|
+
|
|
114
|
+
`aigate-lite explain` lists all 75 rules. `aigate-lite explain <rule>` shows how to change or allow one.
|
|
115
|
+
|
|
116
|
+
**Language coverage.** Python gets every check, using its AST. Go and JavaScript/TypeScript are read with a lexer
|
|
117
|
+
(strings and comments are never mistaken for code) and get secrets, dependencies, tests, suppressions,
|
|
118
|
+
placeholders, function length, complexity and loop nesting (estimated from brace structure, not parsed), duplicated
|
|
119
|
+
blocks, and the reviewer rules below (each rule says which languages it covers). Unused imports and the
|
|
120
|
+
quadratic-pattern, call-in-loop and exponential-recursion checks are Python-only. Other languages get secrets,
|
|
121
|
+
placeholders, TODOs and suppressions.
|
|
122
|
+
|
|
123
|
+
**Size and copy-paste advice is off for people by default.** `size.*` (long functions and files, complexity, big
|
|
124
|
+
diffs), `perf.*` (loop findings) and `code.duplicate_block` are the "core" exception: they are not reported for a
|
|
125
|
+
person's change unless you name them in `[rules]` (`"size.*" = "warn"`) or use `preset = "strict"`. AI agents always get
|
|
126
|
+
them, and so does `aigate-lite audit --strict` (or `check --strict`). On a large existing repository these rules were
|
|
127
|
+
most of what `audit` reported, which is why they are off.
|
|
128
|
+
|
|
129
|
+
### Declaring a task scope (scope creep)
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
aigate-lite scope set 'src/auth/**' 'tests/auth/**' # before you start the AI on a task
|
|
133
|
+
aigate-lite scope show
|
|
134
|
+
aigate-lite scope clear # when the task is done
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The scope is stored inside `.git/`, so it is per-clone and never committed.
|
|
138
|
+
|
|
139
|
+
## AI agents
|
|
140
|
+
|
|
141
|
+
When an AI agent runs `git commit` itself, the gate notices it and becomes stricter. It detects agents
|
|
142
|
+
through `CLAUDECODE`, `AI_AGENT`, `GEMINI_CLI` or `AIGATE_AGENT` in the environment, an `(aider)`
|
|
143
|
+
author name, or AI co-author trailers in pushed commits. You can add your own variables under
|
|
144
|
+
`[provenance] agent_env`. For agent commits:
|
|
145
|
+
|
|
146
|
+
- `forbidden_for_agents` paths are blocked: `.aigate/`, CI workflows and hook configs.
|
|
147
|
+
- The config is read from the last commit, so an agent cannot loosen the gate in the same commit.
|
|
148
|
+
- `AIGATE_ALLOW` and `AIGATE_SKIP` are ignored.
|
|
149
|
+
|
|
150
|
+
Detection is best effort. An agent that runs with none of these signals looks like a human.
|
|
151
|
+
|
|
152
|
+
### Using with AI coding agents
|
|
153
|
+
|
|
154
|
+
`--format agent` prints a short, ASCII-only, stable report an agent can act on line by line:
|
|
155
|
+
|
|
156
|
+
AIGATE verdict=fix risk=30 exit=1
|
|
157
|
+
FIX security.eval app/a.py:7 eval() runs code built at runtime | fix: Avoid eval/exec; parse the input explicitly (ast.literal_eval, JSON.parse).
|
|
158
|
+
TOOL aigate-lite 0.5.0 https://github.com/hitarth1812/AI-Gate
|
|
159
|
+
END
|
|
160
|
+
|
|
161
|
+
At most 50 block/fix lines and 20 warn lines are listed; a `MORE <n>` line says how many were left out.
|
|
162
|
+
The first line and `END` are the contract; `TOOL` (which tool wrote the report) always sits directly before `END`
|
|
163
|
+
and a reader may ignore it.
|
|
164
|
+
Add instructions like these to your agent's instruction file (`CLAUDE.md`, a `.cursor/rules` file,
|
|
165
|
+
`.github/copilot-instructions.md`, …):
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
Before every commit, run: python3 .aigate/aigate_lite.py check --format agent
|
|
169
|
+
Fix every BLOCK and FIX line it prints, then run it again until the first line says exit=0.
|
|
170
|
+
Never use `git commit --no-verify` and never edit files under .aigate/ (the gate's config and baseline).
|
|
171
|
+
If a finding looks wrong, stop and tell the user instead of working around it.
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
These instructions ask; the hooks enforce. Keep the hooks installed (`aigate-lite install`) and run the gate in
|
|
175
|
+
CI, because an agent can ignore instructions.
|
|
176
|
+
|
|
177
|
+
## The reviewer: `aigate-lite review`
|
|
178
|
+
|
|
179
|
+
The gate asks "may this commit go in?". The reviewer reads the same change the way a careful senior reviewer would and
|
|
180
|
+
answers "what changed, what must be fixed, what should I look at, what looks good":
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
aigate-lite review # what is staged
|
|
184
|
+
aigate-lite review --range origin/main..HEAD
|
|
185
|
+
aigate-lite review --pr # the pull request in CI: range against its target branch, plus its title and text
|
|
186
|
+
aigate-lite review --format md # or text (default), json (versioned schema), agent
|
|
187
|
+
aigate-lite check --deep # the gate's normal report, with the reviewer's findings added
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
It runs the gate's checks and six more that look at the rest of the repository, not only the changed lines:
|
|
191
|
+
|
|
192
|
+
| rule | catches | people / AI agents |
|
|
193
|
+
|---|---|---|
|
|
194
|
+
| `api.unknown_symbol` | `from app.utils import parse_date` when there is no `parse_date`; a missing module; `pkg.DoThing()` with no such function (Python, Go, relative JS/TS imports) | warn / fix |
|
|
195
|
+
| `api.bad_call` | a call with an unknown keyword or the wrong number of arguments to a function defined in the repo (Python, Go) | warn / fix |
|
|
196
|
+
| `api.broken_caller` | a function's parameters changed and callers elsewhere were not updated (reported at each stale caller) | warn / fix |
|
|
197
|
+
| `tests.missing_for_change` | functions changed with no related test changed (`[review] test_map` maps your layout) | warn / fix |
|
|
198
|
+
| `review.claim_mismatch` | the commit message or PR text says "add tests", "fix `parse_date`" or "no behaviour change" and the diff says otherwise | warn / warn |
|
|
199
|
+
| `code.error_check_removed` | an `if err != nil` removed, `except ValueError` turned into `except Exception: pass`, a `.catch` or `await` dropped, `_ = f()` where `f` returns an error | warn / fix |
|
|
200
|
+
|
|
201
|
+
How much to trust it:
|
|
202
|
+
|
|
203
|
+
- Everything is read with `ast` (Python) or the lexer (Go, JS/TS). Your code is never imported or run.
|
|
204
|
+
- A file that does not parse, or a module that is dynamic (`__getattr__`, star imports, `getattr`/`hasattr` on the module,
|
|
205
|
+
`globals()`, `__dict__`, `exec`), produces no claim: the reviewer says nothing it cannot prove from the source.
|
|
206
|
+
- Only names inside this repository are judged. Standard library, installed packages and path aliases are left alone.
|
|
207
|
+
- These checks run only in `review` and `check --deep`, never in the commit hook, so a commit is not slower.
|
|
208
|
+
Measured costs are in [PROGRESS.md](PROGRESS.md).
|
|
209
|
+
- The symbol index is cached by git blob id next to the result cache (`symbols-v1.json`, signed); `--no-cache` skips it.
|
|
210
|
+
|
|
211
|
+
```toml
|
|
212
|
+
[review]
|
|
213
|
+
# source glob = where its tests live ({stem}, {dir}, {ext}); added to the usual names (test_x.py, x_test.go, x.test.ts)
|
|
214
|
+
test_map = { "app/**/*.py" = "checks/{stem}_spec.py" }
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Existing project? Accept today's findings with `baseline`
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
python3 .aigate/aigate_lite.py check --all # see what is already there
|
|
221
|
+
python3 .aigate/aigate_lite.py baseline # record non-secret findings in .aigate/baseline.json
|
|
222
|
+
git add .aigate/baseline.json && git commit -m "baseline"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Fingerprints do not depend on line numbers, so unrelated edits do not resurrect old findings. Secrets are never
|
|
226
|
+
baselined unless you pass `--include-secrets` (rotate them instead), and a baseline never hides *new* copies of an old finding.
|
|
227
|
+
|
|
228
|
+
## Presets
|
|
229
|
+
|
|
230
|
+
`preset = "relaxed" | "balanced" | "strict"` in `.aigate/lite.toml` (default `balanced`); `init` picks one for you.
|
|
231
|
+
Your own `[rules]` settings always win (this includes turning the "core" rules above on for people). `strict` turns
|
|
232
|
+
them on. The full table of what each preset changes is in
|
|
233
|
+
[docs/RULES.md](docs/RULES.md) (generated by `scripts/gen_docs.py`).
|
|
234
|
+
|
|
235
|
+
## Troubleshooting
|
|
236
|
+
|
|
237
|
+
Run `python3 .aigate/aigate_lite.py doctor`. It checks git and Python versions, the hooks, the config and the
|
|
238
|
+
registry reachability, and prints a one-line fix for anything wrong. Errors from other commands also end in a
|
|
239
|
+
`fix:` line.
|
|
240
|
+
|
|
241
|
+
## Configuration: `.aigate/lite.toml`
|
|
242
|
+
|
|
243
|
+
See `examples/lite.toml` for every key. The most useful ones:
|
|
244
|
+
|
|
245
|
+
```toml
|
|
246
|
+
[rules]
|
|
247
|
+
"suppress.type" = "warn" # block | fix | warn | off; globs like "perf.*" work
|
|
248
|
+
|
|
249
|
+
[deps]
|
|
250
|
+
private = ["acme-*", "@acme/*"] # internal packages: skip public lookups
|
|
251
|
+
trusted_sources = ["https://pypi.acme.dev/simple"]
|
|
252
|
+
import_map = { mylib = "my-lib-dist" } # import name -> package name
|
|
253
|
+
|
|
254
|
+
[[commands]] # your own checks, e.g. run tests before every push
|
|
255
|
+
name = "tests"
|
|
256
|
+
run = "python -m pytest -q"
|
|
257
|
+
stage = "push" # commit | push | both
|
|
258
|
+
# then approve them once: aigate-lite trust
|
|
259
|
+
|
|
260
|
+
[[allow]] # a known false positive
|
|
261
|
+
rule = "secrets.generic"
|
|
262
|
+
path = "tests/fixtures/**" # blocking rules need a path or a fingerprint (see `check -v`)
|
|
263
|
+
reason = "fake credentials used by tests"
|
|
264
|
+
expires = 2027-06-30
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
To allow a fix- or warn-level finding for one commit: `AIGATE_ALLOW=tests.deleted git commit ...`.
|
|
268
|
+
Blocking findings can only be allowed through `[[allow]]`.
|
|
269
|
+
|
|
270
|
+
Result cache (off by default): `--cache` or `[gate] cache = true` remembers which files the per-file checks
|
|
271
|
+
found clean, so an unchanged file is not checked again. Only clean verdicts are stored (no finding text),
|
|
272
|
+
signed, in two 0600 files in your user cache dir. `--no-cache` turns it off even when the config turns it
|
|
273
|
+
on, and also skips the registry lookup cache. It helps large changes and not small ones: compare the `C`
|
|
274
|
+
and `C-cache` rows (300 files) with `A` and `A-cache` (1 file) in docs/PERF.md.
|
|
275
|
+
|
|
276
|
+
## Output and exit codes
|
|
277
|
+
|
|
278
|
+
- `--format text` (default), `json` (stable schema), `github` (annotations for Actions) or `sarif`
|
|
279
|
+
(SARIF 2.1.0, for code-scanning uploads).
|
|
280
|
+
- `-q` prints only what stops the commit; `-v` adds hints, fingerprints and allowed findings. A text report that prints
|
|
281
|
+
a finding ends with a one-line credit (see "Credit and usage").
|
|
282
|
+
- Exit codes: `0` pass or warnings only, `1` fix or block, `2` usage or git error.
|
|
283
|
+
- The verdict is the strongest action found. A Fix verdict becomes Block when the risk score is 60 or
|
|
284
|
+
higher; the score uses the same formula as the full gate.
|
|
285
|
+
|
|
286
|
+
## Enforce it in CI (hooks can be skipped)
|
|
287
|
+
|
|
288
|
+
Hooks run on the developer's machine, so `--no-verify` (or an agent that commits that way) skips them.
|
|
289
|
+
The check that cannot be skipped is a required CI status on the pull request.
|
|
290
|
+
|
|
291
|
+
**GitHub Actions** — `examples/github-actions.yml`:
|
|
292
|
+
|
|
293
|
+
1. Copy it to `.github/workflows/aigate-lite.yml` and commit `.aigate/aigate_lite.py`
|
|
294
|
+
(`aigate-lite install --vendor` copies it for you).
|
|
295
|
+
2. Open a pull request once so the check runs and GitHub learns its name (the job is called `gate`).
|
|
296
|
+
3. Settings → Branches (or Rules → Rulesets) → protect your default branch → **Require status checks to
|
|
297
|
+
pass** → add `gate`. If you use a merge queue, the workflow already listens to `merge_group`.
|
|
298
|
+
4. **Required for this to mean anything:** GitHub runs the workflow file from the pull request itself, so
|
|
299
|
+
a pull request that edits `.github/workflows/aigate-lite.yml` can change what runs. Put
|
|
300
|
+
`.github/workflows/**` and `.aigate/**` in CODEOWNERS and turn on **Require review from Code Owners**
|
|
301
|
+
(or make the workflow a ruleset-required workflow). Without that, CI is a safety net, not a boundary.
|
|
302
|
+
|
|
303
|
+
The workflow pins every action to a full commit SHA, runs the gate **and its config from the base
|
|
304
|
+
branch** (a pull request cannot loosen the script or `.aigate/lite.toml` that judge it; the first PR that
|
|
305
|
+
adds the gate uses its own copy, with a warning), writes annotations with `--format github`, and uploads
|
|
306
|
+
`--format sarif` to code scanning (Security → Code scanning; the upload is skipped without failing the
|
|
307
|
+
job where code scanning is not enabled). `--no-commands` keeps `[[commands]]` from the pull request from
|
|
308
|
+
running in CI. The gate runs twice (annotations, then SARIF); only the first run decides the result.
|
|
309
|
+
|
|
310
|
+
**GitLab CI** — `examples/gitlab-ci.yml` runs on merge-request pipelines and keeps `aigate.sarif` as an
|
|
311
|
+
artifact. Make it blocking with Settings → Merge requests → **Pipelines must succeed**, and run fork
|
|
312
|
+
merge-request pipelines in the parent project (otherwise a fork is checked against its own copy).
|
|
313
|
+
|
|
314
|
+
**Other CI:** run `python .aigate/aigate_lite.py check --range "origin/main..HEAD" --no-commands` and fail
|
|
315
|
+
the job on exit code 1. `--format json` (schema 1) and `--format sarif` (SARIF 2.1.0) are stable outputs.
|
|
316
|
+
|
|
317
|
+
## Limits (read these)
|
|
318
|
+
|
|
319
|
+
- **Hooks are bypassable.** `git commit --no-verify` and `git push --no-verify` skip them, and some
|
|
320
|
+
agents commit that way. The pre-push hook catches what the commit hook missed, but only a
|
|
321
|
+
server-side check is enforceable: see "Enforce it in CI" above.
|
|
322
|
+
- **Static heuristics, not proof.** Time complexity is flagged from code shape, not measured. Test
|
|
323
|
+
tampering for JS/TS is line-based.
|
|
324
|
+
- **Not covered in lite:** calls to functions or attributes that don't exist (that needs a type
|
|
325
|
+
checker, which you can add as a `[[commands]]` entry), sandboxed test runs, mutation testing, and
|
|
326
|
+
LLM review.
|
|
327
|
+
- **Commands in `.aigate/lite.toml` need your approval.** A cloned or pulled config can't run code on your
|
|
328
|
+
next commit: `[[commands]]` stay off (one `commands.untrusted` warning says so; a repo's `[rules]` can't
|
|
329
|
+
change that rule) until a person runs
|
|
330
|
+
`aigate-lite trust`, which prints every command with hidden characters escaped and records exactly that
|
|
331
|
+
list in `.git/aigate/trusted`. Any change to any command needs a new approval; `trust --rev <branch>`
|
|
332
|
+
approves a config you push but have not checked out; AI agents can't approve. `--config FILE` on the
|
|
333
|
+
command line counts as your own choice and is trusted (so don't point it at a file a pull request controls).
|
|
334
|
+
- **A vendored gate is code from the repo too.** With `install --vendor` the hook runs
|
|
335
|
+
`.aigate/aigate_lite.py` as committed; review changes to that file like any other code you execute.
|
|
336
|
+
- **Offline:** if PyPI/npm can't be reached, dependency findings become `deps.unverified` warnings.
|
|
337
|
+
Set `[gate] offline = "block"` to stop instead.
|
|
338
|
+
|
|
339
|
+
## License & credit
|
|
340
|
+
|
|
341
|
+
aigate-lite is licensed under the [Apache License 2.0](LICENSE). You may use, modify and redistribute it, but you
|
|
342
|
+
must keep the copyright header, the [NOTICE](NOTICE) file and credit to Hitarth Khatiwala (Apache-2.0, Section 4).
|
|
343
|
+
Suggested credit line: "Uses aigate-lite by Hitarth Khatiwala" (https://github.com/hitarth1812/AI-Gate).
|
|
344
|
+
|
|
345
|
+
`aigate-lite doctor` warns (it never fails) if the copyright header in the running file was removed or changed.
|
|
346
|
+
Nothing in the gate depends on it: check results, exit codes and hooks behave the same either way.
|
|
347
|
+
|
|
348
|
+
## Credit and usage
|
|
349
|
+
|
|
350
|
+
Every place the tool names itself is visible text, documented here, and never changes a result or an exit code.
|
|
351
|
+
|
|
352
|
+
| Where | What you see | When it is absent |
|
|
353
|
+
|---|---|---|
|
|
354
|
+
| `check` / `audit` text report | one last line: `aigate-lite by Hitarth Khatiwala · Apache-2.0 · <url>` (ASCII separators on a console that cannot show `·`) | on a clean pass, with `-q`, and in `--format json`, `agent`, `sarif` and `github` |
|
|
355
|
+
| `review` text report | the same line, always | never absent |
|
|
356
|
+
| `review --format md` | a last line `Reviewed by [aigate-lite](<url>) <version>` | never absent |
|
|
357
|
+
| JSON (`check`, `audit`, `review`) | `"author"` and `"url"` next to `"tool"` and `"version"` (`"schema"` is unchanged; nothing was removed or retyped) | |
|
|
358
|
+
| `--format agent` | one line `TOOL aigate-lite <version> <url>` directly before `END` | |
|
|
359
|
+
| SARIF | the tool driver's `name`, `version`, `informationUri` and `organization` | |
|
|
360
|
+
|
|
361
|
+
The credit is credit, not proof: nothing in the tool or in the CI examples trusts it, and nothing is hidden (there are no
|
|
362
|
+
invisible characters or encoded marks anywhere; a test scans the repository for them). The footer is a plain line of
|
|
363
|
+
text; the tool is Apache-2.0, so keep the copyright header and NOTICE when you redistribute it (Section 4).
|
|
364
|
+
|
|
365
|
+
## Development
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
python3 -m pytest -q # registry calls use tests/registry_fixture.json
|
|
369
|
+
python3 bench/bench.py --compare bench/baseline.json # perf gates (same machine as the baseline)
|
|
370
|
+
python3 bench/bench.py --compare bench/baseline.json --markdown docs/PERF.md # regenerate docs/PERF.md
|
|
371
|
+
```
|