Repository navigation
ci(vt-gate): name the engine that flagged, not just the count - #1491
Merged
Merged
Conversation
The gate reported "1 malicious, 0 suspicious / 59 engines" and stopped there —
withholding the one fact a detection is actionable on. A false-positive
submission goes to a SPECIFIC vendor, and triage begins with "known-noisy engine
or a new family?". Neither question is answerable from a count.
It cost exactly that in the 2026-08-07 dry run: three artifacts flagged
(linux-amd64, linux-amd64-portable, darwin-arm64), one engine each, and the logs
could not say by what. The vendor had to be recovered by hand from the web UI
afterwards — and the WDSI developer false-positive path is a web form with no
public API, so guessing the wrong vendor wastes a filing round trip.
The analysis response already carries per-engine results; the gate simply threw
them away. It now prints, under the BLOCKED line, each engine that returned
malicious or suspicious with its detection label and definition date:
BLOCKED: codebase-memory-mcp-linux-amd64 flagged (1 malicious, ...)
detected by: Microsoft = Trojan:Win32/Wacatac.B!ml (engine ..., defs ...)
Engines that did not flag are not listed, or the actionable line drowns in
sixty clean rows.
Deliberately unchanged: the gate's strictness. Zero tolerance still means any
detection on any artifact on any version blocks, and an analysis WITHOUT
per-engine results still blocks on the counts alone — the contract pins both, so
naming engines cannot become a route to tolerating one. A missing engine list
prints an explicit "<engine names unavailable>" rather than nothing, so the gap
is visible instead of reading as a detection-free block.
Verified by revert: against the old gate the new assertions fail with the
counts-only output quoted above.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
DeusData
enabled auto-merge
August 7, 2026 18:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
The VirusTotal gate reported
1 malicious, 0 suspicious / 59 enginesand stopped there — withholding the one fact a detection is actionable on.A false-positive submission goes to a specific vendor, and triage begins with "known-noisy engine, or a new family?". Neither is answerable from a count.
It cost exactly that in the 2026-08-07 dry run: three artifacts flagged (
linux-amd64,linux-amd64-portable,darwin-arm64), one engine each, and the logs could not say by what. The vendor had to be recovered by hand from the web UI afterwards — and the WDSI developer false-positive path is a web form with no public API, so guessing the wrong vendor wastes a filing round trip.The fix
The analysis response already carries per-engine results; the gate simply discarded them. It now prints, under the BLOCKED line, each engine returning malicious or suspicious, with its detection label and definition date:
Engines that did not flag are not listed, or the actionable line drowns in sixty clean rows.
Strictness is deliberately unchanged
Zero tolerance still means any detection, any artifact, any version blocks. Two things pin that so "name the engine" can't become a route to tolerating one:
<engine names unavailable in the analysis response>rather than nothing, so the gap is visible instead of reading as a detection-free blockVerification
tests/test_vt_gate_zero_tolerance_contract.shextended with a stubbed analysis carrying real per-engine results. Asserts the vendor is named, the detection label is reported, non-flagging engines are excluded, and detail-free detections still block.Revert-checked: against the old gate the new assertions fail with precisely the counts-only output quoted above. Release-gate-chain and exec-bit contracts also pass.
Scope
Does not attempt to address the detections themselves. That investigation did not establish causation —
linux-arm64carries the same mimalloc allocator override (#1477) and scanned clean, anddarwin-arm64flagged without it — so a code "fix" there would be guessing at an ML decision boundary. This PR only makes the next detection diagnosable.