Last reviewed: 2026-08-13
Reporting Contract
Canonical objects:
- StandardReportDefinition
- StandardReportResult
- ReportLine
- ReportSourceContribution
- ReportRun
- ReportSnapshot
Purpose:
- define launch financial reports from posted ledger truth;
- distinguish current live calculations from immutable captured runs;
- preserve exact report meaning, attribution, drilldown, replay, and recovery; and
- allow Close to consume Reporting-owned snapshots without making Close a report engine.
Stable values
Standard report definition codes:
trial_balancebalance_sheetincome_statement
Result statuses:
availableunavailable
Persisted ReportRun status:
captured
Report line kinds:
accountsubtotalderived
Issue severities:
blockerwarninginformational
Launch definition version:
standard-financial-reports-v1
Definition and parameter identity
Every execution requires:
- company id;
- report definition code and version;
- parameter schema version;
- normalized parameters;
- actor id;
- generated timestamp; and
- company base or reporting currency.
Parameters:
| Definition | Required parameters | Ledger range |
|---|---|---|
trial_balance |
inclusive start_date, inclusive end_date |
posted entries inside the range |
balance_sheet |
inclusive as_of_date |
all posted entries through the as-of date |
income_statement |
inclusive start_date, inclusive end_date |
posted entries inside the range |
end_date must not precede start_date. An optional financial-period id must
be same-company. For a trial balance or income statement it must match both
range boundaries exactly; for a balance sheet its end date must match the
as-of date. A recognizable period label may be displayed but never supplies
the date parameters.
Definition code, definition version, parameter schema, normalized parameters, company, and currency are report meaning. UI filters, display order, actor, generated timestamp, ReportRun number, filenames, and provider fields are not.
Ledger and account inputs
- Only same-company journal entries with status
postedand their persisted lines are formal report input. - Every included line must resolve its exact same-company account id.
- Report calculations preserve journal-entry id and number, journal-line id, posting date, financial-period id, posting mode, correction target when present, account id, debit, credit, and currency as source contribution identity.
- Routine entries, reversals, and adjustments participate identically by their own posting dates. A correction does not rewrite a target into a net historical line.
- Workflow records, prepared previews, accepted events, report packs, audit events, and source-document metadata are excluded from financial amounts.
- Account type selects statement section and formula. Account normal balance is explanatory; account code and name are recognizable presentation values.
- Live results display current account code and name. A captured snapshot preserves the account id, code, name, type, and normal balance used when it was generated.
- Inactive and retired accounts remain included when posted lines reference them.
- Missing or cross-company account identity blocks availability. Reporting must not silently omit malformed ledger lines or redirect them through a replacement account.
Money and calculation policy
- Calculations use decimal accounting amounts at persisted precision.
- Formal launch statements require the company's base or reporting currency.
- Currency values are never netted across currencies.
- A diagnostic trial-balance result may disclose unexpected currencies in separate totals, but it is unavailable for formal capture until every included posting uses the company currency.
- Snapshot amounts remain at accounting precision. Rendering may format to a currency display scale only when it identifies the display rounding and reconciles totals from unrounded snapshot values.
- No ReportRun creates a rounding journal entry or changes ledger truth.
Trial balance
For each account with posted activity in the inclusive range, preserve:
- debit activity total;
- credit activity total;
- net debit balance when debit activity exceeds credit activity; and
- net credit balance when credit activity exceeds debit activity.
Equal activity produces zero net debit and credit while the account remains available for explanation. Per-currency debit and credit activity totals and net-balance totals must agree. An imbalance is a blocker and makes the result unavailable for capture.
Trial-balance ordering may use current account code within the result. Ordering does not determine classification or amount.
Balance sheet
Account sections and signed formulas:
assets: debit less credit forassetaccounts;liabilities: credit less debit forliabilityaccounts; andequity: credit less debit forequityaccounts.
Income and expense accounts are not presented as balance-sheet account lines.
Reporting derives cumulative_unclosed_earnings through the as-of date:
income credits - income debits - expense debits + expense credits
The derived line is included in total equity. It is a ReportLine of kind
derived, never an account, account role, posting request, or substitute for a
future authorized closing entry.
For the company currency:
total assets = total liabilities + posted equity + cumulative unclosed earnings
The equation must hold at accounting precision. A failure is a blocker and makes the result unavailable. Negative account, section, or derived values remain visible.
Income statement
Account sections and signed formulas:
income: credits less debits forincomeaccounts; andexpenses: debits less credits forexpenseaccounts.
net_income is total income less total expenses. Asset, liability, and equity
accounts are not statement account lines. Negative account, section, or net
income values remain visible.
The initial statement presents only the major income and expense sections. Gross-profit, cost-of-sales, operating/nonoperating, and other subgroups must not be inferred from account codes, names, roles, or provider data.
Result, issues, and fingerprints
A StandardReportResult requires:
- company id and company currency;
- definition code and version;
- parameter schema and normalized parameters;
- optional exact financial-period identity;
- generated timestamp and actor;
- status;
- deterministic ledger-input fingerprint;
- ordered report lines, subtotals, and totals when available;
- structured issues; and
- source contributions sufficient for line drilldown.
The ledger-input fingerprint is versioned and covers at least:
- company and company currency;
- definition code and version;
- parameter schema and normalized parameters;
- optional financial-period identity and boundaries;
- every included journal-entry and journal-line identity, posting date, period, posting mode, correction target, amount, and currency; and
- captured account id, type, normal balance, code, and name.
Ordering, actor, generated time, UI state, and renderer options do not change the fingerprint.
Visible unavailable conditions include:
- missing, malformed, or out-of-range parameters;
- missing, ambiguous, or cross-company period;
- unsupported definition or version;
- missing or cross-company account identity;
- unsupported currency;
- incomplete or inconsistent posted-line identity;
- trial-balance or balance-sheet equation failure;
- calculation overflow or precision failure; and
- repository or recovery failure.
An empty but valid ledger range is available with zero totals. Warning and
informational issues remain visible and do not independently make a report
unavailable.
ReportRun and snapshot
A ReportRun requires:
- id and company id;
- positive company-scoped report-run number;
- definition code and version;
- parameter schema and normalized parameters;
- optional financial-period id;
- company currency;
- request idempotency key;
- ledger-input fingerprint and fingerprint schema;
- snapshot id and snapshot fingerprint;
- status
captured; - generated and captured timestamps;
- generated and captured actor ids; and
- succeeded capture audit-event id.
The user-facing format is RR- followed by the number padded to at least six
digits, such as RR-000001. The number is immutable and unique within a
company; the id remains the durable persistence, replay, Close, backup, and
recovery identity.
A ReportSnapshot requires the exact immutable:
- report header and normalized parameters;
- account labels and classifications used at generation;
- ordered account, subtotal, and derived lines;
- totals and equations;
- source contributions;
- ledger-input and snapshot fingerprints; and
- generated attribution.
Only an available result may be captured. A run and snapshot are persisted as
one durable operation. They are never edited, refreshed, superseded in place,
or silently deleted. A later execution creates a new run.
The snapshot fingerprint is versioned and covers the full canonical snapshot payload. Renderer output, filenames, and filesystem paths are excluded.
Currentness and Close consumption
ReportRun currentness is computed by executing the same definition version and normalized parameters against current repository truth and comparing the ledger-input fingerprint. Currentness is not a mutable ReportRun status.
The Reporting-owned Close resolver returns at least:
- requested ReportRun id;
- company id;
- exact financial-period id when captured for a period;
- definition code and version;
- normalized parameters;
- snapshot fingerprint;
- persisted status; and
- computed currentness.
For launch Close use, the required trial-balance ReportRun must:
- be same-company and captured;
- use
trial_balanceand the accepted launch definition version; - identify the exact target financial period;
- use that period's inclusive start and end dates;
- use the company reporting currency;
- remain current; and
- resolve its snapshot fingerprint.
Close stores only the ReportRun reference and consumes this resolver result.
Close never executes a report, rewrites currentness, or reconstructs formal
report values from Close tables. Internal resolver reads made during an
authorized Close action do not create a second human report.view action;
the owning Close action remains audited.
Authorization and audit
Binding Reporting actions:
report.viewreport_run.capture
Both require company-scoped authorization. Neither requires reason capture or step-up under the launch contract.
report.viewcovers live formal execution and review of a persisted snapshot.report_run.capturecovers creation of an immutable ReportRun and snapshot.- Succeeded, denied, and failed attempts preserve company, actor, action, report definition or ReportRun target, result, machine identity when available, and correlation id.
- A succeeded capture audit id is stored on the ReportRun.
- Denied or failed capture creates no ReportRun, snapshot, or number.
- Report export remains separately governed by
company_data.export.
Adding these actions to a registry or development/test bundle does not grant them to a production role.
Replay, concurrency, recovery, and backup
- Capture commands carry stable company-scoped command and request idempotency identity.
- Exact replay requires the same company, definition/version, normalized parameters, optional period, input fingerprint, and snapshot fingerprint and returns the existing run.
- Conflicting identity reuse is rejected without overwriting the accepted run.
- Concurrent exact capture creates at most one run, snapshot, number, and succeeded audit event.
- Recovery after interruption reuses accepted identities and never creates a second snapshot for the same command.
- Report runs, snapshots, lines, source contributions, number sequence, and audit links are company-owned backup and restore state.
- A Reporting persistence migration must update the Company Backup Snapshot Contract, catalog version, schema conformance, capture/restore tests, and replacement ordering in the same slice.
Review and drilldown
Formal review must distinguish:
- live result versus captured
RR-snapshot; - definition/version and exact parameters;
- company, currency, period when applicable, generated actor, and timestamps;
- available, unavailable, current, and noncurrent meaning;
- account lines, subtotals, derived lines, negative values, and equations;
- captured account labels versus current account labels when they differ;
- source journal-entry and line contributions, including correction identity; and
- protected audit evidence.
Workflow, Close, evidence, and audit records may be shown in separate support sections. They never change formal amounts.
Sales-tax capability profiles, results, facilitator-remitted support, return controls, filing evidence, remittance workflow state, and Finance bank matches may likewise appear only as separately labeled support. Seller-owned Sales Tax Payable and posted remittances affect formal reports solely through their ordinary posted journal-entry lines. Reporting does not create a tax return or tax-basis statement from control records.
Explicitly deferred
- report definitions beyond the three launch codes;
- detailed statement subgroups and configurable report designers;
- comparative, budget, forecast, consolidation, and elimination columns;
- cash-flow statements;
- foreign-currency translation;
- prior-period-adjustment and retrospective-restatement presentation;
- tax-basis or regulatory-basis statements;
- arbitrary user-authored formulas;
- automatic closing entries;
- scheduled/background report execution;
- rendering, printing, PDF/spreadsheet generation, and UI; and
- provider-specific report behavior.
Related truth
../accounting/reporting.mdtrial-balance.contract.mdaccount.contract.mdjournal-entry.contract.mdaccounting-correction.contract.mdfinancial-period.contract.mdbusiness-time.contract.mdclose-run.contract.mdsales-tax-accounting-and-remittance.contract.mdcompany.contract.mdmoney.contract.mdsecurity/role-permission-contract.mdsecurity/audit-event-contract.md../decisions/accepted/0009-persisted-report-runs.md