> ## Documentation Index
> Fetch the complete documentation index at: https://docs.canary.effectiveai.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Check messages: the header and the outcomes

> The `spec` block identifies a rater, and `RatingOutcomes` selects its results.

*Generated from the `rslc` compiler.*

## E-RATING-OUTCOME

**A rater declares its premium outcome.**

`RatingOutcomes` lists the results a rater returns. Each line gives a result its public name and the calculation that produces it: `premium: Policy.premium`.

The check asks for the block, with at least one outcome of type `Premium`. The premium is the rater's money result. Outcomes of type `Num`, `Rate`, `Factor`, `Pct`, `Bool` or an enum publish facts beside it.

The block is the rater's contract with its callers. The compiler follows each outcome back to the inputs it reads, and names any input or calculation that stays outside those paths.

**Example**

The rater ends after `Records` and lacks a `RatingOutcomes` block.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
    }
}
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-RATING-OUTCOME @0-0: strict rater check requires a non-empty top-level `RatingOutcomes` block
```

**Fix**

Add the block at the end of the rater and name the premium calculation.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
    }
}

RatingOutcomes = {
    premium: Policy.premium
}
```

**Other causes**

* An outcome names an input, such as `Policy.payroll`; an outcome names a calculation.
* Two outcomes share one name.
* Two outcomes name the same calculation.
* Every outcome has a type other than `Premium`; declare the premium calculation as `Premium`.
* An outcome has a type outside the list above, such as `Date`.
* The block lists more than 256 outcomes.

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

## E-RATER-METADATA

**The header names carrier, state, product and date.**

The `spec` block identifies a rater. The check asks for four fields, each with a value: `carrier`, `state`, `product` and `effective_date`.

These fields say whose rates the rater holds, where they apply and from which date. A catalog lists each rater by them, so a person finds the right one for a quote.

The compiler prints one message for each missing field. A field with an empty value, such as `carrier: ""`, counts as missing.

**Example**

The `spec` block lacks `carrier`.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.4.1",
    state: AZ,
    product: "Staffing Liability",
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-RATER-METADATA @0-0: strict rater check requires non-empty `spec.carrier` metadata
cost premium: 1 (each list of size 1: 1, 3: 1, 10: 1)
```

**Fix**

Add the field to `spec` with its value.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.4.1",
    carrier: "Example Mutual",
    state: AZ,
    product: "Staffing Liability",
```

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

## E-RATER-METADATA-INVALID

**The header names the rater with product.**

The `spec` block has one field for the rater's label: `product`, the name a customer reads. The check stops a header that writes the label as `name`.

One spelling means every rater in a catalog carries its label in the same field.

**Example**

The `spec` block gives the label as `name`.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
    carrier: "Example Mutual",
    state: AZ,
    name: "Staffing Liability",
    effective_date: 2026-01-01
}
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-RATER-METADATA-INVALID bad/rater.rsl:5:5: `spec.name` is retired; use `spec.product` as the customer-facing rater label
```

**Fix**

Rename the field to `product`. A header that has both fields keeps `product` and drops `name`.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
    carrier: "Example Mutual",
    state: AZ,
    product: "Staffing Liability",
    effective_date: 2026-01-01
}
```

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     name: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

## E-OUTCOME-ROUND

**A rating outcome is a rounded value.**

A filing states how it rounds the premium: to the cent or to the dollar, with a rule for a tie. The check asks every numeric rating outcome to come out of a `round` that states that rule.

A value counts as rounded when it is a `round`, or a sum, difference, `min` or `max` of rounded values and literals. A rounded value multiplied by a factor, such as `self.base * 1.05`, needs a new `round`.

The calculation that holds the `round` cites the page that states the rounding rule. Outcomes of type `Bool` or an enum are exact and pass as they are.

**Example**

The premium returns the exact product of payroll and rate.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
        },
        step rating {
            premium: Premium [cite: manual:p3] = self.payroll / 1000 * rate_per_1000
        }
    }
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-OUTCOME-ROUND bad/rater.rsl:26:13: rating outcome `premium` (Policy.premium) does not pass through an explicit round. State the filing's premium rounding rule with round(x, SCALE, MODE) and cite it, for example `round(x, 0, half_up)` for the nearest whole dollar or `round(x, 2, half_up)` for the nearest cent
cost premium: 1 (each list of size 1: 1, 3: 1, 10: 1)
```

**Fix**

Round the premium with the scale and mode the filing states.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
        },
        step rating {
            premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
        }
    }
```

