Skip to content

trusty-git-analytics · Acquisition due diligence

tga audit

One command walks the git history of the repositories your config already names, and renders a technical due-diligence report for someone deciding whether to buy the codebase. The report has eight sections, and the parts it cannot fill are named as gaps rather than scored.

Command
tga audit
Stages
8
Flags
6, all optional
Output
up to 18 files
Prompts
none

The gaps are printed, not filled in

A due-diligence report is read by someone deciding whether to buy the thing it describes. The failure that matters there is not a missing number. It is a number nobody measured, printed as though somebody had.

tga audit has no PERFORMANCE dimension and no COST dimension — nothing in the pipeline measures either one. So the report declares both as gaps rather than scoring them off a proxy.

Failure works the same way. Point the sweep at a config with no JIRA project key and the jira sync stage fails. That failure becomes a named line in Gaps & Caveats. The alternative — a zero in a cell — is indistinguishable from a project that genuinely had no JIRA activity, and the reader has no way to tell which one they are looking at.

Every report-quality bug fixed in the last milestone was that same shape: a partial signal rendered as an authoritative statement.

The failure you will actually hit

no JIRA project scope: pass --project <KEY> or set jira.project_key in config.yaml

This is the stage that most often fails on an unattended run. It does not stop the sweep, and it does not become a zero.

What you need installed

Two binaries, and one daemon you can skip. tga collects and classifies; trusty-review renders the report at the end of the sweep. They meet at a file — the manifest — rather than at a library edge, which is why the renderer is a separate install rather than something tga carries.

shell

curl -sSf https://raw.githubusercontent.com/bobmatnyc/trusty-tools/main/install.sh | sh
tctl install tga
tctl install trusty-review

Homebrew and cargo install from a checkout both work too; the other install paths are on the home page. Whatever route you take, the sweep looks for trusty-review on your PATH — set TRUSTY_REVIEW_BIN to a full path if it lives somewhere PATH cannot see it.

Required

trusty-review

Without it the sweep still runs and still writes manifest.toml, then stops with an error naming that file. Nothing collected is lost — see the recovery command below. A copy too old to require inference is rejected before stage 1, with the upgrade command, rather than delivering a report with no written analysis.

Required

OPENROUTER_API_KEY

The renderer writes the report's analysis with a model, so an audit cannot finish without a key. It is checked before stage 1, not at the end, so an unset one costs you the error and not the sweep: export OPENROUTER_API_KEY=…

Optional

trusty-analyze

The renderer asks a running analyze daemon for the findings and the complexity distribution, and shrugs when it is absent: the report is produced either way, and the sections it feeds become declared gaps instead.

Point it at a repository set

tga audit audits local checkouts that a config file names. It does not discover or clone anything, so this step is the one that decides what gets audited. tga install is an interactive wizard that writes the config for you; a hand-written one can be as small as a list of repository paths, because every other section has a default.

-c, --config <FILE> is global on tga, so it goes before the subcommand. A missing config logs a warning and runs on defaults rather than failing — which is worth knowing, because an audit of nothing is a report of nothing.

Running it

Six flags, all optional, nothing interactive. Once it starts it never prompts, confirms, or waits for input — start it and walk away.

shell — defaults

tga audit

Bare, it reads ./config.yaml and writes ./audit-output. That is the whole minimal invocation.

shell — named engagement

tga --config config.yaml audit \
  --org acme --client "Acme Holdings" --analyst "J. Reviewer" \
  --weeks 26 --output ./acme-dd
Flags
FlagEffect
--org <ORG>The organisation under audit. Metadata only — it titles the report and nothing else.
--title <TITLE>Defaults to <org> — Technical Due Diligence, or Technical Due Diligence with no --org.
--analyst <NAME>Renders as not stated if omitted.
--client <NAME>Same — absent is recorded as absent.
-o, --output <DIR>Where the audit writes. Defaults to ./audit-output.
--weeks <N>Limit collection to the last N ISO weeks.

What --org is not

It does not discover repositories. The sweep audits whatever local checkouts the resolved config already names, and --org only reaches the report's title block.

Where the report comes out

Everything lands in the output directory — ./audit-output unless --output says otherwise. The run ends by printing the paths it wrote under Report artifacts, so the last lines on your terminal are the deliverable. The Markdown file is the report; open it first.

If the sweep stopped at the render — the renderer was not installed, or the model call failed — the manifest survived it, because it is written before the renderer is called. Fix the cause and run the last stage by hand; this is exactly what the sweep would have run:

shell — render an existing manifest

trusty-review report \
  --manifest ./audit-output/manifest.toml \
  --analyze --synthesize --out ./audit-output

Eight stages, in the order the data flows

The numbering is real: each stage writes what the next one reads, which is why they run in this order and not another. A stage that fails is recorded and named in Gaps & Caveats, and the run continues.

  1. collect — walks the configured repositories into commits via git2.
  2. classify — runs the four-tier classification cascade over those commits.
  3. jira sync — ingests JIRA transitions and comments.
  4. deployments collect — deploy events into fact_deployments.
  5. incidents collect — incidents into fact_incidents.
  6. dora — reduces those two fact tables to the four DORA keys.
  7. pr-metrics — per-engineer pull-request metrics; writes pr-metrics.csv.
  8. report — renders tga's own CSV, JSON and Markdown.

No stage aborts the run

Every stage's result is recorded, never propagated. A stage that fails is marked failed, the sweep moves to the next one, and the failure surfaces as a named gap in the report instead of a halt. One thing stops a sweep: a pre-flight failure creating the output directory.

