Originally created by: grynn-in
Materiality is a literal in the models that post and reconcile intercompany and deal journals. abs(...) >= 0.005 appears throughout the elimination rule table:
{# models/gold/gold_ic_eliminations.sql:143-148 #}
('group', 'matched', ..., 'abs(post_m_a) >= 0.005'),
('group', 'nci', ..., 'abs(post_n_a) >= 0.005'),
('group', 'difference', ..., "ic_difference_account != '' and abs(post_d_a) >= 0.005"),
with the same literal repeated in gold_ic_reconciliation, gold_ic_unmatched, gold_business_combination_journal, gold_business_disposal_journal, gold_goodwill_amortisation_journal and gold_equity_method_associates — 33 occurrences across eight models by a rough count.
Half a cent is a sensible rounding epsilon and is probably right as a default. The problem is that it is the only answer available, and it is not the same kind of number in every currency or at every scale: half a unit of a currency quoted in thousands per USD is not half a cent, and a group consolidating in the billions has a different idea of immaterial from one consolidating in the millions.
konsol#180 records the same class of problem from the other end: the trial-balance balance check is an absolute ±0.01 and rejects good files at large-currency scale.
The epsilon was written inline at each site as the models were built, and there was no declared tolerance to read at the time.
There is already a precedent for this exact thing, one field away: ic_difference_tolerance on the Consolidation Group root, declared in konsol, synced to epm_gold.consolidation_groups, validated non-negative, and already read by the elimination models.
materiality_floor() — as the single definition, so the literal appears once rather than 33 times. That alone is worth doing and changes no behaviour.0.005.usd_log10 on ISO Currency already exists for exactly that purpose in the FX guard (macros/fx_magnitude.sql). Relative rather than absolute is the same fix konsol#180 needs.Step 1 is mechanical and makes 2 and 3 a one-line change later.
Not a failure with the current data — it is a single-scale assumption. Visible as 33 copies of one number that nothing can configure.
🤖 Generated with Claude Code
Originally posted by: grynn-in
Step 1 (one materiality_floor() macro) shipped in PR [#211]. Steps 2-3 (a group-declared or currency-scaled floor) stay open.
Related
Tickets:
#211Originally posted by: grynn-in
Decision: the materiality floor is group-declared, with a currency-scaled default
Decided by Deepak Pai, 18 September 2026.
First, a correction to this issue's premise
Measured on
mainbefore deciding. The issue says "the literal 0.005 in 33places". That is not the current state:
The macro already exists and its own comment anticipates exactly this decision:
"One definition, so a later change (a group-declared floor, a currency-scaled
floor) is one edit." So the work is far smaller than the issue implies.
The decision
materiality_floor()stops returning a constant.A new field on the Consolidation Group root:
materiality_floor(Float).It does not overload
ic_difference_tolerance, which already exists andmeans something different — the intercompany difference tolerance. One field,
one meaning.
When the field is blank, the floor is derived from the currency's declared
minor unit — half the smallest representable unit, read from
ISO Currency.minor_unit:minor_unit 2 → 0.005 76 currencies (reproduces today's constant)
minor_unit 0 → 0.5 8 currencies
minor_unit 3 → 0.0005 4 currencies
The effective floor is written into the build's vars and log, so it is
inspectable rather than computed invisibly inside SQL. A declared default is
only compatible with konsol#247 if someone can see what it resolved to.
The 3 strays in
assert_hierarchy_node_as_of.sqlroute through themacro.
tests/test_materiality_literal.pyhas a hole that let them in;that gap is part of this work.
Why a derived default rather than a hard one
The literal 0.005 is correct only for two-decimal currencies. On a JPY balance
it is a hundred times smaller than the smallest representable amount, and on a
three-decimal currency it is ten times too coarse. Deriving it from
ISO Currency.minor_unitmakes it right across all 15 currencies in playwithout asking anyone, and the rule is declared rather than folklore.
Options rejected
audit, and the constant is the silent fallback konsol#247 forbids.
ic_difference_tolerance. One field meaning two things: a changeto the IC tolerance would silently move materiality. Classic overload.
recommended option, chosen partly because currency-scaling "could turn
assertions red on upgrade". That objection does not apply — there are zero
customers as of 18 September 2026, so there is no installed base to protect
and no reason to ship the less correct default first.
Sequencing
Step 2 needs a currency on the row, which is konsol#253 (now decided: the
trial balance carries its currency and every read names one). Land that column
first; the rest of this issue does not depend on it.
Explicitly out of scope
The 55 occurrences of
0.01across the assertion suite are not themateriality floor — they are tie-out tolerances (
abs(a - b) > 0.01) inindividual assertions, plus 4 float-equality comparisons at
0.000001, 3 at0.0001and 1 at0.001. They are absolute and therefore carry the same defectas konsol#180: meaningless for a zero-decimal currency, too loose for a
three-decimal one. Separate issue, not covered by this decision.