Lifecycle · PG-04
The provisional-to-final entry lifecycle
One object from first draft to final record: revisions as events, one-way finalization, corrections only as typed entries — and as-of reads across effective and knowledge time.
- provisional → final
- one-way finalization
- typed corrections
- as-of (E, K)
Ledgerbook records every journal entry as one lifecycle object: it starts Provisional, may be revised many times, and ends Final — one-way. Each material edit appends an immutable revision (actor, timestamp, content hash) to the same entry; nothing is overwritten. Once Final, postings are immutable, and later economic changes are new, typed corrections — reversal, adjustment or restatement — linked to the original. Because the ledger stores both effective time and knowledge time, you can read what a number is now and what was believed on any past date. Ledgerbook AI is a headless, MCP-native enterprise accounting data layer — for finance teams, planning agents, auditors and application builders alike. The lifecycle ships at PH-1 with T0/T1 approvals and typed reversals; T2/T3 tiers and periods are on the roadmap.
Verified 2026-09-19 · source: lifecycle reference FR-200–238, product taxonomy §1.7
What is the difference between a provisional and a final entry?
The difference is reversibility and evidence. A provisional entry can change: each edit is a revision appended to the same entry object, with who, when and a content hash. A final entry is sealed — its postings are immutable, and any later change is a separate typed correction (reversal, adjustment or restatement) linked to the original. Ledgerbook keeps both visible: as-of queries return what was believed on any past date.
Verified 2026-09-19 · source: lifecycle reference FR-200/205/207/500
One entry, five moments — nothing is ever overwritten
-
Provisional entry.created
Every entry lands Provisional first and keeps one identity for its whole life. Creating one runs the same guards on every surface: balanced postings, a valid chart of accounts and dimensions, entity scope, and an accepted idempotency key. There is no separate draft object.
-
Revision entry.revised · rev n+1
Each material edit — amount, account, dimensions, dates, currency, lines — appends an immutable, addressable revision to the same object: revision number, content hash, actor, timestamp. Prior revisions stay retrievable exactly as written, and a material edit voids any open approval.
-
Approval entry.submitted → entry.approved
An approval binds to the revision it approves — entry, revision number, content hash, policy, tier, approvers, decision inputs — and is usable exactly once, for the hash it names. Reject and withdraw return the entry to Provisional, with a reason.
-
Final entry.finalized · one-way
Finalization is the only writer to the books, and it is irreversible: the same object is sealed with a permanent document number, its entry hash joins the chain by default, and preconditions — period state, locks, the approved hash — are re-evaluated at finalization, not only at approval.
-
Correction entry.reversed · entry.corrected
After Final there is no edit, no delete and no unpost. Later change flows through typed corrections — reversal, adjustment or restatement — each a new entry linked to the original, with both the mistake and its fix staying visible.
-
Period states & higher tiers period.* · T2/T3
Roadmap
Period states, close gates, auto-reversal accruals and the T2/T3 approval tiers are ledger-native by design and arrive with PH-2.
Phase legend: amber = Provisional state · green = Final · red = Correction · blue = Roadmap (PH-2). Labels are always present — colour is never the only signal.
Who may transition an entry
Guards are re-evaluated server-side on every transition; every transition appends one event. Agent credentials carry write and submit scopes only — approve, finalize, correct and restate cannot be granted to an actor of kind agent.
| Transition | Actor scope | Guards | Event |
|---|---|---|---|
| Create or revise | provision.write (creator or entity writer) |
Balanced postings; valid accounts and dimensions; entity scope; idempotency key accepted | entry.created · entry.revised |
| Submit for approval | provision.submit |
Policy requires approval; content hash pinned to the revision | entry.submitted |
| Approve | approve:<tier>@<limit> |
Policy satisfied; creator ≠ approver for agent-originated entries; signature over the pinned hash | entry.approved |
| Finalize | post scope, or the T0 auto-post policy |
Preconditions re-checked at finalization; T0 actions attributed to a system actor with policy_id recorded |
entry.finalized · entry.auto_approved |
| Correct | correct / restate scope |
Typed correction linked to the original; period admission checked | entry.reversed · entry.corrected |
What every edit records — who, when, where, why
Who
Actor kind (human, agent, service or system), identity, hashed credential id, on_behalf_of
where delegated, and the model id for agents.
When
A server-assigned timestamp plus a strictly increasing, gap-detectable sequence. Client times are recorded but never used for ordering.
Where
The channel the edit arrived through — REST, MCP, CLI, streaming, batch or connector — with client name, version and trace id.
Why
Reason code, policy id, approval state and the evaluated materiality tier — the inputs the decision was made on.
No write path is exempt — ingestion included — and a missing or incomplete envelope fails closed instead of defaulting to a system actor. Even autosave micro-edits emit one event per commit, in sequence; storage may coalesce their bodies, never their events. Trace FR-234–238, FR-208, FR-522 · PH-1
Corrections are typed entries — never edits
A Final entry stays Final. Change after Final arrives as a new entry that says what it fixes and why, and the type is enforced on every surface.
| Correction type | Accounting semantics | What happens in the ledger |
|---|---|---|
reversal |
A full mirror of the original posting set | A new entry links reverses → the original; both remain visible and independently verifiable. |
adjustment |
Partial or amounted corrections; IAS 10 adjusting events | An amounted correcting entry carries the delta and its type; the original is never touched. |
restatement |
Prior-period error corrections — IAS 8, ASC 250 | A typed entry records the error and the fix, linked for the audit trail. |
Every correcting entry carries its type across REST, MCP and OCEL exports; an entry that omits its correction type is rejected. “Revision” belongs to the Provisional state only — it is never a correction type. There is no silent repair: nothing after Final is quietly rewritten, so the mistake and its fix both stay attributable.
Trace FR-123–125, FR-205, FR-228, OI-41 · PH-1 · glossary: correction · immutability & verification
As-of reads: what the number was, and what we believed
A bitemporal ledger stores two time axes per record: when the event happened (effective time) and when the ledger recorded or believed it (knowledge time). Ledgerbook adds insertion time as a third axis, answers both “balance as of March 31” and “what we believed on March 31” as first-class queries, and stamps every response with its resolved time points plus restated and stale flags.
Verified 2026-09-19 · source: time & provenance reference FR-500–515, NFR-3
“What was the balance on 31 March?”
The balance at an effective date under current knowledge — the everyday read, served from daily deltas and sealed checkpoints with bounded redo.
“What did we believe it was, when we published?”
The same balance and trial balance evaluated at a past knowledge instant: every term of the answer uses one resolved cut-off, so a composition can never mix two beliefs.
“What was provisional then?”
Final entries plus the in-force provisional versions, evaluated at the same belief cut-off — the provisional overlay is a view over one log, never a second store of balances.
“How much moved after close?”
A belief-delta report: every event between two knowledge cuts with its delta, ordered by sequence — the auditor's reconciliation in one read.
Every posting and every event carries three time axes — effective time (when it happened), insertion time (when the ledger recorded it), and knowledge time (a belief cut-off over the event sequence). The taxonomy is closed: exactly three axes, no fourth. Period assignment and scenario are stored attributes carried within those axes, never axes of their own. Backdated facts are appended as new events — never chain edits — and the effective date sits inside the hashed payload, so a retroactive change is detectable.
Interactive reads — (E, now) and (E, K) — run on checkpoints plus bounded redo: point balances at p99 ≤ 250 ms and trial balances at p99 ≤ 2 s at reference scale. Arbitrary-K full-belief replay is audit-class — a documented minutes budget, not an interactive SLA. Every answer echoes its resolved (E, K) with restated and stale flags, and the same (E, K, scope) reproduces the same number. Once period states ship, the log also answers “was this period closed when the entry reached Final?” as of any belief instant — Roadmap
# the same read twice: a date's balance, and the belief at a past instant
→ tools/call get_balance
{
"ledger": "grp-eu",
"book": "group_ifrs",
"scenario": "actual",
"as_of": "2026-06-30", # effective time (E)
"as_believed": "2026-07-15T18:00:00Z", # knowledge time (K)
"view": "combined"
}
← 200 { "balance_minor": 18425000, "currency": "EUR",
"resolved": { "knowledge_seq": 841223 },
"restated": false, "stale": false }
Trace FR-500–515 · PH-1; period-state-as-of (Q7) labeled Roadmap · arbitrary-K replay is audit-class (NFR-3)
Posting into time — periods, close gates and accruals Roadmap
Close mechanics are ledger-native, not a bolt-on module — and they arrive with PH-2. Every item below is Roadmap except the reverse-only correction path, which ships at PH-1.
| Mechanic | What it establishes | Phase |
|---|---|---|
| Period states | open → soft_closed → closed → reopened, one state per book × scenario pair; every
transition is an event, and “was this period closed when the entry reached Final?” is answerable as
of any belief instant. |
Roadmap |
| Finalization admission | Open admits everything; soft-closed admits mechanical reversal promotions and corrections tagged as post-close adjustments at higher materiality; closed rejects every finalization, backdating included, unless the period is reopened; reopened admits only its restatement scope. | Roadmap |
| Close gates | A period cannot close while approvals are open on entries inside it or aged accruals lack reversal or true-up; an override needs a named approver, a reason code, a higher tier — and leaves a permanent trail. | Roadmap |
| Scoped reopen | Reopening is limited to a named book, scenario and period, with a stated reason and a close-back date; the period returns to closed automatically at window end. | Roadmap |
| Auto-reversal accruals | An accrual carries its reversal schedule as a field; the reversal child is materialised at finalization, promoted when its date arrives and the target period is open, cancellable with a reason, and excluded from actual views until it fires. | Roadmap |
| Reverse-only corrections | A Final entry can be reversed by a typed mirror entry at any time; original and reversal both stay visible. This path ships at PH-1. | PH-1 |
Posting into a closed period is the question this section answers: at PH-2, nothing finalizes into a closed period — backdating included — unless it is reopened or the entry is a tagged post-close adjustment admitted by the matrix. Until then, PH-1 keeps backdated facts honest as new, effective-dated entries.
Approvals: materiality tiers T0–T3, evaluated server-side
The gate is an invariant, not an application feature. Tier is computed server-side from stored policy matched on source, actor kind, document type, amount, account class and period state — and no request field, header or tool argument can downgrade it.
| Tier | Applies to | Decision | Phase |
|---|---|---|---|
| T0 auto | At or below the clearly-trivial threshold, with template or source match, a non-sensitive account class and an open period | Finalizes with no human; attributed to a system actor with the policy id recorded — and sampled into review, as below | PH-1 |
| T1 single | At or below performance materiality | One approver | PH-1 |
| T2 dual | Above performance materiality, sensitive account classes (intercompany, equity, manual revenue, related party), a soft-closed period, or a correction above materiality | Two distinct approvers in different identity groups, neither being the creator | Roadmap |
| T3 governance | Above overall materiality, or a restatement class | Controller plus CFO, with an audit-committee-visible record | Roadmap |
T0 is auto-post plus a post-hoc review control — not unsupervised
- Auto-approved entries are sampled into a review queue at a policy-configurable rate — no less than one daily sample by default.
- Anything outside the configured normal ranges is flagged for review, and review outcomes are recorded as events.
- The reversal path is reachable directly from a review outcome: a reviewer can raise a typed correction on the spot.
- Range definitions are policy data, versioned and recorded — no model runs in the core.
- Accountability is explicit: when a T0-approved entry is later restated, responsibility follows the policy author — the config owner who set the rule and its ceiling. The platform provides provenance only.
Trace FR-217, OI-25/OI-26, FR-218–220 · PH-1 (T0/T1)
Thresholds are derived and recorded, and duties are separated
The entity's materiality benchmark yields performance materiality and the clearly-trivial line — editable, versioned pack fields, not code constants. The evaluated tier, its inputs and the thresholds in force are stamped on the entry, together with the control type auditors scope: fully automated for T0, semi-automated for T1 and T2, governance for T3. Separation of duties holds as policy data: creator ≠ approver for agent-originated entries in all cases; an approval is content-hash-bound and usable once; and any material edit voids a pending approval. Changing the materiality benchmark itself requires dual control and a versioned policy record.
Provisional numbers carry their own honesty envelope
Provisional data travels with a data-quality envelope: the scope it covers, a not-for-external- distribution watermark, the provisional weight (amount, share of total, oldest item) and a manifest hash over the result set that renderers must not strip. Export to any external channel requires the actual view and a period at least soft-closed; anything else needs a named approver, a reason code and a stamped manifest. And the bridge is an identity, not a report: actual + Σ provisional + Σ scheduled = combined, at every granularity — the auditor's reconciliation and the “how much of today's number is soft” question, answered by the same read.
Trace FR-229–232 · PH-1
Depth on the finance-team view: for finance teams · agent write governance: MCP governance
Frequently asked
What is a provisional journal entry?
A provisional journal entry is an entry that is still being drafted, revised and approved — not yet part of the final books. Ledgerbook keeps one object per entry for its whole life and appends every material edit as an immutable revision carrying actor, timestamp and content hash; nothing is overwritten. Finalization is one-way: after it, changes happen only as typed corrections.
What is a bitemporal ledger?
A bitemporal ledger stores two time axes per record: when the event happened (effective time) and when the ledger recorded or believed it (knowledge time). Ledgerbook adds insertion time as a third axis, answers both “balance as of March 31” and “what we believed on March 31” as first-class queries, and stamps every response with its resolved time points plus restated and stale flags.
Can you post into a closed period?
Not into a closed period. The design is a finalization admission matrix: open periods admit everything; soft-closed periods admit mechanical reversals and post-close adjustments at higher materiality; closed periods reject every finalization, backdating included, unless reopened. Reopening is scoped and time-boxed, and returns to closed automatically. Period states arrive with PH-2 (Roadmap); today, backdated facts are new entries, never chain edits.
How do agents interact with the lifecycle?
Agents read and propose; they cannot approve, finalize or correct — enforced at the credential, not the prompt. An agent credential carries write and submit scopes only, and automated finalization happens only under T0 policy, attributed to a system actor with the requesting agent recorded. An edit over MCP is the same revision object as an edit over REST. At PH-1 the MCP surface covers read and propose. How governance works →
Where do provisional numbers go?
Provisional numbers stay in the ledger and travel with a data-quality envelope: the scope covered, a not-for-external-distribution watermark, the provisional weight and a manifest hash that renderers must not strip. Export to any external channel requires the actual view and a period at least soft-closed; anything else needs a named approver and a reason code. Provisional visibility is a separate, time-boxed grant — invisible to external auditors by default.
What Ledgerbook is not
The lifecycle is data. The screens around it are deliberately not ours.
- No approval screens or notification delivery (NG-1). Approval objects, materiality tiers, segregation-of-duties rules and every transition event are ours and are queryable. Approval inboxes, escalation paths, Slack and email belong to the application on top.
- No in-place mutation and no soft delete (NG-7). There is no edit path to expose, so nothing here can be configured to overwrite history. Corrections are typed entries — reversal, adjustment, restatement — and the original stays byte-identical with a link to what corrected it.
- No statutory filing (NG-5). We do not submit to a tax authority or an e-invoicing network. We hold the record those submissions are built from, with the provenance to defend them afterwards.
Bring the lifecycle into your build
One object, revisions as events, typed corrections and as-of reads — the developer preview ships with the quickstart.