Repository navigation
fix(cli): make the CI gate fail on an unreadable findings response - #163
tim-thacker-nullify wants to merge 2 commits into
Conversation
countFindings treated any response it could not parse as zero findings,
so `nullify ci gate` printed "Gate passed: no findings above threshold".
Parse the real {findings, numItems, nextToken} envelope, return an error
for anything else, and exit ExitNetworkError rather than counting an
unreadable response as clean. Drop the dead items/total shapes and the
duplicate totalFindingsCount. The gate requests limit=1 and the API has
no grand total, so the printed counts were the number of failing
scanner/severity pairs; the messages now say that instead.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The gate sent `severity=critical` lower-case and `status=open` to all seven scanner endpoints. /cspm/findings binds severity straight into `severity_label = $N::severity_level` and the Postgres severity_level enum labels are upper-case, so every CSPM request 500'd and the pre-existing `apiErrors > 0` branch returned ExitNetworkError before the gate could reach a verdict. `status` is implemented by no endpoint, so resolved, fixed, false-positive and allowlisted findings were counted. Build the query per endpoint from a capability table: upper-case severity, send it only to /sast/findings and /cspm/findings, and send isResolved=false where the endpoint implements it. Endpoints with no server-side severity filter are queried once instead of once per severity, and say so in their FAIL line rather than implying the threshold was applied. `nullify status` drops its finding count, which limit=1 capped at 1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Left as draft. Both review findings are closed in Checks at Closed:
Open and disclosed, not fixed here:
Ready for promotion once |
|
Out of draft. Built from AGI-2835, then adversarially reviewed and fixed. The ticket's defect: Review found the first cut still could not render a verdict in production; both are fixed on this head:
The root cause is addressed as well as the field names: an unrecognised envelope is now Checks green: Known and not fixed here — |
nullify ci gatecould not reach a verdict: unparseable responses counted as zero findings, and the query it sent made every CSPM request 500. (#155 already added thefindingsbranch; the silent-zero fallback and the query were what remained.)Silent zero:
countFindingsparses the real{findings, numItems, nextToken}envelope and returns(int, error); an unrecognised envelope errors, never0. The gate then exitsExitNetworkErrorinstead of counting it clean, andci reportcounts it a failed request, not a0row.items/totalshapes and the duplicatetotalFindingsCount.Query, now built per endpoint from a capability table:
/cspm/findingsbinds it intoseverity_label = $N::severity_level(cspm/internal/database/cspm_findings/postgres_repository.go:407) and the enum labels are upper-case, socriticalwasinvalid input value for enum→status.Internal→apiErrors > 0→ exit 3 on every default run, clean repo or not./sast/findingscase-folds and took either./sast/findingsand/cspm/findings— no other endpoint declares it. Those five are queried once, not once per severity, and their FAIL line states the threshold was not applied.status=openis gone; no endpoint implements it./cspm/findingsdeclaresStatusbut never copies it intoCSPMFindingFilters; the rest useisResolved. SendingisResolved=falsestops resolved and false-positive findings blocking a build with no way to clear them.nullify statusdrops its finding count —limit=1capped it at 1.Mutation-checked: lower-casing severity, restoring
status=open, or markingsecretsseverity-capable each failTestScannerQueryParamsMatchEndpointFilters.Known gaps, not fixed here:
--reposendsrepository, which no endpoint declares (/sast/findingstakesrepositoryIds), so the gate is tenant-wide. Needs name-to-ID resolution.ci reportrepeats one count across all four severity rows for the five scanners with no severity filter.database.SeverityToNullSeverityLevelbelongs in the monorepo.ci report'slimit=1000exceeds the secrets 100 cap — pre-existing.AGI-2835