diff --git a/AGENTS.md b/AGENTS.md index a433b40d1..49edcde47 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,6 +59,53 @@ These files have `effective_on` dates — rules with future dates are warnings, | Add a shared library function | `policy/lib/` (must have test coverage) | | Fetch and parse an OCI blob as JSON | Use `oci.parsed_blob(ref)` from `data.lib.oci`, not `json.unmarshal(ec.oci.blob(ref))` directly. A Regal lint rule (`prefer-parsed-blob`) enforces this. | +## Rego Evaluation Model (for AI reviewers) + +Rego is a declarative policy language (Datalog-inspired), not imperative code. +Understanding its evaluation model is critical for accurate code review. + +### Evaluation Semantics + +- Multiple rule bodies with the same name are **disjunctions** (OR). Conditions + within a body are **conjunctions** (AND). +- Rules evaluate to `true` or `undefined` — there are no "return values" or + control flow. Do not describe Rego rules as "returning" values or having a + "public API" in the imperative sense. +- There is no call/return mechanism, no early returns, and no try/catch. + +### Testing Idioms + +- Testing each conjunction term independently is **sufficient and idiomatic**. + Because rules compose declaratively (AND/OR), full coverage of individual + clauses provides equivalent assurance to testing the composed rule. +- Do not request integration tests through higher-level rules (e.g., + `is_registry_dependency`) when individual clause tests exist and `make test` + enforces 100% coverage. +- This repo enforces 100% test coverage via `make test`. If coverage is met, + the tests are sufficient. + +### Idiomatic Patterns to Suggest + +When reviewing Rego code, prefer these idiomatic patterns over verbose alternatives: + +| Instead of | Suggest | +|------------|---------| +| Explicit iteration / index-based loops | `some x in collection` | +| Manual key-existence checks | `object.get(obj, key, default)` | +| Chained equality (`x == "a"; x == "b"`) | `x in {"a", "b"}` | +| Verbose negation | `not rule_name` | + +### What NOT to Suggest + +- **Early returns or control flow** — Rego has none. +- **Try/catch or error handling** — Rego has no exceptions. +- **Null guards for parser-guaranteed keys** — if the input schema guarantees a + key exists (e.g., from `ec.oci.blob` or SLSA attestation structure), do not + suggest defensive key-existence checks. +- **Integration tests through higher-level rules** — when individual clause tests + exist and coverage is 100%, this adds no value and reflects imperative testing + assumptions. + ## PR Conventions Conventional commits are encouraged. Run `make ci` before pushing. CI runs on every PR via