TESTNET

Credit Machine · the model · v5

Programmable credit continuity.

Keep XLS-65 / XLS-66 as the origination and pooled-liquidity primitive. Add a deterministic Rescue Window so a loan can move from primary liquidity to a transparent backstop market without breaking settlement continuity or forcing the original lender to negotiate by hand. That is the whole idea; everything below is how.

1 · What is native and what is LiquidLabs

LayerPurposeNative / extensionImplementation
XLS-65 VaultPooled single-asset liquidity, shares as an MPTnative (amendment SingleAssetVault)VaultCreate · VaultDeposit · VaultWithdraw; private vaults via a Permissioned Domain and Credentials
XLS-66 LoanFixed-term origination and repayment through a broker with first-loss covernative (amendment LendingProtocol)LoanBrokerSet · LoanBrokerCoverDeposit · LoanSet · LoanPay · LoanManage; underwriting is off-chain by design
Collateral lockLock a borrower or third-party asset with a haircutLiquidLabsToken Escrow (live on mainnet) whose condition follows the loan; the escrow index travels in the 256-byte Loan.Data
Rescue WindowCrowdfunded cure or refinance after delinquencyLiquidLabsOffer object · eligibility · reservations · atomic settlement (this platform's services/credit)
Recovery claimEconomic claim of the supporters, with seniorityLiquidLabsLedger rows today; an MPT-style entitlement where the legal structure allows

2 · Roles and what each one is accountable for

Depositor / lender
Supplies liquidity to the vault. Wants yield with bounded, visible loss exposure.
Loan broker
Underwrites, sets terms, posts first-loss cover (CoverAvailable ≥ DebtTotal × CoverRateMinimum), can impair or default a loan, earns a management fee on interest.
Borrower
Receives principal, owes the schedule; carries the borrower score.
Collateral provider
Locks the asset — the borrower or an approved third party.
Supporter
Injects rescue capital after delinquency for a claim with a capped premium and new-money priority; earns Rescue Points that vest on performance.
Orchestrator
Publishes state, checks eligibility, enforces the deadline, settles atomically, writes the receipt. On this platform: the Credit Machine service; in the target architecture: a native protocol extension (see the roadmap).

3 · The state machine

time-bounded, deterministic, no hidden manual step
OFFER ──fund──▶ ACTIVE ──pay──▶ ACTIVE ──repay_full──▶ CLOSED
                  │
                 miss
                  ▼
                GRACE ──catch_up──▶ ACTIVE
                  │
         grace_expired ─ admissible ─▶ RESCUE_OPEN ──rescue_filled (cure)──▶ CURED ──resume──▶ ACTIVE
                  │                        │  └────── close (make-whole) ──▶ REFINANCED ──resume──▶ ACTIVE
                  │                        └── rescue_expired ──▶ DEFAULT                └──close──▶ CLOSED
                  └──────── not admissible ──────────────────────▶ DEFAULT ──recover──▶ RECOVERY ──liquidate──▶ LIQUIDATED
  1. 01Requestamount · term · purpose
  2. 02Underwriteidentity · score · limits
  3. 03Securecollateral · haircut · reserve
  4. 04FundXLS-65 vault → XLS-66 loan
  5. 05Monitorhealth · payments · early warning
  6. 06Rescuegrace · auction · cure or refinance
  7. 07Closerepay · release · score update

XLS-66 mapping: ACTIVE and GRACE are the ledger's loan with its PaymentDueDate and GracePeriod; impairment is LoanManage(tfLoanImpair) and shows as the vault's LossUnrealized; DEFAULT is LoanManage(tfLoanDefault), which draws min(DebtTotal × CoverRateMinimum × CoverRateLiquidation, DefaultAmount) from the cover. The Rescue Window, CURED and REFINANCED are the LiquidLabs layer in between.

4 · The mathematics

Decimal on the server, mirrored in the Lab

A_t = missed principal + I_t + F_t

Q_t = B_t + I_t + F_t + close-out

C_eff = C_t × (1 − h)

CR = C_eff / B_t

R_t = A_t (cure) · R_t = Q_t × (1 − discount) (make-whole)

S = Σ S_i · rescue succeeds iff S ≥ R_t before the deadline

w_i = S_i / S · Claim_i = w_i × R_t × (1 + b)

b = b₀ + λ_p PD + λ_l LGD + λ_t τ + λ_u U, capped at 15 %

Proceeds = min(C_eff × (1 − liquidation cost) + FLC, Q_t)

EV_liq = Proceeds

EV_rescue (cure) = p × Q_t + (1 − p) × (A_t + max(0, Proceeds − Claim))

EV_rescue (make-whole) = R_t (the lender is paid now)

E[NPV_s] = p × Claim + (1 − p) × min(Claim, Proceeds) − R_t

Loss = max(0, Q_t − Proceeds); L_FL → L_J → L_S in that order

Amortization is a level-payment schedule whose last row absorbs the rounding so the balance closes at exactly zero; pro-rata allocation uses the largest-remainder method so Σ accepted equals R_t to the micro-unit. Money is Numeric(24,6) everywhere; floats never touch a receipt.

5 · Admission — rescue only when rescue preserves value

five parts, all must hold
  1. Lender's test. EV_rescue ≥ EV_liquidate + SafetyMargin (0).
  2. Coverage after rescue. (C_eff + FLC) / Q_t ≥ C_min (30 %).
  3. Supporter hurdle. E[NPV_s] ≥ m_s (0) under the disclosed seniority (new money priority) — someone rational will fund it.
  4. Affordability. p ≥ p_min (0.50): the broker's estimate that the borrower can carry the restructured plan. If not, liquidate rather than refinance repeatedly.
  5. Not ENFORCE. When collateral fully covers the debt and stress is extreme, enforcement makes the lender whole cheaply — the map says enforce, and the window stays shut.

The thresholds are governance parameters (an AdmissionPolicy), approved like every other decision on this platform, never hard-coded in a template.

6 · Object model

ObjectLayerPurposeHere
VaultXLS-65pooled lender liquidity, shares, NAVcredit_vaults (with the broker's cover and the capital stack)
LoanXLS-66principal, schedule, broker–borrower relationshipcredit_loans + Loan.Data descriptor + terms hash
CollateralLockLiquidLabsasset, owner, valuation, haircut, unlock conditionsToken Escrow index in the descriptor (next iteration: the escrow itself)
RescueOfferLiquidLabstrigger, target, deadline, premium, eligibility, ticket limits, frozen snapshotcredit_rescue_offers
SupportCommitmentLiquidLabssupporter, amount, status, allocationcredit_commitments
RecoveryClaimLiquidLabspro-rata claim, seniority, repayments, points, vestingcredit_claims
SettlementReceiptproofhashes, allocations, transition, digestcredit_receipts — SHA-256 of the canonical receipt
ParticipantLiquidLabsbeneficial owner, independence, role score, pointscredit_participants

The 256-byte Loan.Data descriptor: version (1) · jurisdiction (2) · collateral escrow index (32) · SHA-256 of the signed terms (32) · accepted credential type (32) · originator tag (4) · reserved. Any verifier can tie loan, collateral and contract together without asking us.

7 · Settlement algorithm

  1. Detect the missed payment; confirm the XLS-66 grace condition is reached.
  2. Freeze a deterministic snapshot: B_t, I_t, F_t, Q_t, C_t, h, FLC, eligibility, deadline.
  3. Compute R_t for the mode; run the five-part admission test.
  4. Publish the offer with every economic term visible before the first commitment. Nothing may change afterwards — re-issue instead.
  5. Accept reservations until the deadline: funds are locked, never released to anyone.
  6. If Σ S_i ≥ R_t: allocate exactly R_t (pro rata, largest remainder, concentration cap), refund the excess, settle the vault or payoff account — never the borrower's wallet.
  7. Mint the recovery claims with their seniority; update the borrower's repayment waterfall.
  8. If Σ S_i < R_t at the deadline: release every reservation; DEFAULT → RECOVERY → the loss waterfall.
  9. Write the SettlementReceipt with the transaction hashes and the state transition.

8 · Capital stack and the default waterfall

TrancheRoleLoss priorityReturn source
Senior vaultcore XLS-65 liquiditylastbase loan yield
Junior / backstoppre-committed rescue liquidityafter first-losscommitment fee + utilisation premium
First-lossbroker / sponsor / reservefirsthighest contractual premium or protocol reserve

Distribution of realised value (borrower cash + collateral after haircut and liquidation cost): supporters' claim first — new-money priority — then the vault's exposure.

Absorption of the vault's shortfall: first-loss cover → junior / backstop → senior depositors → uncovered.

Senior protection condition: senior loss = 0 whenever L_total ≤ K_FL + K_J + V_recovery. The purpose of the structure is not to hide losses; it is to pre-assign them.

9 · Dual reputation

Score = 100 × sigmoid(z), z a weighted feature mix

Borrower score

  • 35 % payment history
  • 20 % collateral quality
  • 15 % cashflow stability
  • 10 % tenure
  • 10 % identity confidence
  • 10 % rescue recovery history

Supporter score

  • 30 % commitment reliability
  • 25 % successful rescues
  • 20 % capital duration
  • 15 % recovery performance
  • 10 % identity confidence

RescuePoints_i = Base × CapitalShare_i × Performance × Independence × Vesting

Independence is 1 only for capital whose beneficial owner is not the borrower or a related party; Vesting rises from 0 to 1 as the rescued loan performs (90 days or repayment). A score gain must represent real external value created.

10 · Risk controls, anti-gaming, compliance

  • No offer may change economics after the first commitment — cancel and re-issue.
  • Conservative haircuts; independent or multi-source valuation where collateral is market-valued.
  • Supporter concentration cap per loan (60 % here) and optional caps per borrower.
  • Rescue proceeds settle to the vault or payoff account, never to the borrower's wallet.
  • Permissioned participation (credentials, permissioned domains) where eligibility rules apply.
  • PD, LGD, collateral gaps and fill probability are stress-tested before origination.
  • Seniority is disclosed unambiguously: supporters know they rank first on proceeds and are subordinated on the schedule.
  • Beneficial-owner exclusion: the borrower, controlled entities and linked wallets earn nothing on their own loan.
  • Sybil-linking through KYC/KYB identity, account-graph signals, funding relationships and declared related parties — within privacy law.
  • Vesting, clawback, default friction, cool-down and concentration limits; no reward for wash refinancing.
  • Deterrence: IncrementalDefaultCost ≥ MaxRelatedPartyGain + ε, which strict exclusion reduces to "any positive friction".
  • Legal characterisation stays separate from technical settlement: the claim may be a participation, a note, receivable interest or a security depending on jurisdiction — KYC/AML, consumer-credit rules, licensing and investor protection are the application layer's job (MiCAR / BaFin assessment, BACKLOG P0 #8).

11 · Microcredit pricing — amount, days, score

the volume use case, priced by a printed formula

The worked example is a 100,000 RLUSD loan with collateral. The volume case is the opposite: 50–5,000 RLUSD for a week to a few months, unsecured, decided in seconds. The request page prices it from three inputs and funds it into the same machine.

APR = base 8 % + spread(tier) + tenor premium (up to 4 % under 30 days) + 1 % under 500 RLUSD, capped at 45 %
tier by BorrowerScore: A ≥ 80 (spread 2, fee 1.0 %, PD 2 %) · B ≥ 65 (5, 1.5 %, 5 %) · C ≥ 50 (9, 2.0 %, 10 %) · D ≥ 35 (15, 3.0 %, 18 %) · below 35 no offer
fee = max(1, amount × fee rate) + risk fee · interest from the day-based schedule (apr × days / 365 per installment)
EL = PD × LGD 60 % × amount (per loan) · floor = EL + max(1, 0.5 % × amount) · risk fee = max(0, floor − fee − interest)
price = fee + interest ≥ floor · no offer when price > 8 % of the amount · p for the Rescue Window = 0.50 + (score − 35)/65 × 0.45
  • Why a risk fee and not a higher rate. Microcredit losses are per loan, not per year: a 30-day loan at any lawful APR cannot earn a 5 % default rate back in interest. Hiding that in the rate would mean 60 % APR on a four-week loan; charging it as a named fee is the same money, disclosed.
  • Why a ceiling. When covering the expected loss would cost more than 8 % of the amount, the product does not offer — a guarantor or a supporter who vouches lifts the score, a longer term spreads the cost. Lucía (score 52, 150 for 14 days) gets an offer at 6.7 %; at a score of 41 she does not.
  • Why the same score. The tier that prices the loan and the recovery probability the admission test uses later come from one BorrowerScore, so a cheap loan is also one the Rescue Window will admit.
  • Schedule. One bullet up to 30 days, weekly up to 90, monthly after — the XLS-66 PaymentInterval in seconds, the last installment closing at exactly zero.
  • Rescue on a microcredit — what the machine says, honestly. Run Amara's 300 for 30 days to a missed bullet and let grace expire: the admission test refuses the window (the microcredit policy waives the coverage floor — there is no collateral — but the supporters' expected net is negative at the 15 % premium when a quarter of borrowers do not come back) and the loan goes default → recovery → waterfall: the broker's 5 % first-loss absorbs first, the vault the rest. That is the design: a microcredit is not rescued loan by loan, it is priced so that the portfolio absorbs its losses — the risk fee is exactly that expected loss, collected up front. A supporter-backed rescue becomes admissible only where the score is high enough for the capped 15 % premium to cover the gap (Amara's loan: a score of about 88, p ≈ 0.87), or where a guarantor stands behind the borrower — the social-collateral object the bootcamp roadmap lists.

