Watchdog · System documentation
How a scan works
What we produce, and for whom
Where the code runs
Watchdog does not only read code. It builds it and runs its tests. This page explains where that happens, under what restrictions, and what does and does not leave our machines.
We execute the code we analyse
Many of the properties worth knowing cannot be established by reading source text. Whether a test suite is reliable is a fact about running it. Whether the tests actually cover the code is a fact about observing them run. So the analysis compiles the project and executes its test suite.
This is a deliberate trade. It is more work, it needs stronger isolation, and it means some repositories cannot be fully measured because they do not build in our environment. In exchange, the numbers that depend on execution are measured rather than inferred — and when a project does not build for us, we say so and exclude the affected measurements instead of guessing at them.
The container
Analysis runs inside a single-purpose container that is created for one scan and destroyed afterwards. It is built to assume the code inside it is untrusted:
- No privileges. The container drops all elevated capabilities and cannot acquire new ones while running.
- Bounded resources. Memory, processor share and the number of processes are capped, so a runaway build cannot exhaust the machine or affect another scan.
- Scratch space in memory. Temporary working files live in memory, not on a disk.
- Disposable. The container is removed when the scan ends. Nothing persists into the next one, and no scan can observe another.
- Fixed contents. The analysis image is built ahead of time and pinned. The container does not fetch its own tooling at scan time.
Network access
The container is not fully cut off from the network, and it is worth being precise about why: building a project means restoring the packages it depends on, and those live on public package registries.
So network access exists, but it is not open. Traffic leaves only through a controlled allowlist — enough to fetch the dependencies a project needs in order to build, and nothing else. Direct outbound connections from the analysis container are blocked; anything not on the allowlist is refused rather than quietly permitted.
Precise wording: heavily restricted, not air-gapped. "Hermetic" and "air-gapped" are inaccurate for this container — do not use them.
Observing a project running
Some properties are only visible when an application is actually started. Where a repository declares a reproducible way to start itself, the system is able to boot that declared stack in an isolated environment and observe it running, rather than reasoning about it from configuration files alone.
This capability is applied selectively — it depends on the repository declaring how it starts, and it is not part of every scan.
What happens to the code afterwards
The working copy fetched for a scan exists only in memory, never written to a disk, and is removed when the scan finishes. What we retain is the result — the scores, the findings and the report — not the source they were derived from.
Findings quote the specific lines they refer to, because a finding that cannot show its evidence is not checkable. Those excerpts are part of the report.
Where the work happens, and who else is involved
The system is self-hosted. The analysis engine, the language models used for the judged parts of the analysis, the databases and the stored reports all run on our own infrastructure in Denmark. Code is not sent to a third-party model provider for analysis.
Two external services are involved in running the product: the source-code host the repository comes from, and our payment provider. Neither is part of the analysis.
This page is a summary, not the formal record. Storage, retention periods, encryption and the complete list of subprocessors are documented on the security and data handling page. Where the two differ, that page is authoritative — it is maintained as a compliance document and states precisely which data is encrypted at rest and which is not.
Related guide
- Read-only as a design principle — covers what read-only access means for a team deciding whether to connect a repository.