From 5b27bb0950fd03d29c223b5960faff89baf37970 Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Sun, 20 Sep 2026 09:20:39 +0200 Subject: audit: verify voucher chains and attachment hashes --- docs/STATE.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 8 deletions(-) (limited to 'docs/STATE.md') diff --git a/docs/STATE.md b/docs/STATE.md index d75f3cb..9f2f29f 100644 --- a/docs/STATE.md +++ b/docs/STATE.md @@ -74,11 +74,14 @@ server/protocol/ledger only. cert reload on file change) with client targets `tls:host:port` and system-trust verification (`BOKFD_TLS_CA` for private CAs). Certificates come from a lego sidecar using INWX DNS-01 (`compose.yaml`). Externals - get accounts/roles/tokens, never VPN access. `scripts/deploy.sh` builds - locally and ships over SSH, or builds on the host when architectures - differ. `scripts/deploy.sh --dev` cross-compiles the binaries here and - hot-reloads the daemon (SIGHUP re-exec via `docker cp`), skipping the - image build and container recreate. + get accounts/roles/tokens, never VPN access. The runtime image is + **Alpine + backend only** (`bokfd`, `bokfctl`; the ncurses TUI is a + frontend built on the client machine). `scripts/deploy.sh` builds locally + and ships over SSH, or builds the same image natively on the host when + architectures differ (no cross-compilation — a musl cross toolchain is + not trusted yet). `scripts/deploy.sh --dev` hot-reloads the binaries in + the running container (SIGHUP re-exec via `docker cp`) when the + architecture matches, otherwise it falls back to a full remote build. 15. **Reports in the TUI**: rendered as fixed-width Swedish tables that mirror the Kapitas PDF exports (Saldobalans, Resultatrapport with previous-year column and 89xx bokfört/ej bokfört, Balansrapport with Ing balans/Ing @@ -152,8 +155,15 @@ server/protocol/ledger only. years are flagged in the document. ~~SRU files (INK2/INK2R/INK2S)~~ done as `sru.export` (official 2025P4 field tables, BAS mapping, TUI save in Rapporter -> Inkomstdeklaration). -4. `audit.verify` must also verify the **voucher** hash chain (today only the - audit chain is verified). +4. ~~`audit.verify` must also verify the **voucher** hash chain (today only the + audit chain is verified).~~ Done: recomputes every org's voucher chain in + posting order (SCHEMA.md §7.1), flags unbalanced vouchers as a backstop, + and `full:true` re-hashes attachment content; result carries + `vouchers_checked`, `unbalanced_vouchers`, `attachments_checked` and the + first bad voucher/audit/attachment id. TUI Revision shows both counts and + the bad ids. **Found while testing: `attachments` has no + append-only triggers** (COMPLIANCE.md §2 claims it does); content changes + are detected only by `audit.verify full:true`. 5. ~~`report.general_ledger` and `report.voucher_list`~~ implemented (Huvudbok, Verifikationslista) with Kapitas-style TUI tables; the ledger API supports `accounts`/`from`/`to`, the list an optional `series`. @@ -182,6 +192,21 @@ server/protocol/ledger only. ## Environment / how to run +- **Deployed**: `scripts/deploy.sh` (latest `v0.1.44`, healthy on nas). + Live daemon `tls:bokf.makandra.eu:8788`, token + `~/.config/bokf/migration-token` (scopes `read,write`; owner-only actions + like closing years must be done by the human in the TUI). Git remote + `origin` is `nas:/mnt/data/git-repos/bokf.git` (push `main` and tags). +- **Local test rig** (transient, `/tmp`): daemon + `./build/bokfd --db /tmp/opencode/bokf-local/t.db --socket + /tmp/opencode/bokf-local/sock`, org 1, login `admin`/`testpass123`. + Drive the TUI over a pty with `scripts/tui-sandbox.sh -- ./build/bokftui + --socket /tmp/opencode/bokf-local/sock --org 1 --fy 1 ...` plus a small + driver that feeds keys and an ANSI renderer (recreate if gone; arrows are + `ESC O B/A`, Tab `\t`, `^X` `\x18`, `^Enter` `ESC[27;5;13~`, F5 + `ESC[15~`). Never test against the live daemon. + + - Demo: db `~/bokf-demo/bokfd.db`, socket `~/bokf-demo/bokfd.sock`, pid file `~/bokf-demo/bokfd.pid`; login `admin` / `demo1234`. Start TUI: `cd ~/work/bokf && BOKFD_SOCKET=$HOME/bokf-demo/bokfd.sock \ @@ -207,4 +232,32 @@ server/protocol/ledger only. - Never commit unless the human asks. - SQLite files must not be backed up live with restic; use `backup.snapshot` (`VACUUM INTO`) and point restic at the snapshots. -- Schema version is 3; forward migrations are in `db.c`. +- Schema version is 6 (v3 moms rules; v4/v6 year info; v5 org + description/shares + board members); forward migrations are in `db.c`. + +## Makandra driftstatus (org 2) + +- **Org**: Makandra AB, org 2. Räkenskapsår (id): 2022=3, 2023=4, 2024=5, + 2025=6, 2026=7, **2027=2 (öppet, aktuellt)**. Bokslut/AR/deklaration görs + för det år som är valt i sessionen. +- **FK2027**: importerade Kapitas-böcker + 28 bokförda verifikat (V21–V48) + för bank/skatt maj–sep 2026, samt V49 som makulerar en dubblett (V20). + 1930 stämmer mot banken utom **CDON 2 409 kr** (väntar på kvittots del + 2–4; bokförs när det kommer). 1630 = 40 721 (exakt enligt Skatteverket). +- **Underlag**: 279 attachment i org 2 (alla historikdokument + insamlade + underlag). Bank-/SKV-utdrag ligger i `~/Makandra AB/{bank,skatteverket}` + (Syncthing), källkorpus i `~/Downloads/Makandra AB-…/Bokföring/`. +- **Stängning**: 2022–2026 ska stängas av ägaren via **Räkenskapsår** i + TUI:n; låt FK2027 vara öppen till nästa bokslut. +- **Deklaration**: FK2026 är deklarerad av revisorn. FK2027 deklareras + våren 2027 (INK2/SRU via Bokslutshubben → Inkomstdeklaration). +- **Årshäftet**: fylls i Bokslutshubben (händelser, stämma, utdelning + + datum, medelantal, noter). OBS: `dividend_ore` för FK2027 kan vara ett + testvärde (10 000) — kontrollera före AR/deklaration. +- **Beslut/regler från bokföringsarbetet**: inga bokföringar utan + godkännande; låsta år förblir låsta (rättelser görs i aktuellt år); SIE- + importören ändras inte och importerad data "manipuleras" inte; + historikårens P&L nettar noll pga källsystemets stängningar (AR hoppar + över "Stäng"-verifikat i flerårsöversikten); utdelning bokförs vid stämman + med mallen **Utdelning** (D 2099/K 2898); pappersoriginal finns i fysisk + pärm (får refereras i efterhand, även i stängda år). -- cgit v1.3