Catch it at the pull request,
not at the launch.
The pull request is the point at which a licence problem is still cheap to fix. The gate runs the same binary on the same signed corpus and fails the job on the exit code. Nothing else decides, so the gate can never drift from the CLI.
The check run
The pipeline fails on the exit code, and --fail-on defaults to BLOCK. That code is the whole contract: 1 means DO NOT SHIP, and it will mean that forever.
The PR comment
--format md emits the comment body below, so a caller's step can post it once and edit it in place on re-run. A bot that comments on every push is a bot people mute — and a muted gate protects nothing.
Clearance verdict — DO NOT SHIP
1 blocker · 2 conditions · 47 dependencies scanned · corpus 2026.09.2
You run a MODIFIED version of AGPL-3.0 code as a network service. Section 13 requires you to offer the Corresponding Source to all users interacting with it over the network. AGPL-3.0 §13 · gnu.org/licenses/agpl-3.0.txt
"your modified version must prominently offer all users interacting with it remotely through a computer network the opportunity to receive the Corresponding Source"
Informational findings based on published licence text. Not legal advice. Ambiguous clauses are flagged. Important decisions should be reviewed by a qualified professional. · Clearance v0.1.0-rc.2
SARIF annotation, in the diff
The same finding appears inline on the changed lines, so the fix happens in the file that caused it. SARIF output is validated against the official schema in CI — a schema violation fails the build.
18 "dependencies": { 19 "express": "^4.19.2", + 20 "firecrawl": "^1.2.3", 21 "zod": "^3.23.8" 22 }
You run a MODIFIED version of AGPL-3.0 code as a network service. §13 requires you to offer the Corresponding Source to all users interacting with it over the network.
The workflow
name: Clearance on: [pull_request, push] permissions: contents: read jobs: clearance: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: K1ngBronxo/Clearance-dev/actions/check@v0.1.0-rc.2 with: version: 'latest' path: '.' strict: 'false' args: '--fail-on BLOCK'
One permission: contents: read. The Action downloads a checksummed binary from the v0.1.0-rc.2 release and verifies it against checksums.txt before extracting it. It carries no judgement of its own — the exit code and the JSON on stdout are the same contract you get running clearance check by hand. Uploading SARIF is a separate step in your workflow, and it is the one that needs security-events: write.
Behaviour contract
| Property | Behaviour |
|---|---|
| Binary source | Downloaded from the v0.1.0-rc.2 release, SHA-256 verified against checksums.txt before it is extracted |
| Default fail-on | BLOCK — conditions do not fail a build unless you say so |
| SARIF | --format sarif writes SARIF 2.1.0; uploading it to code scanning is your own step |
| PR comment | --format md writes the comment body; posting it once and editing it in place is your own step |
| Corpus | Supplied by path with --corpus, or bundled in the release archive. Verified on every load |
| Network | The Action downloads a release binary. The binary itself is offline and makes no outbound call. No telemetry, ever |
| Determinism | Same commit, same intent, same corpus → same verdict, byte for byte |
One static binary, so the same exit codes and the same JSON work wherever you can run a file. No container image is required, and none is published.
Nothing ships to wire this up for you, but a scan is one process with no network — cheap enough to run on the way in rather than in CI.
clearance mcp serve exposes the same engine to agents over stdio. Read-only, idempotent, fs.read scoped.