RDetection rules
140 rules140 pattern rules read the diff and the variable-resolved command text. Each is a published pattern with a severity from INFO to FATAL, and a FATAL finding pins the verdict to 100: a bidi-override attack cannot be weighted away. The rules group by the kind of claim they make, from fetch and execution and integrity through obfuscation, deception, temporal context, composition, and indicators, and every match is reported with the line or URL it fired on.
CStructural rules
32 rulesThirty-two context rules reason about the diff as a whole rather than any single line, comparing the old and new states of the same field: a source URL that changed without a version bump, a checksum list that shrank, metadata that contradicts itself, unread content moved under a stable version. Where the pattern rules ask what a line does, the structural rules ask whether the change is internally consistent, across integrity, install and persistence, fetch, composition, staging, metadata, and deception.
DDependency-graph rules
4 rulesFour rules treat the dependency graph as first-class evidence. A review walks a package's AUR dependencies, direct ones by default and deeper with --depth, analysing each as a package in its own right: has it been seen before, does its name resemble a more popular package, does it fetch over the network during build, does it hijack a provides others rely on. Novelty is judged against the same signed seed the URL rules use.
Eight rules look for payloads aimed at the operator's machine rather than at getting something out of it: resource exhaustion, deletion, permission sabotage, service disruption, and resource theft. What unites them is that the machine running the build is the target. Each rule is written against a distinction, not a command: rm -rf inside the sandbox is housekeeping, rm -rf / is an attack, and a mention is not an invocation.
The evasion technique, not the payload it hides. Every other family fires on what a diff does; these fire on how it was written. Partial quoting, array routing, command substitution and other tokenizer-defeating shapes assemble an executable name no pattern ever sees, so a word the tokenizer could not reduce to a literal is itself the signal. One rule covers the evasion surface of every payload rule at once, and a defeated tokenizer produces a CRITICAL finding rather than silence.
MMeta and confluence
6 rulesSix meta rules reason over the finding set and the instrument itself rather than the diff: a declared practice contradicted by structure, a weak signal that spans several layers, or a composition no single family owns, plus three tool-health checks (a co-fire that should have appeared, a licensor absent on a licensed shape, a campaign class re-armed too often). The tool-health findings carry weight 0 and never join a package’s finding set, so a detector-health note cannot move a verdict.
Three entropy rules treat the statistics of the added text as evidence: its compression ratio, the fraction that is encoded alphabet, and identifier entropy. They mark a change that sits outside the normal distribution; suspicion, never a verdict, with thresholds calibrated on the benign corpus.
Five temporal rules track the identity behind the recipe rather than its content: a signing key never seen before, a maintainer domain first seen now, a key rotated, AUR metadata that runs ahead of the git tip (commits were pushed and later stripped), and a packager absent from the retained commit history. They say how new the thing behind the update is, independent of what the diff changed; the packager check is weight 0 and corroborates rather than scores.
Ten correlation rules look across packages in a window rather than inside one: a host, a literal, an adopter, or an upstream dependency shared by several recent analyses, a maintainer publishing name-clones of popular packages, a first-seen account adopting many dormant packages, a watchlisted subject, a package in an active campaign’s neighbourhood, and a plurality of first-seen hosts across strangers. They run at cycle end, never per package, so a campaign that is invisible in any single diff becomes visible in the set. Only the shared-signal rules score; the neighbourhood, watchlist and host-census findings are reported at weight 0.
Eight artifact rules inspect the built package, not the diff. The optional L9 build lane reads the produced manifest to catch a setuid file, an undeclared unit, a library outside depends, or an embedded eBPF object. Reported outside the static score, and off by default.
UUpstream manifests
10 rulesTen upstream rules read only what a recipe declares about upstream, never fetching it. Six manifest rules cover the dependency manifests committed beside the recipe: a manifest added or removed, a dependency delta, a new remote source, a redirected resolver, a dependency-surface jump, and a manifest changed without its lockfile. Four release-integrity rules are fed by a signed upstream baseline: a git-history credential sweep, a new CI surface committed into the AUR repository, and a source the public cannot inspect. Read from the repository tree and the diff; upstream content is never fetched.
PDeclared practice
7 findings, weight 0What the recipe declares, not what the analysis found. These findings read the claims a PKGBUILD makes about itself: checksums declared for every non-VCS source, validpgpkeys present, signatures sourced, sources pinned to a commit hash or tag, downloads over HTTPS, or a branch/unpinned ref tracked. Every one is INFO and checkable by the reader against the file itself. They are reported, never credited: a signal an attacker can assert for free must not move a score.
WUnverifiable
12 findings, weight 0Not a claim about the recipe but about the analysis: something the package will run that this run could not read. A build script that executes a file not declared in source=(), a patch not committed to the repo, a manifest generated at build time, a dependency resolved from a registry, a declared upstream this run was not allowed to fetch, or a terminal render that had to cap its finding list. Each is reported so the reader knows the boundary of what was examined; none contributes to the score.