Balanced twice. Owned by you.
Analytical Ledger keeps the rules of double-entry in two places: the application, and the database underneath it. Your books live in a database that is yours alone, backups prove they restore, and nothing leaves your instance unless you connect it.
Every entry balances
App ✓ posting checkDB ✓ trg_je_balanced
Lines stay in their entity
App ✓ assertAccountsMatchEntityDB ✓ trg_jl_entity_account
Posted entries are permanent
App ✓ read-only once postedDB ✓ trg_jl_immutable
Only open periods take postings
App ✓ period gateDB ✓ trg_je_period_open
Money is exact
App ✓ decimal.jsDB ✓ NUMERIC(20,4)
4100Two locks
Try to break the books.
Pick an attempt. The application refuses it first, and a PostgreSQL trigger refuses it again, so a bug, a script or an agent that skips the app still cannot unbalance your books.
Two locks on every entry
Pick an attempt. The application refuses it first, and a Postgres trigger refuses it again, so a bug or a script that skips the app still cannot unbalance your books.
4200The guard register
Fifteen triggers. Each one named.
These run inside PostgreSQL, below the application. Anything that writes to the database directly meets them too. In the app, posting runs its own balance and entity checks first (src/lib/ledger/post.ts).
Journal
trg_je_balancedRefuses posting an entry whose debits and credits differ, or that has fewer than two lines.trg_jl_immutableRefuses changing or deleting a line of a posted or void entry.trg_je_guardRefuses editing or deleting a posted entry; a void entry is final.trg_je_period_openRefuses posting into a period that is closed or locked.trg_je_actor_guardRefuses posting without a recorded creator and poster.trg_jl_entity_accountRefuses a line booked to another entity's account.
Accounts and entities
trg_account_parent_guardRefuses an account hierarchy that loops back on itself.trg_entity_owner_pct_guardRefuses an entity's owners adding up to more than 100%.
Reconciliation
trg_recon_lock_guardRefuses editing or deleting a locked reconciliation; it can only be reopened, on the record.trg_recon_line_guardRefuses clearing or un-clearing a line once the reconciliation is locked.
Documents
trg_attachment_entity_guardRefuses moving a document to another entity.trg_je_attachment_entity_guardRefuses linking a document to another entity's entry.
Imports
trg_staging_split_guardRefuses approving a split transaction whose parts don't add up exactly.trg_staging_split_consistency_guardRefuses a split left inconsistent at the end of a transaction.
Assistant
trg_assistant_approval_guardRefuses an approval record created already decided, rewritten after the fact, or deleted.
4300Money and corrections
Exact to the cent. Corrected in the open.
A ledger you can trust has to add up exactly and remember everything. Nothing posted is ever edited or deleted; a mistake gets a reversing entry, and the record shows both.
Money is never a float
Amounts are stored as NUMERIC(20,4), carried as decimal strings, and calculated with decimal.js at 40 digits of precision with banker's rounding. 0.10 + 0.20 is 0.30, exactly.
Posted means permanent
Once an entry posts, its lines are frozen by the database. A void is final. You correct a mistake with a reversing entry and a new one, and all of them stay on the record.
Periods gate posting
A period is open, closed or locked, and you can only post into an open one. Every close, lock and reopen is kept in an append-only history.
| Account | Debit | Credit |
|---|---|---|
| JE-1042Oct 24 · October rent and waterPosted | ||
| 6100Rent expense | 2,400.00 | |
| 6230Utilities | 310.50 | |
| 2000Accounts payable | 2,710.50 | |
| JE-1043Oct 27 · Reverses JE-1042Reversal | ||
| 2000Accounts payable | 2,710.50 | |
| 6100Rent expense | 2,400.00 | |
| 6230Utilities | 310.50 | |
| JE-1044Oct 27 · October rent and water, correctedPosted | ||
| 6100Rent expense | 2,300.00 | |
| 6230Utilities | 310.50 | |
| 2000Accounts payable | 2,610.50 | |
| Net effect on the books | ||
| 6100Rent expense | 2,300.00 | |
| 6230Utilities | 310.50 | |
| 2000Accounts payable | 2,610.50 | |
| Totals | 2,610.50 | 2,610.50 |
4400Who can do what
Three roles. Owners hold the keys.
Every action checks the signed-in person's role against the database, not just the screen they are on.
Viewer, accountant, owner
Roles are enforced on every action. Only owners manage users, and only an active owner can let an agent in.
Google or Microsoft sign-in
Sign in with an account you already secure. Deactivate a user and their access ends at once.
Password sign-in
Passwords of at least 12 characters, stored as salted scrypt hashes. Failed sign-ins are limited to five per email and address every 15 minutes.
A first owner, by invitation only
The first owner account is created through a one-time setup link that stops working after use.
Revocation is immediate. Resetting a password or deactivating a user ends every session they have, on the next request. Agents have their own controls: scoped, rate-limited and revocable.
4500Backups
Backups that prove themselves.
A backup you have never restored is a hope. Analytical Ledger's restore loads the snapshot into a scratch database and re-checks the books before it reports a pass.
- 01
A consistent snapshot Shipped
One command writes a consistent logical backup of the whole database.
- 02
A restore that checks the books Shipped
It loads the backup into a scratch database, re-checks that posted debits equal credits and that every entity and account came back, and fails loudly if not.
- 03
Before every upgrade on Windows Preview
The Windows app takes a verified backup before it upgrades itself.
- 04
Nightly on hosted instances Preview
A verified recovery set every night, and a restore drill every month.
| Posted debits | 1,284,330.12 |
| Posted credits | 1,284,330.12 |
| Entities | 4 of 4 |
| Accounts | 236 of 236 |
4600Your data
One client. One database.
Wherever you run it, your books sit in a PostgreSQL database that holds nobody else's. There is no shared tenant database, on any plan.
On your computer
The Windows app brings its own database, and your books and documents stay on the machine.
On your server
One PostgreSQL database you run and back up yourself, under the Fair Source license.
On a hosted instance
Each client gets its own app, database, document storage, secrets, backups and domain, on its own virtual machine by default.
Keys you add are encrypted Preview
API keys you save in Settings (Anthropic, OpenAI, SimpleFIN, Stripe and others) are encrypted with AES-256-GCM. The encryption key is kept outside the database, so a copy of the database alone can't read them. Lose that key and the saved keys have to be entered again.
Leave with everything Preview
If you leave managed hosting, you can take your full SQL database and documents, with checksums, the application release and restore guidance. The credentials key is handed over separately. You confirm it restores before anything is deleted.
4700What leaves your instance
Nothing leaves unless you connect it.
Posting, reconciliation, budgets, reports and document storage all run on your instance. These are the outside services it can talk to, and each one only after you set it up.
| Goes to | Only when | What is sent |
|---|---|---|
| Your agent's provider | Only when an agent you connected calls a tool | Sends the scoped results of that call, under the provider's retention policy |
| Anthropic or OpenAI | Only when you configure a key and use the assistant or AI categorization | Sends prompts, the context they need, and selected transactions or documents |
| A model server you set up | Only when you choose a local or custom model for the assistant | Sends prompts and selected financial inputs; nothing leaves the machine if it runs there |
| Google or Microsoft | Only when you sign in with them | Sends the sign-in exchange and your identity claims; no balances |
| SimpleFIN Bridge | Only when you sync bank feeds | Sends your access credential and the account and date range requested |
| Stripe | Only when you sync payouts | Sends API authentication and payout queries |
| Tax1099 | Only when you submit a 1099 e-file or check its status | Sends payer and payee names, taxpayer IDs, addresses and amounts |
| Resend or Slack | Only when you turn on digests or email a statement pack | Sends the digest or pack contents to the recipients you chose |
No product analytics. The app contains no first-party analytics or crash-reporting code. Next.js build tooling has its own telemetry, which you can turn off with NEXT_TELEMETRY_DISABLED=1, and every provider you connect has its own policy.
Copies you make are yours to guard. Exports, backups, logs, screenshots and emailed packs are extra copies of your books. Logs and assistant conversations can contain financial details even with credentials redacted.
4800Report a vulnerability
Found a hole? Tell us privately.
Email security@analyticalledger.com with the version, how you run it (Windows, self-hosted or hosted), your operating system, the steps to reproduce, and the impact.
Use sample data only: leave out keys, bank details, taxpayer IDs and personal information. Please keep the details out of public issues and discussions while we investigate. During the preview, only the latest release receives security fixes.
- Version and deployment mode
- Steps to reproduce, with sample data
- Impact and any suggested fix
- No secrets or personal data attached
c/fCarried forward
Books you can audit. A database you own.
Ask for early access to the Windows download and the source, or request a hosted instance with its own database.