diagit
AI Cost Tracking
- 🤖 LLM usage: $0.4305 (15 commits)
- 👤 Human dev: ~$727 (7.3h @ $100/h, 30min dedup)
Generated on 2026-08-10 using openrouter/qwen/qwen3-coder-next
diagit is a read-only-by-default auditor for a fleet of Git repositories laid out as
ROOT/owner/repository, for example /home/tom/github/*/*.
It records immutable protobuf events, builds a disposable SQLite CQRS read
model, and exposes a small allowlisted diagit:// process URI catalog. It
never fetches, checks out, commits, pushes, or repairs a repository during an
audit. Separate control plans require a digest-bound authority grant and
independent read-back validation.
Install and run
python -m pip install -e '.[test]'
diagit audit --root ~/github
diagit audit --root ~/github --inventory subactor-repositories.v1.json
diagit audit --root ~/github --organization subactor \
--repository 'subactor/*-agent' --exclude-repository 'subactor/*-worktree'
diagit audit --root ~/github/semcod --repository todo2code
diagit audit --root ~/github/semcod --layout organization
diagit query summary
diagit query findings --severity SEVERITY_CRITICAL
diagit priority readings --document /path/to/organization.v1.json
diagit query repo subactor/core
diagit diagnostics list
diagit diagnostics show DIRTY_WORKTREE
diagit uri 'diagit://fleet/query/summary'
diagit remote audit --organization subactor \
--inventory subactor-repositories.v1.json
# Worktree set of a repository: overlap, leftovers, dead registrations
diagit query findings --severity SEVERITY_ERROR
diagit plan worktrees --output-dir ./plans --advisory
diagit apply ./plans/<plan>.json --authority-file ./grant.json --confirm-apply
diagit remote summary --organization subactor
diagit remote findings --organization subactor --severity SEVERITY_ERROR
diagit uri 'diagit://github/subactor/query/findings?code=PR_CHECKS_FAILED'
diagit plan governance --organization subactor --output governance.json
diagit plan repairs --organization subactor --output-dir repair-plans
diagit plan fleet-repairs --organization subactor \
--repository 'subactor/*-agent' \
--exclude-repository 'subactor/*-worktree' \
--code OPENROUTER_APP_IDENTITY_MISSING --output-dir openrouter-repairs
diagit watch --source local --root ~/github --layout fleet \
--organization subactor --organization wellmanifest \
--interval-seconds 30 --max-cycles 0 --output-dir watch-plans
diagit watch --source github --organization subactor \
--interval-seconds 60 --max-cycles 1 --output-dir remote-watch-plans
diagit plan governance --organization legacy-org \
--rename-default-to-main --archive-unmerged --output governance.json
diagit onedev status \
--onedev-password-file /path/to/onedev-admin-password
diagit onedev monitor \
--onedev-password-file /path/to/onedev-admin-password
diagit forge audit --max-items 1000
diagit forge recommend --require actions --require projects \
--visibility private --prefer-self-managed
diagit grammar
diagit dsl --expression '```diagitdsl
QUERY SUMMARY
```'
diagit shell
diagit serve --root ~/github --bind 127.0.0.1 --port 8765
The default state directory is $XDG_STATE_HOME/diagit, or
~/.local/state/diagit. Override it with --state-dir or
DIAGIT_STATE_DIR.
An audit root may be the fleet directory (ROOT/owner/repository) or one
organization directory (ROOT/repository). Repository selectors containing /
match the canonical owner/repository ID; selectors without / match the bare
repository name. Both forms accept shell-style globs.
--layout auto is the default. Use --layout fleet or --layout organization
when a root contains both direct worktrees and organization directories. A
selected candidate whose Git marker cannot be read remains visible as a typed
PROBE_FAILED result instead of disappearing from audit coverage.
A fleet root also includes one extra grouping level under a recognized
directory name (projekty, projects, repos, or repositories), for
example ROOT/owner/projekty/repository, when that directory is not itself a
Git worktree. The repository identity stays owner/repository, matching the
GitHub remote, so control plans and OneDev handoff keep a two-segment ID.
--layout organization still means only direct worktrees of that root.
Fleet audits normalize common HTTPS, SSH, and SCP-like origin URLs and add
two cross-repository layout findings:
| Code | Meaning |
|---|---|
REMOTE_PATH_MISMATCH |
The owner/repository from origin differs from the canonical local path. |
DUPLICATE_REMOTE_CHECKOUT |
Multiple independent local checkouts reference the same normalized origin. |
Registered linked worktrees are collapsed by their common Git directory and do not produce either finding merely because their checkout path differs.
diagit watch is the bounded near-real-time mode. It repeats a local or GitHub
audit, writes one cycle directory, and prepares only repair plans backed by
registered delegable diagnostics. --max-cycles 0 runs until interrupted;
the default is one cycle so automation must opt in to a long-lived process.
Stable findings whose plan was already submitted or validated are reported as
deduplicated and are not delegated again. Watch never invents an authority
grant or mutates a repository: an operator or authority service must still run
diagit apply for the exact plan digest. That handoff invokes the existing
OneDev Doctor → Repair → Validator lifecycle.
A desired repository inventory uses diagit.desired-repository-inventory/v1,
has an explicit semantic version and content digest, and declares whether its
coverage is selected or complete. Selected coverage can report required
missing repositories without claiming that every other repository is unmanaged;
only complete coverage emits UNMANAGED_REPOSITORY. Remote reconciliation also
distinguishes archived-but-required and policy-divergent repositories.
Repair planning adopts the exact merged skills-agent catalog, routing policy,
priority profile and executable-task bindings. Every delegable finding must map
to one registered operation, governed skill and ready OneDev task. Bootstrap
is a separate repository:bootstrap plan with absent base, explicitly declared
private visibility, a single-use external grant, and ordered mirror registration,
profile validation/application and clean re-audit follow-ups. Diagit never infers
public visibility or a destructive action.
diagit onedev monitor keeps a submitted plan pending until OneDev exposes a
terminal receipt bound to the exact plan digest, independent Validator identity
and exact head, satisfied EQL read-back, and secret-free evidence. A merely
closed ticket or stage=done is not accepted as success.
Git stash storage is shared by linked worktrees. A fleet audit groups worktrees
by their common Git directory and emits one STASHED_CHANGES warning on the
primary, or otherwise deterministic representative, worktree.
Worktree set
git_probe observes one checkout. worktree_probe observes the set of
checkouts a repository owns, which is where a whole class of damage lives.
| Code | Meaning |
|---|---|
WORKTREE_OVERLAP |
Two writer checkouts whose heads git cannot merge. |
WORKTREE_SCOPE_OVERLAP |
Active tickets in sibling worktrees claim overlapping paths without conflictsWith. |
WORKTREE_STALE_REGISTRATION |
A registration whose checkout directory is gone. |
WORKTREE_LEFTOVER |
A linked worktree already merged and clean. |
ORPHAN_LOCAL_BRANCH |
Local branches already contained in the default branch. |
Overlap is decided by git merge-tree --write-tree, not by path intersection:
two branches usually edit different regions of a file and merge cleanly, and a
branch stacked on another shares every path with its own ancestor. A checkout
already contained in the default branch with a clean tree is a leftover, not a
writer, and is never paired.
Only WORKTREE_STALE_REGISTRATION is repairable, because it is the one class
where the effect cannot destroy work — the checkout is already gone. The repair
is a control plan like any other: the pruneable set is pinned into the plan,
execution refuses if that set moved, and the read-back proves the planned
entries went away and every valid registration stayed.
--advisory attaches a SubLLM second opinion to a plan. It is advisory in the
strict sense: deterministic checks decide, and a missing package, credential or
provider degrades the result to advisory_unavailable with a reason rather
than blocking the repair. Install it with pip install -e '.[advisory]'.
Operator service
Running diagit without a subcommand starts the operator service. From
~/github it discovers every organization that contains Git worktrees. From
~/github/<organization> or any repository below it, it limits the initial
scope to that organization. The initial local audit starts immediately and
reports progress for every completed repository.
In a terminal, the service remains active and accepts single-key shortcuts without Enter:
a repeat the local audit
r audit selected GitHub organizations and compile repair planfiles
d explicitly approve and delegate the prepared plans to OneDev
s select one organization or the complete detected scope
q exit cleanly
Delegation requires an additional y confirmation. Diagit then creates a
mode-0600, ten-minute authority grant for each exact plan digest and submits
only CONTROL_ACTION_SUBMIT_REPAIR; Doctor/Repair/Validator evidence remains
mandatory. When stdin is not a TTY, the same bare invocation performs one
bounded local audit, prints progress, and exits instead of waiting for input.
Diagnostic registry
Every finding keeps its concise compatibility code, such as
DIRTY_WORKTREE, and is enriched from the packaged
diagit.diagnostic-registry/v2 catalog with a stable identifier such as
DIAGIT-GIT-003, category, severity, error class, retryability, and an optional
repair URI. The registry is the source of truth: emitting an unknown code or a
severity/message that differs from its definition fails closed.
The four severities have consistent operational meaning: INFO records useful
state, WARNING requires planned attention, ERROR blocks the requested
invariant, and CRITICAL means the audit or control boundary itself is not
trustworthy or available.
Priority readings
Diagit adopts wellmanifest.priority/readings/v1 as a signal producer only.
diagit priority readings reads a valid priority JSON document, resolves only
allowlisted local diagit://fleet/query/findings producers against the latest
completed projection, paginates every findings query, and emits a document-
digest-bound readings envelope on stdout. Signals owned by Queue Agent or other
producers remain absent, so their declared hold policy applies.
The command never evaluates priorities, selects work, executes producer text, or grants execution authority. Queue Agent remains the planned single ranking adapter and Core remains responsible for readiness and execution gates.
Remote pull requests are classified independently of the generic
OPEN_PULL_REQUEST finding. The registry distinguishes green mergeable PRs,
failed, pending or missing checks, merge conflicts, unknown mergeability, and
drafts stale for at least 30 days. A green unmerged PR is always emitted as
PR_GREEN_MERGEABLE. If archive cleanup is requested, the generated plan adds
PR_GREEN_REQUIRES_MERGE as a blocker instead of archiving that branch.
Architecture
- Commands change only the auditor's own state.
AuditFleetobserves Git repositories and appendsAuditRunStarted,RepositoryAudited, andAuditRunCompletedprotobuf events. - The length-delimited
events.pbfile is the canonical event store. New Protobuf events form a deterministic SHA-256 chain and retain read compatibility with legacy version 1 history. - Queries read a rebuildable SQLite projection (
projection.sqlite3). - Forge account observations from GitHub, GitLab, Gitea/Forgejo, and Bitbucket
are stored as
ForgeAccountTwinObservedprotobuf events. Their read model ranks providers from visible scopes, repositories, capabilities, visibility, completeness, and self-managed preference; it never reads repository content. The canonical contract and reviewed decision baseline are pinned touri-twin/uri-twin-forge; Diagit returns that source revision with each audit and recommendation. diagit rebuildrecreates the projection solely from stored events.- URI processes are explicit adapters to the same command/query handlers; an arbitrary URI can never become a shell command.
The canonical GBNF request language maps to the same CQRS messages as CLI,
shell, process URI, and loopback REST. Its Wellmanifest contract binds the
grammar, parser, storage schema, examples, command documentation, errors, and
critical security pages by SHA-256. See
docs/DSL_ARCHITECTURE.md and
dsl-manifest.json.
DSL and API
Every DSL request is exactly one fenced statement:
```diagitdsl
QUERY FINDINGS CODE "*" SEVERITY "SEVERITY_ERROR" LIMIT 1000 OFFSET 0
```
LIMIT is deliberately bounded to 1000. Fleet controllers must increment
OFFSET until the returned page is shorter than the requested limit; values
are never silently truncated.
The REST adapter binds only to loopback and exposes GET /health,
GET /v1/grammar, CQRS query routes, bounded command routes, and POST /v1/dsl. It does not expose GitHub control-plan application. The interactive
shell accepts the inner statement without Markdown fencing but sends it through
the same GBNF parser.
Command help: AUDIT, REBUILD,
SUMMARY, FINDINGS, and
REPOSITORY.
Error help: DIAGIT-REQUEST-INVALID,
DIAGIT-NOT-FOUND,
DIAGIT-ROOT-ESCAPE, and
DIAGIT-EVENT-INTEGRITY.
Supported URI processes:
diagit://fleet/audit?root=/home/tom/github
diagit://fleet/query/summary
diagit://fleet/query/findings?severity=SEVERITY_WARNING&limit=100
diagit://repository/<owner>/<repo>/query/report
diagit://projection/rebuild
diagit://github/<organization>/audit
diagit://github/<organization>/query/summary
diagit://forge/audit?providers=github,gitlab,gitea,bitbucket&max_items=1000
diagit://forge/query/recommend?requires=actions,projects&visibility=private&prefer_self_managed=true
Governed control plans
Remote audit observations can be compiled into the versioned
diagit.control-plan/v1 JSON DSL. Every executable plan embeds a
subactor.process-envelope.v2 with all four governed definitions: AQL authority,
transport-independent OQL operations, exact URI processes, and EQL expectations.
A governance plan closes an open pull request or deletes an extra branch only
when the branch head is already contained in main. By default, unmerged
branches remain blockers. The explicit --archive-unmerged policy first creates
and independently validates a deterministic diagit/archive/<branch>-<sha> tag,
then permits branch deletion and PR closure through dependent URI steps.
--rename-default-to-main safely migrates a default branch only when main
does not already exist and the observed head SHA still matches.
Applying a plan requires a separate mode-0600 diagit.authority-grant/v1 file.
The grant must name the organization and allowed action kinds, bind the exact
plan SHA-256 digest, identify its approver, and have a future expiry. Execution
is explicit:
diagit apply governance.json \
--authority-file authority.json \
--confirm-apply
An archived branch can be restored through a separately authorized plan:
diagit plan restore --repository owner/repository --branch fix/recover \
--tag diagit/archive/fix/recover-0123456789ab \
--expected-head 0123456789abcdef0123456789abcdef01234567 \
--output restore.json
For code repair, generate a single OneDev handoff action. The instruction is data, never a command:
diagit plan repair \
--repository subactor/core \
--task-id 0004_node-domain-tickets \
--instruction-file repair-instruction.txt \
--output repair.json
Before applying an action, Diagit fails closed unless its AQL actor explicitly
allows the matching OQL operation and the action is bound to exactly one URI
step. After an authorized apply, Diagit sends the complete envelope, canonical
plan digest, grant ID, and approving principal to the existing OneDev Agent
/tasks/execute boundary. OneDev independently repeats the AQL/OQL/URI/EQL
checks before materializing a Planfile ticket. OneDev then owns Doctor → Repair
→ Validator, test gates, exact-SHA checks, and publication. A submission receipt
remains submitted; only validator evidence can satisfy the terminal EQL.
The referenced diagit-repair-delegation.pl.aql decision model is packaged with
the wheel, so the envelope never relies on an unresolved model name.
diagit plan repairs compiles the latest remote audit into one independently
authorizable plan per affected repository plus a
diagit.repair-plan-set/v1 manifest. It selects only diagnostics whose
registered repair URI delegates to OneDev, deduplicates them into a bounded
instruction, and preserves the source audit run ID. --code can be repeated
to restrict generation to specific delegable diagnostic codes. Generating the
set never submits work; each plan still requires its own digest-bound authority
grant before diagit apply can cross the OneDev boundary.
Across later audits, a plan already in submitted or validated state is
deduplicated by its stable action identity. A changed finding produces a new
identity and therefore needs a new exact-digest grant.
diagit audit accepts repeatable exact or glob repository selectors. The
fleet-repairs variant compiles local findings from the latest completed audit,
so one diagnostic becomes an independently authorized OneDev ticket for each
selected repository rather than one unbounded fleet mutation.
OpenRouter application attribution
DIAGIT-LLM-001 / OPENROUTER_APP_IDENTITY_MISSING identifies tracked runtime
consumers of OpenRouter that do not provide verifiable cost attribution. A
compliant repair declares OPENROUTER_APP_NAME and an application URL in the
environment template and binds them to X-OpenRouter-Title and HTTP-Referer.
The URL may use the canonical OPENROUTER_APP_URL name or the established
OPENROUTER_SITE_URL compatibility alias.
When the name is blank, runtime code must use the repository directory name.
Environment templates and policy implementations are not consumers by
themselves. Applications routed through subllm receive provider identity from
its central application/function policy and do not duplicate this local binding.
Diagit reads only variable names and bounded tracked source files; finding
evidence never contains environment values or API keys.
The audit uses only local Git metadata. Ahead/behind values therefore describe the locally known upstream refs and do not imply a network refresh.
Release readiness
diagit audit --root ~/github --organization subactor --check-registries adds bounded
release checks to the normal event-sourced fleet audit. Local checks validate goal.yaml,
package file boundaries, and version tags. Registry checks compare public package.json
and pyproject.toml manifests with npm and PyPI; Node packages with private: true are
never treated as publication candidates.
The command is read-only: it reports unpublished packages and version drift but never publishes, tags, or pushes. Registry access is opt-in because it requires network I/O.
Development
python -m grpc_tools.protoc -Iproto --python_out=src --pyi_out=src proto/diagit/v1/audit.proto
scripts/verify
scripts/verify-dsl
The package distribution name is diagit, its Python import is
diagit, and its executable is diagit (which also permits the Git
external-command form git diagit).
License
Licensed under Apache-2.0.
Metadata
Release files for diagit 0.12.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| diagit-0.12.1.tar.gz | 152.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| diagit-0.12.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 280.5 kB
Release files / diagit-0.12.1.tar.gz
| Download URL | diagit-0.12.1.tar.gz |
|---|---|
| Size | 152.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bdd98d488d7f091890d266a6652813cee2f4eb875048dd038bd8231c5df17eb2
|
|
BLAKE2b-256 checksum How to use checksums |
b9041b5472445233b9593c72f207f10b6b0bd112f783a5faba392f7b68e8cdc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / diagit-0.12.1-py3-none-any.whl
| Download URL | diagit-0.12.1-py3-none-any.whl |
|---|---|
| Size | 127.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d47897c55107b43cefd5ef03957ce56edf7b2359574902013efbbd331277d136
|
|
BLAKE2b-256 checksum How to use checksums |
64e15790df9f33eeb816ec1b65028db256ec091ae73d53b96c5ad36c8d673a03
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|