Allow income receipt to settle another user's receivable (debt assumption) #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Today, submitting income creates a receivable on the submitter: DR
Assets:Receivable:User-B/ CRIncome:X. But a common real-world case is that the money User B physically receives is being paid by User A to settle User A's existing debt to the entity. In that case the correct effect is:Assets:Receivable:User-Adecreases (their debt is paid)Assets:Receivable:User-Bdoes not increase (B isn't holding entity cash — they handed it on, or already passed it to the entity)Right now this requires two manual entries (an income entry on B, then a manual receivable settlement) and there's no link between them. We should let an income receipt optionally indicate that it's settling some other user's outstanding receivable.
Possible Shape
Add an optional
settles_user_id(orsettles_receivable_links: list[str]) toIncomeEntry. When set:Assets:Cash/Bank/Lightningdirectly (a new required field, or a settings-default), CRIncome:X.Assets:Receivable:User-A, DR same asset account) — or wire it through the existing/settle-receivablepath so the settlement is linked back to the original receivable entry.Alternatively model it as "User B assumes User A's debt" — receivable transferred between users — but that's harder to reason about and less common.
Out of scope (handled separately)
POST /api/v1/settle-receivable.Why this is non-trivial
!flag, super-user review) or an out-of-band confirmation.^settle-{id}link).Discovered while wiring up #9 — the simple model is correct for most cases; this is the next refinement once that lands.
Open: which unit-of-account convention?
Concrete case from the design discussion:
The 50,000 sats difference has to land somewhere. The choice forces a unit-of-account question that's bigger than #16 — every income/expense entry already crosses sats↔fiat at the time of accrual.
What Libra does today (fiat-first,
@@price notation)The holding is 200.00 USD; SATS is metadata about that day's price, not the unit of account. A later settlement at the same fiat amount nets to zero in USD; the sats difference disappears because each posting carries its own price annotation. Balances stay stable for users ("you owe $200" stays $200), and stakeholders unfamiliar with BTC can still read the books.
What bitcoin-first would look like (cost-basis
{}notation)SATS is the unit of account, USD is the cost basis on the lot. When the receivable is reduced, Beancount's PNL plugin routes the 50k sats delta to a configured gain/loss account — same mechanism the canonical Beancount stock-trading docs describe (trading_with_beancount). Community "bitcoin-only" Beancount setups follow this pattern.
Trade-off: balances now move with BTC price. "You hold 200,000 sats of receivable" is stable in sats but reads as a fluctuating USD number to anyone looking at the books.
Hybrid option
Keep day-to-day postings fiat-first (stable for users today), but add Beancount
pricedirectives so any reporting date can re-derive a SATS valuation. Doesn't change the unit of account; gives us a reversible path. The fiat-first ledger remains the source of truth; a sats-perspective report becomes a derived view.Bearing on #16
If the convention stays fiat-first, this issue's cross-user settlement is fiat-clean: User B's $200 income settles User A's $200 receivable, balances net, no FX gain account needed. The BTC volatility is invisible in the ledger but recoverable from price metadata.
If we eventually flip to bitcoin-first, this issue grows: every settlement (cross-user or not) needs gain/loss routing, all existing
@@-notated entries need migration to{}cost-basis, and the user-facing UI has to communicate fluctuating sats balances.Suggestion
The unit-of-account decision is upstream of #16 and probably deserves its own design issue once we have a concrete use case forcing it. For now this issue can proceed assuming the current fiat-first convention — implementing it that way doesn't preclude a later flip, and a flip would touch far more than this one feature anyway.
Open question worth filing separately: "Choose unit-of-account convention: fiat-first vs bitcoin-first (and migration path)". Want me to file that?