Skip to main content
For the canonical, RSS-feeded changelog, see 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.

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

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.