12 · What v5 corrected in the v4 concept

found by running the maths, not by reading it
  1. The v4 state map liquidated every loan with coverage below 90 %. That is DeFi logic — enforce while collateral still covers the debt. XLS-66 loans are unsecured by design and LiquidLabs collateral is optional, so for a partially covered loan enforcing early guarantees the loss. v5 reserves ENFORCE for collateral that covers the debt under extreme stress and lets the expected-value test decide the rest. Under v4 the concept's own worked example (coverage 55 %) was not admissible.
  2. Supporters lost money in expectation. A 1.08× claim with a 70 % chance is an expected loss of 24 %; no rational supporter funds that, so the market would never form. v5 gives rescue capital new-money priority on realised proceeds in a later default (the restructuring-law principle), which bounds the supporters' downside by the collateral and makes the worked example fundable at +8 %.
  3. Admission was one-sided. v5 adds the supporter hurdle, the coverage-after-rescue floor and an affordability floor to the lender's EV test, so the stress case is refused for the right reasons (coverage 24 %, p = 35 %) and the over-collateralised case is enforced rather than rescued.
  4. The worked example's figures were illustrative. The engine computes them exactly: installment 8,745.15; B_7 = 51,120.61; A_7 = 8,995.15; Q_7 = 51,754.02; claim pool 9,714.76 at 8 %.
  5. Protocol units. Rates in 1/10 basis points, intervals in seconds, loan amounts as asset-agnostic Number strings, the management fee capped at 10 % — the builders refuse anything else.

