> ## Documentation Index
> Fetch the complete documentation index at: https://ormaprotocol.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction: What Orma Measures and Why It Matters

> Orma catches the metadata gap that makes the first vault impairment invisible to indexers, then scores, publishes, and enforces on the result.

Orma exists because one credit event — the first impairment of a previously healthy lending vault — is invisible to every tool that reads vault state by diffing transaction metadata. A vault on XRPL Devnet took 51 XRP of subscriptions, lent 10 XRP through its LoanBroker, and the borrower stopped paying. The manager did the correct and honest thing: they impaired the loan, recognising the loss before anyone redeemed. The transaction succeeded. And every indexer watching that transaction was told nothing at all. Orma's answer is three steps: measure from ledger state instead of from metadata diffs, publish the result where any counterparty can act on it, and give independent third parties a way to enforce on it at the ledger level.

## The problem: an empty change set

When a manager impairs a loan under cash-basis accounting (`LEVersion = 1`), only one field on the Vault ledger object changes: `LossUnrealized` moves from `0` to the impaired amount. `AssetsTotal` stays the same. `AssetsAvailable` stays the same. Units outstanding, which live on the share token's `MPTokenIssuance`, stay the same.

Here is the Vault object for **Meridian Trade Finance I** before and after its impairment, in drops:

| Field                               | Before     | After      |
| ----------------------------------- | ---------- | ---------- |
| `AssetsTotal`                       | `51000000` | `51000000` |
| `AssetsAvailable`                   | `41000000` | `41000000` |
| `LossUnrealized`                    | `0`        | `10000000` |
| `MPTokenIssuance.OutstandingAmount` | `51000000` | `51000000` |

A naive reading divides assets by units:

$\text{NAV}_{\text{naive}} = \frac{A}{S} = \frac{51{,}000{,}000}{51{,}000{,}000} = 1.000000$

The correct reading nets out the recognised loss first:

$\text{NAV}_{\text{held}} = \frac{A - L}{S} = \frac{51{,}000{,}000 - 10{,}000{,}000}{51{,}000{,}000} = 0.803922$

That is a gap of **1961 basis points** between two readings of the same object at the same instant.

<Warning>
  The first impairment of a previously healthy vault emits `PreviousFields: {}` — an empty change set. `rippled` omits from `PreviousFields` any field whose previous value was the type default, and `LossUnrealized` was `0`. Under cash-basis accounting, impairment changes nothing else on the Vault object, so there is no field left to diff. An indexer watching transaction metadata sees a node touched but unchanged, and keeps serving NAV = 1.000000.

  Every subsequent impairment is visible because `LossUnrealized` is no longer `0`. The single event that matters most is the one that disappears.
</Warning>

The impairment transaction is `075FE6D2E0F29919AF477A2A8F581A680805A006138BB967D8434611E49229C3`, result `tesSUCCESS`. Its metadata for the Vault node reads:

```json theme={null}
{
  "previousFields": {},
  "finalFields": {
    "AssetsTotal": "51000000",
    "AssetsAvailable": "41000000",
    "LossUnrealized": "10000000"
  }
}
```

This is not a bug in `rippled`. It is correct metadata. It is also a silent wrong answer for every downstream consumer that builds vault state by applying deltas. Orma's reader therefore never diffs `PreviousFields`. It polls a known list of vault IDs every 4,000 ms and re-reads each object in full.

## One asymmetry, two levers

The impairment above was discretionary. Nothing in the protocol required the manager to declare it that day rather than a week later. During the Investment phase, `VaultWithdraw` returns `tecTOO_SOON` for the entire phase regardless of how much cash the vault holds, so an investor who suspects a problem cannot leave. That is **lever one: when** a loss is recognised.

**Lever two** is in what order losses are realised, and it moves real money. When a loan defaults, the cover the broker forfeits is sized against the broker's **total** drawn debt at that moment, not against the principal of the loan that defaulted:

$T(p) = \min\Big(\big\lceil D \cdot c_{\min} \cdot c_{\text{liq}} \big\rceil,\; p,\; C\Big)$

Because $D$ is decremented as each default lands, declaring a large exposure first shrinks the base for everything that follows. Total cover consumed across a fixed set of defaults therefore depends entirely on the order they are declared.

**Kestrel Bridge Financing II** had two loans — 30 XRP and 10 XRP — both of which defaulted. The manager declared the 30 XRP loan first:

| Order declared                     | Step 1 cover consumed | Step 2 cover consumed | Total        |
| ---------------------------------- | --------------------- | --------------------- | ------------ |
| 30 XRP then 10 XRP (what happened) | `⌈40 × 0.01⌉ = 0.40`  | `⌈10 × 0.01⌉ = 0.10`  | **0.50 XRP** |
| 10 XRP then 30 XRP (investor-best) | `⌈40 × 0.01⌉ = 0.40`  | `⌈30 × 0.01⌉ = 0.30`  | **0.70 XRP** |

Same two losses, same rates, same day — 0.20 XRP difference in what the manager's own first-loss capital absorbed. That 0.20 XRP fell on unit holders. By the rearrangement inequality this is general: total first-loss capital consumed is always minimised by declaring the largest exposure first. See [Mathematics](/mathematics) for the full derivation and three independent proofs.

The party who chooses the order is the LoanBroker owner, who is necessarily the vault owner — `LoanBrokerSet` returns `tecNO_PERMISSION` otherwise, and XLS-75 delegation is `temMALFORMED` for the entire lending suite. So the same account decides when a loss is recognised and in what order losses are realised, and both decisions move money from investors to them.

