Chapter 06: Periods, accrual, and timing
A modern ledger is an append-only event log plus a set of derived views.
In Chapter 04 we treated the general ledger like a database: postings are the fact table, and statements are queries.
This chapter adds one crucial dimension to the database mental model:
Time. (a.k.a. the accounting period)
Why periods exist
Periodization is a measurement choice:
We want to describe performance for a slice of time (a month, quarter, year).
But real-world business activity does not arrive neatly “inside the slice.” Invoices, bills, and prepayments create timing gaps.
Accounting solves this with two different lenses:
Accrual basis
Accrual basis says:
recognize revenue when earned (often at invoice / delivery),
recognize expenses when incurred (even if paid later).
From a developer perspective, accrual accounting is:
a rule for mapping events to which period they affect,
plus a pipeline of deterministic derived views that make that mapping auditable.
Cash basis
Cash basis says:
recognize revenue when cash is received,
recognize expenses when cash is paid.
Cash basis is a useful baseline because it is intuitive. It also helps you see why accrual adjustments exist: cash timing can make a “good month” look bad (or vice versa).
What you will build
You will run a tiny 2-month journal (Jan/Feb) that includes timing differences:
invoice in January, cash collected in February (Accounts Receivable timing)
utilities incurred in January, paid in February (Accounts Payable timing)
rent prepaid in January for February (prepaid timing)
a cash sale + a cash purchase (where cash and accrual match)
Then you will materialize two income statement views by period:
Accrual-basis income statement (derived from Revenue and Expenses postings)
Cash-basis income statement (derived from cash movements, classified as “customer receipts” or “payments”)
Finally, you will generate a cutoff diagnostic table that explains why the two differ.
Run it
From the repo root:
make ll-ch06
Or directly:
python -m ledgerloom.chapters.ch06_periods_accrual_timing --outdir outputs/ledgerloom --seed 123
Artifacts
The runner writes:
outputs/ledgerloom/ch06/postings.csv
outputs/ledgerloom/ch06/balances_by_period.csv
outputs/ledgerloom/ch06/income_statement_accrual_by_period.csv
outputs/ledgerloom/ch06/income_statement_cash_by_period.csv
outputs/ledgerloom/ch06/cutoff_diagnostics.csv
outputs/ledgerloom/ch06/balances_as_of.csv
outputs/ledgerloom/ch06/invariants.json
outputs/ledgerloom/ch06/manifest.json
How to read the outputs
- postings.csv
The canonical fact table: one row per posting, with derived columns such as
raw_deltaandsigned_delta. (Period is derived downstream by slicingdate.)- balances_by_period.csv
A materialized view: signed balances grouped by
periodand(root, account). This is the “query result” you can build many reports from.- income_statement_accrual_by_period.csv
Accrual profit by period, computed as:
Net Income = Revenue - Expenses
where Revenue and Expenses are derived from postings using normal-balance sign conventions.
- income_statement_cash_by_period.csv
Cash profit by period, computed from cash movements classified as:
cash revenue: cash increases tied to customer activity (cash sales or collections on receivables)
cash expense: cash decreases tied to operating activity (cash purchases, AP payments, prepayments)
- cutoff_diagnostics.csv
A per-entry explanation table that shows, for each event, the accrual impact and the cash impact. This table is your “period boundary debugger.”
- balances_as_of.csv
A tiny “as-of” snapshot for month-end boundaries, showing how timing differences live on the balance sheet: receivables, payables, and prepaids are exactly the mechanism by which accrual moves income without moving cash.
Software engineering takeaways
This chapter is intentionally designed to reinforce an engineering mindset:
An immutable log + derived views is a powerful architecture for correctness.
Period handling becomes explicit: time is a dimension, not a side effect.
Deterministic artifacts + golden tests give you confidence to extend the system (Chapter 07 and beyond).
Diagnostics matter: when something looks “wrong,” you want data structures that explain why.
Next
Chapter 07 treats adjusting entries as late-arriving data with provenance and auditability, building directly on the cutoff diagnostic patterns introduced here.