Dev log · 2026-07-07

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

RheoServ Waumpaum is a core banking system that a credit union owns, controls, and uses offline. It is an alternative to enterprise core banking. It has the same person-centered model and the same real-time transaction posts as a large enterprise core. But it is different in three areas:

RheoServ Waumpaum is one self-contained HTML file. It uses no server and no network, and it encrypts the data at rest. The interface shows the brand of a fictional credit union, Prairie Rivers Credit Union.

Do not load real data. This app is a proof of concept only. It has no Privacy Impact Assessment, no threat and risk assessment, and no security authorization. Prairie Rivers Credit Union is fully synthetic. The members, the accounts, and the balances are not real. The data contains no real PANs and no PII of real members.

From the offline HRIS to a banking core

RheoServ Waumpaum came from the offline HRIS experiment. That experiment put CRDT SQLite in one HTML file. The experiment was a temporary change from the work on plastron. The HRIS showed that the difficult parts operate correctly:

RheoServ Waumpaum uses all these parts again. It applies them to a much larger domain: credit-union core banking.

Familiar, but not a copy

Enterprise core banking is the reference. It is a person-centered core. You search for a person. Then you go to the accounts of that person, and then to the real-time transactions. RheoServ Waumpaum uses the same structure:

RheoServ Waumpaum is deliberately not a copy of a product. It does not integrate with a product. It is a new, offline, open design of the same model, and it is familiar to an operator.

What a waumpaum is

A waumpaum is not a parallel ledger, and it is not a table. It is a slice of the Rtxn table: one or more transactions that have flags. The flags are WaumpaumInd = 1, WaumpaumBeltId, and WaumpaumPeerInstCd. The flags set the transactions apart for exchange with a different institution.

The name comes from wampum, with respect, as a design metaphor. Wampum belts recorded agreements between nations. In this system, a waumpaum is a signed record that attests a ledger state. Thus two credit unions can settle, and they do not show their encrypted ledgers to each other. (The name is a metaphor, not a claim of Indigenous ownership.)

Three audiences

The remaining sections of this post give instructions for three audiences:

Each story has a short video from the live app. The videos come from the same Playwright tests that the repo includes. The written instructions are in USER-MANUAL.md.

One file. The app operates offline. The file that you download is the product.
  1. Open the built app.
  2. Select Demo data.
  3. Set a passphrase of your choice.
  4. Select an operator.
Export your changes before you lock the session. By design, you lose the changes that you did not export.

Part 1 — The teller

Start a session US-1

Load the data for the day with a passphrase. Then select your operator identity. (Your role sets your screens.)

  1. Open the file. The app shows a locked gate screen first.
  2. Keep Demo data selected.
  3. Type a passphrase.
  4. Click Start session.
  5. Select an operator. The Dashboard shows the members, the balances, the holds, and the unsettled waumpaums.

Person Search → Account Inquiry US-2

Start with the person. Find a member, go to the accounts of that member, and open one account.

  1. In Person Search, type a name (for example, Broadwater).
  2. Click the member. The app shows the accounts of the member through AcctRole.
  3. Open one account.

The Account Inquiry header shows Cur Bal and Avail Bal. The tabs are History, Holds, and Roles.

Real-Time Transaction Post US-3

Post a deposit, a withdrawal, a transfer, or a fee. The ledger changes in real time.

  1. Select an Acct Nbr.
  2. Set Rtxn Typ Cd (for example, WD).
  3. Set Post Amt.
  4. Post the transaction.

If a debit is more than the available balance, the app refuses the debit with Insufficient Funds. If not, the Rtxn posts and the balance decreases. Each post writes a change_event that identifies the operator.

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

A card authorization decreases the available balance. It does not change the ledger.

  1. Click Place Hold. The app creates an AcctHold and an AUTH Rtxn. Avail Bal decreases, and Cur Bal does not change.
  2. Click Release Hold. The available balance increases again. The hold changes to RLSD, and the AUTH changes to RVSD.

If a hold is more than the available balance, the app refuses the hold with Hold Amt Exceeds Avail Bal.

Lock the session US-6

Erase the decrypted data from memory when you go away from the computer.

  1. Export your changes first. By design, you lose the changes that you did not export.
  2. Click Lock session. The app goes back to the gate screen. It erases the database, the key, the passphrase, and the identity.

Part 2 — The credit union merges one day of changes