## Orma's three-step answer

### Measure

Orma scores five factors independently on a 20-step ordinal ladder from AAA to D: liquidity, first-loss adequacy, concentration, recognition lag, and the redemption cliff. No weights are applied anywhere — a weighted average lets a strong factor pay for a broken one. The composite grade anchors on the redemption cliff and is notched down by rule. A separate conduct score assesses the manager rather than the book: the observed default sequence against its best and worst possible orders, plus penalties for losses written off without prior impairment.

The key design choice is realised capital destruction, $\rho = \max(0, (S - A)/S)$, measured against $A$ rather than $A - L$. A write-off removes the asset from `AssetsTotal`, releases the provision, and leaves the book reading clean. Without this term, a vault that lost 79% of subscribed capital would grade AAA — identical to one that never lost a penny. With it, Kestrel grades **B**.

### Publish

The reading goes on-chain twice. First as a native **XLS-47 Price Oracle**: six `PriceData` entries per vault, one per dimension — `NAV`, `HDL`, `LIQ`, `COV`, `CNC`, `DDL`. An Oracle is a native ledger object, and `get_aggregate_price` computes a median across independent publishers inside the ledger, so a second publisher who disagrees changes the aggregate without asking. Second, as a **pointer inside the share token's own XLS-89 metadata**, under an `orma` key carrying a `nav_url` template, so a lender holding nothing but the MPT issuance ID can resolve to a valuation without knowing Orma exists.

See [Mathematics — Publication as an Oracle Object](/mathematics) and [NAV Pointer](/nav-pointer) for details.

### Enforce

A grade nobody acts on is a press release. Orma issues an **XLS-70 credential** of type `ORMA-IG` to a limited partner. The LP accepts it (issuance alone grants nothing — a deposit without the accept is still `tecNO_AUTH`). A vault owner who wants graded capital names Orma's issuer in a `PermissionedDomain` and creates the vault with `tfVaultPrivate`. After that, the ledger itself refuses a deposit from an uncredentialed account. Orma signs nothing in that step, is never asked, and cannot refuse to be cited.

Revocation is asymmetric on purpose: deleting the credential bounces the next deposit and leaves the existing position fully withdrawable. A rater who can trap capital is a worse problem than the one being solved.

See [Gate](/gate) for the full enforcement walkthrough.

## The four live Devnet facilities

All four facilities are live on Devnet and readable by anyone pointed at `wss://s.devnet.rippletest.net:51233` (network id 2). The reader loads all four at startup.

| Facility                     | Vault ID                                                           | What it demonstrates                                                                                                                                                                                         |
| ---------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Meridian Trade Finance I     | `864C5A2DDCED78C6198B0703169D533B747A56E5F9398D832033F79E37E8C835` | The empty `PreviousFields`. Impaired at `075FE6D2...E49229C3`, NAV reported 1.000000 vs. held 0.803922 — 1961 bp apart on the same transaction.                                                              |
| Kestrel Bridge Financing II  | `24EAA01AD4CE70D8ABB4ACB4255DC4C216B8AF3B9E7315DB8052BFC1E5810089` | The ordering lever. Two defaults declared largest-first; 0.50 XRP of cover consumed where the investor-best order would have consumed 0.70 XRP. Conduct grade E, vault grade B.                              |
| Calder Structured Credit III | `5763707D11EA19D1B5FF04E4EBA4F9336057955CDE65B725D1FF3EF2A96CB0E5` | The NAV pointer. Share token `000000014D667775372D5B78E07FFF294678C7F9CE82AFBC` carries its own valuation URL. A second lender prices a pledge from the token ID alone — no relationship with Orma required. |
| Thorne Senior Secured I      | `4A5A8E3716D52E334AEB077ADB09456EF4A941CC26021A8EAD37F95B00190DF5` | The gate. Private vault behind domain `FFBEC89D...C5A2FB`, accepting credential type `ORMA-IG` from issuer `rKQjjU5KFs9RAZCDvYVjcaoVK5gGsCJgkP`. The ledger refused the ungraded LP, not Orma.               |

<Tip>
  Every monetary quantity Orma serves on the wire is a decimal string, never a JSON number. XRPL `NUMBER` fields carry up to 19 significant digits and `Number()` destroys them silently. Orma uses `decimal.js` at 40 digits of precision throughout.
</Tip>

## Where to go next

<CardGroup cols={2}>
  <Card title="Concepts" icon="layer-group" href="/concepts">
    Vault phases, the LoanBroker relationship, cash-basis accounting, and why the broker owner is always the vault owner.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Clone, prove the toolchain, start the reader, and call your first API endpoint.
  </Card>

  <Card title="Mathematics" icon="function" href="/mathematics">
    Every formula Orma computes: NAV two ways, the cover formula, the ordering proof, the five scoring factors, and the oracle encoding.
  </Card>

  <Card title="Gate" icon="shield-halved" href="/gate">
    Issue XLS-70 credentials, bind them to a permissioned domain, and enforce access at the ledger level.
  </Card>

  <Card title="NAV Pointer" icon="arrow-pointer" href="/nav-pointer">
    Write a valuation pointer into share token metadata so any lender can price a pledge from the token ID alone.
  </Card>

  <Card title="Use Cases" icon="lightbulb" href="/use-cases">
    Four worked cases against three live Devnet facilities, including collateral pricing and gate enforcement.
  </Card>
</CardGroup>
