Contributing to TrustSight¶
TrustSight is a CLI tool that audits AUR PKGBUILD diffs for supply-chain risk. It is an instrument, not a judge: it reads changes, applies published detection rules, and reports what it found and what it could not see. It never decides whether a package is safe; a person does. Every contribution is measured against the same thesis, which the security model states and each part below applies to work on the tool itself.
- Development Setup: getting started, running tests, linting, and evaluation
- Writing a Rule: how to add R-series or C-series rules, fixture guidelines, fire-rate gate
- Re-baselining: when and how to re-baseline after config or rule changes
- Publishing Baselines: the maintainer workflow for building, signing, verifying, and publishing the corpus and IOC baselines
- Reviewing a Security Control: how to scope a gate so it covers the entry point an attacker reaches, and the failure mode that keeps recurring
The boundary¶
TrustSight does three things, and only three: it reads the repository and the AUR endpoint (plus the signed release assets an operator explicitly asks for), it computes evidence locally and deterministically without ever executing a PKGBUILD, and it reports findings and gaps. A change that adds a fourth job to the analysis stage (running code, fetching a declared URL, writing outside the data directories) violates the boundary and will not be merged.
The guarantees a contribution must keep¶
Every agreed guarantee has a gate in CI; a change that breaks a gate is a change that is not done. The list is stated in full in the enforcement map. The ones most likely to be touched by a rule or pipeline change:
- Determinism. The same input produces the same score and evidence record. Nondeterminism in scoring is a mandatory-review bug at any scale.
- Fail-closed on doubts. A bound that drops input must record a coverage gap; a run that did not see the whole change can never present an UNFLAGGED verdict. Adding a new truncation seam without a gap is a vulnerability, not a rule.
- Locked invariants. FATAL rules cannot be switched off, baseline and seed can only supply state, and the network boundary is never widened.
- A claim without a gate is a claim not made. New guarantees go into
scripts/security_gates.pyand the security model page, together.
Tokenizer and regex changes require hostile-input tests. Run the deterministic tokenizer fuzz suite with the regular tokenizer tests and security gates. Do not replace Python's re module or add a regex engine dependency without a comparative benchmark, syntax-compatibility review, packaging review and a maintainer discussion.
Signed Commits¶
GPG-signed commits are required for changes to security-critical paths: the tokenizer, scoring, config, database, security gates, CI workflows, packaging, and baseline keys. The CODEOWNERS file and the verify-commit-sigs workflow enforce this.
For changes that do not touch critical paths, such as documentation, tests, fixtures, or cosmetic fixes, signing is encouraged but not required.
Non-guarantees to respect¶
Absence of alerts is not a certificate, and absence on a test machine is not proof a rule is safe to ship. It is input to a human decision. A rule whose only evidence is "nothing fired" is not evidence of anything; fire rates on the benign corpus and real case reports are the arguments that matter.
Quick reference¶
| Metric | Value |
|---|---|
| Tests | 1,535 (43 files) |
| Python | 3.11+ |
| Test runner | pytest |
| Linter | ruff |
| Rules | R001-R140 (R133-R135 not implemented), P001-P007, C001-C007, D001-D004 |
| Rule config | rules.toml |
| Benign corpus lock | tests/fixtures/corpus.lock |