Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] internal consistency

The statement Do not describe Rego rules as returning values contradicts actual Rego semantics. Rego functions and complete rules DO produce values. The guidance is overly prescriptive.

Suggested fix: Soften to: Avoid imperative framing like early return or fallthrough. It is acceptable to say a rule or function evaluates to or produces a value.

- 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] technical accuracy

The claim that rules evaluate to true or undefined is incomplete and misleading. Rego rules can evaluate to arbitrary values. Complete rules (defined with :=) evaluate to their assigned value, set rules produce sets, and object rules produce objects. This codebase uses value-producing rules extensively. Only boolean rules evaluate to true/undefined.

Suggested fix: Revise to: Boolean rules (no :=) evaluate to true or undefined. Rules defined with := evaluate to their assigned value, or undefined if no body matches. Functions accept arguments and produce values.

- There is no call/return mechanism, no early returns, and no try/catch.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] technical accuracy

The claim there is no call/return mechanism is factually incorrect. Rego has user-defined functions that are called with arguments and produce values. This codebase uses them pervasively. While Rego functions are not imperative, stating there is no call/return mechanism is wrong.

Suggested fix: Revise to: Rego has functions but no imperative control flow — no early returns, no exceptions, no side effects. A function evaluates to the value of whichever body conditions are satisfied.

### 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
Expand Down
Loading