Dev log · 2026-07-07

RheoServ Waumpaum — a credit-union core in one HTML file 🏦

RheoServ Waumpaum is a sovereign, offline-first counterpart to enterprise core banking: the same person-centered, real-time posting model you'd find in a big core, but convergent (CRDT) instead of always-online, encrypted-portable instead of data-centre-bound, and settled between institutions with waumpaums instead of proprietary gateways. It runs as one self-contained HTML file — no server, no network, encrypted at rest — skinned for a fictional Prairie Rivers Credit Union.

Proof of concept only. No Privacy Impact Assessment, threat/risk assessment, or security authorization. Prairie Rivers Credit Union is entirely synthetic — invented members, accounts, and balances, no real PANs or member PII. Do not load real data.

From an HRIS detour to a banking core

This grew out of the offline HRIS experiment — CRDT SQLite in one HTML file — which was itself a detour from plastron. The HRIS proved the hard parts: an in-memory cr-sqlite engine inlined as WASM, AES-256-GCM encrypted portable dumps, an in-browser multi-operator merge, and a strict connect-src 'none' so nothing can leave the page. RheoServ Waumpaum reuses that whole spine and points it at a much bigger domain: credit-union core banking.

Familiar, not a clone

Enterprise core banking is the reference: a person-centered core where you search a person, walk to their accounts, then to real-time transactions. Waumpaum borrows that shape — the table and column names (Pers, Acct, Rtxn, AcctHold, AcctRole), the screen titles (Person Search, Account Inquiry, Real-Time Transaction Post), and the spaced-abbreviation labels an experienced operator expects (Acct Nbr, Rtxn Typ Cd, Cur Bal, Avail Bal). It is deliberately not a clone or integration of any product — just a familiar-feeling, offline, open re-imagining of the same model.

What a waumpaum is

A waumpaum is not a parallel ledger and not a table. It is a slice of the Rtxn table — one or more transactions flagged (WaumpaumInd = 1, WaumpaumBeltId, WaumpaumPeerInstCd) and earmarked for exchange with another institution. The name borrows, respectfully and as a design metaphor, from wampum — the belts that memorialized agreements between nations. Here a waumpaum is a signed record that attests a ledger state so two credit unions can settle without opening their encrypted books to each other. (It is a metaphor, not a claim of Indigenous ownership.)

Three audiences

The rest of this post is a walkthrough for the three people who touch the system — the teller inside one CU, the credit union merging a day of offline work, and the payment provider settling between institutions. Each story has a short recording from the live app (the same Playwright tests that ship in the repo). The written version is USER-MANUAL.md.

One file. Open the built app, choose Demo data, set any passphrase, and pick an operator. It works offline — the download is the product. Export your changes before locking; unsaved work is lost by design.

Part 1 — The teller

Start a session US-1

Load the day's data behind a passphrase, pick your operator identity (role sets your screens).

  1. Open the file — a locked gate first.
  2. Keep Demo data, enter a passphrase, Start session.
  3. Pick an operator; the Dashboard shows members, balances, holds, and unsettled waumpaums.

Person Search → Account Inquiry US-2

Person-first: find a member, walk to their accounts, open one.

  1. Person Search — type a name (e.g. Broadwater); click the member.
  2. Their accounts appear via AcctRole; open one.
  3. Account Inquiry header shows Cur Bal and Avail Bal; tabs for History, Holds, Roles.

Real-Time Transaction Post US-3

Post a deposit, withdrawal, transfer, or fee; the ledger moves in real time.

  1. Pick an Acct Nbr, set Rtxn Typ Cd (WD) and Post Amt, post.
  2. A debit over available is refused with Insufficient Funds; otherwise the Rtxn posts and the balance drops.
  3. Every post writes an attributed change_event.

Hold Inquiry — place & release a card hold US-4

A card authorization reduces available balance without moving the ledger.

  1. Place Hold creates an AcctHold + AUTH Rtxn; Avail Bal drops, Cur Bal unchanged.
  2. A hold over available is refused with Hold Amt Exceeds Avail Bal.
  3. Release Hold restores available (hold → RLSD, AUTH → RVSD).

Lock the session US-6

Wipe decrypted data from memory when you step away.

  1. Lock session — returns to the gate; clears DB, key, passphrase, and identity.
  2. Export changes first; unsaved work is gone by design.

Part 2 — The credit union: merging a day

Several tellers work the same morning truth offline. Because cr-sqlite is a CRDT, their days converge with no server and no last-writer-wins clobbering — the coordinator merges everyone's encrypted deltas right in the browser.

Export changes & merge (no Node) US-5

The coordinator converges everyone's offline edits inside the same HTML file.

  1. Operator: Export my changes → encrypted .waumpaumchanges.
  2. Coordinator: Data & Security → Merge Operator Changes → select the deltas.
  3. Export merged truth for tomorrow. cr-sqlite converges divergent edits per column.

Attribution survives the merge US-12

See who changed what — audit that travels with each changeset.

  1. Audit — change log (operator, entity, action) + session events.
  2. change_event and session_log are CRRs; they merge into the truth with everything else.

Part 3 — Payment providers & the Waumpaum Exchange

CRDT merge converges edits inside one CU. Between CUs, a separate networked Waumpaum Exchange nets obligations. A waumpaum — a signed slice of Rtxn — is the record that crosses the boundary: the CU issues a .waumpaumproof, the Exchange weaves proofs into a .clearbelt, and each CU reads the belt back into its ledger.

Issue a waumpaum US-7

Flag a transaction for exchange and export its signed attestation.

  1. Waumpaum Desk — pick a recent Rtxn, Issue a Waumpaum, choose the counterparty (WaumpaumPeerInstCd).
  2. The row is flagged WaumpaumInd = 1 (it enters v_WaumpaumRtxn).
  3. A signed .waumpaumproof is exported — the atomic negotiable record for the Exchange.

The Exchange weaves a belt CLI

Single-writer netting collects proofs into a settlement belt (runs outside the offline core).

cd exchange
node net-belt.mjs --proofs ./proofs --belt-id 2026-07-07T18:00Z --out ../fixtures/woven.clearbelt

It sums each proof's settlement amount by (AcctNbr, counterparty) and emits a .clearbelt the CU can read.

Read the Belt US-10

Import the Exchange's settlement belt back into the ledger.

  1. Read the Belt — load the .clearbelt, preview each settlement string.
  2. Post: each becomes a Rtxn (RtxnTypCd='CLR') tagged with the belt id, updating balances.
  3. Unknown accounts are skipped and reported — never invented.

Post to the longhouse (deferred). Signaling "a new belt is ready" over a public image feed via ChaosEdgeSteg steganography is designed but not shipped — it relaxes CSP, so it belongs in a separate build flavor, never the teller core.

The other roles

Loan officer — Loan Payment Post US-8

Work the loan book and apply a payment.

  1. Loan PipelineLoan Inquiry — balances, next due, rate, payment history.
  2. Loan Payment Post — a DP Rtxn moves the balance toward zero and records AcctPmtHist.

Planner — Reports → encrypted CSV US-9

Run canned reports; exports are encrypted only.

  1. Member 360 is the book of business (deposits, loans per member).
  2. Reports → run → Export CSV produces .csv.enc only — never plain CSV.

References

More from the dev log