That is what makes an unattended run worth starting. A pipeline that stops on the first unreachable source produces nothing; this one produces a report whose missing pieces are labelled.

What lands in the output directory

Up to 18 files, from three producers.

FromFilesWhat
report stage149 CSV, 4 JSON, 1 Markdown.
pr-metrics stage1pr-metrics.csv.
the seam1manifest.toml — what tga hands to trusty-review.
trusty-review2{slug}.md and {slug}.json — the due-diligence report itself.

The report, section by section

Eight sections, in this order. A model writes the executive summary, the top-risk rationale, and the RED/AMBER finding prose, working only from what the sweep collected — every figure it cites is checked against that data and the sentence is dropped if the figure is not there. Section 2 falls back to a roll-up composed from the report's own counts whenever that check rejects the written one.

§Section
1Report Metadata
2Executive Summary, with Top Risks
3Scoring Model Normalization
4Per-Application Scorecard
5Findings by Severity
  • 5.1 RED / CRITICAL — full detail
  • 5.2 AMBER / MEDIUM — compact
  • 5.3 GREEN / POSITIVE — topic list only
6Risk Registers
  • 6.1 Security Violations
  • 6.2 Open-Source / CVE Exposure
  • 6.3 License / IP Risk
  • 6.4 Obsolescence
  • 6.5 Cloud Readiness Blockers
  • 6.6 Technical-Debt / Remediation Economics
7Graph-Ready Data Appendix
8Gaps & Caveats
From tga

§1 in full, and §4's tech stack, lines of code, and frameworks.

From trusty-analyze

§5, §6.1, and §7's complexity_distribution and loc_by_technology.

Declared gap

§4 Benchmark Position, §6.2, §6.3, §6.4, §6.5, §6.6 — no data source behind any of them, and the report says so rather than scoring them.

Red, amber, green — and what routes a finding there

The colours are the report's own convention, and the mapping is mechanical: the diagnostic's own severity decides, nothing else.

BandDiagnostic severityHow it renders
Rederror · critical§5.1, full detail.
Amberwarning · high§5.2, compact.
Greeneverything else§5.3, topic list only.

The ceiling that matters

A refactor suggestion caps at Amber. It can never come out Red, no matter what the underlying tool called it — because "extract this method" is advice, and a buyer reading a RED line is entitled to assume something is broken.

What the last fix actually changed

Measured on one run, over the ripgrep repository, before and after the report stage was corrected.

MeasureBeforeAfter
RED findings200
AMBER findings, each carrying real numbers020
Non-code components scored20
Complexity buckets sum to1,0004,328

The 20 pre-fix RED entries were all "Extract method" refactor suggestions misrouted into RED. The two non-code components were CHANGELOG.md and FAQ.md, scored as if they were applications. The complexity buckets summed to a round 1,000 instead of the 4,328 units actually counted.

All three are the same defect wearing different clothes: output that looked like a measurement and was not one.

Scope of that evidence

These numbers are the ripgrep run only. The trusty-tools audit was not re-run after the fix, so nothing here says the same before-and-after holds on a second codebase.

What this does not do

The buyer's alternative is a tool that would have guessed at all six of these. Read this section as part of the pitch, not as a disclaimer at the bottom.

It does not find or clone repositories

Every entry in the sweep is a local checkout that the resolved config already names. Discovery is open work (#5215); until it lands, naming a GitHub organisation or a Bitbucket workspace in --org gets you a report title, not a repository list.

There is no engineering-velocity section

DOC-67 §8 specifies one; it is not implemented (#5241, #5242). DORA is computed at stage 6 and never reaches the report. If you need deployment frequency or change failure rate in the deliverable, this does not produce it today.

§6.1 is linter output, not a security scan

It carries general-purpose linter findings — clippy, ruff, biome, rubocop, PMD. A linter flagging an unwrap() is a different claim from a scanner flagging SQL injection or a hardcoded credential, and this section is only ever making the first one.

Six registers have no data source

§4 Benchmark Position, and §6.2 through §6.6 — CVE exposure, license and IP risk, obsolescence, cloud readiness, remediation economics. Each is declared a gap. None is estimated.

agentic_pct counts markers, not AI

The undercount that made this figure unquotable is fixed (#5249, #5403): measured against tga's own history the catch rate went from 47.70% to 91.04%. What the number means did not change. Detection is marker-based only — the run's own disclosure line says so — so commits whose trailers or footers were stripped, squashed, or rewritten are indistinguishable from human commits, and a low share means "no markers emitted", not "no AI assistance". Twelve markers cover seven tool labels, and five of those (Devin, OpenHands, Aider, Copilot, Cursor) are exercised only by synthetic tests, because this repository's history contains none of their markers. Read it as a floor on marker-emitting work, not as a provenance figure.

No PERFORMANCE or COST dimension exists

Nothing in the pipeline measures runtime behaviour or spend, so neither is scored. Both appear in Gaps & Caveats, which is the whole design: the report would rather be visibly incomplete than quietly wrong.

Start to finish

Four steps to a report

  1. Install tga and trusty-review.
  2. Write config.yaml, by hand or with tga install.
  3. Run the sweep. It will not ask you anything.
  4. Open the Markdown file whose path it printed last, and read Gaps & Caveats before the scores.

shell

tga audit --org acme --output ./acme-dd

← Back to trusty-git-analytics

trusty-tools

One Cargo workspace for the trusty-* tooling ecosystem. MIT licensed.

© 2026 · MIT · github.com/bobmatnyc/trusty-tools