Skip to content

ADR 0003: Deterministic policy in a Python DSL, mirrored in Rego

  • Status: accepted
  • Date: 2026-09-26

Context

The gate decision has to be auditable and reproducible. The spec rules out an LLM in the decision path. OPA/Rego is the industry default for policy-as-code, but OPA is a Go binary that the core package should not require.

Decision

The rules live in tracegate/policy.py as small generator functions. Each yields (verdict, reason), and every reason carries the graph path (commit to dependency to ...) that triggered it. The same rules are ported to policies/tracegate.rego and evaluated over tracegate export --format opa. CI installs OPA and checks that the two engines agree on every demo scenario.

Scores (Warden risk, typosquat score, EPSS in future) are only ever inputs to thresholds in the rules. They never produce a verdict directly.

Consequences

  • Rules are unit-testable in Python with no extra runtime.
  • Keeping two implementations in sync costs effort. The CI parity check keeps that honest.