Hapax · Case study · Finance & controlling

The board pack that answers back.

We hid four scenarios in two years of fabricated monthly financials for a fictional Nordic personal-care company, and recorded the correct answer to each in advance. Three independent AI analyses were then asked to explain what had moved and why.

iThe problem

A board pack tells you what moved. Material costs up 12%, gross margin down three points. The figures are usually right. What the pack cannot tell you is why those numbers moved. Was it commodity inflation, or a promotional programme that shifted volume into an expensive product line? The cause sits in the product-level detail, and nobody has time to reach it before the meeting. So the obvious explanation goes into the commentary, the board moves on, and the real cause keeps eating margin.

iiWhat we hid

The company is invented. Paju Consumer Products Oy is a Nordic personal-care and home-care manufacturer with three business units, four product lines, about €155M of net revenue and 480 people, generated in full by a seeded Python model. We built two years of monthly financials for it and hid four scenarios in the data, each designed to test a different way that monthly reporting fails. The correct findings were written before any analysis ran and kept away from everything that followed.

The first scenario is a cost alarm with the wrong cause. Material costs in the Nordics business unit rise 12% year-on-year while unit material costs stay flat. A promotional programme shifted volume into Home Care, which carries nearly 50% material cost against a 30% line average. The board pack flags the cost rise correctly. A finance team reading only the headline will attribute it to commodity inflation. The answer is in the product-line mix, and the evidence, flat unit costs and a volume spike in the expensive line, is in the detail tables.

The second is a real problem the pack partly flags. One large customer in Central Europe, Rheinkauf Gruppe, stretches its effective payment terms from about 45 to 105 days over six months. By December, receivables have grown from €2.06M to €4.49M. In April the company sells and leases back a warehouse, bringing €5.5M of cash and a €2.2M gain in other income. Reported EBITDA falls just 1.4% year-on-year where the underlying fall is 13.7%, and cash looks comfortable all year. The standard pack flags the Central Europe DSO deterioration every month from April, but not the cause, not the customer, and not the link to cash conversion.

The third is good news with a bad story underneath. Revenue in the Baltics grows 27%, ahead of plan, bought with promotional discounts that escalate from 8% to 17% of gross revenue over the year. Three of the ten named Baltic accounts carry discount rates above 18% by December. By the second half of the year, each promotional euro buys 38% less volume than in the first.

The fourth is a trap. January revenue drops 28.7% month-on-month. In isolation that looks like a crisis. But the seasonal pattern is identical to the prior January and to budget: revenue is up 2.6% year-on-year and within 1.6% of plan. The correct answer is to stand down. If an analysis treats a known seasonal pattern as a crisis, the board will question its other findings too.

iiiWhat happened

We ran two layers over the same data. A mechanical variance engine computed the differences between actuals and budget, and between this year and last, and flagged everything that breached a threshold. In twelve months it raised 327 flags, all correct. But a flag only says that a number moved. It does not say why, and it does not say whether the movement matters.

Three independent AI analyses then went through the data and the flags. Each received the same tables and the same briefing, blind to the others and to the answer key, and each logged every file it opened. The briefing named six recurring flag clusters, and for each one the analysis had to explain the cause with evidence or say that no action was needed. Each run produced ten findings.

All three found all four scenarios. The Nordics cost rise was traced in every run to promotional pricing and the mix shift into Home Care, with flat unit costs cited as the decisive evidence. From the per-customer receivables table, all three named Rheinkauf Gruppe and connected the warehouse sale to the comfortable-looking EBITDA. Each run identified the Baltic revenue growth as bought with escalating discounts, at the cost of declining margin. January was stood down cleanly: year-on-year positive, within budget, identical seasonal pattern in both years. Across thirty findings there were no false positives among those worth acting on, and no cited figure was wrong.

Two pieces of evidence in the Baltics scenario went unexamined. Per-customer discount rates were in the data, with three accounts above 18% by December. The fading volume response was there too, 38% weaker in the second half of the year. One run checked customer-level revenue concentration, found it broad, and stopped one column short of discount concentration. All three identified the discounting, but none found the data that shows it is running out of road.

ivExplore it

The explorer below shows a month of the board pack, what the variance engine flagged, what each analysis made of those flags, and how the findings checked against the answer key.

vWhat is real here

Everything on this page is invented. We generated the financials, hid four scenarios in them, and wrote the correct findings before anything ran. A marking script checked the three analyses against that answer key. The full testing method is on the work page.

The method applies to a real month-end. Run the threshold checks on the numbers, then have independent analyses explain the flagged variances with evidence, each working without seeing the others. On a real ledger there is no answer key, so the test is whether the analyses agree and whether a reader trusts their evidence.

The specific figures belong to this dataset. Your numbers, your commentary and your real variances will produce different results.

viReproduce it

The data is generated by a seeded Python script: the same seed always produces the same numbers. A validator checks that the financials are internally consistent before anything else runs: row identities to the cent, aggregation totals, receivables roll-forwards. The variance engine then produces the flags, the three analyses investigate them, and a marking script checks the findings against the answer key. The scorecard was adjudicated by hand against the raw findings, with the mechanical worksheet as the starting point.

The code, the dataset and the full writeup are in the public repository, together with the three analyses as they were written.

viiWrite to us

If your board pack is accurate and still leaves the cause to guesswork, tell us which variances keep coming back and what sits under them.

enquiries@hapax.fi