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_delta and signed_delta. (Period is derived downstream by slicing date.)

balances_by_period.csv

A materialized view: signed balances grouped by period and (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.