Decisions & Scoring

How BlazeRules turns matched rules into a decision, a score, a risk band, and a winning rule per record.

For every record, BlazeRules produces four things from the rules that matched: a categorical decision (chosen by precedence), a numeric score (accumulated from weights), a risk band, and the winning rule. This page explains how each is derived and how you route on the results.

Actions

Each rule declares an action, the categorical verdict it votes for when it matches:

approve · flag · review · block · score

The precedence ladder

When several rules match one record, the record's decision is the strongest matched action, chosen by a precedence ladder. The default ladder, from strongest to weakest:

block > review > flag > score > approve

Ties are broken by severity, then by priority.

Higher severity wins over lower severity; if severity is also tied, the higher numeric priority wins.

You can override the ladder — and the default action for records that match nothing — with a top-level decisions: block:

decisions:
  default: approve
  precedence: [approve, flag, review, block]

Here default: approve is the verdict for unmatched records, and precedence reorders the ladder (listed weakest to strongest in this example).

precedence is ordered weakest to strongest. A later label in the list outranks an earlier label.

Scoring and risk bands

Independently of the decision, every non-shadow matched rule's weight is added into the record's score. If a matching rule has no weight and its action is not approve, the engine contributes a severity-derived default score. A positive score_cap caps the accumulated score after that rule contributes.

The result exposes per-record scores, and each score maps to a risk_bands value:

Risk bandRule
HIGHdecision is BLOCK, or score is >= 80
MEDIUMdecision is REVIEW, or score is >= 40
LOWdecision is FLAG, score is positive, or no higher band matched

Decision vs score

These are two separate outputs derived from the same matches:

Decision — a categorical verdict (approve / flag / review / block). Chosen by the precedence ladder among matched actions.

Score — a number, the sum of the weights of all matched rules. Mapped to a risk band (HIGH / MEDIUM / LOW).

Shadow rules

A rule marked shadow: true is evaluated and counted, but excluded from the verdict. Use shadow rules to measure a candidate rule's match rate against live traffic before letting it affect decisions — a safe rollout path.

Shadow matches still appear in match_counts / rule_match_counts. They do not add score, do not change decision_codes, and cannot become the winning_rule_id.

Routing outputs

The result object carries everything you need to route records. The key fields:

n_records, n_matched,
decisions, decision_codes,
scores, risk_bands,
winning_rule_ids, match_counts,
matched_indices, timing_ms,
messages_processed, messages_skipped,
error_counts, error_samples

Route with the result's helper methods:

approved = result.indices_for_decision("APPROVE")
not_approved = result.indices_for_not_decision("APPROVE")
by_decision = result.grouped_decision_indices()

To get these routing outputs, run the engine with OutputDetail.DECISIONS. Use OutputDetail.BITMASKS instead when you need per-rule match bitmasks rather than routed decisions.

Where to go next