summaryrefslogtreecommitdiff
path: root/AGENTS.md
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-17 19:55:36 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-17 19:55:36 +0200
commit380195f7cd5e57acf2c1cf2bc41069e6b0b979ed (patch)
tree32a88fb22a7fbe8f1fd5c105156d1f928c93950d /AGENTS.md
downloadbokf-380195f7cd5e57acf2c1cf2bc41069e6b0b979ed.tar.gz
bokf-380195f7cd5e57acf2c1cf2bc41069e6b0b979ed.zip
Initial commit: daemon, clients, docs, Docker deploy pipelinev0.1.0
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md77
1 files changed, 77 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..e54f786
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,77 @@
+# AGENTS.md — working on bokf
+
+`bokf` is a self-hosted Swedish bookkeeping system in C11: one daemon
+(`bokfd`) owning a SQLite database, one JSON protocol, three clients
+(`bokfctl`, `bokftui`, agents). GPL-3.0-or-later.
+
+## Build and test
+
+```sh
+make -j$(nproc) # bokfd, bokfctl, bokftui
+make test # server/protocol test suite — must be green before you stop
+```
+
+No new dependencies without asking. SQLite, yyjson, SHA-256 and Argon2 are
+vendored in `vendor/` and pinned; the only system library is libncursesw.
+
+## Layout
+
+| Path | What |
+|---|---|
+| `src/` | daemon, protocol, ledger, reports, SIE, seed, formula |
+| `clients/` | `bokfctl.c`, `bokftui.c`, shared `client.c` |
+| `docs/` | PROTOCOL.md, SCHEMA.md, COMPLIANCE.md, TUI-GUIDELINES.md |
+| `tests/` | in-process protocol/ledger tests (`test_core.c`) |
+| `data/` | BAS charts (third-party, see THIRD_PARTY_NOTICES.md) |
+
+## Invariants — do not break these
+
+- **Protocol first.** All state changes go through commands in `PROTOCOL.md`;
+ clients never touch the database or bypass the daemon.
+- **Amounts are integer öre**, dates `YYYY-MM-DD`, account numbers strings.
+- **Append-only ledger.** Vouchers/rows/audit are immutable; corrections are
+ new vouchers. Never add an UPDATE/DELETE path for them.
+- **Everything is audited** via `audit_append`; secrets never reach the log.
+- **Tenant isolation**: every tenant table carries `org_id`, references are
+ composite FKs. New tables follow the same pattern.
+- **Hash chains**: if you change what a voucher stores, check the canonical
+ encodings in `SCHEMA.md` §7.1/§9.1 and `ledger.c`.
+
+## Changing the schema
+
+Bump `BOKF_SCHEMA_VERSION` in `db.h`, add a forward migration in `db.c`, update
+`SCHEMA.md`, and make sure an existing test database upgrades (the test suite
+opens a fresh DB; migration is exercised by running the daemon on the demo DB).
+Never rewrite ledger rows in a migration.
+
+## Adding a command
+
+1. Handler in `commands.c` (or the domain file it belongs to), using the
+ `fail()/failf()` helpers and stable error codes from `PROTOCOL.md` §5.3.
+2. Entry in `g_commands[]` with permission, `need_org`, `mutating`, `dry_run`.
+3. Audit (`audit_append`) for mutations, after success.
+4. Update `docs/PROTOCOL.md`; add tests in `tests/test_core.c`.
+5. `agent.instructions` in `commands.c` if agents need to know about it.
+
+## Server code style
+
+C11, no comments unless the reason is non-obvious, static helpers, no VLAs.
+Bounded buffers with `snprintf`, check every `sqlite3_step`, free what you
+allocate with a clear owner. Warnings must be zero (`-Wall -Wextra …`).
+User-visible server messages are English; the TUI is Swedish.
+
+## TUI work
+
+Read `docs/STATE.md` first for status, locked decisions, pending decisions
+and the prioritized backlog. Then read `docs/TUI-GUIDELINES.md` and follow it. Summary: one shared line editor,
+universal keys (Ctrl+N new, F5 refresh, Esc/q back, digits jump, `g` goto),
+forms behave the same everywhere, hints always visible, errors shown as
+`CODE: message`. Prefer reusing the shared helpers (`select_list`, `menu`,
+`field_edit`, `pad_field`, `message`, `show_error`) over new local loops.
+
+## Verifying
+
+- Server changes: `make test`. UI changes: also drive `bokftui` over a pty
+ (`script -qec`) or against the demo daemon and check the real behaviour.
+- Never commit unless the human asks. When asked, keep the message short and
+ in the repo's style.