Skip to main content
An insurance program has two kinds of rules. The filed rating plan says what a risk costs. The underwriting guideline says which risks the carrier writes, who decides, and what each decision rests on. RSL keeps the two in separate files that share one language. This page reads the staffing example of the synthetic carrier Example Mutual. Save both files in one folder, staffing/, to run the commands on this page.
staffing/rater.rsl
staffing/guideline.rsl

What each file owns

The split follows who changes each file, and why. A filed rate changes with a filing, on the regulator’s calendar. An authority limit changes when the carrier decides, often between filings. The split also keeps the rater plain. A rater that a guideline uses declares only rating, so the same file still rates a whole book as a bundle. One rater serves several guidelines, and this page adds a second one below. The facts of one submission live in a third place: the submission log. Its answers and sign-offs go into the guideline, and the stage and the open questions come out.

One kind of program

A guideline is the same kind of program as a rater: answers go in, and outcomes come out. Three lines of the guideline connect the two files:
use links the rater under the name ts. The rater’s record is one input of the guideline, so the rater’s questions keep their names and types. The call ts(self.policy) gives the rater’s own result for that policy. Because both files are one kind of program, one check covers both:
The check holds the guideline to the rules of a rater: types, citations and rounding. A referral is a calculated outcome, so the check reports its cost beside the premium. A guideline reads a rater through its inputs and its outcomes only. A guideline line that reads a calculation inside the rater gets the check message E-USE. So the rater’s steps stay free to change, and each guideline that uses it stays correct.

Two ways to read the rater

The rater has a coded rule: it rates a payroll of $1,000 or more. A guideline chooses what that rule means for a submission.

The short call

The short call reads one outcome. A policy that breaks a coded rule of the rater makes the whole submission ineligible, with the rater’s code:

The match form

A second guideline for the same rater writes small accounts at a minimum premium, with a manager’s sign-off. Save it beside the rater as small-accounts.rsl.
staffing/small-accounts.rsl
A call’s result is a value with two cases. Rated(r) holds the rater’s outcomes, read as r.premium. Declined means that a coded rule of the rater failed. The guideline says what happens in each case, so the same payroll now gives a referral and a premium:
The premium is known before the loss experience is, because the Declined case reads only the minimum premium. A guideline reads one rater in one form: every call is short, or every call is a match.

Roles in chains and roles beside each other

A chain lists roles from lowest to highest. A role does what the roles below it do: it answers their questions and replaces their answers. A write replaces only an answer from the writer’s own role or a role below it, so an assistant leaves a manager’s decision in place. Authority in underwriting is a ladder, and a chain states it once. Each question and each referral then names only its lowest role. The second guideline has two chains:
assistant and bureau stand beside each other, because each chain holds only one of them. Each one answers its own questions and leaves the other’s answers alone. This is how a data source is a role: a loss-data bureau owns the loss experience, and an underwriter above it may correct it.
One order of roles answers one question: who may answer this. A tool and a person get the same kind of name, role:name, and the same rules.

Referrals and sign-offs

A rule with a code makes a submission ineligible. A referral asks a person to decide:
A referral is a named condition with a role and a reason. The compiler treats the condition as one more outcome. So the log knows a referral as soon as the answers it reads are known, often before the premium. A sign-off stands for what its signer read. The status lists, under each open referral, the answers that its condition reads. The sign-off entry records those answers and a hash of them. So the answers that the signer saw are exactly the answers that the sign-off covers. A manager approves facts, and the approval covers those facts only. A higher payroll leaves the approval of a new venture in place. A different age of the firm asks the manager again.

Why a decline is a decision

A decline is the most serious thing that a submission records: the carrier tells the broker that it turns the risk down. So the log keeps two things apart. A typing error meets a rule as readily as a true answer does. A firm of 20 years, typed as 2, fails the same rule as a firm of 2 years. The log has one way to tell them apart: a person or an agent with authority says so. So an answer is recorded or refused, and the account stays open either way. The decline itself is an entry by the role that may offer a quote, and it names the codes that it rests on. The log accepts it only while a rule or a sign-off declines.

Why the log only grows

The log holds what people and tools said and did: one entry for each answer, sign-off, quote, bind and close. Commands only add entries. The status is computed from the entries and the program each time someone asks.
  • The status always agrees with the answers, because the log stores only the answers.
  • Each entry was valid when it was written. The log checks the type of an answer and the role of its writer first.
  • Each moment is still there. The status after any entry is the status that the log had then.
  • The program is fixed. A log holds a hash of its guideline and rater, and it refuses to read under a changed program.
For the same reason, a lapse repairs itself. A sign-off or a quote lapses because its hash differs from the present one, and it stands again when the answers return. Storage is separate from these rules. A log is a .jsonl file or a .sqlite database, and both hold the same entries under the same rules. Each store adds an entry only at the end that the writer read, so two writers take turns.

Why a list item is named by its key

An answer to one item of a list needs an address that stays with that item. A place in the list, such as the first item, moves when someone adds or removes an item before it. An answer at a place then lands on another item. So the log uses the identity that the program already gives: the key of a list that is keyed by a field. An address reads placements[class="clerical"].share, and it names that item for the life of the log.
  • A list that lacks a key is answered whole, as one value.
  • A keyed list is a set of items. The same items in another order are the same answers, and a quote of them stands.

Why a quote is kept and named

A broker holds a quote, so the log keeps each quote as its own entry with the outcomes it gave. A later answer changes the status of the quote, and the entry stays as it was.
  • A log holds several quotes, such as two options for the broker. bind names the one that the insured accepts.
  • A quote rests on the program, every answer and every sign-off. It lapses when one of them changes, and stands again when they return.
  • bind takes a quote only while it stands. So a bound premium is always the premium that the answers give.

Why every quote prices one risk

A broker often wants options: the same firm at two limits. The options differ in the terms of the policy, and the facts about the firm stay the same. The program draws that line. An input marked per quote is a term, and every other input is a fact:
A quote option holds its own answers to terms, laid over the shared answers. A quote of the option prices both together. The log refuses an answer to a fact in an option with the code NOT_A_TERM. Run a submission quotes two limits on one submission.

What --based-on protects

The log takes one write at a time, which puts writes in order. Order leaves one gap open. A correction that lands between a manager’s read and the manager’s sign-off gets approved unseen. --based-on closes the gap. The writer names the last entry that they read, and the log compares what the command reads at that entry and now. A difference refuses the write with the code STALE. The log compares what the command reads, and leaves the length of the log aside. So an unrelated write by a colleague leaves the sign-off valid, and the writer retries only for a real change.