This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# General Ledger service design
|
||||
|
||||
Status: append-only model accepted on 2026-08-14; authority and availability policy revised on 2026-08-28.
|
||||
Status: append-only model accepted on 2026-08-14; authority and availability policy revised on 2026-08-28; standalone GL authority API implemented on 2026-10-05.
|
||||
|
||||
## Purpose and ownership
|
||||
|
||||
@@ -30,9 +30,10 @@ disabled automatically.
|
||||
5. Account, asset, source transaction, correlation, actor, occurrence time, and
|
||||
recording time are retained on every applicable record.
|
||||
6. A journal commits atomically with all its entries or not at all.
|
||||
7. A financial effect is journaled only when Wallet has committed that effect.
|
||||
7. In normal Wallet ingestion, a financial effect is journaled only when Wallet has committed that effect.
|
||||
Pending and failed lifecycle events may be retained as audit events but do
|
||||
not create monetary entries.
|
||||
not create monetary entries. For standalone GL-only execution, the GL journal
|
||||
commit itself is the financial effect; any Wallet copy is a projection.
|
||||
8. Derived balances are rebuildable solely by ordering and summing immutable
|
||||
entries. Cached balances are disposable projections, never source data.
|
||||
|
||||
@@ -115,6 +116,37 @@ does not hold a wallet database transaction open.
|
||||
|
||||
## Operating modes and failure semantics
|
||||
|
||||
GL now exposes its own persisted `NORMAL` / `GL_ONLY` operating state through
|
||||
`GetOperatingMode` and the authenticated `SetOperatingMode` RPC. This is
|
||||
distinct from Wallet's existing `KUKNOS_DISABLED` configuration, which still
|
||||
makes Wallet read-only until its callers are integrated with this API.
|
||||
|
||||
In `GL_ONLY`, `PostInternalJournal` executes balanced internal effects
|
||||
synchronously. PostgreSQL locks user accounts and checks available/frozen
|
||||
balances in the same commit; conflicting spends cannot both succeed. All
|
||||
journal append paths enforce the GL-only funds rules; ordinary ingestion rejects
|
||||
new effects in this mode, so internal execution cannot be bypassed. Blockchain
|
||||
references
|
||||
and external blockchain account movements are forbidden, new settlement
|
||||
requests are rejected, and the worker stops claiming existing settlements.
|
||||
The mode survives restarts and changes have immutable actor/reason/revision
|
||||
audits and OpenTelemetry spans. Switching drains posting transactions and
|
||||
rejects in-flight settlement claims or negative user balances. Returning to
|
||||
`NORMAL` requires explicit operator reconciliation confirmation.
|
||||
|
||||
The ledger must be complete before switching: restore/import opening balances
|
||||
and drain committed Wallet outbox effects and in-flight Wallet processing.
|
||||
GL-only mode keeps ledger reads/writes available while reporting settlement as
|
||||
paused; existing normal-mode Wallet clients therefore fail closed rather than
|
||||
continuing blockchain-dependent processing. Internal executions must not also
|
||||
be delivered through that outbox as new monetary effects. User authorization,
|
||||
asset eligibility, fees, and business counterparty mapping remain admission
|
||||
responsibilities. Actual external payment settlement cannot occur internally.
|
||||
See [the authority API](deployment/AUTHORITY_API.md) and
|
||||
[standalone operation](deployment/STANDALONE.md).
|
||||
|
||||
The broader Wallet availability policy remains:
|
||||
|
||||
- `NORMAL`: GL and Kuknos must both be healthy. A transaction is successful
|
||||
only after its required GL journal and Kuknos settlement evidence exist.
|
||||
- `KUKNOS_DISABLED`: explicitly enabled and disabled by an authorized operator
|
||||
@@ -145,6 +177,9 @@ The first `ledger.v1.GeneralLedgerService` contract provides:
|
||||
- `AppendTransactionEvent` for non-monetary lifecycle history;
|
||||
- `GetJournal` and `ListEntries` for audit and replay inspection;
|
||||
- `GetBalance` for a rebuildable account/asset projection;
|
||||
- `GetUserBalances` for available, frozen, and total balances per user asset;
|
||||
- `GetOperatingMode` / `SetOperatingMode` for attributable operator cutover;
|
||||
- `PostInternalJournal` for atomic internal execution in `GL_ONLY`;
|
||||
- `Health` for readiness and database health.
|
||||
|
||||
Wallet depends on its own `Ledger` port. Its gRPC implementation translates
|
||||
|
||||
Reference in New Issue
Block a user