Crownridge — Monitoring, Observability & Analytics
Production observability (spec §86). Everything here is env-gated and inert until configured — with its provider unset, the system behaves identically. No fabricated metrics; every value is derived from chain state.
Readiness
- Indexer exposes
GET /healthz→{ status, dbConnected, lastIndexedBlock, chainId, addressesConfigured }(503 when the DB is unreachable). Fly.io healthcheck + the website/statuspage consume it. - Website
/statusperforms a real RPC probe (chain head) and reads the Treasury conservation flag.
On-chain signals monitored (indexer alerts engine)
Written to the alerts table and surfaced at GET /api/v1/alerts; a production monitor also pages the
guardian. Rules (indexer/src/alerts.ts):
| Code | Severity | Trigger |
|---|---|---|
conservation_breach |
critical | recognizedReserve > USDG.balanceOf(Treasury) (should be impossible) |
nav_drop |
warning | NAV per CRWN falls ≥ 5% between snapshots (founder withdrawal, write-down, or accounting event) |
founder_withdrawal |
warning | any FounderTreasuryWithdrawal event |
Additional events to alert on in a full production monitor (spec §86/§147): unexpected mint (any
Issued not originating from Genesis), unexpected Treasury outflow, oracle deviation, supply mismatch,
unauthorized call reverts, contract pause/unpause, role changes, upgrade scheduling (N/A — immutable
core), and large transfers. The indexer already ingests the mint/deposit/buyback/founder events these
build on.
Error capture (env-gated)
The website error.tsx boundary and the indexer both log structured errors and expose a hook for an
error-capture provider (e.g. Sentry). It is wired but no-ops until SENTRY_DSN / equivalent is set —
boot never depends on it (a real integration that stays inert when unconfigured, never a fake that
simulates success).
North-star & product events
The metrics that define whether Crownridge is working — all derived from real chain data, never invented:
- Recognized Treasury reserve (the core: is capital entering and staying?).
- NAV per CRWN over time (is backing compounding?).
- Genesis deposits (count + volume).
- CRWN burned via buybacks and USDG spent (is the accretion loop running?).
- Conservation holds (must always be true).
- Founder withdrawals (transparency + trust signal).
These come from the snapshots and events tables and the /api/v1/summary endpoint.
Dashboards
The public dashboard (/dashboard) is the primary operational view for current state; the indexer API
feeds historical charts. Internal operators additionally watch the alerts feed and the guardian
runbook in docs/INCIDENT_RESPONSE.md.