**Other causes**

* The `round` sits in a calculation whose only citation is on the enclosing `step`; cite the rounding rule on the calculation itself.

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = self.payroll / 1000 * rate_per_1000
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

## E-RSL-VERSION

**A rater declares an RSL version rslc reads.**

The `spec` block declares the RSL version a rater is written in: `rsl: "0.4.1"`. This compiler reads RSL 0.4 and 0.4.1.

The compiler reads the declaration before anything else in the file. A rater that declares another version gets this one message, and the compiler stops there. One clear message replaces a page of syntax messages about a file written for a different compiler.

A patch version such as 0.4.1 only adds to 0.4, so a rater that declares `"0.4"` keeps passing.

**Example**

The rater declares RSL 0.3.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.3",
    carrier: "Example Mutual",
    state: AZ,
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-RSL-VERSION bad/rater.rsl:2:10: RSL's latest version is 0.4.1. This rater is written for RSL 0.3. Rewrite the rater in RSL 0.4.1 and declare `rsl: "0.4.1"` as the first field of `spec`.
```

**Fix**

Declare `rsl: "0.4.1"`. The body of this example already reads as RSL 0.4.1. A rater written for an older version also needs its body rewritten in the current forms.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.4.1",
    carrier: "Example Mutual",
    state: AZ,
```

**Other causes**

* The `spec` block lacks the `rsl` field.
* The rater declares a version newer than the compiler reads, such as `"0.4.2"` or `"0.5"`; update `rslc`.
* The value is something other than a quoted version, such as `rsl: 0.4` or `rsl: "latest"`.
* The `spec` block declares `rsl` twice.

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.3",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] = round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```

## E-RSL-PATCH

**A rule clause needs RSL 0.4.1.**

RSL 0.4.1 adds rule clauses to RSL 0.4. A calculation ends with `exception when … then …`, `with … as … otherwise …` or `overridden by …`. The function `select(low..high, position)` picks a value inside a range.

The check asks a rater that uses one of these forms to declare `rsl: "0.4.1"`. The declared version tells each reader and each tool which forms to expect in the file.

**Example**

The rater declares RSL 0.4, and its premium ends with an `exception when` clause.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.4",
    carrier: "Example Mutual",
    state: AZ,
```

```sh theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
rslc check bad/rater.rsl
```

```text theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
FAIL bad/rater.rsl (strict)
error: E-RSL-PATCH bad/rater.rsl:27:17: rule clauses and `select(…)` are RSL 0.4.1, and this rater declares RSL 0.4; declare `rsl: "0.4.1"` in `spec`
```

**Fix**

Declare `rsl: "0.4.1"` in `spec`. Every RSL 0.4 form keeps its meaning under 0.4.1, so the rest of the rater stays as it is.

```rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
spec {
    rsl: "0.4.1",
    carrier: "Example Mutual",
    state: AZ,
```

> [accordion] Complete files
>
> ```rsl bad/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] =
>                 round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>                                exception when self.payroll < 50000 then 100
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```
>
> ```rsl good/rater.rsl theme={"languages":{"custom":["languages/rsl.tmLanguage.json"]}}
> spec {
>     rsl: "0.4.1",
>     carrier: "Example Mutual",
>     state: AZ,
>     product: "Staffing Liability",
>     effective_date: 2026-01-01
> }
>
> Sources = {
>     manual: Source = {
>         artifact: artifact("00000000-0000-4000-8000-000000000000"),
>         kind: pdf
>     }
> }
>
> Constants = {
>     rate_per_1000 [cite: manual:p3] = 2
> }
>
> Records = {
>     Policy = {
>         inputs {
>             payroll: Num {precision: int} where self in [0, 100000000]
>         },
>         step rating {
>             premium: Premium [cite: manual:p3] =
>                 round(self.payroll / 1000 * rate_per_1000, 2, half_up)
>                                exception when self.payroll < 50000 then 100
>         }
>     }
> }
>
> RatingOutcomes = {
>     premium: Policy.premium
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.