TypedScope or ScopeFacade
Array of DecideRule (function or filter when clauses)
Branch taken when no rule matches. Either the branch
id ('rejected') or the id plus what falling back to it MEANS
({ branch: 'rejected', label: 'No rule fired' }). The label lands on
evidence.defaultLabel — the default is chosen by no rule, so it is the
one branch that rules[].label can never describe.
Error behavior: If a when function throws during evaluation, the rule is
treated as non-matching (matched: false) and the error message is captured in
matchError on that rule's RuleEvidence entry. Execution continues with
subsequent rules; errors do not propagate to the caller.
Under a redaction policy the evidence is served where it is built, so one form reaches every
observer and the returned result: a threshold is a detached copy read once, or a hole
(thresholdRedacted), and matchError may be masked. The rules still evaluate on the real values. A
rule's label and the default's label are author text and are served as written: do not build one
from a selected value.
Empty-filter behavior (anti-vacuous-truth): a filter rule whose when is
{} (no evaluable conditions) NEVER matches. This deliberately inverts the
Prisma/SQL where: {} intuition ("match everything") — a rule that asserts
nothing must not win a branch on vacuous truth. Use defaultBranch for the
catch-all instead. Unknown filter operators also never match (dev mode warns).
Evaluates rules in order (first-match). Returns a branded DecisionResult.