← Back to home PT
Metodologia aberta

Lineage — from the published number to the line in CVM's file

Lineage — from the published number to the line in CVM's file

There is a difference between auditable and reproducible, and it is the reason this page exists.

Until now this database stated two things: the formula behind each indicator (in /metodologia) and the CVM account each input came from. That is auditable — you can check whether the right account was used. It is not reproducible: to redo the number yourself, you would still have to download CVM's file and guess which line, from which document, in which version.

Lineage closes that chain. For any published indicator it delivers:

ROIC · WEGE3 · 2025 · 0.3846 │ ├─ formula: NOPAT / average invested capital │ ├─ document: annual filing (DFP) 2025, version 1 │ period end 2025-12-31 · made public 2026-02-25 │ file: dfp_cia_aberta_2025.zip (dados.cvm.gov.br) │ └─ inputs ├─ ebit ......... income statement 3.05 "Resultado Antes do Resultado │ Financeiro e dos Tributos" = 7,998,741,000 ├─ lair ......... income statement 3.07 ... ├─ ir_csll ...... income statement 3.08 ... ├─ div_curta .... balance sheet 2.01.04 ... ├─ div_longa .... balance sheet 2.02.01 ... ├─ pl_total ..... balance sheet 2.03 ... ├─ caixa ........ balance sheet 1.01.01 ... └─ aplic_fin .... balance sheet 1.01.02 ...

Every line carries the account code, the description the company itself wrote, the value and the document version. If that account was later restated, lineage shows the value before and after, with the difference. And the link points to CVM's raw ZIP — the actual file, not a copy of ours.

Coverage, measured rather than estimated

Of 60,085 published indicators with a value, 58,951 (98.1%) have every input traceable down to the exact line in the file.

The remaining 1.9% is not a tracing failure: those are items the company did not publish in that filing. The two dominant cases:

missing input occurrences what it means
lucro_controladores 1,001 the company does not split out non-controlling interests
pl_minoritarios 888 same, on the balance sheet
cfo (Piotroski) 129 no cash flow statement filed that year

In those cases the input is marked not traceable, with the reason — and the indicator that depended on it carries the matching flag. There is never an invented account papering over the gap.

Composite origins

The cash-flow chart of accounts varies from company to company: capex sometimes lives in one line, sometimes in two. When the origin is composite (DFC_MI:6.02.01 + 6.02.02), lineage shows both lines separately, each with its value, and their sum must equal the published number. An invariant blocks publication if it does not — today, zero mismatches.

What building this page found

Building lineage was, in practice, an audit of the calculation — and it found a defect that had been live from the start.

Invested capital and net debt were computed with cash or 0. That treats "the company did not publish cash" and "cash is zero" as the same thing. They are different: the first is absence of information, the second is information. The effect was to inflate invested capital (depressing ROIC) and net debt — and the number went out with no flag at all, i.e. clean.

It affected three indicators for one company (ARMAC, fiscal 2021). Small in volume, serious in kind: it is exactly the silence this database exists not to have. The or 0 stays — it is the only arithmetic available — but it now declares itself, via the caixa_nao_publicado flag, and invariant I-L03 blocks publication of any clean indicator whose required input has no backing.

Worth recording that Piotroski had been doing this right all along: when a criterion is missing it publishes parcial_7_de_9 rather than pretending it added up nine.

The lineage invariants

id what it blocks
I-L01 the sum of a composite origin's lines equals the fact's value
I-L02 every account cited as an origin actually exists in the accounts table
I-L03 a clean indicator cannot have a required input without backing
I-L04 every published indicator has its inputs declared
I-L05 end-to-end cross-check: the whole chain, for a sample

I-L02 proved its worth on the very first build: it failed because the origin field can carry an annotation after a ; (one case of a cost line published with an inverted sign, corrected via the income-statement identity), and the naive read looked for an account with the annotation glued to its code. A defect in the reader, not in the data — but it would have become a broken link on the page, and nobody would have seen it.

How to use it

On each company's page, every indicator opens its chain. Through the API, the same object comes back as JSON — the same truth in two formats, so that an AI agent can walk the provenance exactly as a person would.

The standing request holds: find a number that does not match CVM's filing. Now with the whole path in hand.