MFN Engine
Most Favoured Nation eligibility calculation: rule layers, cascade detection, and the impact-emit pattern.The Most Favoured Nation engine determines which clauses each LP is eligible to elect into their side letter. It runs as a pure in-memory calculation over a pre-loaded data bundle.
Rule layers
Rules are applied in order. Each layer narrows or overrides the eligibility determined by the previous layer.
| # | Layer | Description |
|---|---|---|
| 1 | Basic rule | Fund-wide comparator gates. Dimensions: amount (commitment size), date (admission date), closing (closing sequence). Logic operator: AND or OR. If the basic rule says "OFF" on all dimensions, MFN is universal. |
| 2 | General rules | Per investor-category include/exclude. E.g. "Exclude sovereign wealth funds from fee-waiver clauses." |
| 3 | Individual rules | Per commitment include/exclude overrides. E.g. "Exclude LP X from clause Y with rationale Z." |
| 4 | Clause exclusions | Per-clause carve-outs at fund-wide, category, or commitment scope. |
Cascade detection
When a mutation touches any MFN-relevant state (rule CRUD, commitment amount change, clause assignment), the withImpact helper in src/services/impact-emit.ts performs a before/after diff:
- Snapshot the MFN bundle before the mutation
- Execute the write
- Snapshot the MFN bundle after the mutation
- Run
calculateMfnFromDatafor every commitment - Emit
mfn_eligibility_changedevents for each (commitment, clause) pair where eligibility flipped
These derived events point back at the root mutation via the caused_by column in fund_events, enabling full provenance walks: "this LP gained eligibility for clause X because user Y created general rule Z."
Performance
Caching
The MFN bundle is cached per-fund for 60 seconds. Cache invalidation is triggered by any write to the MFN rule tables, clause assignments, or commitment amounts.