What gets sent to the model
This is the question a security review asks first, so here it is precisely, per call, from the code that makes them.
Three calls, and what each carries#
| Call | What is in the prompt | How many |
|---|---|---|
| Stage 4 — propose | One changed file's diff, plus the assembled context bundle: the enclosing functions of changed lines, the callers of any changed function and, by default, their callers, and the definitions of functions the changed lines call. | One per changed file |
| Stage 5 — verify | One finding's title, category and quoted line, plus the evidence pool — the whole diff and every context block. | One per candidate finding that passed the free checks |
| Stage 6 — summarize | The verified findings only: severity, file, line, category, title and quoted line for each. No diff, no context. | One per pull request |
Stages 1, 2, 3 and 7 make no model call at all. Parsing, the caller search, the quote match, the fingerprinting and the ranking all happen locally.
What never leaves#
- Files outside the diff and outside the context bundle. The rest of the repository is never read into a prompt. A file is only included if it was changed, if it contains a caller of a changed function or a caller of that caller, or if it defines a function the changed lines call.
caller_depth: 1andinclude_callees: falsenarrow that to direct callers, and--dry-runlists exactly what would be sent. - Your key, anywhere but the provider. It is read from the environment and used to authenticate the call to the provider you chose. It is never written to a file, never logged, and the config loader refuses to start if it finds something key-shaped in
.groundtruth.yml. - To a server the reviewed code chooses. The endpoint cannot be set from
.groundtruth.yml, because that file can be edited by the pull request under review. Only the environment and the command line — the place your key lives — can say where requests go. - Telemetry. There is none. There is no service operated by this project for anything to be sent to — no accounts, no hosted component, no phone-home.
--dry-run — makes no network call, which is why a dry run works with no key at all.Where it goes#
- Straight to your provider by default. Anthropic, OpenAI, Azure, Bedrock — whichever your
modelnames, called directly from the CI job with your key. - To any endpoint you name with
GROUNDTRUTH_BASE_URLor--base-url— NVIDIA's API catalog, Azure, a model on your own hardware, or a self-hosted LiteLLM proxy. Point it at a proxy you run and nothing talks to a provider except infrastructure you control, which is also where org-wide spend caps and audit logs belong. - Nowhere at all if you point
modelatollama/<model>. Every call goes to a local endpoint, no key exists, and no code leaves the machine running the review.
The optional ingest server#
Only if you set GROUNDTRUTH_INGEST_URL, which is unset by default. After the review has posted, the adapter then sends that run's result to the URL you gave: each finding's file, line, category, severity, title and quoted line of code, the summary, the model and the cost estimate. On GitHub and GitLab it also sends the fingerprints of its earlier findings with counts of the thumbs up, thumbs down and resolved threads they received; that part carries no code. The server is one you run yourself, so none of this goes to this project. Unset, nothing is sent and the adapter makes no extra calls to your platform.
Retention#
Groundtruth stores nothing. It is a process that starts, reads a diff and exits — no database, no cache, no artifacts beyond the comments it posts. The one piece of state it keeps between runs is the list of fingerprints in the summary comment on your own pull request, and a fingerprint is a SHA-1 of the file path, the surrounding code and the category — not the code itself.
What your provider retains is your provider's policy, and worth reading. If that answer is unacceptable for your codebase, the local-model path exists precisely for that case.