13 · The road: bootcamp, then hackathon

from a simulated ledger to our own node with the amendments on

Core-dev bootcamp (rippled / xrpld, C++)

  1. Node C with the amendments force-enabled. Build rippled with SingleAssetVault, LendingProtocol and LendingProtocolV1_1 in standalone mode; point this platform's credit.ledger decision at it. The real adapter already refuses any network that does not list them.
  2. Replay the walkthrough on-ledger. VaultCreate → VaultDeposit → LoanBrokerSet → LoanBrokerCoverDeposit → LoanSet (two signatures) → LoanPay → LoanManage with the exact builders in services/credit/ledger.py; compare rippled's tec codes with the engine's refusals.
  3. Read the Application layer where our rules live. LoanSet's counterparty-signature check, LoanManage's default accounting (DefaultCovered), the vault's LossUnrealized arithmetic — the places a Rescue Window would hook into.
  4. Prototype the protocol extension. A RescueOffer ledger entry (loan id, target, deadline, premium, eligibility domain), RescueCommit (reserve, never release), RescueSettle (atomic pro-rata fill, refund, LoanPay to the vault, claim MPT mint) and RescueExpire; invariants: Σ accepted == target; economics immutable after the first commit; proceeds never reach the borrower. Write it the way XLS-66 is written — transactors, ledger objects, invariant checks, unit tests.
  5. Draft the XLS. "Rescue Window for XLS-66 loans" — motivation, objects, transactions, failure codes, with this platform's engine as the reference implementation and its receipts as test vectors.

XRPL Commons Hackathon, New York (36 hours)

  1. Track B, honest slide one: the amendments are not active on mainnet; the demo runs on our node with them enabled.
  2. Compliance bridge. Uphold-verified KYC → on-chain Credential → private vault with a Permissioned Domain; a jury member's unverified account fails VaultDeposit with tecNO_PERMISSION.
  3. Land-backed working capital. LiquidAcre land shares in a Token Escrow as the collateral layer; the escrow index in Loan.Data; a watcher correlating LoanPay → EscrowFinish.
  4. The Credit Machine live. This walkthrough against the node: fund, miss, impair, Rescue Window (first as the orchestrator service, then the prototype transactors from the bootcamp), settle, claims — every hash on the public explorer of our node.
  5. Vault X-ray. vault_info and loan_broker_info feeding one screen the verifier can reproduce without our API.
  6. Open-source API. /v1/verify reads a loan's descriptor and receipts; the playbook ships the schema so others can integrate the ecosystem.

What to claim, honestly: underwriting is off-chain by the protocol's design — our value is the compliance bridge, the collateral composition, the human-in-the-loop gates and programmable credit continuity, not "trustless credit".