> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vinmake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The seven guarantees

> What GreatBook promises, the code that enforces each promise, and the test that would fail if it broke.

# The seven guarantees

Seven things are true of GreatBook's ledger, and each one is true because something refuses to let it be false.
This page is the spine the whole [Capabilities](/greatbook/capabilities/index) tab hangs off.

A guarantee that lives only in a document is a wish.
Each row below names the place it is enforced, so it can be checked rather than believed.

## The seven

<Steps>
  <Step title="The GL is the single source of truth" icon="landmark">
    Every business event becomes a balanced journal entry, or it does not exist to the system.
    No derived balance is trusted unless it can be recomputed as a `GROUP BY` over the GL.

    **Enforced by** the absence of any stored balance column.
    **Proved by** the Close checksums, which tie each sub-ledger back to its GL control account.
  </Step>

  <Step title="Single-writer posting" icon="pen-line">
    There is exactly one function that writes to the ledger: `LedgerService.post_entry()`.
    Every router, agent node, MCP action and connector funnels through it.
    Validation happens inside the writer, before the write.

    **Enforced by** the writer owning the whole validate-then-write sequence.
    **Proved by** a static import check that no agent module can reach a writer, and by the
    engine's own test suite exercising every refusal path.
  </Step>

  <Step title="Immutable, and corrections are reversals" icon="lock">
    Posted entries are never mutated or deleted.
    A correction is a new reversing entry.
    This is what preserves both the audit trail and the hash chain.

    **Enforced by** database triggers that reject an UPDATE on a posted entry, so the rule holds
    even against a direct SQL session.
    **Proved by** the Auditor recomputing the chain rather than trusting a stored flag.
  </Step>

  <Step title="Exact replay by source key" icon="copy">
    Every entry carries `(org_id, source_type, source_id, entry_set)`.
    An exact replay returns the existing entry, while reuse of the key with different immutable request facts conflicts.
    This is what makes retries, replays and agent re-runs safe.

    **Enforced by** the idempotency lookup inside the writer, before the write.
    **Proved by** the duplicate double-post suite, which drives the same source twice and asserts
    one entry.
  </Step>

  <Step title="Dimensions on the line, not multiplied accounts" icon="tags">
    The chart stays lean, around 45 IFRS accounts.
    Per-supplier, per-customer, per-order and per-activity detail lives as dimensions on the
    journal line.
    This scales to thousands of counterparties without bloating the chart.

    **Enforced by** the writer requiring the Tier-1 dimensions before it will accept a line.
    **Proved by** the invariant tests that reject a line missing a required dimension.
  </Step>

  <Step title="A human gate precedes every agent-proposed ledger write" icon="shield-check">
    The graph pauses at a gate before posting.
    The human approves, edits or rejects, and the graph resumes from its checkpoint rather than
    re-running the pipeline.

    **Enforced by** the Bookkeeper's durable pause, plus a posting mandate the browser cannot mint.
    **Proved by** the trust-boundary suite, which attempts the forgeries and asserts an empty ledger.
    Native subledger, reversal and system-origin events use their applicable canonical domain controls rather than invented intake identities.
  </Step>

  <Step title="Every correction is training data" icon="sparkles">
    At each gate the system captures `{proposed, committed, reason}`.
    That delta stream is the signal that lets a behaviour graduate from "ask every time" toward
    acting unattended.

    **Enforced by** the gate recording the decision alongside the proposal.
    **Proved by** the audit trail on every intake row, which carries the whole sequence.
  </Step>
</Steps>

## The two things called "checks", and why they are not the same

Two different mechanisms in this system are both "checks" in the code, and conflating them would blur the strongest claim the finance layer makes.
The naming below is binding on every page in this documentation.

| Say this            | What it is                                                                                               | Count   | When it runs                                                | What it does |
| ------------------- | -------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------- | ------------ |
| **GL invariants**   | integrity rules enforced inside the single writer                                                        | **18**  | *before* any write, on every posting                        | **refuses**  |
| **Close checksums** | the v12 workbook's reconciliation tie-outs, run as live queries over the GL and the seven Books families | **104** | 78 of them **continuously**, nightly; the other 26 at close | **reports**  |

A **GL invariant** is a precondition.
An unbalanced entry, a two-sided line, a closed period or a missing Tier-1 dimension never reaches the database at all.
It is a property of the writer.

A **Close checksum** is a reconciliation.
AP control against the AP sub-ledger, cross-foot, per-rail reconciliation against external evidence.
It is a property of the whole book across seven sub-ledgers.

<Warning>
  Calling the second set "invariants" would imply the system refuses a posting that would break a Close
  tie-out.
  It does not, and it should not: a broken tie-out is a finding for a human, not a rejected transaction.
  The canonical phrasing when both appear together is **"18 GL invariants + 104 Close checksums"**.
</Warning>

## The 18 GL invariants

Validated inside `LedgerService.post_entry()`, before any write.
On any failure the writer raises a typed error and writes nothing.

| #  | Invariant                                                                                                                |
| -- | ------------------------------------------------------------------------------------------------------------------------ |
| 1  | The entry has at least two lines.                                                                                        |
| 2  | Each line is one-sided: exactly one of debit and credit is non-zero.                                                     |
| 3  | All amounts are non-negative `Decimal`s.                                                                                 |
| 4  | `sum(debit_base) == sum(credit_base)` within the shared balance tolerance.                                               |
| 5  | Every account exists, is active, and is owned by the posting org.                                                        |
| 6  | The line currency resolves, and an exchange rate is present for any non-base currency.                                   |
| 7  | Base-currency amounts are computed and stored on every line.                                                             |
| 8  | The required Tier-1 dimensions are present.                                                                              |
| 9  | The entry date falls inside an **open** fiscal period.                                                                   |
| 10 | Exact replay returns an existing `(org, source_type, source_id, entry_set)` only when the immutable request facts match. |
| 11 | The entry number is allocated monotonically per org.                                                                     |
| 12 | A versioned checksum binds the previous checksum, the entry head and canonical lines, chained per org.                   |
| 13 | Status is set to `posted` atomically.                                                                                    |
| 14 | An `event_stream` record is appended, itself hash-chained.                                                               |
| 15 | No previously posted entry is mutated. Database triggers enforce this.                                                   |
| 16 | A per-org advisory lock serialises chain extension.                                                                      |
| 17 | The caller owns commit and rollback. The writer does neither.                                                            |
| 18 | On any invariant failure, raise a typed error and write nothing.                                                         |

<Note>
  Invariants 12, 14 and 16 are what make the chain trustworthy rather than decorative.
  The checksum is taken over a **canonical** serialisation that sorts the lines and stringifies the
  decimals, so neither line order nor `10` versus `10.0000` can change a checksum.
  The advisory lock means two concurrent postings cannot both extend the chain from the same head.
</Note>

## Related

* [Why a ledger, not a spreadsheet](/greatbook/why-a-ledger) - the failure class these guarantees remove
* [How it fits together](/greatbook/architecture) - where the writer sits relative to everything else
* [The golden path](/greatbook/guides/golden-path) - the guarantees, seen from a reviewer's chair
