The brief. A treaty specified only in prose — the way they actually arrive. Your first deliverable is not code: it is a battery of assertions, one pinned net per sentence of the spec (and one per collision between sentences). Only when the battery is written — and failing against the stub — do you implement
Ceded. The sign rule is easy; the two boundary rules interact, and the interactions are where a real cession quietly leaks money.
This is the hard version of Lesson 1's claim that ceded is just a negative amount. Yes — but how much is negative depends on rules that read innocently until they meet each other. Pin them before you code, and you will never ship a cession that cedes more than the claim, or one that quietly cedes the attritional bulk.
The spec — all of it, in prose (the only prose you get)
Alpina places a per-risk facultative treaty over the 2025 book. Ceded(claim, kind, gross) returns the ceded amount (stored negative); net is always gross + Ceded(...).
- Flat cession. Every individual claim cedes a flat 100 — so its net is
gross − 100. - No over-cession. A certificate can never cede more than the claim is worth. The ceded amount is capped at the claim's gross, so net never goes below 0.
- The attritional bulk is untouchable. The attritional amount has no individual claim sizes, so a per-claim treaty cannot cede from it — its ceded is 0, its net stays the gross.
The rules of the game
- Battery first. One row per spec sentence — and, where the marks are, one row per interaction: the flat 100 meeting a claim smaller than 100 (rule 1 vs rule 2), and the flat 100 meeting the attritional row (rule 1 vs rule 3). Read rule 2 against
C1(80) andC6(90). Read rule 3 againstATT. - Watch it fail. With the stub in place your battery must be red — the stub cedes nothing, so no line's net is right yet. A battery that cannot fail proves nothing.
- Then implement
Cededuntil every row is green. No editing a pinned net to match your code — the prose is the authority.
Your workbench
using MeshWeaver.Layout;
using MeshWeaver.Layout.Composition;
using MeshWeaver.Layout.DataGrid;
using MeshWeaver.Utils;
// YOUR TREATY — nothing yet. Implement the three sentences of the spec, in order.
// Ceded is stored NEGATIVE; net = gross + Ceded(claim, kind, gross).
static double Ceded(string claim, string kind, double gross)
=> 0.0; // TODO: flat 100 per INDIVIDUAL claim, capped so net never < 0, and 0 from the attritional bulk.
record Case(string Spec, string Claim, string Kind, double Gross, double ExpectedNet);
record Row(string Spec, string ExpectedNet, string ActualNet, string Result);
// TWO rows are seeded (both plain claims). Grow this battery straight from the prose —
// the floor (C1 = 80, C6 = 90) and the untouchable attritional (ATT) are where the marks
// are — BEFORE you trust your implementation.
var cases = new[]
{
new Case("plain claim: C4 760 cedes 100 -> net 660", "C4", "Individual", 760, 660),
new Case("plain claim: C2 240 cedes 100 -> net 140", "C2", "Individual", 240, 140),
};
var rows = cases.Select(c =>
{
var net = c.Gross + Ceded(c.Claim, c.Kind, c.Gross);
var ok = Math.Abs(net - c.ExpectedNet) < 1e-9;
return new Row(c.Spec, c.ExpectedNet.ToString("N0"), net.ToString("N0"), ok ? "✓ green" : "✗ red");
}).ToArray();
var green = rows.Count(r => r.Result.StartsWith("✓"));
Controls.Stack
.WithView(Controls.H4($"Treaty battery — {green}/{rows.Length} green (grow it, then implement)"))
.WithView(Controls.DataGrid(rows)
.WithColumn(new PropertyColumnControl<string> { Property = nameof(Row.Spec).ToCamelCase() }.WithTitle("Spec sentence"))
.WithColumn(new PropertyColumnControl<string> { Property = nameof(Row.ExpectedNet).ToCamelCase() }.WithTitle("Expected net").WithAlign("end"))
.WithColumn(new PropertyColumnControl<string> { Property = nameof(Row.ActualNet).ToCamelCase() }.WithTitle("Actual net").WithAlign("end"))
.WithColumn(new PropertyColumnControl<string> { Property = nameof(Row.Result).ToCamelCase() }.WithTitle("Result"))
.Resizable(false))
A hint that is not a spoiler: three of the seven claims do not simply lose 100. Two are too small to give it, and one is not a claim at all. Your battery must know which before your code does.
Battery written, treaty green — or arguing with a sentence? Reveal the solution — the full seven-claim battery with both interactions pinned, and the two-line treaty that satisfies it.