From cae489c434fc84306f3676dea7b7dfee314bfb78 Mon Sep 17 00:00:00 2001 From: fullsend-code <278716306+fullsend-ai-coder[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:12:40 +0000 Subject: [PATCH] docs(#1757): add Rego evaluation model guidance to AGENTS.md Add a "Rego Evaluation Model (for AI reviewers)" section to AGENTS.md covering Rego's declarative semantics, idiomatic testing patterns, and common anti-patterns that AI reviewers should avoid suggesting. Key additions: - Evaluation semantics: rules are OR/AND propositions, not functions with return values or control flow - Testing idioms: testing conjunction terms independently is sufficient; do not request integration tests when clause coverage exists - Idiomatic patterns table: some x in collection, object.get, set membership, negation - Anti-patterns: no early returns, try/catch, null guards for parser-guaranteed keys, or integration test requests when coverage is 100% This addresses repeated false-positive findings from PR #1745 where the review agent applied imperative-language heuristics to Rego code across 5 review cycles. Closes #1757 --- AGENTS.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) 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