Several tellers start with the same morning truth. Each teller makes changes offline. cr-sqlite is a CRDT, thus the changes of all tellers converge with no server. No last-writer-wins rule overwrites the changes of a teller. The coordinator merges the encrypted changes of all tellers in the browser.

The offline merge in one credit union Three tellers start with the same morning truth and edit offline. Each teller exports an encrypted changes file. The coordinator merges the files in the browser and exports the merged truth for tomorrow. The same morning truth Teller 1 edits offline Teller 2 edits offline Teller 3 edits offline exports exports exports Encrypted changes .waumpaumchanges Encrypted changes .waumpaumchanges Encrypted changes .waumpaumchanges The coordinator merges in the browser Export merged truth Merged truth for tomorrow
Figure 1. The coordinator merges the encrypted changes of all tellers in the same HTML file.

Export changes and merge (no Node) US-5

The coordinator makes the offline edits of all operators converge in the same HTML file.

  1. Operator: click Export my changes. The app makes an encrypted .waumpaumchanges file.
  2. Coordinator: open Data & Security → Merge Operator Changes.
  3. Coordinator: select the changes files of the operators.
  4. Coordinator: click Export merged truth for tomorrow.

cr-sqlite makes the divergent edits converge for each column.

The merge keeps the attribution US-12

See the operator that made each change. The audit data goes with each changeset.

  1. Open Audit. It shows the change log (operator, entity, action) and the session events.

change_event and session_log are CRRs. They merge into the truth together with all the other data.

Part 3 — Payment providers and the Waumpaum Exchange

The CRDT merge makes edits converge in one credit union. Between credit unions, a separate Waumpaum Exchange nets the obligations. The Exchange is on a network. A waumpaum is a signed slice of Rtxn. It is the record that goes from one institution to the other. Figure 2 shows the three steps of the settlement.

Settlement between credit unions Each credit union issues a waumpaum and sends a signed proof to the Waumpaum Exchange. The Exchange nets the obligations and makes one settlement belt. Each credit union reads the belt back into its ledger. Credit union A issues a waumpaum Credit union B issues a waumpaum signed proof .waumpaumproof signed proof .waumpaumproof Waumpaum Exchange nets the obligations makes a settlement belt Settlement belt .clearbelt Read the Belt Ledger of credit union A Ledger of credit union B
Figure 2. Signed proofs go to the Exchange, and one settlement belt comes back to each credit union.

Issue a waumpaum US-7

Flag a transaction for exchange. Then export its signed attestation.

  1. Open the Waumpaum Desk.
  2. Select a recent Rtxn.
  3. Click Issue a Waumpaum.
  4. Select the counterparty (WaumpaumPeerInstCd).

The app sets the flag WaumpaumInd = 1 on the row. (The row goes into v_WaumpaumRtxn.) The app exports a signed .waumpaumproof. This file is the atomic negotiable record for the Exchange.

The Exchange makes a belt CLI

Netting with a single writer collects the proofs into a settlement belt. (The netting runs outside the offline core.)

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

The script adds the settlement amounts of the proofs for each (AcctNbr, counterparty) pair. Then it writes a .clearbelt that the credit union can read.

Read the Belt US-10

Import the settlement belt of the Exchange back into the ledger.

  1. Open Read the Belt.
  2. Load the .clearbelt.
  3. Preview each settlement string.
  4. Post the settlement strings. Each string becomes a Rtxn (RtxnTypCd='CLR') that has the belt id. The post updates the balances.

The app does not post a string for an unknown account. It reports the unknown accounts, and it never invents an account.

Post to the longhouse (deferred). This feature sends the signal "a new belt is ready" through a public image feed. It uses ChaosEdgeSteg steganography. The feature has a design, but the app does not include it. The feature makes the CSP less strict. Thus it belongs in a separate build variant, and never in the teller core.

The other roles

Loan officer — Loan Payment Post US-8

Examine the loan book and apply a payment.

  1. Open Loan Pipeline.
  2. Open Loan Inquiry. The screens show the balances, the next payment due, the rate, and the payment history.
  3. Use Loan Payment Post to apply a payment. A DP Rtxn moves the balance nearer to zero and records AcctPmtHist.

Planner — Reports → encrypted CSV US-9

Run the predefined reports. The app exports encrypted files only.

  1. Open Member 360. It is the book of business (the deposits and the loans for each member).
  2. Open Reports.
  3. Run a report.
  4. Click Export CSV. The app makes a .csv.enc file only. It never makes a plain CSV file.

References

More from the dev log