Overview / Trust
TRUST
Airlock makes a claim about a repository, so the model behind that claim has to be readable. This page states what it trusts, what it refuses to guess, and what it does not cover.
Hard rules
Never brokenNever execute, import or evaluate scanned content. The tree under scan is untrusted input, and nothing in it is run to find out what it does.
Never run scanner code from the scanned checkout. The tool comes from a pinned path or the installed package, not from the repository it is judging.
Read policy from the trusted base. In pr and push modes, policy, suppressions and the Wasm manifest come from the base commit, never from HEAD.
No network and no telemetry during a scan. A scan that needs to fetch is a scan that can be told what to see.
No runtime dependencies. Python 3.11 and the standard library. A wheel with no rules cannot scan, so the rules travel inside the package.
Never skip a file silently. Every skip is a finding with a rule id, a severity and a path.
No default directory skips. Vendored directories are read like any other path.
No inline suppression markers. Suppressions are fingerprint-keyed, occurrence-aware and carry a reason.
Never return 0 after an error. A detector exception, an invalid configuration or an unresolvable base is a failure, not a clean run.
Match raw text. There is no comment or string masking, because the line a reviewer reads and the line the matcher sees have to be the same line.
Fail closed
State findingsThese ids are decisions about the scan itself rather than matches inside a file. A skip is reported, and a setting that changed inside the change is judged by the base copy.
| Rule id | Severity | What it means |
|---|---|---|
| skipped-oversize | HIGH in a sensitive role, WARN otherwise | The file is over max_file_bytes and was not read in full. |
| skipped-unreadable | HIGH | The file could not be read, or changed size while it was being read. |
| skipped-symlink | INFO | A tracked symlink is recorded; its target is never read. |
| skipped-unmerged | HIGH in a sensitive role, WARN otherwise | The path is unmerged in the index, so there is no agreed content to scan. |
| submodule-present | INFO | An embedded repository; its contents belong to its own pipeline. Task 7.2 decides whether this rises. |
| nul-in-text | HIGH | A NUL byte after BOM handling: the file is not the text its extension claims. |
| non-utf8-text | HIGH in a sensitive role, WARN otherwise | The bytes are not valid UTF-8 even after BOM handling. |
| cfg-long-line | HIGH in a sensitive role, WARN otherwise | A line over line_cap. The regexes deliberately do not run on it, so its length is the finding. |
| detector-error | HIGH | A detector raised. Findings it produced before raising are kept. |
| history-rewritten | HIGH | The pushed before is not an ancestor of HEAD, so the base policy cannot be trusted. |
| no-trusted-base | WARN | A push created the branch. The shipped defaults apply, and the scan still runs at full strength. |
| policy-changed | WARN | The policy changed inside this change. The base copy is what ran. |
| policy-unknown-key | WARN | A key this build does not read. The setting stays at its default. |
| untrusted-policy-source | INFO | full mode read policy from the working tree, which the change can edit. |
| suppression-invalid | HIGH | A suppression entry matches no applicable finding, so it is hiding nothing and claiming otherwise. |
| suppression-expiring | WARN | An entry expires within 30 days. Renew it with a reason, or let the finding return. |
The seven bypasses
Appendix B / MeasuredFive public Soroban repositories shipped the same scan step. On 2026-10-27 each shape below was committed to a scratch repository and the real script was run the way the workflow runs it. All seven exited 0.
Six are now regressions under tests/bypass, and they assert rule ids and severities rather than a bare exit code so an unrelated HIGH cannot make them pass. The seventh waits on the Cargo detector, and its test is skipped with that reason in the fixture rather than deleted.
The probe that measured the old script and the tests that judge this package import the same case table, so the harness and the regression cannot drift. The payloads are assembled from fragments at run time, which is why no live-looking string is committed here.
| Case | Shape | Old gate | Airlock |
|---|---|---|---|
| B-01 | A .wasm file of any content | EXIT 0 | CAUGHT wasm-unlisted, HIGH |
| B-02 | A NUL byte in the first 4 KB of a text file | EXIT 0 | CAUGHT nul-in-text, HIGH |
| B-03 | A payload line ending in the old inline allow marker | EXIT 0 | CAUGHT the marker changes nothing |
| B-04 | An allowlist file containing a single wildcard | EXIT 0 | CAUGHT no allowlist exists, the payload is read |
| B-05 | A decode-then-evaluate line in a tooling config | EXIT 0 | CAUGHT cfg-dynamic-code, HIGH |
| B-06 | A .cargo/config.toml runner invoking a shell | EXIT 0 | PENDING Cargo vectors, task 6.4 |
| B-07 | A payload under a directory the old script skipped | EXIT 0 | CAUGHT pat-decode-eval, HIGH |
What it does not do
LimitsIt is not an antivirus and not a dependency-advisory tool. It does not resolve lockfiles, compare package versions or read a vulnerability database. It does not unpack archives, and it does not parse JavaScript with a lexer.
It does not fetch wasm from a chain, validate SEP-58 metadata, or check a contract size limit. Those are Phase 6 work and they stay unclaimed until the detectors exist.
A clean report means nothing matched the rules that ship. It is a narrower and more honest claim than "no compromise found", and it is the only claim a rule set of this size can support.
SARIF output and the composite Action are not shipped. There is no signed release, so no commit before the first attested tag carries a release guarantee.
Residual risk
Stated, not hiddenWhoever can push a workflow file can remove the scan. A required status check covers pull requests, because a pull request that deletes the step never reports the check. It does not cover a direct push by a stolen credential.
The control for that is an external watcher that clones a repository and compares its last seen commit (backlog D-04), plus hardware-key two-factor authentication on the accounts that can push.
A required check also does not help if the check is not required, and branch rules are repository settings rather than files. The roadmap tracks those tasks separately from the code, because neither can be verified by a test in this tree.