AIROM’s exit status answers one question: did the scan run? It does not tell you whether the scan found anything. Failing the build on a finding is an explicit, opt-in decision you make with --fail-on and --exit-code.

The contract

Everything downstream of source acquisition degrades instead of failing. Detector errors, unreadable files, and corrupt headers become Unknown records in the output — they never change the exit code. A partial inventory is still a successful scan.
Exit 0 on findings is deliberate, not an oversight. If you want “fail the build when a hosted LLM shows up,” you must say so with --fail-on. Nothing else will fail your build for you.

Turning on the gate

1

Scan and report (no gate)

Report only — always exits 0
2

Add a policy

--fail-on compiles an expression and evaluates it against the assembled inventory after all output has been written. A match exits 1.
Fail when a high-confidence hosted LLM is present
3

Choose the exit status

Match exits 3 instead of 1

--exit-code and --fail-on interact

--exit-code must be in [0,255]; anything else is a configuration error (exit 2).
--min-confidence is a presentation filter. It trims what the writers emit; it does not change what --fail-on evaluates. Put your confidence threshold in the policy expression (confidence>=0.8) if you want it to affect the gate.

The --fail-on grammar

Grammar
& binds tighter than |, so a|b&c reads as a | (b & c). Whitespace around tokens is ignored. A dangling & or | is a configuration error (exit 2). A --fail-on that is empty or all whitespace sets no policy at all — it is not an error, and it does not gate.

Each clause must be satisfied by a single component

This is the rule that surprises people. hosted-llm&confidence>=0.9 means “some one component is a hosted LLM and that same component has confidence ≥ 0.9.” It does not mean “a hosted LLM exists somewhere and, separately, something else is high-confidence.”
The application root component — the scan target itself — is never eligible to match a policy. It is the thing you scanned, not a finding.

Terms

ComponentKind
A component kindhosted-llm, local-model-file, embedding-model, framework, library, vector-db, prompt, dataset, ai-config, infra, service, rag-pipeline, application.
risk | risk:severity | risk:slug
Matches a component carrying an artifact risk. risk matches any risk; risk:high / risk:medium / risk:low match by severity; risk:<slug> matches one catalog entry (pickle-import, keras-lambda, gguf-template, savedmodel-pyfunc, unsafe-load). pickle-risk remains as a deprecated alias for risk:pickle-import.
compliance | compliance:framework[:control]
Fires on a compliance gap (a manual control is not a failure; a met is a pass). compliance:gap — any gap; compliance:<framework> — a gap in that framework; compliance:<framework>:<control> — that control is a gap. It is inventory-level, so it cannot be &-combined with a component term (use |), and it requires --compliance to have been given — gating on a framework you never evaluated is a configuration error, not a silent pass. Like every selector it evaluates the full assembly, so --min-confidence never relaxes it.
comparison
Compares the component’s confidence against a bound in [0,1]. Operators: >=, <=, >, <, =. A bound outside [0,1] is a configuration error. Bare confidence with no operator is rejected — it is almost always a typo.

Worked examples

--exit-code 1 with no --fail-on fails on any component, including low-confidence noise. Extension-only dataset detection and keyword-only ai-config detection emit components at confidence 0.5–0.6 on general-purpose directories. Prefer an explicit --fail-on expression with a confidence bound. See confidence.

Shell notes

Quote the expression. Both & and | are shell metacharacters:
Always quote --fail-on
You can also set the policy through the config layers — flags beat env vars beat .airom.yaml:
Unknown keys and unknown AIROM_* variables fail loudly with exit 2. A typo never silently disables your gate.

Next

GitHub Actions

A copy-pasteable workflow: scan, upload SARIF, gate.

CLI reference

Every command and global flag.