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

# Honesty about limits

> What Pegana does not model. Where the signal can lie. When to mistrust an alert.

Pegana's signal is good enough to act on for monitoring, risk dashboards, alerting, and
AI agent pre-flight checks. It is **not** a low-level price oracle for liquidation
engines, large-size routing, or settlement of high-value derivatives without
additional checks.

This page is the explicit list of failure modes. If a future incident bites you,
chances are it's already here.

## Slippage at size is not modeled

The Jupiter probe size is fixed per asset (\~$10k notional for most). Your effective
swap price at $5M will be measurably worse. If you intend to act on Pegana state to
execute a large trade, use Jupiter's quote API directly at your real size.

## Single source per class

We deliberately do not blend prices. If **Sanctum** is wrong about `sol_value` for an
LST, every LST spread is wrong. If **Pyth** is wrong about SOL/USD, every USD spread is
wrong. If **Hylo's** Exchange PDA decode drifts, hyUSD's CR is wrong.

We accept this trade-off because reproducibility and clear failure modes matter more
than belt-and-suspenders robustness — but you should know it. For high-value
automation (insurance payout, liquidation), **cross-check against your own oracle of
choice** before pulling the trigger.

## Thin venues lie

Even with Jupiter routing, an asset whose dominant venue dries up will print a
crash-shaped spread that reflects venue stress, not asset stress. The
[mSOL/Pyth case](/docs/case-studies/msol-pyth-may-2022) is the textbook example.

Mitigation: every asset has a `confidence` field in the API — a discrete label
(`high` / `medium` / `low` / `unknown`) derived from the Pyth confidence interval. When a
feed's interval widens or the feed goes stale, the label degrades and the consumer can
choose to ignore the print. The default rule is to act only on `confidence: "high"`. See
[confidence label](/docs/concepts/confidence-score).

## Program upgrades

Any LST or CDP whose stake pool / vault is mid-upgrade may pause redemptions or change
account layout. Our decoders are pinned to specific IDLs. **IDL drift** is the silent
failure mode. When a decode fails or drifts, the engine **skips the recompute and holds
the last published state** rather than emitting a confident-but-wrong number — it does
not flip the asset to `UNKNOWN`.

<Note>
  An automated hourly pinned-IDL check against the on-chain canonical IDL (with a Sentry
  alert on divergence) is **not yet shipped** — that detector is not in the current Rust
  source. Today, decode drift surfaces as a warn log plus a Prometheus counter, and the
  mitigation for unreliable single-source assets is a provisional `monitoring_only`
  (beta) label on their alerts plus the NAV-sanity gate, which publishes `UNKNOWN`
  when an anchor is detectably broken.
</Note>

## Best-effort delivery

Alerts are best-effort. Telegram delivery is rate-limited by Telegram's own API; in a
burst (e.g., dozens of assets transitioning at once during a market-wide event), delivery
may take 10–30 seconds. Webhook delivery has 6 attempts with 5s / 30s / 5m / 30m /
2h backoff. If your endpoint is unreachable for the full retry envelope, the
attempts are visible in `/v1/me/webhooks/:id/deliveries` and the event can be
replayed.

**For mission-critical automation, poll `/v1/assets/:symbol/state` as a safety
net** — that endpoint is the source of truth and is always reachable.

## We do not score "predicted" depegs

Pegana publishes what is happening **right now**, smoothed by an asymmetric dwell window:
a worsening transition must hold for **30s** before it confirms (`CONFIRM_UP_SECS`), while
a recovery must hold for **120s** before the state relaxes (`DECAY_DOWN_SECS`) — quick to
flag stress, slow to declare all-clear. We do not project forward, do not score
"likelihood of depeg in the next hour," do not model correlation between assets.

If you want forward-looking risk modeling, build it on top of our raw `/v1/assets/.../history`
data. We expose 1-minute aggregates and raw discount points for that purpose.

## We do not arbitrate

When Sanctum's `sol_value` says jitoSOL = 1.180 SOL and Jupiter's routed quote says
1.176 SOL, the spread is `-34 bps`. We do not decide whether Sanctum or Jupiter is
"right." We report the spread.

If you need a single "fair price" — i.e., a number to liquidate against — that's a
different product. Pegana is the *state* oracle, not the *price* oracle.

## Frozen / dropped assets

When an asset's mechanism becomes untrustworthy, we freeze it. A frozen entry
remains in [`assets.toml`](https://github.com/lrafasouza/pegana-replay/blob/main/assets.toml)
for historical continuity but the engine no longer polls it. `dSOL` (Drift's LST)
was soft-deactivated on 2026-05-26 after the 2026-04-01 exploit — no live counterparty
for redemption. Rather than an `active = false` entry, its definition is preserved as a
commented-out block in `assets.toml` so historical snapshots remain reproducible while the
indexer and engine skip it entirely. It is excluded from the 63 assets tracked live (50
monitoring-only) and no longer polled.

## How to verify mistrust

Every alert includes the `intrinsic_usd`, `market_usd`, and `discount` values at the
moment it fired. Re-fetch the asset's history endpoint around the alert timestamp:

```bash theme={"theme":"github-dark"}
curl "https://api.pegana.xyz/v1/assets/USDC/history?from=2026-05-26T14:32:00Z&to=2026-05-26T14:33:00Z&bucket=raw"
```

If the raw spread series doesn't show the threshold crossing, the alert is wrong and
you should open a Sentry ticket — but in practice you will see exactly the print that
fired the alert, with the same numbers.
