agent-config-score 0.18.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.
Files changed (34) hide show
  1. agent_config_score-0.18.0/LICENSE +21 -0
  2. agent_config_score-0.18.0/PKG-INFO +532 -0
  3. agent_config_score-0.18.0/README.md +505 -0
  4. agent_config_score-0.18.0/pyproject.toml +43 -0
  5. agent_config_score-0.18.0/setup.cfg +4 -0
  6. agent_config_score-0.18.0/src/agent_config_score/__init__.py +1 -0
  7. agent_config_score-0.18.0/src/agent_config_score/cli.py +457 -0
  8. agent_config_score-0.18.0/src/agent_config_score/config.py +201 -0
  9. agent_config_score-0.18.0/src/agent_config_score/doctor.py +183 -0
  10. agent_config_score-0.18.0/src/agent_config_score/entrypoint.py +154 -0
  11. agent_config_score-0.18.0/src/agent_config_score/gitdiff.py +110 -0
  12. agent_config_score-0.18.0/src/agent_config_score/history.py +80 -0
  13. agent_config_score-0.18.0/src/agent_config_score/initializer.py +103 -0
  14. agent_config_score-0.18.0/src/agent_config_score/regression.py +113 -0
  15. agent_config_score-0.18.0/src/agent_config_score/rules.py +83 -0
  16. agent_config_score-0.18.0/src/agent_config_score/sarif.py +84 -0
  17. agent_config_score-0.18.0/src/agent_config_score/scanner.py +496 -0
  18. agent_config_score-0.18.0/src/agent_config_score.egg-info/PKG-INFO +532 -0
  19. agent_config_score-0.18.0/src/agent_config_score.egg-info/SOURCES.txt +32 -0
  20. agent_config_score-0.18.0/src/agent_config_score.egg-info/dependency_links.txt +1 -0
  21. agent_config_score-0.18.0/src/agent_config_score.egg-info/entry_points.txt +3 -0
  22. agent_config_score-0.18.0/src/agent_config_score.egg-info/top_level.txt +1 -0
  23. agent_config_score-0.18.0/tests/test_benchmark.py +46 -0
  24. agent_config_score-0.18.0/tests/test_cli.py +99 -0
  25. agent_config_score-0.18.0/tests/test_config.py +275 -0
  26. agent_config_score-0.18.0/tests/test_contracts.py +78 -0
  27. agent_config_score-0.18.0/tests/test_doctor.py +138 -0
  28. agent_config_score-0.18.0/tests/test_gitdiff.py +165 -0
  29. agent_config_score-0.18.0/tests/test_history.py +78 -0
  30. agent_config_score-0.18.0/tests/test_initializer.py +82 -0
  31. agent_config_score-0.18.0/tests/test_release_workflow.py +56 -0
  32. agent_config_score-0.18.0/tests/test_rules.py +55 -0
  33. agent_config_score-0.18.0/tests/test_scanner.py +376 -0
  34. agent_config_score-0.18.0/tests/test_schema.py +53 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zhibo Lin
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,532 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-config-score
3
+ Version: 0.18.0
4
+ Summary: Regression gate for AI coding-agent configs: catch PRs that make AGENTS.md, CLAUDE.md, Cursor or Copilot instructions worse.
5
+ Author: Zhibo Lin
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/LE0-Lin/AgentConfigScore
8
+ Project-URL: Repository, https://github.com/LE0-Lin/AgentConfigScore
9
+ Project-URL: Issues, https://github.com/LE0-Lin/AgentConfigScore/issues
10
+ Project-URL: Changelog, https://github.com/LE0-Lin/AgentConfigScore/blob/main/CHANGELOG.md
11
+ Keywords: agents-md,claude-code,cursor,copilot,ai-agents,github-actions,ci,developer-tools
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: Software Development :: Testing
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Dynamic: license-file
27
+
28
+ # AgentConfigScore
29
+
30
+ <p align="center">
31
+ <img src="https://raw.githubusercontent.com/LE0-Lin/AgentConfigScore/main/assets/agent-config-score.svg" alt="AgentConfigScore A 100" />
32
+ </p>
33
+
34
+ <p align="center"><strong>Codecov for AI coding-agent instructions.</strong></p>
35
+
36
+ <p align="center">
37
+ Stop pull requests from quietly making <code>AGENTS.md</code>, <code>CLAUDE.md</code>, Cursor, Copilot and Gemini instructions worse.
38
+ </p>
39
+
40
+ <p align="center">
41
+ <a href="https://github.com/LE0-Lin/AgentConfigScore/actions/workflows/ci.yml"><img src="https://github.com/LE0-Lin/AgentConfigScore/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
42
+ <a href="https://pypi.org/project/agent-config-score/"><img src="https://img.shields.io/pypi/v/agent-config-score" alt="PyPI" /></a>
43
+ <img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python 3.10+" />
44
+ <img src="https://img.shields.io/badge/platforms-Linux%20%7C%20Windows%20%7C%20macOS-informational" alt="Linux, Windows, macOS" />
45
+ <img src="https://img.shields.io/badge/runtime_dependencies-0-brightgreen" alt="0 runtime dependencies" />
46
+ <img src="https://img.shields.io/badge/license-MIT-green" alt="MIT" />
47
+ </p>
48
+
49
+ <p align="center">
50
+ <img src="https://raw.githubusercontent.com/LE0-Lin/AgentConfigScore/main/assets/agent-config-score-demo.gif" alt="AgentConfigScore detects an instruction regression and blocks the pull request" width="100%" />
51
+ </p>
52
+
53
+ AgentConfigScore is a deterministic regression gate for coding-agent configuration. It compares a change with its baseline and answers one CI-friendly question:
54
+
55
+ > **Did this change make our agent instructions worse?**
56
+
57
+ It is regression-first rather than perfection-first: an existing repository can start at 72/100 and adopt the gate immediately. A pull request that stays at 72 can pass; one that drops to 65 can fail.
58
+
59
+ | What usually goes wrong | What the gate does |
60
+ |---|---|
61
+ | A pull request weakens its own quality threshold | Uses the baseline branch's policy to judge the change |
62
+ | A new instruction contradicts or duplicates existing guidance | Reports deterministic, line-addressable findings |
63
+ | An exception becomes a permanent silent ignore | Requires a reason and expiry, then preserves an audit trail |
64
+ | A scanner update becomes noisy on real projects | Replays a pinned, manually reviewed [real-repository benchmark](https://github.com/LE0-Lin/AgentConfigScore/blob/v0/benchmarks/README.md) |
65
+
66
+ ## Get running
67
+
68
+ ```bash
69
+ python -m pip install agent-config-score
70
+ agent-config-score init
71
+ ```
72
+
73
+ To test the latest stable pre-1.0 source directly from GitHub instead:
74
+
75
+ ```bash
76
+ python -m pip install "git+https://github.com/LE0-Lin/AgentConfigScore.git@v0"
77
+ ```
78
+
79
+ `init` safely creates:
80
+
81
+ - `.agentconfigscore.json` — version-controlled policy, suppressions, and editor schema annotation
82
+ - `.github/workflows/agent-config-score.yml` — pull-request regression gate
83
+
84
+ Review and commit those files. Pull requests are then checked automatically.
85
+
86
+ Validate the integration and run the same regression check locally before pushing:
87
+
88
+ ```bash
89
+ agent-config-score doctor
90
+ agent-config-score diff
91
+ ```
92
+
93
+ `diff` auto-detects a safe local default-branch baseline when possible. You can still pass an explicit ref such as `origin/main` whenever you want full control.
94
+
95
+ Initialization is conservative: every target is preflighted before anything is written, conflicting files are never overwritten by default, and rerunning against matching generated files is idempotent.
96
+
97
+ ```bash
98
+ agent-config-score init --dry-run # preview without writing
99
+ agent-config-score init --no-workflow # config only
100
+ agent-config-score init --force # intentionally replace conflicting generated files
101
+ ```
102
+
103
+ `v0` is the rolling stable ref for the current pre-1.0 series.
104
+
105
+ ## Repository policy + editor validation
106
+
107
+ A generated config looks like this:
108
+
109
+ ```json
110
+ {
111
+ "$schema": "https://raw.githubusercontent.com/LE0-Lin/AgentConfigScore/v0/schema/agentconfigscore.schema.json",
112
+ "version": 1,
113
+ "policy": {
114
+ "max_drop": 0,
115
+ "fail_on_new_errors": true
116
+ }
117
+ }
118
+ ```
119
+
120
+ The `$schema` annotation enables live validation and completion in editors that support JSON Schema. It can catch misspelled policy keys, wrong value types, unknown suppression rule IDs, missing suppression fields, and malformed path scopes before CI runs.
121
+
122
+ The schema is Draft 2020-12 and lives at `schema/agentconfigscore.schema.json`. AgentConfigScore's tests verify that its suppression rule enum stays exactly aligned with the stable Rule Catalog, so editor hints cannot silently drift away from scanner behavior.
123
+
124
+ Policy fields:
125
+
126
+ | Key | Default | Meaning |
127
+ |---|---:|---|
128
+ | `max_drop` | `0` | Maximum score decrease allowed by `diff` / `compare` |
129
+ | `fail_on_new_errors` | `false` in the CLI; `true` in the Action when no policy file exists | Fail on newly introduced active error findings |
130
+ | `fail_under` | unset | Optional absolute score floor for a normal scan |
131
+
132
+ An absolute floor is optional:
133
+
134
+ ```json
135
+ {
136
+ "$schema": "https://raw.githubusercontent.com/LE0-Lin/AgentConfigScore/v0/schema/agentconfigscore.schema.json",
137
+ "version": 1,
138
+ "policy": {
139
+ "max_drop": 0,
140
+ "fail_on_new_errors": true,
141
+ "fail_under": 90
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Why the baseline policy governs a PR
147
+
148
+ A pull request must not be able to weaken the gate that reviews it.
149
+
150
+ For `diff`, `compare`, and the reusable GitHub Action, AgentConfigScore uses the **baseline** policy to decide pass/fail. The candidate config is still parsed and validated, but new thresholds only become active after that config is reviewed, merged, and becomes a later baseline.
151
+
152
+ A candidate changing `max_drop` to `100` therefore cannot use that weaker value to pass itself. Explicit CLI or Action inputs remain available as trusted invocation-time overrides.
153
+
154
+ ## Auditable exceptions
155
+
156
+ Sometimes a finding is understood and intentionally accepted. AgentConfigScore supports suppressions, but does not treat them as a permanent ignore list.
157
+
158
+ Every suppression must name a stable rule, explain the exception, and expire:
159
+
160
+ ```json
161
+ {
162
+ "$schema": "https://raw.githubusercontent.com/LE0-Lin/AgentConfigScore/v0/schema/agentconfigscore.schema.json",
163
+ "version": 1,
164
+ "policy": {
165
+ "max_drop": 0,
166
+ "fail_on_new_errors": true
167
+ },
168
+ "suppressions": [
169
+ {
170
+ "rule": "dead-path",
171
+ "reason": "Generated docs reference paths that only exist after deployment.",
172
+ "expires": "2026-12-31",
173
+ "paths": ["docs/**"]
174
+ }
175
+ ]
176
+ }
177
+ ```
178
+
179
+ Rules for suppressions:
180
+
181
+ - `rule` must be a known stable AgentConfigScore rule ID
182
+ - `reason` must be non-empty and is limited to 500 characters
183
+ - `expires` must be `YYYY-MM-DD`
184
+ - an expired suppression is a configuration error; remove it or explicitly renew it
185
+ - `paths` is optional and accepts unique instruction-file glob patterns
186
+ - path-scoped suppressions never hide repository-level findings such as cross-file contradiction
187
+ - duplicate rule/path scopes are rejected
188
+
189
+ Suppressions are **not silent**. A matching finding stops contributing to score and regression decisions, but remains visible in the `suppressed_findings` audit trail in JSON and is shown with its reason and expiry in terminal, HTML, and Markdown output.
190
+
191
+ Suppressions are baseline-governed too: a PR cannot add a suppression and use it to excuse a finding introduced by that same PR. The baseline suppression set is applied to both sides of a regression comparison.
192
+
193
+ ## Check locally before you push
194
+
195
+ The common path is now zero-config:
196
+
197
+ ```bash
198
+ agent-config-score doctor
199
+ agent-config-score diff
200
+ ```
201
+
202
+ `doctor` validates the repository integration. `diff` compares the current working tree—including uncommitted changes—with a safe local default-branch baseline.
203
+
204
+ When no `BASE_REF` is provided, AgentConfigScore detects a baseline conservatively in this order:
205
+
206
+ 1. locally configured `origin/HEAD`
207
+ 2. local `main`
208
+ 3. local `master`
209
+ 4. local `trunk`
210
+ 5. an upstream whose branch name itself is `main`, `master`, or `trunk`
211
+
212
+ It deliberately does **not** use a feature-branch upstream such as `origin/my-feature` as the baseline, because doing so could hide committed changes relative to the real default branch.
213
+
214
+ AgentConfigScore creates an isolated detached baseline worktree, compares it with your current repository, then removes the temporary worktree automatically. Automatic detection is fully offline and never runs `git fetch`.
215
+
216
+ If no safe local baseline can be identified, pass one explicitly:
217
+
218
+ ```bash
219
+ agent-config-score diff origin/main
220
+ ```
221
+
222
+ If that ref is not available locally, fetch it yourself and retry. AgentConfigScore never fetches a missing ref behind your back.
223
+
224
+ Trusted threshold overrides are explicit:
225
+
226
+ ```bash
227
+ agent-config-score diff \
228
+ --max-drop 3 \
229
+ --no-fail-on-new-errors
230
+ ```
231
+
232
+ You can run `diff` from any subdirectory inside the repository. Use `--path DIR` to point at another local repository.
233
+
234
+ ## What a failing PR looks like
235
+
236
+ ```text
237
+ AgentConfigScore regression A 96 → B 84 (-12)
238
+ New findings: 2 Resolved: 0 Suppressed: 0
239
+
240
+ + ERROR curl-pipe-shell Remote script piped directly to a shell
241
+ .github/copilot-instructions.md:12
242
+ + WARNING dead-path Referenced path does not exist: src/legacy_auth.py
243
+ AGENTS.md:31
244
+ ```
245
+
246
+ **Live proof:** [PR #6](https://github.com/LE0-Lin/AgentConfigScore/pull/6) deliberately added an unsafe `curl | bash` instruction. AgentConfigScore changed the score from **A 100 → B 82 (-18)**, reported a new `curl-pipe-shell` error, failed the GitHub Actions job, and the PR was closed without merging.
247
+
248
+ ## Real-repository benchmark
249
+
250
+ The v0.17.0 scanner was replayed against pinned commits from three public AI coding projects; source code was scanned but never executed.
251
+
252
+ | Repository | Commit | Files found | Result | Manually reviewed signal |
253
+ |---|---|---:|---:|---|
254
+ | [`openai/codex`](https://github.com/openai/codex) | `d58d0e5` | 2 | B 82 | 3 references to absent `.rs` files; 1 context-size warning |
255
+ | [`anomalyco/opencode`](https://github.com/anomalyco/opencode) | `9f69463` | 18 | A 94 | 1 context-size warning |
256
+ | [`browser-use/browser-use`](https://github.com/browser-use/browser-use) | `d379a32` | 2 | B 88 | 1 context-size warning |
257
+
258
+ All six findings matched their rule definitions in manual review. This small corpus is a reproducible smoke benchmark, not a quality leaderboard or a claim of broad statistical accuracy. The pinned inputs, reviewed expectations, limitations, and one-command runner live in [`benchmarks/`](https://github.com/LE0-Lin/AgentConfigScore/blob/v0/benchmarks/README.md).
259
+
260
+ ## Manual GitHub Actions setup
261
+
262
+ If you do not want to use `init`, create `.github/workflows/agent-config-score.yml` yourself:
263
+
264
+ ```yaml
265
+ name: agent-config-regression
266
+
267
+ on:
268
+ pull_request:
269
+
270
+ permissions:
271
+ contents: read
272
+
273
+ jobs:
274
+ regression:
275
+ runs-on: ubuntu-latest
276
+ steps:
277
+ - uses: actions/checkout@v7
278
+ with:
279
+ fetch-depth: 0
280
+ - uses: LE0-Lin/AgentConfigScore@v0
281
+ ```
282
+
283
+ The Action installs AgentConfigScore, resolves the PR base commit, applies baseline policy and suppressions, writes a Markdown report to the GitHub Actions Step Summary, exposes structured outputs, and returns the final regression status.
284
+
285
+ Without a policy file, the Action preserves its conservative compatibility defaults: `max_drop = 0` and `fail_on_new_errors = true`.
286
+
287
+ ## Keep score history
288
+
289
+ Optionally record a read-only score snapshot whenever your default branch changes:
290
+
291
+ ```yaml
292
+ name: agent-config-score-history
293
+
294
+ on:
295
+ push:
296
+ branches: [main]
297
+
298
+ permissions:
299
+ contents: read
300
+
301
+ jobs:
302
+ snapshot:
303
+ uses: LE0-Lin/AgentConfigScore/.github/workflows/score-history.yml@v0
304
+ ```
305
+
306
+ Each successful run uploads an immutable artifact containing `snapshot.json`, `report.json`, `report.html`, and `badge.svg`. Artifact names include the commit SHA and run attempt, and retention defaults to 30 days. The history workflow does not write generated files back to the repository and does not fail merely because the current score is low.
307
+
308
+ See [`docs/score-history.md`](https://github.com/LE0-Lin/AgentConfigScore/blob/v0/docs/score-history.md) for retention controls, monorepo paths, workflow outputs, and the history/security model. A copy-paste workflow is also available at [`examples/score-history.yml`](https://github.com/LE0-Lin/AgentConfigScore/blob/v0/examples/score-history.yml).
309
+
310
+ ## Nested AGENTS.md scopes and overrides
311
+
312
+ AgentConfigScore recursively discovers both `AGENTS.md` and Codex `AGENTS.override.md` files and understands their directory scoping instead of treating every instruction file as one global policy.
313
+
314
+ For a nested AGENTS-family file, file-like path references may be repository-root-relative, package-root-relative, or relative to the directory containing that file. The conservative `dead-path` analysis ignores ambiguous extensionless tokens, code fences, URLs, package imports, API symbols, absolute paths, Windows drive-qualified paths, and relative paths that escape the repository.
315
+
316
+ Codex gives `AGENTS.override.md` priority over `AGENTS.md` in the same directory. Across directories, sibling scopes do not overlap and deeper instructions are more specific inside their subtree. AgentConfigScore therefore does not report an exact positive/negative pair across two different AGENTS-family files as an ambiguous contradiction. A contradiction inside one file still fails, and cross-system contradictions such as AGENTS-family instructions versus `CLAUDE.md` remain detectable.
317
+
318
+ Codex can also be configured with custom `project_doc_fallback_filenames`. AgentConfigScore does not guess those user-specific filenames automatically; only the standard built-in AGENTS filenames are discovered by default.
319
+
320
+ ## Stable rule catalog
321
+
322
+ Scoring logic is not hidden inside prose. Every rule has one canonical definition containing:
323
+
324
+ - rule ID
325
+ - default severity
326
+ - scoring category
327
+ - penalty before category caps
328
+ - short summary
329
+ - longer explanation
330
+
331
+ Inspect all rules or one rule:
332
+
333
+ ```bash
334
+ agent-config-score rules
335
+ agent-config-score rules curl-pipe-shell
336
+ agent-config-score rules --json
337
+ agent-config-score rules dead-path --json
338
+ ```
339
+
340
+ The scanner, scoring categories, CLI rule inspection, SARIF metadata, suppression validation, and config JSON Schema all derive from or are tested against the same stable catalog.
341
+
342
+ Current rule families include context size, cross-file duplication, contradictions, dead paths, dangerous shell commands, common credential patterns, and missing canonical `AGENTS.md` coordination.
343
+
344
+ ## CLI reference
345
+
346
+ Score the current repository:
347
+
348
+ ```bash
349
+ agent-config-score .
350
+ ```
351
+
352
+ Validate the repository integration:
353
+
354
+ ```bash
355
+ agent-config-score doctor
356
+ agent-config-score doctor --json
357
+ ```
358
+
359
+ Run a local regression check with automatic baseline detection:
360
+
361
+ ```bash
362
+ agent-config-score diff
363
+ ```
364
+
365
+ Save a regression Markdown report:
366
+
367
+ ```bash
368
+ agent-config-score diff --markdown regression.md
369
+ ```
370
+
371
+ Use an explicit baseline when needed:
372
+
373
+ ```bash
374
+ agent-config-score diff origin/main
375
+ ```
376
+
377
+ Advanced: compare two already checked-out trees directly:
378
+
379
+ ```bash
380
+ agent-config-score compare ../repo-base . --markdown regression.md
381
+ ```
382
+
383
+ Generate local reports:
384
+
385
+ ```bash
386
+ agent-config-score . \
387
+ --html .agent-config-score/report.html \
388
+ --badge .agent-config-score/badge.svg \
389
+ --sarif .agent-config-score/results.sarif
390
+ ```
391
+
392
+ Override an absolute floor:
393
+
394
+ ```bash
395
+ agent-config-score . --fail-under 90
396
+ ```
397
+
398
+ Machine-readable output is available with `--json` for scans, `doctor`, `diff`, `compare`, and the rule catalog.
399
+
400
+ ```bash
401
+ agent-config-score --version
402
+ agent-config-score --help
403
+ ```
404
+
405
+ ## GitHub code scanning with SARIF
406
+
407
+ `--sarif` writes SARIF 2.1.0 with rule IDs, severity, source location, descriptions, categories, and scoring penalties. Active findings can therefore be uploaded into GitHub code scanning. Suppressed findings remain in AgentConfigScore's explicit audit output rather than being emitted as active SARIF results.
408
+
409
+ ```yaml
410
+ name: agent-config-code-scanning
411
+
412
+ on:
413
+ push:
414
+
415
+ permissions:
416
+ contents: read
417
+ security-events: write
418
+
419
+ jobs:
420
+ scan:
421
+ runs-on: ubuntu-latest
422
+ steps:
423
+ - uses: actions/checkout@v7
424
+ - uses: actions/setup-python@v7
425
+ with:
426
+ python-version: "3.12"
427
+ - run: python -m pip install "git+https://github.com/LE0-Lin/AgentConfigScore.git@v0"
428
+ - run: agent-config-score . --sarif agent-config-score.sarif
429
+ - uses: github/codeql-action/upload-sarif@v4
430
+ with:
431
+ sarif_file: agent-config-score.sarif
432
+ category: agent-config-score
433
+ ```
434
+
435
+ Repository-level findings remain repository-level SARIF results instead of receiving invented file locations.
436
+
437
+ ## What it scans
438
+
439
+ Supported discovery includes:
440
+
441
+ - `**/AGENTS.md` — root and nested directory scopes
442
+ - `**/AGENTS.override.md` — Codex local overrides
443
+ - `CLAUDE.md`
444
+ - `GEMINI.md`
445
+ - `.cursorrules`
446
+ - `.cursor/rules/*.md` / `*.mdc`
447
+ - `.github/copilot-instructions.md`
448
+ - `.github/instructions/*.md`
449
+ - `.claude/**/*.md`
450
+ - `.clinerules`
451
+ - `.windsurfrules`
452
+
453
+ `.agentconfigscoreignore` can exclude discovery paths when needed.
454
+
455
+ ## Action inputs
456
+
457
+ | Input | Default | Meaning |
458
+ |---|---:|---|
459
+ | `base-sha` | PR base SHA | Explicit baseline commit SHA |
460
+ | `max-drop` | empty | Optional trusted override for baseline `policy.max_drop` |
461
+ | `fail-on-new-errors` | empty | Optional trusted override for baseline `policy.fail_on_new_errors` |
462
+ | `python-version` | `3.12` | Python used by the composite action |
463
+
464
+ ## Action outputs
465
+
466
+ | Output | Meaning |
467
+ |---|---|
468
+ | `base-score` | Baseline AgentConfigScore |
469
+ | `head-score` | Candidate AgentConfigScore |
470
+ | `delta` | Candidate minus baseline score |
471
+ | `new-findings` | Number of newly introduced active findings |
472
+ | `new-errors` | Number of newly introduced active error findings |
473
+ | `resolved-findings` | Number of active findings resolved by the candidate |
474
+
475
+ ```yaml
476
+ - name: Check agent config
477
+ id: acs
478
+ uses: LE0-Lin/AgentConfigScore@v0
479
+
480
+ - name: Print regression metrics
481
+ if: always()
482
+ run: |
483
+ echo "score: ${{ steps.acs.outputs.base-score }} -> ${{ steps.acs.outputs.head-score }}"
484
+ echo "delta: ${{ steps.acs.outputs.delta }}"
485
+ echo "new errors: ${{ steps.acs.outputs.new-errors }}"
486
+ ```
487
+
488
+ The Action emits outputs before returning its final regression status. Use `if: always()` when a downstream step must consume metrics even after the gate intentionally fails.
489
+
490
+ ## Design principles
491
+
492
+ 1. **Regression-first.** Existing repositories do not have to become perfect before CI becomes useful.
493
+ 2. **Baseline-governed policy.** A candidate cannot weaken the gate evaluating itself.
494
+ 3. **Auditable exceptions.** Suppressions need a reason and expiry, remain visible, and cannot self-authorize.
495
+ 4. **Local-first.** Repository content is not uploaded to a hosted analysis service, and automatic Git baseline detection does not fetch.
496
+ 5. **Explainable.** Scores map to stable rule IDs and visible findings.
497
+ 6. **Conservative.** Prefer a missed warning over noisy fake certainty.
498
+ 7. **Zero runtime dependencies.** Python 3.10+ standard library only.
499
+
500
+ ## Roadmap
501
+
502
+ - [x] deterministic 0–100 scoring
503
+ - [x] baseline → candidate regression comparison
504
+ - [x] Markdown PR / Step Summary report
505
+ - [x] first-class reusable GitHub Action
506
+ - [x] structured GitHub Action outputs
507
+ - [x] SARIF output for GitHub code scanning
508
+ - [x] Git-aware local diff without manual worktrees
509
+ - [x] automatic local default-branch baseline detection
510
+ - [x] baseline-governed repository policy
511
+ - [x] safe one-command repository initialization
512
+ - [x] repository integration doctor
513
+ - [x] stable Rule Catalog and rule inspection
514
+ - [x] reasoned / expiring suppressions
515
+ - [x] JSON Schema + editor validation
516
+ - [x] end-to-end behavior contract fixtures
517
+ - [x] score-history artifact / badge workflow
518
+ - [x] scope-aware nested `AGENTS.md` analysis
519
+ - [x] Codex `AGENTS.override.md` discovery / precedence
520
+ - [ ] optional semantic contradiction plugin
521
+
522
+ ## Development
523
+
524
+ ```bash
525
+ python -m pip install -e .
526
+ python -m unittest discover -s tests -v
527
+ agent-config-score . --fail-under 90
528
+ ```
529
+
530
+ MIT licensed. Contributions and real-world agent-config failure examples are welcome.
531
+
532
+ If AgentConfigScore catches a regression in your repository, a ⭐ helps other maintainers discover it.