aletheore 0.2.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 (59) hide show
  1. aletheore-0.2.0/LICENSE +201 -0
  2. aletheore-0.2.0/PKG-INFO +361 -0
  3. aletheore-0.2.0/README.md +320 -0
  4. aletheore-0.2.0/aletheore/__init__.py +1 -0
  5. aletheore-0.2.0/aletheore/adapters/__init__.py +1 -0
  6. aletheore-0.2.0/aletheore/adapters/base.py +13 -0
  7. aletheore-0.2.0/aletheore/adapters/claude_code.py +38 -0
  8. aletheore-0.2.0/aletheore/architecture.py +137 -0
  9. aletheore-0.2.0/aletheore/cli.py +417 -0
  10. aletheore-0.2.0/aletheore/dashboard.py +892 -0
  11. aletheore-0.2.0/aletheore/endpoints.py +1121 -0
  12. aletheore-0.2.0/aletheore/evidence.py +118 -0
  13. aletheore-0.2.0/aletheore/git_intel/__init__.py +1 -0
  14. aletheore-0.2.0/aletheore/git_intel/analyzer.py +176 -0
  15. aletheore-0.2.0/aletheore/healthcheck.py +102 -0
  16. aletheore-0.2.0/aletheore/history.py +190 -0
  17. aletheore-0.2.0/aletheore/licenses.py +176 -0
  18. aletheore-0.2.0/aletheore/mcp_server.py +209 -0
  19. aletheore-0.2.0/aletheore/query.py +90 -0
  20. aletheore-0.2.0/aletheore/report.py +79 -0
  21. aletheore-0.2.0/aletheore/scanner/__init__.py +1 -0
  22. aletheore-0.2.0/aletheore/scanner/detect.py +280 -0
  23. aletheore-0.2.0/aletheore/scanner/graph.py +1169 -0
  24. aletheore-0.2.0/aletheore/secrets.py +192 -0
  25. aletheore-0.2.0/aletheore/static/logo.png +0 -0
  26. aletheore-0.2.0/aletheore/vulnerabilities.py +108 -0
  27. aletheore-0.2.0/aletheore.egg-info/PKG-INFO +361 -0
  28. aletheore-0.2.0/aletheore.egg-info/SOURCES.txt +57 -0
  29. aletheore-0.2.0/aletheore.egg-info/dependency_links.txt +1 -0
  30. aletheore-0.2.0/aletheore.egg-info/entry_points.txt +2 -0
  31. aletheore-0.2.0/aletheore.egg-info/requires.txt +19 -0
  32. aletheore-0.2.0/aletheore.egg-info/top_level.txt +1 -0
  33. aletheore-0.2.0/pyproject.toml +61 -0
  34. aletheore-0.2.0/setup.cfg +4 -0
  35. aletheore-0.2.0/tests/test_adapters.py +53 -0
  36. aletheore-0.2.0/tests/test_architecture.py +255 -0
  37. aletheore-0.2.0/tests/test_cli.py +723 -0
  38. aletheore-0.2.0/tests/test_dashboard.py +235 -0
  39. aletheore-0.2.0/tests/test_detect.py +229 -0
  40. aletheore-0.2.0/tests/test_endpoints.py +823 -0
  41. aletheore-0.2.0/tests/test_evidence.py +304 -0
  42. aletheore-0.2.0/tests/test_git_intel.py +174 -0
  43. aletheore-0.2.0/tests/test_graph.py +160 -0
  44. aletheore-0.2.0/tests/test_graph_cpp.py +162 -0
  45. aletheore-0.2.0/tests/test_graph_csharp.py +137 -0
  46. aletheore-0.2.0/tests/test_graph_go.py +161 -0
  47. aletheore-0.2.0/tests/test_graph_java.py +198 -0
  48. aletheore-0.2.0/tests/test_graph_php.py +142 -0
  49. aletheore-0.2.0/tests/test_graph_ruby.py +147 -0
  50. aletheore-0.2.0/tests/test_graph_rust.py +201 -0
  51. aletheore-0.2.0/tests/test_healthcheck.py +188 -0
  52. aletheore-0.2.0/tests/test_history.py +313 -0
  53. aletheore-0.2.0/tests/test_licenses.py +242 -0
  54. aletheore-0.2.0/tests/test_mcp_server.py +353 -0
  55. aletheore-0.2.0/tests/test_query.py +188 -0
  56. aletheore-0.2.0/tests/test_scaffold.py +5 -0
  57. aletheore-0.2.0/tests/test_secrets.py +178 -0
  58. aletheore-0.2.0/tests/test_secrets_history.py +128 -0
  59. aletheore-0.2.0/tests/test_vulnerabilities.py +95 -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. Do not 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 Veridion contributors
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.
@@ -0,0 +1,361 @@
1
+ Metadata-Version: 2.4
2
+ Name: aletheore
3
+ Version: 0.2.0
4
+ Summary: Evidence-grounded repository audit CLI: deterministic scanner, MCP server, live dashboard, and a GitHub Action that posts PR diffs.
5
+ Author-email: Arihant Kaul <arihantkaul@outlook.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/Aletheore/Aletheore
8
+ Project-URL: Repository, https://github.com/Aletheore/Aletheore
9
+ Project-URL: Issues, https://github.com/Aletheore/Aletheore/issues
10
+ Keywords: code-review,static-analysis,secrets-detection,dependency-vulnerabilities,mcp-server
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Classifier: Topic :: Security
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: tree-sitter<0.26,>=0.25
23
+ Requires-Dist: tree-sitter-python<0.26,>=0.25
24
+ Requires-Dist: tree-sitter-javascript<0.26,>=0.25
25
+ Requires-Dist: tree-sitter-typescript<0.24,>=0.23
26
+ Requires-Dist: tree-sitter-go<0.26,>=0.25
27
+ Requires-Dist: tree-sitter-rust<0.25,>=0.24
28
+ Requires-Dist: tree-sitter-java<0.24,>=0.23
29
+ Requires-Dist: tree-sitter-ruby<0.24,>=0.23
30
+ Requires-Dist: tree-sitter-php<0.25,>=0.24
31
+ Requires-Dist: tree-sitter-c<0.25,>=0.24
32
+ Requires-Dist: tree-sitter-cpp<0.24,>=0.23
33
+ Requires-Dist: tree-sitter-c-sharp<0.24,>=0.23
34
+ Requires-Dist: certifi>=2024.0.0
35
+ Requires-Dist: networkx<4.0,>=3.0
36
+ Requires-Dist: mcp<2.0,>=1.23
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest>=8.0; extra == "dev"
39
+ Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
40
+ Dynamic: license-file
41
+
42
+ <p align="center">
43
+ <img src="../assets/logo.png" alt="Aletheore" width="360">
44
+ </p>
45
+
46
+ # Aletheore Prototype
47
+
48
+ **Status:** Unratified prototype under VDP-0000-REQ-009 ("Prototypes and experiments MAY
49
+ precede specifications, but they MUST NOT become normative without the VDP process").
50
+
51
+ This directory is deliberately out-of-band from the constitutional apparatus in
52
+ `../constitution/`, `../GOVERNANCE.md`, `../VISION.md`, and `../ROADMAP.md`. It does not
53
+ modify, supersede, or depend on any of that. It is not a proposal and should not be treated as
54
+ one — it's just the actual, working tool.
55
+
56
+ ## What this is
57
+
58
+ A deterministic scanner (tree-sitter + git log, no LLM, fully unit-tested) reads a repository
59
+ and writes `.aletheore/evidence.json`: languages, module dependency graph, modularity-based
60
+ clusters, git ownership and commit cadence, secrets, dependency vulnerabilities, layer-
61
+ convention violations, dependency licenses, and static API endpoint maps. Every other feature
62
+ below is built on top of that same evidence and
63
+ never states anything it can't cite back to a specific field in it.
64
+
65
+ Secrets, git activity, and dependency-vulnerability checks are language-agnostic. The module
66
+ dependency graph (imports, clusters, layer violations) currently understands **Python,
67
+ JavaScript/JSX, TypeScript/TSX, Go, Rust, Java, Ruby, PHP, C, C++, and C#** — other languages
68
+ are still scanned for secrets/git/vulnerabilities, but get no dependency-graph or architecture
69
+ analysis until a grammar is added for them.
70
+
71
+ Go resolution needs a `go.mod` at the repo root to know the module's own import-path prefix;
72
+ without one, Go imports are left unresolved (same as any import Aletheore can't place) rather
73
+ than guessed at. An import is resolved to every non-test `.go` file in its target directory,
74
+ since Go imports whole packages, not individual files.
75
+
76
+ Rust resolution needs `src/lib.rs` or `src/main.rs` at the repo root (workspace repos with
77
+ multiple crates aren't supported yet); without one, nothing resolves. It assumes directory
78
+ structure mirrors the module tree (true for the vast majority of real code; `#[path = "..."]`
79
+ escape hatches aren't supported), and handles `crate::`/`self::`/`super::` paths, the implicit
80
+ crate-relative form (`use handlers::Handler;` from the crate root), grouped (`{Bar, Baz}`),
81
+ wildcard (`::*`), and aliased (`as`) forms.
82
+
83
+ Java resolution has no repo-root config to read at all (no go.mod/Cargo.toml equivalent) - the
84
+ source root (Maven/Gradle's `src/main/java`, a bare `src/`, or the repo root itself) is
85
+ inferred per-file from each file's own `package` declaration matching its actual directory,
86
+ so it works across layouts without assuming one. Handles direct imports, wildcard imports
87
+ (fanning out to every `.java` file in that package, same idea as Go's package-level imports),
88
+ and `import static` (resolving to the class, not the imported member).
89
+
90
+ Ruby's `require_relative` always resolves relative to the current file, unambiguous. Plain
91
+ `require` is genuinely ambiguous (the overwhelming majority are gems, external), so it only
92
+ resolves against a repo-root `lib/` directory - the near-universal Ruby convention for a
93
+ project's own internal requires - and is left unresolved otherwise, same as an unrecognized
94
+ import in any other language here.
95
+
96
+ PHP reads `composer.json`'s `autoload.psr-4` mapping (namespace prefix -> directory, longest
97
+ prefix wins when more than one could match) to resolve `use` statements; with no composer.json,
98
+ `use` doesn't resolve at all. `require`/`require_once`/`include`/`include_once` (including the
99
+ idiomatic `__DIR__ . '/../lib/util.php'` form) resolve relative to the current file, the same
100
+ as Ruby's `require_relative`.
101
+
102
+ C/C++ only resolves quoted `#include "foo.h"` (relative to the current file's own directory,
103
+ the only part of the real preprocessor search order knowable without a build system's `-I`
104
+ flags) - angle-bracket `#include <foo.h>` is always treated as external/system, never resolved,
105
+ since a project using `<>` for its own headers via `-I` isn't distinguishable from a real system
106
+ header without that same build info. `.h` is parsed with the C++ grammar (a superset that
107
+ parses valid C too) since header files are ambiguously C-or-C++.
108
+
109
+ C# resolves `using Namespace;` at namespace granularity, not class granularity - unlike every
110
+ other language here, a C# `using` doesn't name a specific type at all, only a namespace, so it's
111
+ resolved the same way Go's package-level import already is: fan out to every `.cs` file in the
112
+ directory that namespace corresponds to (namespace-mirrors-directory is only a convention here,
113
+ not compiler-enforced, so real misses are expected for code that doesn't follow it). Also
114
+ accounts for `<RootNamespace>` (set by every `dotnet new` template by default), which prepends
115
+ an implicit prefix to every file's effective namespace with no corresponding directory on disk
116
+ at all - verified directly against a real `dotnet build`/`dotnet run`, which is also what
117
+ surfaced this: a naive "namespace must fully mirror the directory" version (correct for Java,
118
+ which has no such feature) resolved nothing at all until this was accounted for.
119
+
120
+ ## Setup
121
+
122
+ Not yet on PyPI (the packaging and a tag-triggered publish workflow exist, but nothing has
123
+ been published - see `../.github/workflows/publish-pypi.yml`). Once it is:
124
+
125
+ ```bash
126
+ pipx install aletheore # or: pip install aletheore
127
+ ```
128
+
129
+ Until then, install from source:
130
+
131
+ ```bash
132
+ cd prototype
133
+ pip install -e ".[dev]"
134
+ pytest
135
+ ```
136
+
137
+ Requires Python 3.11+.
138
+
139
+ ## Configuration
140
+
141
+ A scanned repo can commit a `.aletheore.json` at its root to extend the architecture checks —
142
+ it's read as part of `scan`/`audit`, the same deterministic way `requirements.txt` or a policy
143
+ doc already is (repo-declared conventions are themselves a fact about the repo, so this
144
+ doesn't break reproducibility: same repo content in, same evidence out).
145
+
146
+ ```json
147
+ {
148
+ "layer_markers": { "biz": 1 },
149
+ "cluster_resolution": 1.5,
150
+ "accepted_secrets": [
151
+ { "path": "tests/fixtures/sample.py", "pattern": "aws_access_key_id", "match_preview": "AKIA****...MNOP" }
152
+ ]
153
+ }
154
+ ```
155
+
156
+ - `layer_markers` — extends/overrides the built-in folder-name -> layer-rank table used by
157
+ layer-violation detection (e.g. a repo using a `biz/` folder that isn't one of the built-in
158
+ names would otherwise never get `convention_detected: true`). Merges with the built-in table
159
+ for non-overlapping keys; only overlapping keys get overridden.
160
+ - `cluster_resolution` — passed straight into the modularity-clustering algorithm (default
161
+ `1.0`). Higher values favor more, smaller clusters; lower values favor fewer, larger ones.
162
+ - `accepted_secrets` — a baseline of reviewed, accepted secret findings (e.g. a genuinely
163
+ fake key in a test fixture that will always match a pattern). Every secrets scanner needs
164
+ this: without it, `--fail-on-new-secrets` has no escape hatch for a known false positive -
165
+ one review-and-accept, and it stops blocking CI, permanently, for that exact finding. Match
166
+ on the finding's exact `path`, `pattern`, and `match_preview` (copy these from a scan's
167
+ output or `aletheore query secrets <path>` - `match_preview` is already redacted, safe to
168
+ commit). Accepted findings are **not hidden** - they still appear in `evidence.json`,
169
+ `aletheore query secrets`, the dashboard, and the PR comment, each flagged
170
+ `"accepted": true`/labeled "accepted (in .aletheore.json baseline)" - only the fail-gates and
171
+ inline PR annotations skip them.
172
+
173
+ All three keys are optional and independently defaulted/empty if the file is missing,
174
+ malformed, or only sets some of them. `layer_markers`/`cluster_resolution` (or `null` if
175
+ there's no config file at all) are recorded verbatim in `evidence.json` at
176
+ `architecture.config_applied`, so a report can cite exactly what convention was in effect for
177
+ that scan.
178
+
179
+ ## Commands
180
+
181
+ ### `aletheore scan [path]`
182
+
183
+ Runs only the deterministic scan phase. Writes `.aletheore/evidence.json` and a rolling history
184
+ snapshot under `.aletheore/history/`. No LLM call — safe to run repeatedly, in CI, or from a
185
+ script.
186
+
187
+ ```bash
188
+ aletheore scan .
189
+ aletheore scan . --no-check-vulnerabilities # skip the OSV.dev dependency check
190
+ aletheore scan . --no-scan-git-history # skip walking git history for secrets
191
+ aletheore scan . --no-check-licenses # skip the dependency-license check
192
+ aletheore scan . --no-map-endpoints # skip static API endpoint mapping
193
+ ```
194
+
195
+ The license check reads each pinned PyPI/npm dependency's registry metadata (PyPI's `license`
196
+ field falling back to its OSI classifiers; npm's `license` field) and categorizes it as
197
+ `permissive`, `copyleft-weak` (LGPL, MPL, EPL), `copyleft-strong` (GPL, AGPL), or `unknown` —
198
+ only non-permissive dependencies show up as findings, the same way OSV vulnerability checking
199
+ only reports actual vulnerabilities, not every clean dependency. It also detects the repo's own
200
+ declared license (`pyproject.toml`'s `license` field, `package.json`'s `license` field, or
201
+ pattern-matching a `LICENSE` file's text) so a report can flag a copyleft dependency alongside
202
+ what license the repo itself claims to be under - a factual categorization, not a legal
203
+ compatibility verdict, which is genuinely subjective and outside what a deterministic scanner
204
+ should claim.
205
+
206
+ Static API endpoint mapping records `repository.api_endpoints` for Flask, FastAPI-style
207
+ decorators, Django `urlpatterns`, Express route calls, Go (`net/http`/`gorilla/mux` and Gin),
208
+ Rust (Axum), Java (Spring Boot), Ruby (Rails), PHP (Laravel), and C# (both attribute-routed
209
+ Controllers and Minimal API). It is intentionally source-derived: literal route declarations
210
+ are recorded with method, path, framework, file, line, handler, whether the entry is an
211
+ unresolved include/mount-style indirection, and an optional `note` for known same-file prefixes
212
+ that are present but deliberately not composed into the recorded path.
213
+
214
+ ### `aletheore audit [path]`
215
+
216
+ Runs a scan, then shells out to an installed coding-agent CLI (Claude Code today, via
217
+ `--agent` to force a specific one) to write a full grounded report to
218
+ `.aletheore/audit-report.md`, following the per-section instructions in `manual/` (repository
219
+ intelligence, git intelligence, architecture, security, AI-usage detection, audience
220
+ perspectives, roadmap synthesis) and citing exact evidence fields throughout.
221
+
222
+ This is a genuinely different kind of operation from everything else in this list: it spawns
223
+ a full second agent CLI process (up to a 10-minute timeout) to produce prose, rather than
224
+ answering a fast, deterministic query. It's meant to be run by hand, when you actually want a
225
+ written document — it is not wired into CI or the MCP server, and shouldn't be: a CI gate
226
+ needs to be fast and pass/fail on concrete facts, and an agent already driving an MCP session
227
+ can reason over the evidence itself without spawning a nested agent process.
228
+
229
+ ```bash
230
+ aletheore audit .
231
+ aletheore audit . --agent claude
232
+ ```
233
+
234
+ ### `aletheore query <kind> [target]`
235
+
236
+ Answers one targeted question from an existing `evidence.json`, without re-scanning or an LLM
237
+ call.
238
+
239
+ ```bash
240
+ aletheore query imports app/routes.py --path .
241
+ aletheore query imported-by app/routes.py --path .
242
+ aletheore query symbols app/routes.py --path .
243
+ aletheore query branch main --path .
244
+ aletheore query ownership --path .
245
+ aletheore query secrets app/routes.py --path . # findings within just that file
246
+ aletheore query vulnerabilities --path .
247
+ aletheore query licenses --path .
248
+ aletheore query endpoints --path .
249
+ aletheore query cluster app/routes.py --path .
250
+ aletheore query layer-violations --path .
251
+ aletheore query changes --path . # diff against the previous history snapshot
252
+ ```
253
+
254
+ ### `aletheore diff <old.json> <new.json>`
255
+
256
+ Compares two `evidence.json` files directly — new/resolved secrets, API endpoints, layer
257
+ violations, dependency vulnerabilities, architecture deltas. Powers the GitHub Action below.
258
+
259
+ ```bash
260
+ aletheore diff old/evidence.json new/evidence.json
261
+ aletheore diff old/evidence.json new/evidence.json --fail-on-new-secrets
262
+ aletheore diff old/evidence.json new/evidence.json --fail-on-new-vulnerabilities
263
+ aletheore diff old/evidence.json new/evidence.json --fail-on-new-layer-violations
264
+ ```
265
+
266
+ All three `--fail-on-new-*` flags can be combined; the command exits 1 if any of them find
267
+ something new.
268
+
269
+ ### `aletheore healthcheck [path] --base-url <url>`
270
+
271
+ Runs a GET-only live check of mapped API endpoints against a running app instance. This reads
272
+ `repository.api_endpoints` from evidence, substitutes placeholder values for path parameters
273
+ such as `<int:id>`, `{id}`, and `:id`, skips non-GET endpoints without calling them, and writes
274
+ a rotated result file under `.aletheore/healthchecks/`.
275
+
276
+ This command depends on live runtime state, so it is deliberately **not** part of deterministic
277
+ scan evidence or `aletheore diff`.
278
+
279
+ ```bash
280
+ aletheore healthcheck . --base-url http://127.0.0.1:5000
281
+ ```
282
+
283
+ ### `aletheore mcp [path]`
284
+
285
+ Starts a stdio MCP server scoped to one repository, so a coding agent can query its structure
286
+ directly instead of shelling out via Bash or re-reading files on every lookup. Exposes 16
287
+ tools:
288
+
289
+ - The 11 query kinds above as tools (`aletheore_imports`, `aletheore_imported_by`,
290
+ `aletheore_symbols`, `aletheore_branch`, `aletheore_ownership`, `aletheore_secrets`,
291
+ `aletheore_vulnerabilities`, `aletheore_licenses`, `aletheore_endpoints`, `aletheore_cluster`,
292
+ `aletheore_layer_violations`), plus `aletheore_changes`.
293
+ - `aletheore_neighborhood(target)` — a module's imports, dependents, and cluster in one call,
294
+ instead of three round-trips.
295
+ - `aletheore_search(pattern, regex=False, path_glob=None)` — literal or regex full-text search
296
+ over tracked source files, capped at 200 matches.
297
+ - `aletheore_scan()` — triggers a fresh deterministic scan and returns a compact summary (not
298
+ the full evidence dump). Does **not** run the agent-driven `audit` report — see the note
299
+ under `aletheore audit` above for why that's a deliberate boundary, not a gap.
300
+ - `aletheore_healthcheck(base_url)` — runs the same GET-only live health check as the CLI and
301
+ persists the result under `.aletheore/healthchecks/`.
302
+
303
+ ```bash
304
+ aletheore mcp .
305
+ ```
306
+
307
+ ### `aletheore dashboard [path]`
308
+
309
+ A live local web UI (Starlette + SSE, opens in your browser): repo overview, git activity,
310
+ trend charts for module/secrets/vulnerability counts across scan history, an interactive
311
+ dependency graph, a separate community-aware "clusters" graph with zoom/pan, and the list of
312
+ MCP tools available for the repo.
313
+
314
+ ```bash
315
+ aletheore dashboard . --port 8420
316
+ ```
317
+
318
+ ## GitHub Action
319
+
320
+ `../action.yml` ("Aletheore" on the Marketplace) is a composite Action that scans a PR's
321
+ base and head refs and reports the diff three ways:
322
+
323
+ - **A PR comment** — new/resolved secrets, new/resolved secrets found in git history,
324
+ new/resolved dependency vulnerabilities, new/resolved layer-convention violations, and
325
+ aggregate deltas (module count, dependency-graph edge count, commit count). Updates the same
326
+ comment on subsequent pushes instead of spamming new ones.
327
+ - **Inline annotations** on new secrets specifically — shown directly on the changed line in
328
+ the PR's "Files changed" tab. Scoped to current-tree secrets only, since that's the only
329
+ finding type with both a real file path and a real line number: history-secret findings
330
+ point at an old commit with no line in the current tree, vulnerabilities are package-level,
331
+ and layer violations are file-level (a "from" file imports a "to" file) — none of those have
332
+ a specific line to honestly point at, so they stay in the PR comment rather than getting a
333
+ fabricated line number.
334
+ - **The run's Step Summary** — the same content as the PR comment, written on every run
335
+ regardless of event type, so a plain push (no PR to comment on) still shows something.
336
+
337
+ A secret accepted via `.aletheore.json`'s `accepted_secrets` (see Configuration above) is
338
+ labeled, not omitted, in the comment and Step Summary, and is excluded from inline annotations
339
+ and every `--fail-on-new-*` gate.
340
+
341
+ It only ever calls `aletheore scan` and `aletheore diff`, matching the reasoning above: CI needs
342
+ something fast and deterministic, not a full agent-driven audit.
343
+
344
+ ```yaml
345
+ - uses: Aletheore/Aletheore@master # pin to a tagged release once one exists past 0.1.0
346
+ with:
347
+ fail-on-new-secrets: true # exit 1 if a new real (non-placeholder) secret appears
348
+ fail-on-new-vulnerabilities: true # exit 1 if a new dependency vulnerability appears
349
+ fail-on-new-layer-violations: true # exit 1 if a new layer-convention violation appears
350
+ ```
351
+
352
+ Posting the PR comment needs `permissions: pull-requests: write` (and `issues: write`, since
353
+ PR comments use the Issues API) on the calling workflow's job — set `post-pr-comment: false`
354
+ to skip just that part and still get annotations, the step summary, and the `diff-json`
355
+ output.
356
+
357
+ ## Continuity
358
+
359
+ Every `scan` (and `audit`, which scans first) saves a timestamped snapshot to
360
+ `.aletheore/history/` (last 20 kept). `aletheore query changes` / `aletheore_changes` diff the
361
+ two most recent snapshots, and the dashboard's trend charts read the full history.