Library · Data Practice OS
Where business rules run after migration
Reference guide · Published · Source reviewed
Extracting business rules covers extracting rules from legacy code. This page covers the next question: once extracted, where does a rule live, and what executes it?
Source and status. a platform team Options paper: executable rules for registration and licensing (draft, 29 Oct 2026, "not ready for a decision"; the scores are provisional). One input is accepted: an architecture decision record from the business-rules programme, that the governed rule stays canonical.
The principle: one rule of record, many projections
- The rule of record is a rule card in a governed rule repository. It has a Given/When/Then statement, citations, an owner,
effective_from/effective_to, and a mapping to where it is implemented (how to keep that mapping evidenced and queryable: Tracing rules from legacy code to modern code; its claim dates are record time, noteffective_from/effective_to). - dbt tests, DMN decision tables, engine code and documentation are projections: generated from the rule, or tested against it. None of them is the record.
- Every decision an engine makes keeps a trace: which rules and which parameter versions produced it.
This matters for AI too. An agent answering "why was this fee charged?" should cite the rule card and its effective version, not a code path.
Rule authority
From the source draft AI-Ready Data and Context Lifecycle (revised 4 Nov 2026). Proposed practice, not an agreed decision. See Rule authority and AI readiness assessment.
- Text extracted from a policy is evidence, not executable logic. Before a rule is encoded, its card records the approval, applicability, effective dates and exception precedence.
- Rules or relationships generated by a model, including those mined from legacy code by an LLM, stay proposals until the responsible owner validates them. Mark them
status: proposedon the card; onlystatus: approvedcards may be projected into dbt tests, decision tables or engines. - Each decision records the facts used and the rule version that supported it (Decision provenance).
Options the platform team compared
| Option | Score (max 60) | Note |
|---|---|---|
| 1. Effective-dated reference data | 46 | Complete scoring |
| 5. Bespoke rules language (Rust/Go) | 39 | One unknown |
| 0. Rules in service code | 34 | Today's default |
| 2. OpenFisca | 33 | One unknown |
| 4. DMN or GoRules ZEN | 32 | Two unknowns |
| 3. Catala | 25 | Reference only: unstable compiler |
The gates: the governed rule stays canonical, and the option is vendor-neutral with an exit. The platform team's draft recommendation is effective-dated reference data for parameters, plus a logic engine (OpenFisca or DMN/ZEN) chosen in a spike. The spike runs real renewal rules and known hard cases against the Given/When/Then cases.
Two timelines for reference data
Fee tables, eligibility sets and thresholds are dated rows (Effective dating, SCD2). The platform team adds a second date: when each version was deployed. With both, you can replay a past decision with the rules as they were known then, not as later corrected. That is often what an appeal or an audit needs.
-- parameter as at a decision date, as known at a deploy date
select fee_amount
from dw.fee_schedule
where fee_code = :fee_code
and :decision_date between effective_from and coalesce(effective_to, '9999-12-31')
and deployed_at <= :as_known_at
qualify row_number() over (partition by fee_code order by deployed_at desc) = 1;
This table is also the parameter store for any rules engine, so the data platform holds rule parameters even where application code holds the logic.
Mine once, use twice
The platform team extracted 2,050 rule cards from GEN (661 validation, 639 policy, 377 lifecycle, 373 calculation). For an analytics migration you keep only rules that affect derived data. Feed all extracted cards to the rule repository anyway, because application modernisation will need them. Mine the legacy once.
Not when
- A handful of stable rules with no effective dating: plain SQL in a
DWmodel with tests is enough. - Do not choose an engine before the spike has run your hardest real cases, including a rule with a suspected legacy defect.
Related: Extracting business rules, Code conversion, Medallion layers and modelling.
Source links: Data Practice reading list.