agent-code-guard 0.3.0__tar.gz → 0.4.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.
- {agent_code_guard-0.3.0/src/agent_code_guard.egg-info → agent_code_guard-0.4.0}/PKG-INFO +33 -22
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/README.md +32 -21
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/pyproject.toml +1 -1
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/SKILL.md +20 -2
- agent_code_guard-0.4.0/skills/code-guard/references/markdown-size-policy.md +33 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/adapters.py +4 -4
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/callable_identity.py +1 -2
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/facts.py +21 -1
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/pipeline.py +15 -9
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/regions.py +24 -14
- agent_code_guard-0.4.0/src/agent_code_guard/baseline_files.py +139 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/code_guard.py +107 -56
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/config_validation.py +17 -19
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/file_selection.py +42 -17
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/callable_size.py +14 -20
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/complexity.py +14 -19
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/loc.py +27 -36
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/markdown_document_size.py +35 -23
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/markdown_section_size.py +16 -18
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/nesting.py +14 -19
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/human_output.py +8 -3
- agent_code_guard-0.4.0/src/agent_code_guard/invocation.py +54 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/loc_baseline.py +20 -115
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/markdown/facts.py +1 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/markdown/scanner.py +15 -6
- agent_code_guard-0.4.0/src/agent_code_guard/markdown_baseline.py +171 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/result_model.py +9 -1
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0/src/agent_code_guard.egg-info}/PKG-INFO +33 -22
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard.egg-info/SOURCES.txt +3 -0
- agent_code_guard-0.3.0/skills/code-guard/references/markdown-size-policy.md +0 -16
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/LICENSE +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/MANIFEST.in +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/setup.cfg +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/LICENSE.txt +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/agents/openai.yaml +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/references/callable-size-policy.md +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/references/complexity-policy.md +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/references/loc-policy.md +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/skills/code-guard/references/nesting-policy.md +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/__init__.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/__init__.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/branch_normalization.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/csharp_compat.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/errors.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/language_specs.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/provider.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/syntax_nodes.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/doctor.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/guards/__init__.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/markdown/__init__.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/path_matching.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/reporting.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/skill_distribution.py +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard.egg-info/dependency_links.txt +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard.egg-info/entry_points.txt +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard.egg-info/requires.txt +0 -0
- {agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-code-guard
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Deterministic cross-language guardrails for agent-assisted development
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Source, https://github.com/stef-k/agent-code-guard
|
|
@@ -21,9 +21,13 @@ Dynamic: license-file
|
|
|
21
21
|
Deterministic maintainability guardrails for source code and Markdown changed by
|
|
22
22
|
a human or coding agent.
|
|
23
23
|
|
|
24
|
+
[Documentation](https://stef-k.github.io/agent-code-guard/) ·
|
|
25
|
+
[Get started](https://stef-k.github.io/agent-code-guard/#get-started) ·
|
|
26
|
+
[Releases](https://github.com/stef-k/agent-code-guard/releases)
|
|
27
|
+
|
|
24
28
|
[](https://github.com/stef-k/agent-code-guard/actions/workflows/analysis.yml)
|
|
25
29
|
[](https://pypi.org/project/agent-code-guard/)
|
|
26
|
-
[](https://
|
|
30
|
+
[](https://stef-k.github.io/agent-code-guard/platform-support.html)
|
|
27
31
|
[](https://github.com/stef-k/agent-code-guard/blob/main/LICENSE)
|
|
28
32
|
|
|
29
33
|
Agent Code Guard measures file size, callable size, structural nesting,
|
|
@@ -75,7 +79,7 @@ code-guard doctor
|
|
|
75
79
|
```
|
|
76
80
|
|
|
77
81
|
`--version` confirms the installed distribution identity. `doctor` checks the
|
|
78
|
-
active installation's health. See the [usage guide](https://
|
|
82
|
+
active installation's health. See the [usage guide](https://stef-k.github.io/agent-code-guard/usage.html) for virtual
|
|
79
83
|
environment, uv, and developer alternatives.
|
|
80
84
|
|
|
81
85
|
### Ask your agent to adopt it
|
|
@@ -89,13 +93,13 @@ Copy this prompt to a coding agent:
|
|
|
89
93
|
> activating or exporting its installed, version-matched skill for the current
|
|
90
94
|
> agent environment. Verify `code-guard --version` and run `code-guard doctor`,
|
|
91
95
|
> then locate the skill with `code-guard --skill-path`. Follow the
|
|
92
|
-
> [skill activation guide](https://
|
|
96
|
+
> [skill activation guide](https://stef-k.github.io/agent-code-guard/skill-distribution.html):
|
|
93
97
|
> activate that installed path when the platform supports it, or export it with
|
|
94
98
|
> `code-guard --export-skill <target-directory>` to the platform's documented
|
|
95
99
|
> skill directory. Do not guess a target or overwrite an existing export; verify
|
|
96
100
|
> that `.agent-code-guard-version` matches the installed distribution. Follow the
|
|
97
|
-
> [agent workflow](https://
|
|
98
|
-
> without creating
|
|
101
|
+
> [agent workflow](https://stef-k.github.io/agent-code-guard/agent-workflow.html)
|
|
102
|
+
> without creating an adoption baseline. After meaningful source or Markdown edits, run
|
|
99
103
|
> `code-guard . --changed-only --json --json-mode compact`; outside Git, pass the
|
|
100
104
|
> exact edited files. Inspect REVIEW and FAIL findings, make only genuine
|
|
101
105
|
> improvements, rerun the check, and report the result. Never weaken thresholds,
|
|
@@ -118,7 +122,7 @@ No configuration is needed. A REVIEW asks for inspection and judgment, not an
|
|
|
118
122
|
automatic refactor. Outside Git, pass the exact edited files instead, such as
|
|
119
123
|
`code-guard src/app.py docs/guide.md`.
|
|
120
124
|
|
|
121
|
-
See the [agent workflow guide](https://
|
|
125
|
+
See the [agent workflow guide](https://stef-k.github.io/agent-code-guard/agent-workflow.html) for repeated human and
|
|
122
126
|
agent use.
|
|
123
127
|
|
|
124
128
|
## Recommended workflow
|
|
@@ -140,7 +144,7 @@ report the result before completion
|
|
|
140
144
|
Use `code-guard . --changed-only --json --json-mode compact` for a structured,
|
|
141
145
|
low-noise manual agent check. Hooks are optional, platform-owned, and require
|
|
142
146
|
user authorization; Code Guard does not install them. The
|
|
143
|
-
[workflow guide](https://
|
|
147
|
+
[workflow guide](https://stef-k.github.io/agent-code-guard/agent-workflow.html) owns the complete manual and
|
|
144
148
|
hook-assisted process.
|
|
145
149
|
|
|
146
150
|
## Interpreting results
|
|
@@ -177,7 +181,7 @@ measurement. A REVIEW is not proof of a defect or a mandatory refactor.
|
|
|
177
181
|
Comparisons are strictly greater-than, so equality passes. All guards except
|
|
178
182
|
file LOC are REVIEW-only; only file LOC can FAIL. A new guard must provide
|
|
179
183
|
distinct, deterministic value rather than duplicate conventional tooling. See
|
|
180
|
-
[Guard admission](https://
|
|
184
|
+
[Guard admission](https://stef-k.github.io/agent-code-guard/guard-admission.html).
|
|
181
185
|
|
|
182
186
|
### Result and JSON reference
|
|
183
187
|
|
|
@@ -186,7 +190,7 @@ all-guard-excluded file counts. Bare `--json` is the compatible full output;
|
|
|
186
190
|
`--json-mode debug` is byte-identical for the same completed invocation, while
|
|
187
191
|
`--json-mode compact` removes only normalized `pass` findings and retains the
|
|
188
192
|
result, scope, required policies, guards, ordering, and actionable findings.
|
|
189
|
-
Named modes require `--json`. See [Usage](https://
|
|
193
|
+
Named modes require `--json`. See [Usage](https://stef-k.github.io/agent-code-guard/usage.html) for the schema and
|
|
190
194
|
option contract.
|
|
191
195
|
|
|
192
196
|
Known per-file syntax or provider failures instead produce `overall:
|
|
@@ -221,7 +225,7 @@ Generic `.h` files are not syntax-dispatched; `.markdown` is not enabled; Vue
|
|
|
221
225
|
template and style regions are not executable syntax input; and unsupported
|
|
222
226
|
artifacts are inapplicable. Malformed applicable syntax or a required provider
|
|
223
227
|
failure is unavailable evidence, distinct from both an inapplicable file and a
|
|
224
|
-
completed FAIL finding. See [Language support](https://
|
|
228
|
+
completed FAIL finding. See [Language support](https://stef-k.github.io/agent-code-guard/language-support.html).
|
|
225
229
|
|
|
226
230
|
### Skill integration
|
|
227
231
|
|
|
@@ -233,38 +237,45 @@ code-guard --export-skill <target-directory>
|
|
|
233
237
|
```
|
|
234
238
|
|
|
235
239
|
Skill activation is platform-specific and is not performed by pipx or Code
|
|
236
|
-
Guard. See [Skill distribution](https://
|
|
240
|
+
Guard. See [Skill distribution](https://stef-k.github.io/agent-code-guard/skill-distribution.html). The checkout
|
|
237
241
|
compatibility runner is for repository development, not normal installation.
|
|
238
242
|
|
|
239
243
|
### Configuration
|
|
240
244
|
|
|
241
245
|
Built-in defaults require no configuration. Configure a project only for a
|
|
242
|
-
concrete policy reason; see the [configuration guide](https://
|
|
246
|
+
concrete policy reason; see the [configuration guide](https://stef-k.github.io/agent-code-guard/configuration.html).
|
|
243
247
|
The LOC baseline is an explicit adoption tool for established legacy
|
|
244
248
|
repositories, not an ordinary-use requirement or a way to silence findings.
|
|
245
249
|
Its default `ratchetAt: "fail"` policy freezes files above `failAt`; choose
|
|
246
250
|
`ratchetAt: "review"` only when every established file above `warnAt` must be
|
|
247
251
|
non-increasing while ordinary findings in that range remain REVIEW.
|
|
248
252
|
|
|
253
|
+
Reviewed oversized Markdown documents have a separate, explicit
|
|
254
|
+
[document-size ratchet](https://stef-k.github.io/agent-code-guard/usage.html#reviewed-markdown-document-ratchet).
|
|
255
|
+
`--create-markdown-baseline` records accepted physical-line counts;
|
|
256
|
+
`--update-markdown-baseline` only lowers or prunes them. Documents within their
|
|
257
|
+
allowance pass the document-size guard; growth produces REVIEW. Section
|
|
258
|
+
findings remain active, and ordinary analysis never writes either baseline.
|
|
259
|
+
|
|
249
260
|
## Trust, CI, and platform support
|
|
250
261
|
|
|
251
262
|
CI installs Agent Code Guard and analyzes its own real checkout. REVIEW findings
|
|
252
263
|
remain visible but non-blocking, while FAIL findings and tool errors block the
|
|
253
|
-
workflow; the repository intentionally uses no
|
|
264
|
+
workflow; the repository intentionally uses no adoption baseline.
|
|
254
265
|
|
|
255
266
|
The maintained interpreter range is **CPython 3.10–3.14**. See
|
|
256
|
-
[Platform support](https://
|
|
267
|
+
[Platform support](https://stef-k.github.io/agent-code-guard/platform-support.html) for supported binary platforms and
|
|
257
268
|
source-build boundaries.
|
|
258
269
|
|
|
259
270
|
## Documentation
|
|
260
271
|
|
|
261
|
-
- [Documentation index](https://
|
|
262
|
-
- [Agent workflow](https://
|
|
263
|
-
- [Usage and CLI reference](https://
|
|
264
|
-
- [Configuration](https://
|
|
265
|
-
- [Language support](https://
|
|
266
|
-
- [Platform support](https://
|
|
267
|
-
- [Skill distribution](https://
|
|
272
|
+
- [Documentation index](https://stef-k.github.io/agent-code-guard/)
|
|
273
|
+
- [Agent workflow](https://stef-k.github.io/agent-code-guard/agent-workflow.html)
|
|
274
|
+
- [Usage and CLI reference](https://stef-k.github.io/agent-code-guard/usage.html)
|
|
275
|
+
- [Configuration](https://stef-k.github.io/agent-code-guard/configuration.html)
|
|
276
|
+
- [Language support](https://stef-k.github.io/agent-code-guard/language-support.html)
|
|
277
|
+
- [Platform support](https://stef-k.github.io/agent-code-guard/platform-support.html)
|
|
278
|
+
- [Skill distribution](https://stef-k.github.io/agent-code-guard/skill-distribution.html)
|
|
268
279
|
|
|
269
280
|
## Feedback, security, and license
|
|
270
281
|
|
|
@@ -7,9 +7,13 @@
|
|
|
7
7
|
Deterministic maintainability guardrails for source code and Markdown changed by
|
|
8
8
|
a human or coding agent.
|
|
9
9
|
|
|
10
|
+
[Documentation](https://stef-k.github.io/agent-code-guard/) ·
|
|
11
|
+
[Get started](https://stef-k.github.io/agent-code-guard/#get-started) ·
|
|
12
|
+
[Releases](https://github.com/stef-k/agent-code-guard/releases)
|
|
13
|
+
|
|
10
14
|
[](https://github.com/stef-k/agent-code-guard/actions/workflows/analysis.yml)
|
|
11
15
|
[](https://pypi.org/project/agent-code-guard/)
|
|
12
|
-
[](https://
|
|
16
|
+
[](https://stef-k.github.io/agent-code-guard/platform-support.html)
|
|
13
17
|
[](https://github.com/stef-k/agent-code-guard/blob/main/LICENSE)
|
|
14
18
|
|
|
15
19
|
Agent Code Guard measures file size, callable size, structural nesting,
|
|
@@ -61,7 +65,7 @@ code-guard doctor
|
|
|
61
65
|
```
|
|
62
66
|
|
|
63
67
|
`--version` confirms the installed distribution identity. `doctor` checks the
|
|
64
|
-
active installation's health. See the [usage guide](https://
|
|
68
|
+
active installation's health. See the [usage guide](https://stef-k.github.io/agent-code-guard/usage.html) for virtual
|
|
65
69
|
environment, uv, and developer alternatives.
|
|
66
70
|
|
|
67
71
|
### Ask your agent to adopt it
|
|
@@ -75,13 +79,13 @@ Copy this prompt to a coding agent:
|
|
|
75
79
|
> activating or exporting its installed, version-matched skill for the current
|
|
76
80
|
> agent environment. Verify `code-guard --version` and run `code-guard doctor`,
|
|
77
81
|
> then locate the skill with `code-guard --skill-path`. Follow the
|
|
78
|
-
> [skill activation guide](https://
|
|
82
|
+
> [skill activation guide](https://stef-k.github.io/agent-code-guard/skill-distribution.html):
|
|
79
83
|
> activate that installed path when the platform supports it, or export it with
|
|
80
84
|
> `code-guard --export-skill <target-directory>` to the platform's documented
|
|
81
85
|
> skill directory. Do not guess a target or overwrite an existing export; verify
|
|
82
86
|
> that `.agent-code-guard-version` matches the installed distribution. Follow the
|
|
83
|
-
> [agent workflow](https://
|
|
84
|
-
> without creating
|
|
87
|
+
> [agent workflow](https://stef-k.github.io/agent-code-guard/agent-workflow.html)
|
|
88
|
+
> without creating an adoption baseline. After meaningful source or Markdown edits, run
|
|
85
89
|
> `code-guard . --changed-only --json --json-mode compact`; outside Git, pass the
|
|
86
90
|
> exact edited files. Inspect REVIEW and FAIL findings, make only genuine
|
|
87
91
|
> improvements, rerun the check, and report the result. Never weaken thresholds,
|
|
@@ -104,7 +108,7 @@ No configuration is needed. A REVIEW asks for inspection and judgment, not an
|
|
|
104
108
|
automatic refactor. Outside Git, pass the exact edited files instead, such as
|
|
105
109
|
`code-guard src/app.py docs/guide.md`.
|
|
106
110
|
|
|
107
|
-
See the [agent workflow guide](https://
|
|
111
|
+
See the [agent workflow guide](https://stef-k.github.io/agent-code-guard/agent-workflow.html) for repeated human and
|
|
108
112
|
agent use.
|
|
109
113
|
|
|
110
114
|
## Recommended workflow
|
|
@@ -126,7 +130,7 @@ report the result before completion
|
|
|
126
130
|
Use `code-guard . --changed-only --json --json-mode compact` for a structured,
|
|
127
131
|
low-noise manual agent check. Hooks are optional, platform-owned, and require
|
|
128
132
|
user authorization; Code Guard does not install them. The
|
|
129
|
-
[workflow guide](https://
|
|
133
|
+
[workflow guide](https://stef-k.github.io/agent-code-guard/agent-workflow.html) owns the complete manual and
|
|
130
134
|
hook-assisted process.
|
|
131
135
|
|
|
132
136
|
## Interpreting results
|
|
@@ -163,7 +167,7 @@ measurement. A REVIEW is not proof of a defect or a mandatory refactor.
|
|
|
163
167
|
Comparisons are strictly greater-than, so equality passes. All guards except
|
|
164
168
|
file LOC are REVIEW-only; only file LOC can FAIL. A new guard must provide
|
|
165
169
|
distinct, deterministic value rather than duplicate conventional tooling. See
|
|
166
|
-
[Guard admission](https://
|
|
170
|
+
[Guard admission](https://stef-k.github.io/agent-code-guard/guard-admission.html).
|
|
167
171
|
|
|
168
172
|
### Result and JSON reference
|
|
169
173
|
|
|
@@ -172,7 +176,7 @@ all-guard-excluded file counts. Bare `--json` is the compatible full output;
|
|
|
172
176
|
`--json-mode debug` is byte-identical for the same completed invocation, while
|
|
173
177
|
`--json-mode compact` removes only normalized `pass` findings and retains the
|
|
174
178
|
result, scope, required policies, guards, ordering, and actionable findings.
|
|
175
|
-
Named modes require `--json`. See [Usage](https://
|
|
179
|
+
Named modes require `--json`. See [Usage](https://stef-k.github.io/agent-code-guard/usage.html) for the schema and
|
|
176
180
|
option contract.
|
|
177
181
|
|
|
178
182
|
Known per-file syntax or provider failures instead produce `overall:
|
|
@@ -207,7 +211,7 @@ Generic `.h` files are not syntax-dispatched; `.markdown` is not enabled; Vue
|
|
|
207
211
|
template and style regions are not executable syntax input; and unsupported
|
|
208
212
|
artifacts are inapplicable. Malformed applicable syntax or a required provider
|
|
209
213
|
failure is unavailable evidence, distinct from both an inapplicable file and a
|
|
210
|
-
completed FAIL finding. See [Language support](https://
|
|
214
|
+
completed FAIL finding. See [Language support](https://stef-k.github.io/agent-code-guard/language-support.html).
|
|
211
215
|
|
|
212
216
|
### Skill integration
|
|
213
217
|
|
|
@@ -219,38 +223,45 @@ code-guard --export-skill <target-directory>
|
|
|
219
223
|
```
|
|
220
224
|
|
|
221
225
|
Skill activation is platform-specific and is not performed by pipx or Code
|
|
222
|
-
Guard. See [Skill distribution](https://
|
|
226
|
+
Guard. See [Skill distribution](https://stef-k.github.io/agent-code-guard/skill-distribution.html). The checkout
|
|
223
227
|
compatibility runner is for repository development, not normal installation.
|
|
224
228
|
|
|
225
229
|
### Configuration
|
|
226
230
|
|
|
227
231
|
Built-in defaults require no configuration. Configure a project only for a
|
|
228
|
-
concrete policy reason; see the [configuration guide](https://
|
|
232
|
+
concrete policy reason; see the [configuration guide](https://stef-k.github.io/agent-code-guard/configuration.html).
|
|
229
233
|
The LOC baseline is an explicit adoption tool for established legacy
|
|
230
234
|
repositories, not an ordinary-use requirement or a way to silence findings.
|
|
231
235
|
Its default `ratchetAt: "fail"` policy freezes files above `failAt`; choose
|
|
232
236
|
`ratchetAt: "review"` only when every established file above `warnAt` must be
|
|
233
237
|
non-increasing while ordinary findings in that range remain REVIEW.
|
|
234
238
|
|
|
239
|
+
Reviewed oversized Markdown documents have a separate, explicit
|
|
240
|
+
[document-size ratchet](https://stef-k.github.io/agent-code-guard/usage.html#reviewed-markdown-document-ratchet).
|
|
241
|
+
`--create-markdown-baseline` records accepted physical-line counts;
|
|
242
|
+
`--update-markdown-baseline` only lowers or prunes them. Documents within their
|
|
243
|
+
allowance pass the document-size guard; growth produces REVIEW. Section
|
|
244
|
+
findings remain active, and ordinary analysis never writes either baseline.
|
|
245
|
+
|
|
235
246
|
## Trust, CI, and platform support
|
|
236
247
|
|
|
237
248
|
CI installs Agent Code Guard and analyzes its own real checkout. REVIEW findings
|
|
238
249
|
remain visible but non-blocking, while FAIL findings and tool errors block the
|
|
239
|
-
workflow; the repository intentionally uses no
|
|
250
|
+
workflow; the repository intentionally uses no adoption baseline.
|
|
240
251
|
|
|
241
252
|
The maintained interpreter range is **CPython 3.10–3.14**. See
|
|
242
|
-
[Platform support](https://
|
|
253
|
+
[Platform support](https://stef-k.github.io/agent-code-guard/platform-support.html) for supported binary platforms and
|
|
243
254
|
source-build boundaries.
|
|
244
255
|
|
|
245
256
|
## Documentation
|
|
246
257
|
|
|
247
|
-
- [Documentation index](https://
|
|
248
|
-
- [Agent workflow](https://
|
|
249
|
-
- [Usage and CLI reference](https://
|
|
250
|
-
- [Configuration](https://
|
|
251
|
-
- [Language support](https://
|
|
252
|
-
- [Platform support](https://
|
|
253
|
-
- [Skill distribution](https://
|
|
258
|
+
- [Documentation index](https://stef-k.github.io/agent-code-guard/)
|
|
259
|
+
- [Agent workflow](https://stef-k.github.io/agent-code-guard/agent-workflow.html)
|
|
260
|
+
- [Usage and CLI reference](https://stef-k.github.io/agent-code-guard/usage.html)
|
|
261
|
+
- [Configuration](https://stef-k.github.io/agent-code-guard/configuration.html)
|
|
262
|
+
- [Language support](https://stef-k.github.io/agent-code-guard/language-support.html)
|
|
263
|
+
- [Platform support](https://stef-k.github.io/agent-code-guard/platform-support.html)
|
|
264
|
+
- [Skill distribution](https://stef-k.github.io/agent-code-guard/skill-distribution.html)
|
|
254
265
|
|
|
255
266
|
## Feedback, security, and license
|
|
256
267
|
|
|
@@ -148,8 +148,9 @@ reviews and never fails. Load `references/complexity-policy.md` only when
|
|
|
148
148
|
|
|
149
149
|
Markdown document and direct-section size count all physical lines. Sections
|
|
150
150
|
run from a supported heading through the line before the next heading of any
|
|
151
|
-
level, or EOF. Exact effective thresholds pass; greater measurements
|
|
152
|
-
never fail.
|
|
151
|
+
level, or EOF. Exact effective thresholds pass; greater measurements normally
|
|
152
|
+
review and never fail. A document measurement within an explicitly accepted
|
|
153
|
+
Markdown document baseline passes the document-size guard. Load `references/markdown-size-policy.md` when either
|
|
153
154
|
`markdownDocumentSize` or `markdownSectionSize` appears in `requiredPolicies`.
|
|
154
155
|
Review navigation and responsibility without mechanically splitting coherent
|
|
155
156
|
specifications or gaming headings/formatting.
|
|
@@ -161,3 +162,20 @@ REVIEW requires inspection and justification, not mandatory refactoring.
|
|
|
161
162
|
Agent Code Guard is the canonical LOC implementation. Agent LOC Guard is the completed prototype/reference whose mature behavior was migrated from commit `75ab39d261dbc65f78815836fac90add16d265d1`.
|
|
162
163
|
|
|
163
164
|
Project-specific architecture rules, framework-specific checks, arbitrary style preferences, security scanners, and dependency auditing are outside the universal core.
|
|
165
|
+
|
|
166
|
+
## Reviewed Markdown document baselines
|
|
167
|
+
|
|
168
|
+
After explicit acceptance of a cohesive oversized document, use
|
|
169
|
+
`code-guard docs/architecture.md --create-markdown-baseline` to record its current
|
|
170
|
+
physical-line count in `.agent-tools/code-guard.markdown-baseline.json` at the
|
|
171
|
+
analysis root. Normal analysis reads this file without writing. Unchanged or
|
|
172
|
+
smaller accepted documents pass `markdownDocumentSize`; growth above both the
|
|
173
|
+
allowance and effective threshold returns REVIEW. `markdownSectionSize` remains
|
|
174
|
+
independent and has no baseline support.
|
|
175
|
+
|
|
176
|
+
`--update-markdown-baseline` only lowers or prunes existing allowances within
|
|
177
|
+
positional bounds; it never adds or increases one. Neither write command is
|
|
178
|
+
part of routine checks. Do not create, replace, remove, or increase allowances
|
|
179
|
+
merely to silence findings. Review and commit explicit acceptance decisions.
|
|
180
|
+
Human/full JSON output retains acceptance context; compact omits accepted PASS
|
|
181
|
+
findings. Load the Markdown policy for actionable document or section reviews.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Markdown Size Review Policy
|
|
2
|
+
|
|
3
|
+
Use this policy when `markdownDocumentSize` or `markdownSectionSize` appears in
|
|
4
|
+
`requiredPolicies`.
|
|
5
|
+
|
|
6
|
+
A Markdown size REVIEW is an instruction to inspect navigation and
|
|
7
|
+
responsibility, not an automatic instruction to split the document or section.
|
|
8
|
+
`reviewed; coherent; keep` is a valid outcome for cohesive specifications,
|
|
9
|
+
reference material, tables, procedures, and code-heavy sections.
|
|
10
|
+
|
|
11
|
+
Improve navigation or responsibility boundaries only when the result is
|
|
12
|
+
genuinely clearer. Do not add meaningless headings to lower section size,
|
|
13
|
+
mechanically split coherent material, compress formatting or remove useful
|
|
14
|
+
blank lines, or hide content in fenced code. Agents must not raise thresholds or
|
|
15
|
+
disable either guard merely to silence a finding; project or user authority is
|
|
16
|
+
required for configuration changes.
|
|
17
|
+
|
|
18
|
+
## Explicit document acceptance
|
|
19
|
+
|
|
20
|
+
An explicitly reviewed, cohesive oversized document may use a source-controlled
|
|
21
|
+
allowance created with `--create-markdown-baseline`. The separate
|
|
22
|
+
`.agent-tools/code-guard.markdown-baseline.json` records exact root-relative paths
|
|
23
|
+
and current physical-line counts. Within that allowance the document finding
|
|
24
|
+
passes; growth above both the allowance and effective threshold is REVIEW,
|
|
25
|
+
never FAIL. At or below the ordinary threshold, an allowance is no longer needed.
|
|
26
|
+
|
|
27
|
+
This applies only to `markdownDocumentSize`. Inspect section REVIEW findings
|
|
28
|
+
independently; document acceptance does not exempt sections. Normal analysis
|
|
29
|
+
never changes a baseline. After reductions or deletions,
|
|
30
|
+
`--update-markdown-baseline` can explicitly lower or prune existing entries but
|
|
31
|
+
cannot add or increase allowances. Agents must not create or replace baselines,
|
|
32
|
+
remove allowances, raise thresholds, or add exclusions merely to silence growth.
|
|
33
|
+
Baseline acceptance requires explicit authority and source-control review.
|
|
@@ -116,11 +116,11 @@ def _range_end_node(node, language: str):
|
|
|
116
116
|
|
|
117
117
|
def _callable_range(node, region: ExecutableRegion) -> SourceRange:
|
|
118
118
|
"""Snapshot provider points once before mapping them to original source."""
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
start = callable_source_start(node, region.language)
|
|
120
|
+
end = _range_end_node(node, region.language)
|
|
121
121
|
return SourceRange(
|
|
122
|
-
region.
|
|
123
|
-
region.
|
|
122
|
+
region.original_point_at_byte(start.start_byte),
|
|
123
|
+
region.original_point_at_byte(end.end_byte),
|
|
124
124
|
)
|
|
125
125
|
|
|
126
126
|
|
{agent_code_guard-0.3.0 → agent_code_guard-0.4.0}/src/agent_code_guard/analysis/callable_identity.py
RENAMED
|
@@ -272,8 +272,7 @@ def _javascript_lexical_name(node, source: bytes) -> str | None:
|
|
|
272
272
|
|
|
273
273
|
|
|
274
274
|
def _callback_name(node, region: ExecutableRegion) -> str:
|
|
275
|
-
|
|
276
|
-
point = region.original_point(row, column)
|
|
275
|
+
point = region.original_point_at_byte(node.start_byte)
|
|
277
276
|
return f"<callback@{point.line}:{point.byte_column}>"
|
|
278
277
|
|
|
279
278
|
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from dataclasses import dataclass
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
from types import MappingProxyType
|
|
8
|
+
from typing import Mapping
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
@dataclass(frozen=True, order=True)
|
|
@@ -82,11 +84,20 @@ class FileFacts:
|
|
|
82
84
|
controls: tuple[ControlFlowFact, ...]
|
|
83
85
|
decisions: tuple[DecisionFact, ...]
|
|
84
86
|
region_count: int
|
|
87
|
+
reporting_path: str | None = None
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
@dataclass(frozen=True)
|
|
88
91
|
class AnalysisFacts:
|
|
89
92
|
files: tuple[FileFacts, ...]
|
|
93
|
+
_reporting_paths: Mapping[Path, str] = field(init=False, repr=False, compare=False)
|
|
94
|
+
|
|
95
|
+
def __post_init__(self) -> None:
|
|
96
|
+
object.__setattr__(self, "_reporting_paths", MappingProxyType({
|
|
97
|
+
file.path: file.reporting_path
|
|
98
|
+
for file in self.files
|
|
99
|
+
if file.reporting_path is not None
|
|
100
|
+
}))
|
|
90
101
|
|
|
91
102
|
@property
|
|
92
103
|
def callables(self) -> tuple[CallableFact, ...]:
|
|
@@ -99,3 +110,12 @@ class AnalysisFacts:
|
|
|
99
110
|
@property
|
|
100
111
|
def decisions(self) -> tuple[DecisionFact, ...]:
|
|
101
112
|
return tuple(fact for file in self.files for fact in file.decisions)
|
|
113
|
+
|
|
114
|
+
def reporting_path_for(self, path: Path, root: Path | None = None) -> str:
|
|
115
|
+
stored = self._reporting_paths.get(path)
|
|
116
|
+
if stored is not None:
|
|
117
|
+
return stored
|
|
118
|
+
try:
|
|
119
|
+
return path.relative_to(root).as_posix() if root is not None else path.as_posix()
|
|
120
|
+
except ValueError:
|
|
121
|
+
return path.as_posix()
|
|
@@ -5,6 +5,8 @@ from __future__ import annotations
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
+
from ..invocation import SelectedFile
|
|
9
|
+
|
|
8
10
|
from .adapters import extract_facts
|
|
9
11
|
from .csharp_compat import corrected_csharp_root
|
|
10
12
|
from .errors import ProviderUnavailableError, SyntaxAnalysisError
|
|
@@ -13,16 +15,20 @@ from .provider import ParserProvider, TreeSitterProvider
|
|
|
13
15
|
from .regions import executable_regions, is_applicable
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
def analyze_files(files: tuple[
|
|
18
|
+
def analyze_files(files: tuple[SelectedFile, ...] | list[SelectedFile], provider: ParserProvider | None = None) -> AnalysisFacts:
|
|
17
19
|
"""Analyze only applicable entries from the already-resolved caller scope."""
|
|
18
20
|
active_provider = provider or TreeSitterProvider()
|
|
19
|
-
results = [
|
|
21
|
+
results = [
|
|
22
|
+
_analyze_file(selected.physical_path, active_provider, selected.reporting_path)
|
|
23
|
+
for selected in files if is_applicable(selected.physical_path)
|
|
24
|
+
]
|
|
20
25
|
return AnalysisFacts(tuple(results))
|
|
21
26
|
|
|
22
27
|
|
|
23
28
|
@dataclass(frozen=True)
|
|
24
29
|
class UnavailableAnalysis:
|
|
25
30
|
path: Path
|
|
31
|
+
reporting_path: str
|
|
26
32
|
language: str
|
|
27
33
|
kind: str
|
|
28
34
|
message: str
|
|
@@ -35,27 +41,27 @@ class BatchAnalysis:
|
|
|
35
41
|
|
|
36
42
|
|
|
37
43
|
def analyze_files_for_runner(
|
|
38
|
-
files: tuple[
|
|
44
|
+
files: tuple[SelectedFile, ...], provider: ParserProvider | None = None,
|
|
39
45
|
) -> BatchAnalysis:
|
|
40
46
|
"""Analyze selected files independently while retaining only known unavailable evidence."""
|
|
41
47
|
active_provider = provider or TreeSitterProvider()
|
|
42
48
|
results: list[FileFacts] = []
|
|
43
49
|
unavailable: list[UnavailableAnalysis] = []
|
|
44
|
-
for
|
|
45
|
-
path =
|
|
50
|
+
for selected in files:
|
|
51
|
+
path = selected.physical_path
|
|
46
52
|
if not is_applicable(path):
|
|
47
53
|
continue
|
|
48
54
|
try:
|
|
49
|
-
results.append(_analyze_file(path, active_provider))
|
|
55
|
+
results.append(_analyze_file(path, active_provider, selected.reporting_path))
|
|
50
56
|
except (SyntaxAnalysisError, ProviderUnavailableError) as exc:
|
|
51
57
|
if exc.language is None:
|
|
52
58
|
raise
|
|
53
59
|
kind = "syntax" if isinstance(exc, SyntaxAnalysisError) else "provider"
|
|
54
|
-
unavailable.append(UnavailableAnalysis(path, exc.language, kind, str(exc)))
|
|
60
|
+
unavailable.append(UnavailableAnalysis(path, selected.reporting_path, exc.language, kind, str(exc)))
|
|
55
61
|
return BatchAnalysis(AnalysisFacts(tuple(results)), tuple(unavailable))
|
|
56
62
|
|
|
57
63
|
|
|
58
|
-
def _analyze_file(path: Path, provider: ParserProvider) -> FileFacts:
|
|
64
|
+
def _analyze_file(path: Path, provider: ParserProvider, reporting_path: str | None = None) -> FileFacts:
|
|
59
65
|
callables = []
|
|
60
66
|
controls = []
|
|
61
67
|
decisions = []
|
|
@@ -83,4 +89,4 @@ def _analyze_file(path: Path, provider: ParserProvider) -> FileFacts:
|
|
|
83
89
|
callables.extend(region_callables)
|
|
84
90
|
controls.extend(region_controls)
|
|
85
91
|
decisions.extend(region_decisions)
|
|
86
|
-
return FileFacts(path, tuple(callables), tuple(controls), tuple(decisions), len(regions))
|
|
92
|
+
return FileFacts(path, tuple(callables), tuple(controls), tuple(decisions), len(regions), reporting_path)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
+
from bisect import bisect_right
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
from .errors import SyntaxAnalysisError
|
|
@@ -29,21 +30,31 @@ class ExecutableRegion:
|
|
|
29
30
|
source: bytes
|
|
30
31
|
original_source: bytes
|
|
31
32
|
original_byte_offset: int = 0
|
|
33
|
+
original_line_starts: tuple[int, ...] | None = None
|
|
34
|
+
local_line_starts: tuple[int, ...] | None = None
|
|
35
|
+
|
|
36
|
+
def __post_init__(self) -> None:
|
|
37
|
+
if self.original_line_starts is None:
|
|
38
|
+
object.__setattr__(self, "original_line_starts", _line_starts(self.original_source))
|
|
39
|
+
if self.local_line_starts is None:
|
|
40
|
+
object.__setattr__(self, "local_line_starts", _line_starts(self.source))
|
|
32
41
|
|
|
33
42
|
def original_point(self, local_row: int, local_byte_column: int) -> SourcePoint:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
local_offset = self.local_line_starts[local_row] + local_byte_column
|
|
44
|
+
return self.original_point_at_byte(local_offset)
|
|
45
|
+
|
|
46
|
+
def original_point_at_byte(self, local_byte_offset: int) -> SourcePoint:
|
|
47
|
+
"""Map a parser byte offset without reconstructing its local row prefix."""
|
|
48
|
+
absolute = self.original_byte_offset + local_byte_offset
|
|
49
|
+
row = bisect_right(self.original_line_starts, absolute) - 1
|
|
50
|
+
line = row + 1
|
|
51
|
+
byte_column = absolute - self.original_line_starts[row] + 1
|
|
39
52
|
return SourcePoint(line, byte_column, absolute)
|
|
40
53
|
|
|
41
54
|
def original_range(self, node) -> SourceRange:
|
|
42
|
-
start_row, start_column = node.start_point
|
|
43
|
-
end_row, end_column = node.end_point
|
|
44
55
|
return SourceRange(
|
|
45
|
-
self.
|
|
46
|
-
self.
|
|
56
|
+
self.original_point_at_byte(node.start_byte),
|
|
57
|
+
self.original_point_at_byte(node.end_byte),
|
|
47
58
|
)
|
|
48
59
|
|
|
49
60
|
|
|
@@ -69,6 +80,7 @@ def _vue_regions(path: Path, source: bytes, provider: ParserProvider) -> tuple[E
|
|
|
69
80
|
f"unable to parse {path}: Vue container syntax tree contains errors", language="vue",
|
|
70
81
|
)
|
|
71
82
|
regions: list[ExecutableRegion] = []
|
|
83
|
+
original_line_starts = _line_starts(source)
|
|
72
84
|
for element in root.named_children:
|
|
73
85
|
if element.type != "script_element":
|
|
74
86
|
continue
|
|
@@ -83,15 +95,13 @@ def _vue_regions(path: Path, source: bytes, provider: ParserProvider) -> tuple[E
|
|
|
83
95
|
if raw_text is not None:
|
|
84
96
|
regions.append(ExecutableRegion(
|
|
85
97
|
path, language, source[raw_text.start_byte:raw_text.end_byte], source, raw_text.start_byte,
|
|
98
|
+
original_line_starts,
|
|
86
99
|
))
|
|
87
100
|
return tuple(regions)
|
|
88
101
|
|
|
89
102
|
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
for _ in range(row):
|
|
93
|
-
position = source.index(b"\n", position) + 1
|
|
94
|
-
return position + column
|
|
103
|
+
def _line_starts(source: bytes) -> tuple[int, ...]:
|
|
104
|
+
return (0, *(index + 1 for index, value in enumerate(source) if value == 10))
|
|
95
105
|
|
|
96
106
|
|
|
97
107
|
def _attributes(start_tag, source: bytes) -> dict[str, str | None]:
|