diagit 0.9.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.
- diagit-0.9.0/LICENSE +201 -0
- diagit-0.9.0/MANIFEST.in +5 -0
- diagit-0.9.0/PKG-INFO +275 -0
- diagit-0.9.0/README.md +247 -0
- diagit-0.9.0/proto/diagit/v1/audit.proto +288 -0
- diagit-0.9.0/pyproject.toml +87 -0
- diagit-0.9.0/setup.cfg +4 -0
- diagit-0.9.0/src/diagit/__init__.py +3 -0
- diagit-0.9.0/src/diagit/__main__.py +3 -0
- diagit-0.9.0/src/diagit/application/__init__.py +1 -0
- diagit-0.9.0/src/diagit/application/control_service.py +529 -0
- diagit-0.9.0/src/diagit/application/forge_service.py +140 -0
- diagit-0.9.0/src/diagit/application/service.py +123 -0
- diagit-0.9.0/src/diagit/aql/diagit-github-governance.pl.aql +26 -0
- diagit-0.9.0/src/diagit/aql/diagit-repair-delegation.pl.aql +26 -0
- diagit-0.9.0/src/diagit/cli.py +311 -0
- diagit-0.9.0/src/diagit/control_dsl.py +497 -0
- diagit-0.9.0/src/diagit/diagnostics.py +98 -0
- diagit-0.9.0/src/diagit/diagnostics.v1.json +24 -0
- diagit-0.9.0/src/diagit/diagnostics.v2.json +42 -0
- diagit-0.9.0/src/diagit/domain.py +96 -0
- diagit-0.9.0/src/diagit/infrastructure/__init__.py +1 -0
- diagit-0.9.0/src/diagit/infrastructure/event_store.py +92 -0
- diagit-0.9.0/src/diagit/infrastructure/git_probe.py +266 -0
- diagit-0.9.0/src/diagit/infrastructure/github.py +612 -0
- diagit-0.9.0/src/diagit/infrastructure/onedev_control.py +121 -0
- diagit-0.9.0/src/diagit/infrastructure/projection.py +425 -0
- diagit-0.9.0/src/diagit/infrastructure/release_probe.py +266 -0
- diagit-0.9.0/src/diagit/messages.py +81 -0
- diagit-0.9.0/src/diagit/operator.py +222 -0
- diagit-0.9.0/src/diagit/py.typed +1 -0
- diagit-0.9.0/src/diagit/schemas/__init__.py +1 -0
- diagit-0.9.0/src/diagit/schemas/authority-grant.v1.schema.json +35 -0
- diagit-0.9.0/src/diagit/schemas/control-plan.v1.schema.json +130 -0
- diagit-0.9.0/src/diagit/schemas/diagnostic-registry.v1.schema.json +31 -0
- diagit-0.9.0/src/diagit/schemas/diagnostic-registry.v2.schema.json +31 -0
- diagit-0.9.0/src/diagit/schemas/repair-plan-set.v1.schema.json +31 -0
- diagit-0.9.0/src/diagit/uri.py +79 -0
- diagit-0.9.0/src/diagit/v1/__init__.py +1 -0
- diagit-0.9.0/src/diagit/v1/audit_pb2.py +113 -0
- diagit-0.9.0/src/diagit/v1/audit_pb2.pyi +535 -0
- diagit-0.9.0/src/diagit.egg-info/PKG-INFO +275 -0
- diagit-0.9.0/src/diagit.egg-info/SOURCES.txt +57 -0
- diagit-0.9.0/src/diagit.egg-info/dependency_links.txt +1 -0
- diagit-0.9.0/src/diagit.egg-info/entry_points.txt +3 -0
- diagit-0.9.0/src/diagit.egg-info/requires.txt +8 -0
- diagit-0.9.0/src/diagit.egg-info/top_level.txt +1 -0
- diagit-0.9.0/tests/test_control_dsl.py +175 -0
- diagit-0.9.0/tests/test_diagnostics.py +52 -0
- diagit-0.9.0/tests/test_event_store.py +34 -0
- diagit-0.9.0/tests/test_forge_twin.py +52 -0
- diagit-0.9.0/tests/test_git_probe.py +122 -0
- diagit-0.9.0/tests/test_onedev_control.py +46 -0
- diagit-0.9.0/tests/test_operator.py +50 -0
- diagit-0.9.0/tests/test_projection_migration.py +29 -0
- diagit-0.9.0/tests/test_release_probe.py +134 -0
- diagit-0.9.0/tests/test_remote_control.py +608 -0
- diagit-0.9.0/tests/test_service.py +45 -0
- diagit-0.9.0/tests/test_uri.py +54 -0
diagit-0.9.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
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.
|
diagit-0.9.0/MANIFEST.in
ADDED
diagit-0.9.0/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: diagit
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: Git fleet diagnostics and AQL-governed control plans with CQRS, event sourcing, protobuf, and URI processes.
|
|
5
|
+
Author: Tom Sapletta
|
|
6
|
+
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
Keywords: git,audit,cqrs,event-sourcing,protobuf
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Operating System :: POSIX
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: protobuf<7,>=6.33.5
|
|
21
|
+
Requires-Dist: subactor-credential-vault<0.3,>=0.2.1
|
|
22
|
+
Provides-Extra: test
|
|
23
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
24
|
+
Requires-Dist: ruff>=0.12; extra == "test"
|
|
25
|
+
Requires-Dist: mypy>=1.11; extra == "test"
|
|
26
|
+
Requires-Dist: grpcio-tools>=1.66; extra == "test"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# diagit
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## AI Cost Tracking
|
|
33
|
+
|
|
34
|
+
   
