Reproduced against current main (2026-09-28)
At fcf6e8d66463ddcb23a0abc1ba6fa9732ea595bd, .github/workflows/hypatia-scan-reusable.yml, Validate findings and count severities, changed from exactly-one-document validation (jq -e -s, length == 1, then validate .[0]) to:
type == "array" and length > 0 and all(.[];
type == "object" and (.severity as $s |
["critical", "high", "medium", "warn", "low", "info", "informational"] | index($s) != null))
Two different lengths have been conflated: one JSON document vs one or more findings. The comment calls an empty findings array indistinguishable from a crashed/truncated scan, but [] is a complete document and is distinguishable from zero bytes or malformed JSON.
Hypatia 43124f025af26dadc9d268460410a205cfccefe8, lib/hypatia/cli.ex, explicitly succeeds when length(filtered) == 0; it serializes the filtered list. Thus a successful clean scan can legitimately emit [].
Executed controls
Extracted each exact jq expression from GitHub's pinned/current source and executed locally with jq (no rewritten approximation):
| Input |
standards da2c748a (knot-knot's pin) |
current fcf6e8d6 |
[] |
exit 0 |
exit 1 |
[{"severity":"warn"}] |
exit 0 |
exit 0 |
malformed { |
exit 4 |
exit 4 |
two documents: [] newline [{"severity":"high"}] |
exit 1 |
exit 0 |
The shell's -s file-size guard still rejects a zero-byte file. It does not fix either regression above. The second case passes this validation step; later count/output handling may fail separately, so this is not a claim that the whole workflow passes a multi-document payload.
Required contract / acceptance
- One well-formed findings document, including
[], is valid only when the scanner succeeded.
- Missing/zero-byte/whitespace-only/truncated output, multiple documents, wrong top-level type, invalid element shape and unknown severities fail closed.
- Scanner nonzero error remains a failure even if a file exists. No fallback
[], fabricated placeholder finding, new ignore or disabled gate.
- Restore single-document validation and change the regression controls/comments (including the referenced
science-ci-security-test.rb) so a clean scan is a positive control rather than an expected failure.
- Prove the workflow adapter against Hypatia's actual CLI contract with empty, warn, high and crash fixtures; a clean fixture should produce SARIF with zero results and pass.
Found while triaging metadatastician/knot-knot's obsolete CodeRabbit comparison. Not the cause of its current failure: its existing run fails earlier at scanner build (see #1050). This is a separate reason not to blindly refresh callers to current main.
Reproduced against current main (2026-09-28)
At
fcf6e8d66463ddcb23a0abc1ba6fa9732ea595bd,.github/workflows/hypatia-scan-reusable.yml, Validate findings and count severities, changed from exactly-one-document validation (jq -e -s,length == 1, then validate.[0]) to:Two different lengths have been conflated: one JSON document vs one or more findings. The comment calls an empty findings array indistinguishable from a crashed/truncated scan, but
[]is a complete document and is distinguishable from zero bytes or malformed JSON.Hypatia
43124f025af26dadc9d268460410a205cfccefe8,lib/hypatia/cli.ex, explicitly succeeds whenlength(filtered) == 0; it serializes the filtered list. Thus a successful clean scan can legitimately emit[].Executed controls
Extracted each exact jq expression from GitHub's pinned/current source and executed locally with jq (no rewritten approximation):
da2c748a(knot-knot's pin)fcf6e8d6[][{"severity":"warn"}]{[]newline[{"severity":"high"}]The shell's
-sfile-size guard still rejects a zero-byte file. It does not fix either regression above. The second case passes this validation step; later count/output handling may fail separately, so this is not a claim that the whole workflow passes a multi-document payload.Required contract / acceptance
[], is valid only when the scanner succeeded.[], fabricated placeholder finding, new ignore or disabled gate.science-ci-security-test.rb) so a clean scan is a positive control rather than an expected failure.Found while triaging
metadatastician/knot-knot's obsolete CodeRabbit comparison. Not the cause of its current failure: its existing run fails earlier at scanner build (see #1050). This is a separate reason not to blindly refresh callers to current main.