5.2 KiB
Balance Sheet Parser Spec
Purpose
This document defines the backend-only balance-sheet parsing rules for fiscal-xbrl-core.
This pass is limited to Rust parser behavior and taxonomy packs. It must not modify frontend files, frontend rendering logic, or frontend response shapes.
Hydration Order
- Load the selected surface pack.
- For non-core packs, merge in any core balance-sheet surfaces that the selected pack does not override.
- Resolve direct canonical balance rows from statement rows.
- Resolve aggregate-child rows from detail components when direct canonical rows are absent.
- Resolve formula-backed balance rows from already-resolved canonical rows.
- Emit
unmappedonly for rows not consumed by canonical balance parsing.
Category Taxonomy
Balance rows use these backend category keys:
current_assetsnoncurrent_assetscurrent_liabilitiesnoncurrent_liabilitiesequityderivedsector_specific
Default rule:
- use economic placement first
- reserve
sector_specificfor rows that cannot be expressed economically
Canonical Precedence Rule
Canonical balance mappings take precedence over residual classification.
If a statement row is consumed by a canonical balance row, it must not remain in detail_rows["balance"]["unmapped"].
Alias Flattening Rule
Synonymous balance concepts flatten into one canonical surface row.
Example:
AccountsReceivableNetCurrentReceivablesNetCurrent
These must become one accounts_receivable row with period-aware provenance.
Per-Period Resolution Rule
Direct balance matching is resolved per period, not by choosing one row globally.
For each canonical balance row:
- Collect all direct candidates.
- For each period, choose the best candidate with a value in that period.
- Build one canonical row from those period-specific winners.
- Preserve the union of all consumed aliases in
source_concepts,source_row_keys, andsource_fact_ids.
Formula Evaluation Rule
Structured formulas are evaluated only after their source surface rows have been resolved.
Supported operators:
sumsubtract
Formula rules:
- formulas operate period by period
summay treat nulls as zero whentreat_null_as_zerois truesubtractrequires exactly two sources- formula rows inherit provenance from the source surface rows they consume
Residual Pruning Rule
balance.unmapped is a strict remainder set.
A balance statement row must be excluded from unmapped when either of these is true:
- its row key was consumed by a canonical balance row
- its concept key was consumed by a canonical balance row
Helper Surface Rule
Some balance rows are parser helpers rather than user-facing canonical output.
Current helper rows:
deferred_revenue_currentdeferred_revenue_noncurrentcurrent_liabilitiesleases
Behavior:
- they remain available to formulas
- they do not appear in emitted
surface_rows - they do not create emitted detail buckets
- they still consume matched backend sources so those rows do not leak into
unmapped
Synonym vs Aggregate Child Rule
Two cases must remain distinct.
Synonym aliases
Different concept names for the same canonical balance meaning.
Behavior:
- flatten into one canonical surface row
- do not emit duplicate detail rows
- do not remain in
unmapped
Aggregate child components
Rows that legitimately roll into a subtotal or total.
Behavior:
- may remain as detail rows beneath the canonical parent when grouping is enabled
- must not remain in
unmappedafter being consumed
Sector Placement Decisions
Sector rows stay inside the same economic taxonomy.
Mappings in this pass:
loans->noncurrent_assetsallowance_for_credit_losses->noncurrent_assetsdeposits->current_liabilitiespolicy_liabilities->noncurrent_liabilitiesdeferred_acquisition_costs->noncurrent_assetsinvestment_property->noncurrent_assets
sector_specific remains unused by default in this pass.
Required Invariants
- A consumed balance source must never remain in
balance.unmapped. - A synonym alias must never create more than one canonical balance row.
- Hidden helper surfaces may consume sources but must not appear in emitted
surface_rows. - Formula-derived rows inherit canonical provenance from their source surfaces.
- The frontend response shape remains unchanged.
Test Matrix
The parser must cover:
- direct alias flattening for
accounts_receivable - period-sparse alias merges into one canonical row
- formula derivation for
total_cash_and_equivalents - formula derivation for
unearned_revenue - formula derivation for
total_debt - formula derivation for
net_cash_position - helper rows staying out of emitted balance surfaces
- residual pruning of canonically consumed balance rows
- sector packs receiving merged core balance coverage without changing frontend contracts
Learnings Reusable For Other Statements
The same parser rules should later apply to cash flow:
- canonical mapping outranks residual classification
- direct aliases should resolve per period
- helper rows can exist backend-only when formulas need them
- consumed sources must be removed from
unmapped - sector packs should inherit common canonical coverage rather than duplicating it