feat: SARIF/JSON output for CI code scanning (closes #8)#9
Merged
Conversation
New taintline.report module. to_text is the existing human report; to_json is a stable sorted view of the findings; to_sarif emits SARIF 2.1.0 for GitHub code scanning (one result per finding, detector->ruleId, severity->level, span ids in the message + properties + per-location logicalLocations, trace path as the artifactLocation). All three are pure, offline and byte-deterministic: object keys emitted sorted and findings already contract-sorted, so nothing depends on PYTHONHASHSEED. Typed SARIF nodes, no loose dict assembly.
Thread a keyword-only fmt + trace_uri through run_check and dispatch to the new serializers; default stays text and byte-identical to today (render now delegates to report.to_text). Exit still gates on --fail-on regardless of format, so a SARIF run both surfaces findings and fails the build. main passes the trace path as the SARIF artifact uri.
A seeded taint trace: assert the SARIF has the expected taint result (ruleId/level=error/message/logicalLocations/span_ids) and all required SARIF 2.1.0 fields ($schema, version, runs[].tool.driver, results[] with ruleId in the declared rules, valid level, message.text, artifactLocation). JSON + SARIF are byte-identical across five PYTHONHASHSEED values (subprocess). Default output confirmed unchanged (text == to_text, not JSON).
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.
Closes #8.
Adds
--format {text,json,sarif}totaintline check, keeping the deterministic,zero-LLM, zero-dependency contract.
What
taintline.report— three pure serializers of aVerdict:text— the existing human report (default; byte-identical to today).json— a stable, sorted view of the findings for scripting.sarif— SARIF 2.1.0 for GitHub code scanning: oneresultper finding,detector → ruleId,severity → level(error/warning), span ids in themessage +
properties.span_ids+ per-locationlogicalLocations, and thetrace path as the
artifactLocation.uri. Includes$schema,version,runs[].tool.driver(nametaintline, rules),results[]— accepted bygithub/codeql-action/upload-sarif.--formatoncheck(defaulttext); exit still gates on--fail-onregardless of format, so a SARIF run both surfaces findings and fails the build.
Deterministic, no LLM
Object keys are emitted sorted and findings are already contract-sorted, so output
is byte-identical across runs and independent of
PYTHONHASHSEED. No network, notimestamps, no rng. Zero new runtime deps.
Tests (
tests/test_report.py)ruleId/level=error/message/logicalLocations/span_ids) and all required SARIF 2.1.0 fields(structural validation — kept offline/zero-dep per the issue's fallback).
PYTHONHASHSEEDvalues(subprocess), mirroring the existing determinism harness.
Docs
README
## Output formats & GitHub code scanningwith the--format sarif→upload-sarifsnippet (continue-on-error+if: always()so findings uploadeven when the gate trips).
Gates:
ruff check .,ruff format --check .,mypy src,pytestall green (45 tests).