|
|
35
|
+
  
|
|
36
|
+
|
|
37
|
+
- 🤖 **LLM usage:** $0.4500 (3 commits)
|
|
38
|
+
- 👤 **Human dev:** ~$100 (1.0h @ $100/h, 30min dedup)
|
|
39
|
+
|
|
40
|
+
Generated on 2026-08-08 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
`diagit` is a read-only-by-default auditor for a fleet of Git repositories laid out as
|
|
47
|
+
`ROOT/owner/repository`, for example `/home/tom/github/*/*`.
|
|
48
|
+
|
|
49
|
+
It records immutable protobuf events, builds a disposable SQLite CQRS read
|
|
50
|
+
model, and exposes a small allowlisted `diagit://` process URI catalog. It
|
|
51
|
+
never fetches, checks out, commits, pushes, or repairs a repository during an
|
|
52
|
+
audit. Separate control plans require a digest-bound authority grant and
|
|
53
|
+
independent read-back validation.
|
|
54
|
+
|
|
55
|
+
## Install and run
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
python -m pip install -e '.[test]'
|
|
59
|
+
diagit audit --root ~/github
|
|
60
|
+
diagit audit --root ~/github --organization subactor \
|
|
61
|
+
--repository 'subactor/*-agent' --exclude-repository 'subactor/*-worktree'
|
|
62
|
+
diagit query summary
|
|
63
|
+
diagit query findings --severity SEVERITY_CRITICAL
|
|
64
|
+
diagit query repo subactor/core
|
|
65
|
+
diagit diagnostics list
|
|
66
|
+
diagit diagnostics show DIRTY_WORKTREE
|
|
67
|
+
diagit uri 'diagit://fleet/query/summary'
|
|
68
|
+
diagit remote audit --organization subactor
|
|
69
|
+
diagit remote summary --organization subactor
|
|
70
|
+
diagit plan governance --organization subactor --output governance.json
|
|
71
|
+
diagit plan repairs --organization subactor --output-dir repair-plans
|
|
72
|
+
diagit plan fleet-repairs --organization subactor \
|
|
73
|
+
--repository 'subactor/*-agent' \
|
|
74
|
+
--exclude-repository 'subactor/*-worktree' \
|
|
75
|
+
--code OPENROUTER_APP_IDENTITY_MISSING --output-dir openrouter-repairs
|
|
76
|
+
diagit plan governance --organization legacy-org \
|
|
77
|
+
--rename-default-to-main --archive-unmerged --output governance.json
|
|
78
|
+
diagit onedev status \
|
|
79
|
+
--onedev-password-file /path/to/onedev-admin-password
|
|
80
|
+
diagit forge audit --max-items 1000
|
|
81
|
+
diagit forge recommend --require actions --require projects \
|
|
82
|
+
--visibility private --prefer-self-managed
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The default state directory is `$XDG_STATE_HOME/diagit`, or
|
|
86
|
+
`~/.local/state/diagit`. Override it with `--state-dir` or
|
|
87
|
+
`DIAGIT_STATE_DIR`.
|
|
88
|
+
|
|
89
|
+
## Operator service
|
|
90
|
+
|
|
91
|
+
Running `diagit` without a subcommand starts the operator service. From
|
|
92
|
+
`~/github` it discovers every organization that contains Git worktrees. From
|
|
93
|
+
`~/github/<organization>` or any repository below it, it limits the initial
|
|
94
|
+
scope to that organization. The initial local audit starts immediately and
|
|
95
|
+
reports progress for every completed repository.
|
|
96
|
+
|
|
97
|
+
In a terminal, the service remains active and accepts single-key shortcuts
|
|
98
|
+
without Enter:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
a repeat the local audit
|
|
102
|
+
r audit selected GitHub organizations and compile repair planfiles
|
|
103
|
+
d explicitly approve and delegate the prepared plans to OneDev
|
|
104
|
+
s select one organization or the complete detected scope
|
|
105
|
+
q exit cleanly
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Delegation requires an additional `y` confirmation. Diagit then creates a
|
|
109
|
+
mode-0600, ten-minute authority grant for each exact plan digest and submits
|
|
110
|
+
only `CONTROL_ACTION_SUBMIT_REPAIR`; Doctor/Repair/Validator evidence remains
|
|
111
|
+
mandatory. When stdin is not a TTY, the same bare invocation performs one
|
|
112
|
+
bounded local audit, prints progress, and exits instead of waiting for input.
|
|
113
|
+
|
|
114
|
+
## Diagnostic registry
|
|
115
|
+
|
|
116
|
+
Every finding keeps its concise compatibility code, such as
|
|
117
|
+
`DIRTY_WORKTREE`, and is enriched from the packaged
|
|
118
|
+
`diagit.diagnostic-registry/v2` catalog with a stable identifier such as
|
|
119
|
+
`DIAGIT-GIT-003`, category, severity, error class, retryability, and an optional
|
|
120
|
+
repair URI. The registry is the source of truth: emitting an unknown code or a
|
|
121
|
+
severity/message that differs from its definition fails closed.
|
|
122
|
+
|
|
123
|
+
The four severities have consistent operational meaning: `INFO` records useful
|
|
124
|
+
state, `WARNING` requires planned attention, `ERROR` blocks the requested
|
|
125
|
+
invariant, and `CRITICAL` means the audit or control boundary itself is not
|
|
126
|
+
trustworthy or available.
|
|
127
|
+
|
|
128
|
+
Remote pull requests are classified independently of the generic
|
|
129
|
+
`OPEN_PULL_REQUEST` finding. The registry distinguishes green mergeable PRs,
|
|
130
|
+
failed, pending or missing checks, merge conflicts, unknown mergeability, and
|
|
131
|
+
drafts stale for at least 30 days. A green unmerged PR is always emitted as
|
|
132
|
+
`PR_GREEN_REQUIRES_MERGE` and cannot be archived by the governance cleanup
|
|
133
|
+
policy.
|
|
134
|
+
|
|
135
|
+
## Architecture
|
|
136
|
+
|
|
137
|
+
- Commands change only the auditor's own state. `AuditFleet` observes Git
|
|
138
|
+
repositories and appends `AuditRunStarted`, `RepositoryAudited`, and
|
|
139
|
+
`AuditRunCompleted` protobuf events.
|
|
140
|
+
- The length-delimited `events.pb` file is the canonical event store.
|
|
141
|
+
- Queries read a rebuildable SQLite projection (`projection.sqlite3`).
|
|
142
|
+
- Forge account observations from GitHub, GitLab, Gitea/Forgejo, and Bitbucket
|
|
143
|
+
are stored as `ForgeAccountTwinObserved` protobuf events. Their read model
|
|
144
|
+
ranks providers from visible scopes, repositories, capabilities, visibility,
|
|
145
|
+
completeness, and self-managed preference; it never reads repository content.
|
|
146
|
+
The canonical contract and reviewed decision baseline are pinned to
|
|
147
|
+
[`uri-twin/uri-twin-forge`](https://github.com/uri-twin/uri-twin-forge);
|
|
148
|
+
Diagit returns that source revision with each audit and recommendation.
|
|
149
|
+
- `diagit rebuild` recreates the projection solely from stored events.
|
|
150
|
+
- URI processes are explicit adapters to the same command/query handlers; an
|
|
151
|
+
arbitrary URI can never become a shell command.
|
|
152
|
+
|
|
153
|
+
Supported URI processes:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
diagit://fleet/audit?root=/home/tom/github
|
|
157
|
+
diagit://fleet/query/summary
|
|
158
|
+
diagit://fleet/query/findings?severity=SEVERITY_WARNING&limit=100
|
|
159
|
+
diagit://repository/<owner>/<repo>/query/report
|
|
160
|
+
diagit://projection/rebuild
|
|
161
|
+
diagit://github/<organization>/audit
|
|
162
|
+
diagit://github/<organization>/query/summary
|
|
163
|
+
diagit://forge/audit?providers=github,gitlab,gitea,bitbucket&max_items=1000
|
|
164
|
+
diagit://forge/query/recommend?requires=actions,projects&visibility=private&prefer_self_managed=true
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Governed control plans
|
|
168
|
+
|
|
169
|
+
Remote audit observations can be compiled into the versioned
|
|
170
|
+
`diagit.control-plan/v1` JSON DSL. Every executable plan embeds a
|
|
171
|
+
`subactor.process-envelope.v2` with all four governed definitions: AQL authority,
|
|
172
|
+
transport-independent OQL operations, exact URI processes, and EQL expectations.
|
|
173
|
+
A governance plan closes an open pull request or deletes an extra branch only
|
|
174
|
+
when the branch head is already contained in `main`. By default, unmerged
|
|
175
|
+
branches remain blockers. The explicit `--archive-unmerged` policy first creates
|
|
176
|
+
and independently validates a deterministic `diagit/archive/<branch>-<sha>` tag,
|
|
177
|
+
then permits branch deletion and PR closure through dependent URI steps.
|
|
178
|
+
`--rename-default-to-main` safely migrates a default branch only when `main`
|
|
179
|
+
does not already exist and the observed head SHA still matches.
|
|
180
|
+
|
|
181
|
+
Applying a plan requires a separate mode-0600 `diagit.authority-grant/v1` file.
|
|
182
|
+
The grant must name the organization and allowed action kinds, bind the exact
|
|
183
|
+
plan SHA-256 digest, identify its approver, and have a future expiry. Execution
|
|
184
|
+
is explicit:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
diagit apply governance.json \
|
|
188
|
+
--authority-file authority.json \
|
|
189
|
+
--confirm-apply
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
An archived branch can be restored through a separately authorized plan:
|
|
193
|
+
|
|
194
|
+
```sh
|
|
195
|
+
diagit plan restore --repository owner/repository --branch fix/recover \
|
|
196
|
+
--tag diagit/archive/fix/recover-0123456789ab \
|
|
197
|
+
--expected-head 0123456789abcdef0123456789abcdef01234567 \
|
|
198
|
+
--output restore.json
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
For code repair, generate a single OneDev handoff action. The instruction is
|
|
202
|
+
data, never a command:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
diagit plan repair \
|
|
206
|
+
--repository subactor/core \
|
|
207
|
+
--task-id 0004_node-domain-tickets \
|
|
208
|
+
--instruction-file repair-instruction.txt \
|
|
209
|
+
--output repair.json
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Before applying an action, Diagit fails closed unless its AQL actor explicitly
|
|
213
|
+
allows the matching OQL operation and the action is bound to exactly one URI
|
|
214
|
+
step. After an authorized apply, Diagit sends the complete envelope, canonical
|
|
215
|
+
plan digest, grant ID, and approving principal to the existing OneDev Agent
|
|
216
|
+
`/tasks/execute` boundary. OneDev independently repeats the AQL/OQL/URI/EQL
|
|
217
|
+
checks before materializing a Planfile ticket. OneDev then owns Doctor → Repair
|
|
218
|
+
→ Validator, test gates, exact-SHA checks, and publication. A submission receipt
|
|
219
|
+
remains `submitted`; only validator evidence can satisfy the terminal EQL.
|
|
220
|
+
The referenced `diagit-repair-delegation.pl.aql` decision model is packaged with
|
|
221
|
+
the wheel, so the envelope never relies on an unresolved model name.
|
|
222
|
+
|
|
223
|
+
`diagit plan repairs` compiles the latest remote audit into one independently
|
|
224
|
+
authorizable plan per affected repository plus a
|
|
225
|
+
`diagit.repair-plan-set/v1` manifest. It selects only diagnostics whose
|
|
226
|
+
registered repair URI delegates to OneDev, deduplicates them into a bounded
|
|
227
|
+
instruction, and preserves the source audit run ID. `--code` can be repeated
|
|
228
|
+
to restrict generation to specific delegable diagnostic codes. Generating the
|
|
229
|
+
set never submits work; each plan still requires its own digest-bound authority
|
|
230
|
+
grant before `diagit apply` can cross the OneDev boundary.
|
|
231
|
+
|
|
232
|
+
`diagit audit` accepts repeatable exact or glob repository selectors. The
|
|
233
|
+
`fleet-repairs` variant compiles local findings from the latest completed audit,
|
|
234
|
+
so one diagnostic becomes an independently authorized OneDev ticket for each
|
|
235
|
+
selected repository rather than one unbounded fleet mutation.
|
|
236
|
+
|
|
237
|
+
## OpenRouter application attribution
|
|
238
|
+
|
|
239
|
+
`DIAGIT-LLM-001 / OPENROUTER_APP_IDENTITY_MISSING` identifies tracked runtime
|
|
240
|
+
consumers of OpenRouter that do not provide verifiable cost attribution. A
|
|
241
|
+
compliant repair declares `OPENROUTER_APP_NAME` and `OPENROUTER_APP_URL` in the
|
|
242
|
+
environment template and binds them to `X-OpenRouter-Title` and `HTTP-Referer`.
|
|
243
|
+
When the name is blank, runtime code must use the repository directory name.
|
|
244
|
+
Diagit reads only variable names and bounded tracked source files; finding
|
|
245
|
+
evidence never contains environment values or API keys.
|
|
246
|
+
|
|
247
|
+
The audit uses only local Git metadata. Ahead/behind values therefore describe
|
|
248
|
+
the locally known upstream refs and do not imply a network refresh.
|
|
249
|
+
|
|
250
|
+
## Release readiness
|
|
251
|
+
|
|
252
|
+
`diagit audit --root ~/github --organization subactor --check-registries` adds bounded
|
|
253
|
+
release checks to the normal event-sourced fleet audit. Local checks validate `goal.yaml`,
|
|
254
|
+
package file boundaries, and version tags. Registry checks compare public `package.json`
|
|
255
|
+
and `pyproject.toml` manifests with npm and PyPI; Node packages with `private: true` are
|
|
256
|
+
never treated as publication candidates.
|
|
257
|
+
|
|
258
|
+
The command is read-only: it reports unpublished packages and version drift but never
|
|
259
|
+
publishes, tags, or pushes. Registry access is opt-in because it requires network I/O.
|
|
260
|
+
|
|
261
|
+
## Development
|
|
262
|
+
|
|
263
|
+
```sh
|
|
264
|
+
python -m grpc_tools.protoc -Iproto --python_out=src --pyi_out=src proto/diagit/v1/audit.proto
|
|
265
|
+
scripts/verify
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The package distribution name is `diagit`, its Python import is
|
|
269
|
+
`diagit`, and its executable is `diagit` (which also permits the Git
|
|
270
|
+
external-command form `git diagit`).
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
Licensed under Apache-2.0.
|