> ## 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.

# Changelog

> Notable changes to the Pegana API, MCP server, webhook contract, and docs. Live mirror at pegana.xyz/changelog.

For the **canonical, RSS-feeded changelog**, see [pegana.xyz/changelog](https://pegana.xyz/changelog).
This page is a curated subset focused on developer-facing changes (API contracts, MCP tools,
webhook payload schema, breaking config changes).

Subscribe to the RSS feed: [pegana.xyz/feed/changelog.xml](https://pegana.xyz/feed/changelog.xml).

***

## 2026-07-01 — methodology 0.5.0 + verify version-pinning

* **Methodology 0.5.0** (intrinsic-sanity): a garbage-HIGH intrinsic (a broken NAV/RR feed print,
  > 30% "discount" on a NAV-anchored asset) now publishes honest-dark **UNKNOWN** instead of a false
  > CRITICAL/BLACK\_SWAN. Mirror of the 0.4.0 premium-sanity, on the discount side. Proven inert on the
  > live universe and the 2025-10-10 backtest (no verdict moved).
* **Verify version-pinning:** receipts declare their `methodology_version`. `cargo install pegana-replay`
  (latest, 0.4.2) re-derives 0.5.0+ receipts; to verify a historical 0.4.0 receipt, pin
  `cargo install pegana-replay@0.4.1`. Both versions stay published — history remains byte-exact verifiable.
* **`state_reason` on the dashboard:** UNKNOWN assets now show *why* (e.g. "price above NAV looks
  unreliable — thin market") instead of a generic wait message.
* **PST + ONyc** market source moved DexScreener → Jupiter (deeper route; kills thin-pair flapping).

## 2026-06-24 — asset expansion (+37 assets, now 63 tracked)

* Added **37 net-new significant assets** (>\$1M Solana liquidity): 6 fiat/synthetic stables
  (USX, USDG, USD1, USDu, CASH, AUSD), 2 yield-bearing stables (eUSX, PST) + Perena `USD*`,
  and 28 liquid staking tokens (BNSOL, dynoSOL, PSOL, JSOL, hSOL, STKESOL, …). Coverage is
  now **63 active assets across 7 classes**; the live list is always [`GET /v1/assets`](/docs/guides/rest-api).
* New intrinsic sources: a **generic SPL stake-pool reader** for significant LSTs outside
  the Sanctum registry (STKESOL/rkuSOL/corvusSOL), and a **Perena savings-vault reserve NAV**
  decode for `USD*`. eUSX and PST use existing Pyth Redemption-Rate feeds.
* All 37 ship `monitoring_only: true` (**beta**) — alerts live but flagged, on a 7-day
  recalibration window. No API/MCP/webhook contract change: they appear automatically in
  `/v1/assets`, `/v1/assets/:symbol`, `/v1/assets/by-mint/:mint`, `/v1/stats`, and the MCP
  `get_assets` / `get_asset_state` tools.

## 2026-06-16 — monitoring\_only assets released as beta

* The 13 `monitoring_only` assets now **alert publicly**, labeled **beta** (provisional calibration). The read-time egress gate was removed, so `/v1/alerts`, the `/v1/audit` index + `.csv`, and `/v1/stats.alerts_24h` now include them.
* `/v1/alerts` rows and the `/v1/audit` index rows gain an additive `monitoring_only: boolean` so consumers can label beta rows.
* **Webhook payload:** beta assets carry `"calibration": "provisional"` (additive field; signature contract unchanged). The Telegram bot appends a "🧪 Beta — provisional calibration" footer.
* A beta `BLACK_SWAN` no longer bypasses dedup (30-min floor) so a provisional signal can't blast subscribers every recompute.

## 2026-06-14 — Asset containment + FX-weekend banner

* `hyloSOL+` (migration 0049) and `ONyc` (migration 0050) moved to monitoring\_only (contained from public alert/audit/stats egress; still visible in `/v1/assets` with `monitoring_only:true`). The freeze-detector approach was evaluated and Rejected (ADR-0024) — containment, not detection.
* A calm 'FX market closed' StaleBanner variant ships for FX assets (EURC) over the forex weekend (Pyth EUR/USD feed closed Fri \~22:00 → Sun \~22:00 UTC). EURC has been monitoring\_only since Phase-0 launch.

## 2026-06-12 — monitoring\_only egress gate + JupUSD EWMA guard

* Public ledger feeds (`/v1/alerts`, `/v1/stats.alerts_24h`, `/v1/audit` index, `/v1/audit.csv`) now exclude monitoring\_only assets at read time. By-id lookups (`/v1/audit/{id}`, `/onchain`, `/replay-bundle`) stay public and ungated. `/v1/assets` is NOT gated — monitoring\_only assets still render with a `monitoring_only` boolean.
* Engine plausibility guard tightened from `|discount| <= 1.0` to `|discount| < 1.0` after a \$0 Jupiter quote poisoned the EWMA and painted JupUSD CRITICAL for \~7.5 min.

## 2026-06-11 — Public launch (FEATURE\_PUBLIC\_ALERTS)

* The public alert ledger is now live. `/v1/alerts`, `/v1/stats.alerts_24h`, and the `/v1/audit` index/csv now return real data (previously gated empty by ADR-0020's `feature_public_alerts=false`). 5 Phase-0 assets (JupUSD, JLP, EURC, dzSOL, vSOL) activated monitoring-grade.

## 2026-06-10 — API JSON-error hardening (Gecko report)

* Added `GET /health` alias for `/healthz`; every error path now returns an application/json `{error, message}` envelope (incl. 404, 429 with `Retry-After`, malformed-body `invalid_body`); deduplicated operationIds; PegState/Confidence documented as enums.

## 2026-06-09 — Webhook channel types

* Webhooks now auto-detect channel by host: Discord (embed, unsigned), Slack (attachment, unsigned), Generic (Ed25519-signed). Migration 0046. 429 `Retry-After` honored.

## 2026-06-04 — Methodology 0.3.0 (CR-side deadband)

* ADR-0023: added a magnitude deadband on the hyUSD CR path (`CR_DEADBAND_PCT=2`), cutting CR band-flapping \~52→\~10 transitions/2d. Migration 0044.

## 2026-06-03 — Bot is English-only

* ADR-0022: removed pt-BR localization and the `/lang` command; the bot is now English-only.

## 2026-06-01 — Methodology 0.2.0 (deadband + LST premium carve-out)

* ADR-0021: bps-path magnitude deadband (`DEADBAND_PCT=25`) and LST/stable\_yield premium carve-out (a premium is forced to PEGGED). Migration 0041.

## 2026-05-31 — API surface polish (close-deferred sweep)

Developer-facing changes from closing out the deferred B-005/B-006/B-007/B-011 items.
All additive — HTTP status codes are unchanged, so status-based clients are unaffected.

* **`GET /v1/audit/{id}/onchain`** now explains *why* a receipt is not anchored instead
  of collapsing every case into `not_committed_yet`. The body carries a `commit_status`
  and a discriminating `error`: `not_applicable` (cost-gated, never anchored — ADR-0004),
  `not_committed_yet` (in-flight/queued/unknown), `retry_exhausted`, `wallet_drained`, or
  `persistence_failed` (ADR-0006 dead-letter terminal — the same state `/detail` returns as
  410\). **All stay HTTP 404** by design (clients such as `pegana-replay --verify-onchain`
  treat 404 as "skip the on-chain check"). Note: for `DRIFT` alerts the body `error` is now
  `not_applicable` (previously `not_committed_yet`) — the 404 status is unchanged.
* **`GET /v1/methodology/current`** widened from `{version, status}` to also include
  `git_tag`, `released_at`, `status_reason`, and `superseded_by`. When a version is `broken`,
  `fix_url` now points at the live `#lifecycle` section (the old per-version anchor never
  existed). The same fix applies to the broken-version retraction notices the dispatcher sends.
* **OpenAPI spec** (`/openapi.json`) now covers all 35 router path-items — the `/v1/auth/*`,
  `/v1/me/*`, webhook CRUD, and `/v1/ws` surfaces are documented — and registers the
  `telegram_jwt` HTTP bearer scheme so authed routes resolve their security reference.
* **MCP paid tools** now declare a per-tool `resource.url` (`mcp://tool/{name}`) on each
  x402 402-challenge, so `ping_paid`, `get_asset_history`, and `subscribe_peg_events` are
  distinguishable in the payment-required body. Verification/settlement are unaffected.

## 2026-05-30 — API input validation + list caching

* `GET /v1/alerts?limit=` / `?offset=` out-of-range values now return **400**
  instead of being silently clamped (B-018/019/021). Same for
  `GET /v1/assets/{symbol}/history?bucket=` — an unrecognized bucket is now a 400
  rather than falling back to a default (B-020). If you were relying on the old
  clamp-and-continue behavior, send in-range values.
* `GET /v1/assets` (the full asset list) is now memoized in Redis for 5s, cutting
  p50 from \~1.2s (B-022). Response shape is unchanged.

## 2026-05-29 — Audit receipts: server-side state filter + raw/smoothed series

* `GET /v1/audit?state=<PEGGED|DRIFT|DEPEG|CRITICAL|BLACK_SWAN>` now filters
  server-side (AC42). The previous client-side filter was bounded by page size;
  the full `limit` now applies to matching rows. An unknown `state` returns 400
  (`error: invalid_state`).
* Audit receipt discount charts now expose both the raw and EWMA-smoothed series
  so a transition can be traced against the exact inputs that produced it.

## 2026-05-27 — Mintlify docs launched

* New docs site at `pegana.xyz/docs` (Mintlify). Replaces the inline `/concepts`,
  `/learn`, `/developers`, `/methodology` routes on the marketing site. Old URLs
  redirect.
* OpenAPI spec published; API Reference tab is auto-generated from `openapi.yaml`.

## 2026-05-27 — MCP instrumentation

* `mcp-ts` now records per-tool metrics (`ping_paid` instrumented via `withMetrics`).
  No payload changes. Visible in Prometheus / Grafana.

## 2026-05-26 — Webhook 7-day dogfood window

* Started 7-day dogfood for webhook delivery. First mainnet deliveries returning
  200 OK. Webhook channel is in **preview** in the channels table; promoting to
  live after dogfood concludes.

## 2026-05-26 — First mainnet x402 paid call

* MCP paid tools (`get_asset_history`, `subscribe_peg_events`) are now settling on
  Solana mainnet via the **Coinbase CDP facilitator** (`api.cdp.coinbase.com`).
  The public `x402.org` facilitator still advertises Solana devnet only, so the
  CDP swap is what unblocked mainnet. First 3 mainnet settlements recorded
  (commit `7da9158`).

## 2026-05-25 — Account UX shipped

* AccountChip in global header, persistent left sidebar on `/account/*`,
  AlertMeButton + SubscribeModal on dashboard.

## 2026-05-25 — Production deploy to Hetzner

* Migrated from prod-local Docker stack to Hetzner CPX32 (Falkenstein). All 9
  containers healthy.

## 2026-05-25 — Bot session storage → Postgres

* Replaced in-memory grammY session storage with Postgres-backed adapter. Sessions
  now survive bot restarts. Migration `0014_bot_sessions.sql`.

## 2026-05-22 — Calibrated thresholds

* Per-asset, per-class drift / depeg / critical thresholds shipped. Calibrated
  against 24h p99 noise. `assets.toml` documents every threshold.

## 2026-05-20 — API rate limit raised

* REST per-IP rate limit raised from 60 → 300 req/min after observing legitimate
  dashboard burst patterns (MockDataBanner re-fetch on reload). Note: 300/min is a
  **production host override** — the repo default remains 60/min, so handle 429 and
  back off rather than relying on the higher limit.

## 2026-05-19 — Hysteresis FSM v2

* Asymmetric entry/exit thresholds and longer exit dwell (120s vs 30s entry). See
  [hysteresis FSM](/docs/concepts/hysteresis-fsm).

## 2026-05-15 — Pyth confidence + Hermes jitter

* Confidence field populated 100% (range 1e-8 to 0.091).
* Hermes SSE reconnect uses ±50% jitter + exponential 500ms → 30s backoff.

## 2026-04-02 — dSOL frozen

* After the Drift exploit on 2026-04-01, `dSOL` was frozen in `assets.toml` —
  the entry remained for historical continuity but the engine no longer polled
  the asset. It was subsequently removed as an asset entry ahead of the public
  launch (so the symbol no longer resolves at the API edge) and survives only as
  a historical comment.

***

For the full list of commits, see
[`github.com/lrafasouza/pegana-replay/commits`](https://github.com/lrafasouza/pegana-replay/commits/main).
