# Recording decisions ## Task and place A decision record captures a choice the act text alone cannot settle, so a later reader inherits the reasoning instead of redoing it. This stage sits after construct choice and before review: inventory and construct choice flag the close calls, records settle them, and review reads the records alongside the rules. ## Inputs - The close calls flagged by inventory and construct choice: tariff shape, payout bound, penalty rounding, and the premium base in the running example. - The [decision record template](/handbook/files/templates/decision-record.md). - The filled examples: the [EAI tariff decision](/handbook/files/filled/eai-decision-tariff.md), the [EAI threshold decision](/handbook/files/filled/eai-decision-threshold.md), the [EAI penalty decision](/handbook/files/filled/eai-decision-penalty.md), and the [EAI premium-base decision](/handbook/files/filled/eai-decision-premium-base.md). ## Actions - Record what a later reader cannot re-derive: construct choices among close neighbors, boundary readings, and policies for act silence such as rounding. - Do not record direct transcription: rule text that follows the act word for word needs a source label, not a record. - For each record, state the question, list the options with their costs, take a position, justify it from the act and the machine behavior, and — for a semantic choice — name the test that breaks if the position flips. A choice of representation between semantically equivalent forms gets no such test: no scenario can fail a correct decision table while passing identical strict rules, so the record judges the form by traceability, maintenance, and diagnostics instead. - Link each record to the rules and tests it governs, and reopen it when the cited article changes. ## Decisions The stage's own decision is which items earn records. In the running example four items qualify: the tariff shape (EAI-D1), the payout bound (EAI-D2), the penalty rounding policy (EAI-D3), and the premium base (EAI-D4). Everything else in the modeled articles transcribes directly and needs only source labels. ## Artifact The artifact is one record per close call, with fields following the [decision record template](/handbook/files/templates/decision-record.md): record id, status, context, question, options considered, position, justification, distinguishing scenario, assumptions, consequences, open questions, and review. EAI-D1, tariff as twenty-two strict rules. Status: accepted. Context: Article Seventeen pairs twenty-two risk classes with rates from 0.12 percent to 2.96 percent, and the premium base multiplies the insured sum by the rate (amended from payroll by finding EAI-R3; see EAI-D4). Question: one decision table or twenty-two strict rules? Options considered: a decision table routing class to rate under a uniqueness policy, or twenty-two strict rules each guarded by one class. Position: twenty-two strict rules. Justification: each class-rate pair carries its own source label, so a wrong row fails and reads alone; strict fits because the article admits no exceptions; the premium computation stays a separate rule reading the derived tariff. Consequences: adding a class means adding a rule, and each row owns its premium check — removing the class-7 rule fails exactly the class-7 check. This is a representation choice: an equivalent decision table would pass the same suite, so no test prefers the rules; the record prefers them for per-row labels and per-row failures. Filled form: the [EAI tariff decision](/handbook/files/filled/eai-decision-tariff.md). *Non-runnable sketch: the rejected decision-table form, shown for contrast only; never checked or tested.* ```law decision TariffByClass(risk: Integer) -> Decimal { table hit unique { when risk == 1 => 0.0012; otherwise => 0.0296; } } ``` EAI-D2, inclusive thirty boundary. Status: accepted. Context: Article Nineteen conditions payout on capacity loss from thirty to one hundred percent. Question: inclusive or exclusive bounds? Options considered: inclusive at both ends, exclusive lower bound, exclusive upper bound. Position: inclusive at both ends. Justification: the act's range wording gives no exception at either end, and the strict rule then stays silent outside the range instead of denying. Consequences: thirty percent qualifies while twenty-nine does not, one hundred qualifies while one hundred one stays silent — and each end owns its pair of tests, because the lower pair alone never exercised the upper bound. Filled form: the [EAI threshold decision](/handbook/files/filled/eai-decision-threshold.md). EAI-D3, no rounding policy. Status: accepted. Context: Article Nine sets the penalty at one and a half percent of the unpaid sum per day of delay, with no rounding instruction. Question: round the penalty, and if so how? Options considered: the exact product, or rounding to whole currency units. Position: the exact product, with no rounding step. Justification: any rounding rule would be authorial invention; the act states a plain product, and the package computes unpaid times 0.015 times days exactly. Distinguishing scenario: the fractional probe — one hundred unpaid over one day yields exactly 1.5 KZT, and smuggling `round(…, 0, "HALF_UP")` into the rule fails exactly that probe while the round-figure check still passes. Assumptions: exact engine arithmetic, unrounded amounts acceptable downstream. Consequences: downstream readers see unrounded amounts; revisit this record if the act or a regulator instruction adds a rounding rule. Filled form: the [EAI penalty decision](/handbook/files/filled/eai-decision-penalty.md). EAI-D4, premium base is tariff times insured sum with the minimum floor. Status: accepted. Context: Article Seventeen point 1 multiplies the tariff by the contract insured sum, point 2-1 raises a below-floor base to the minimum wage, and Article Sixteen point 1 sets the sum at or above payroll without ever equating them. Question: payroll times rate, or insured sum times rate with the floor? Position: the base reads the insured sum from the case; the due premium is the base at or above the case-supplied wage, else the wage. Justification: each norm maps to one rule with its own source label, and the two premium rules split the input space on a single comparison. Distinguishing scenario: payroll one million with insured sum two million answers 59200 (the old payroll reading answered 29600); the floor and boundary probes pin the minimum branch from both sides. Assumptions: the insured sum arrives from the case, S ≥ F is assumed rather than enforced, and the wage figure is case input with no pinned statutory value. Filled form: the [EAI premium-base decision](/handbook/files/filled/eai-decision-premium-base.md). ## Worked example The four records read against the candidate suite as follows. The tariff record trips row by row: an insured sum of one million at rate 0.0296 yields twenty-nine thousand six hundred for class twenty-two, and every other class owns the same shape of check with its expectation derived from the source percent. The threshold record trips on two boundary pairs, thirty against twenty-nine and one hundred against one hundred one. The rounding record trips on the fractional probe: one hundred unpaid over one day yields exactly 1.5 KZT, with no rounding step in the rule. The premium-base record trips on sum-versus-payroll: the same million of payroll with a doubled insured sum answers fifty-nine thousand two hundred. Observed on the accepted candidate with the pinned tool (`law` 0.1.0, semantics law.core/0.2, published build): ```text ok [kz.corpus.employee_accident_insurance#authored] tests/bounds.lawtest / EAI-LOSS-100-QUALIFIES ok [kz.corpus.employee_accident_insurance#authored] tests/bounds.lawtest / EAI-LOSS-101-SILENT ok [kz.corpus.employee_accident_insurance#authored] tests/penalty-fractional.lawtest / EAI-PENALTY-FRACTIONAL-EXACT ``` ## Pitfall Two failures bracket this stage. Recording nothing leaves the next reader to reopen every close call from scratch. Recording everything buries transcription under process paper. The test is simple: if the act text plus the rules answer the question, no record; if two competent readers could differ, write one. A semantic record without a named tripwire test rots first; a representation record without named traceability grounds never stood up. ## Verification The stage is done when every semantic record names the tripwire failures its fault must produce, the representation record names its traceability grounds, and the candidate suite passes thirty-seven of thirty-seven. Criterion per record: flip the position in a scratch copy and watch the expected failures arrive — every failure explained by the broken requirement, and any unexpected failure investigated on its own. A lone failing test is the special case of an isolated probe (the class-7 row removal, the floor-rule removal), not the general rule: the `>= 30` → `> 30` weakening trips three independent checks for one requirement, and that is healthy overlap. The boundary excerpt above is the tripwire evidence for EAI-D2; the per-row tariff checks are the tripwires for EAI-D1's rows (the rule-vs-table form itself has no failing test by design); the fractional probe is the tripwire for EAI-D3; the sum-distinguishes probe is the tripwire for EAI-D4. The source seven-of-seven measures the snapshot, not the records. ## Limits Records explain; they prove nothing about the act. An amended article reopens every record citing it, and a record never overrides the pinned text. When the act and a record disagree, the act wins and the record is rewritten. ## Next step Continue with [Absence, negation, and conflict](/handbook/absence-negation-conflict/), which turns boundary readings into explicit policies for every relation. ## Sources - [Tutorials](/tutorials/) — the worked drills behind vocabulary, constructs, and checks. - [Language reference](/constructs/) — syntax and semantics of every construct. - [Command line](/cli/) — the check and test commands used above. - [Vocabulary first](/handbook/vocabulary/) and [Choosing a construct](/handbook/constructs/) — the previous stages.