Books / Law as Code in Practice: French Family Benefits / Chapter 5
Part II · Chapter 5
How a Scenario Is Written

Contents of Law as Code in Practice: French Family Benefits
By the end you can read one scenario and explain what its successful execution does and does not establish.
Lawyer: whether the expectation follows the displayed wording.
Analyst: which boundary the case exercises.
Developer: facts, question, expectations and declared test world.
The family’s question
The Garniers ask: “How do you check a rule before applying it to our file?” Predict whether a successful scenario proves every possible household correct.
Use the Moreau birth-grant card from Chapter 2 for a small example. Article L. 531-2 CSS, pinned December 2020 edition, uses ressources ne dépassent pas un plafond: resources do not exceed a ceiling. Scénario → worked test situation → a .lawtest file. The equality boundary is a useful first scenario because the phrase includes equality.
Facts, question, expectation
This is the complete equality-right test in the Moreau case package; the file’s language, package and namespace header is omitted:
test "PlafondEgal-droit" {
given {
context { legal_time @2025-07-15; decision_time @2025-07-15T12:00:00Z; knowledge_time @2025-07-15T12:00:00Z; timezone "Europe/Paris"; }
assert "grossesse": fr.pf.paje::attente_naissance(entity_ref("urn:law:examples:fr:moreau:menage"), entity_ref("urn:law:examples:fr:moreau:enfant")) { origin case_input; }
assert "base": fr.pf.paje::plafond_base_taux_plein(entity_ref("urn:law:examples:fr:moreau:menage"), 30000 EUR) { origin case_input; }
assert "bmaf": fr.pf.paje::bmaf_applicable(entity_ref("urn:law:examples:fr:moreau:menage"), 400 EUR) { origin case_input; }
assert "examen": fr.pf.paje::date_examen_situation(entity_ref("urn:law:examples:fr:moreau:menage"), entity_ref("urn:law:examples:fr:moreau:enfant"), @2025-07-01) { origin case_input; }
assert "ressources": fr.pf.paje::ressources_annuelles(entity_ref("urn:law:examples:fr:moreau:menage"), 35841.00 EUR) { origin case_input; }
}
evaluate truth(fr.pf.paje::droit_prime_naissance(entity_ref("urn:law:examples:fr:moreau:menage"), entity_ref("urn:law:examples:fr:moreau:enfant")));
expect truth_status == TRUE_ONLY;
expect evaluation_status == COMPUTED;
}
Read it in three passes. given supplies the dated situation and the origin of each fact. evaluate asks about the right. TRUE_ONLY requires support for the proposition and no support for its opposite. COMPUTED means that evaluation completed; it does not certify legal correctness. The examination date is a supplied file fact here, not an invented reply to a judgment request.
| Recorded check | Outcome |
|---|---|
| Equality: birth-grant right | Established |
| Equality: €919 award claim | Established |
| Above ceiling: right and award claims | Not established |
| Missing resources: right and award claims | Not established; a separate why_not query identifies the unresolved annual-resource premise |
Recorded on 11 October 2026 with law 0.1.12. These are artificial teaching inputs, as explained in Chapter 2.
The declared world
A test must also say which model it runs against. The manifest names the suite and the world, starting with the case package:
[[tests]]
family = "examples.fr.pf.paje.prime_naissance_moreau#cas"
regression = false
suites = ["tests/prime-naissance.lawtest"]
world = ["examples.fr.pf.paje.prime_naissance_moreau", "fr.pf.paje"]
The case package imports the benefit canon; it does not copy the grant rule. The saved law ask questions and the declared scenarios cover the same family files.
Change one thing
The neighbouring test adds a cent above the ceiling. Another removes annual resources. Both ask the same proposition. They check different risks: a boundary comparison and an incomplete file. A single successful equality test would leave both risks untested.
A second reading and a hand computation
The case’s hand computation records the arithmetic independently of the result: the ceiling comes from the base and statutory rate; the award comes from the BMAF and grant rate. A reviewer can recompute those steps with fractions, then inspect the answer’s applied rules and source anchors.
A useful method is a blind second reading: give another reader the pinned text and case facts before showing the expected answer. Compare their reading, including exclusions and dates, with the proposed test. Agreement on arithmetic is a different check from agreement on the legal construction.
The package’s check.py also checks the rule identifiers in the proof and the annual-resource premise in the why_not graph, then runs the declared tests. Testing the status alone would miss an answer reached on unintended grounds.
What this gives the fund
A reviewable example connects a legal phrase to its boundary, supplied facts and expected outcome. The fund can preserve that expectation through a change and explain why a new result should be investigated. Passing it does not establish legal correctness for every file or certify the entire benefit model.
Where Catala stands on this
Catala has a mature testing workflow: clerk test discovers scope tests and command-output tests, with backend checks available (Catala book, ch. 3.3). This is shared ground: both approaches preserve examples and expectations. Arxo adds built-in query statuses and a why_not graph whose missing premises the check can inspect. Catala 1.3.0 has no dedicated built-in form for the “not established, missing this premise” query answer; an application can define its own checks for absent inputs. For the fund, a scenario can preserve the reason a file is incomplete as well as the amount on a complete file.
Run the scenario
From a local checkout with law and Python 3.12+ installed, start at the repository root:
cd corpus/laws/fr/pf-paje/examples/prime-naissance-moreau
law test . --json
python3 check.py --law "$(command -v law)" --out "$(mktemp -d)"
These local commands use the case package from Chapter 2 and its installed checkout dependencies. The declared tests preserve expectations; the saved questions preserve full answer documents for inspection.
Exercise
- Which block holds the family facts?
- Which assertion covers the equality boundary?
- Why inspect the applied rule in addition to the truth status?