Skip to main content

Colver Logo

Play on colver.net PyPI version Models on Hugging Face MIT license

Colver

Lire en francais

Fast Belote Contree game environment for reinforcement learning. Rust core with Python bindings.

Play online: colver.net — a self-hosted public site: solo or multiplayer games, accounts, ratings and analysis.

Quickstart

pip install colver
import colver

env = colver.Env.deal(dealer=1, seed=35)   # reproducible deal; South opens the bidding
# South holds   ♠ —   ♥ 10 J   ♦ K Q J 9   ♣ K 8

# What does South bid?
env.load_bid_model(colver.download_bid_model())   # fetched from the Hub on first use
print(colver.Env.action_name(env.action_bid_nn()["best_action"], 0))
# 120♦

# And what does South lead? The model bids the auction out at all four seats;
# nobody outbids it, so South plays 120♦ for North-South.
while env.phase() == 0:
    env.step(env.action_bid_nn()["best_action"])

env.load_dmc_model(colver.download_model())
print(colver.Env.action_name(env.action_dmc_with_stats()["best_action"], 1))
# J♦ — the master trump, in 0.6 ms on CPU

Both calls also return q_values, the model's full ranking, already restricted to the legal actions.

Model weights live on the Hugging Face Hub — one repo per model, each with a card explaining what it does, what it is worth and what it cannot do. download_*() caches them under ~/.cache/colver/models/ (GitHub Releases is kept as a fallback); point COLVER_MODEL_PATH & co. at your own files to override.

Features

  • ~1.4M rollouts/sec single-threaded (play phase), ~895K rollouts/sec on a full deal
  • ≤96-byte Copy game state for fast MCTS cloning
  • Six AI agents — DMC Q-network, IS-DD, DD oracle, Smart/Naive IS-MCTS, and heuristic
  • NN bidding — "Bid V6 IS-DD", a score- and belote-aware Dueling DQN (117→512³→43) trained 75M steps on real IS-DD points with full match simulation, used by all agents
  • ML interpretability — XGBoost distillation + hidden-layer probe reveal the NN's implicit scoring system, translated into human-usable rules (88-94% agreement)
  • Playgen world model — a causal transformer that continues a deal from what one seat can see; rolling it out reveals the hidden hands, which is where IS-DD's sampled worlds now come from
  • One agent layer — a bot is a TOML spec ([bid] / [play] / [worlds]), built by the Rust side and driven identically by the arena, the web and colver.Agent
  • A site running on itcolver.net: solo games and multiplayer rooms, per-card analysis, training problems. The site is not distributed with the package; the engine above is what it runs
  • Python bindings via PyO3 — Env, Agent, Analyst and Beliefs with full type stubs, installable from PyPI
  • Zero dependencies in the core (only rand behind a feature flag)

Web Interface

Play against AI agents directly in your browser at colver.net.

What is published — this repository and the colver package — is the engine: the rules, the search, the agents and the Python bindings. That is what you need to check that a deal is not rigged and that the bots play what they claim to, and that is what publishing it is for. The site itself is the product, and is not distributed.

Everything is in French, behind four destinations: Jouer, Analyser, Apprendre, Classement. An account is optional — it is what links games to you, and what makes matches resumable and rated.

Jouer

Humain vs IA — Play as South against three bots. There are exactly two settings, both chosen before the deal:

  • TempoStandard (Dede, ~40 s a deal) or Rapide (DouDou50, ~15 s). The bundle is deliberate: an IS-DD search costs real wall-clock per move, so a fast tempo is only honest behind a bot that answers instantly. All four AI seats run the same bot — a table where your partner is weaker than your opponents tells you nothing about how you played.
  • Match length — a single deal (default), or a match to 1000 / 2000 points. The running score is passed to the bots, and Bid V6 reads it: it bids differently at 900-200 than at 0-0.

Cards are played instantly on click; the pause belongs to the position before a move and the bot thinks inside it, not on top of it. Forced passes are played for you, the last trick (where nobody has a choice left) runs itself, and the final trick is held 2 s before the end-of-deal panel. Signed-in players can leave a match and resume it later.

Play tab

Salon multijoueur — Rooms with a 4-character join code; bots fill whatever seats humans do not. The host picks the tempo and the match length. Every broadcast state is filtered to the viewer's own hand and rotated so the viewer always sits South. Seats are account-bound, so a disconnected player can come back to their seat.

Salon

IA vs IA — Spectate AI vs AI matches with all hands visible. Assign a different agent to each of the 4 seats. Step through actions, play full tricks, or use auto-play. The stats panel shows Q-values, DD scores, or hand evaluations for each decision. Paste a CFN string to load a specific position.

Watch tab

Analyser

Rejouer — Browse and replay past deals (played, spectated or shared) and step through them card by card. Two independent analysis passes run on top, each cached and fetched separately so the slow one never blocks the fast one:

  • the DD pass — the exact cost of every card, plus a bid review carrying two opinions per auction action: Bid V6's Q-values and playgen's 43-way auction head;
  • the agent review — what DouDou50, the Oracle and Dede would have played at every non-forced card, streamed in as it computes.

Every card and every bid links out to its own analysis page, and back.

Rejouer

Annonces — Compose an 8-card hand, set the bids that preceded your turn, and see what Bid V6 IS-DD would call — Q-values for every legal action, plus an XGBoost-distilled "key factors" panel (which features drove the decision). Two tables then play the hand out over hundreds of random deals of the other 24 cards: Jeu parfait (each deal solved double-dummy by the Oracle — a theoretical ceiling) and Jeu reel (the full auction bid by the NN at all four seats, then 8 tricks played by DouDou50 — what actually happens). One tab per bid analysed, so two bids on the same hand can be compared side by side, and analysed hands are kept in a sidebar. Runs server-side or fully in the browser via WASM ("Calcul local").

Annonces tab

Jeu de la carte — One row per playable card at a given position, answering two questions that must not be confused: the worlds of the information set (deals compatible with what the seat could know, each solved double-dummy — this is where the decision is judged) and the real world (a single exact solve on the deal as it actually was). A third block forces the card and lets DouDou50 finish the deal. A card that was second-best in the real deal but best in 70 % of the worlds was a good play against bad luck.

Jeu de la carte

Croyances — Watch playgen locate the hidden cards as a deal unfolds, during the auction as well as during play. Step through a generated deal and read the per-card probability bars against ground truth, from any of the four seats.

Croyances tab

Problemes d'annonce — Bidding practice problems. See a hand and bidding history, then find the right bid. The AI evaluates your answer against the NN bidder's recommendation.

Problemes de jeu — Card play practice problems. See a mid-game position and find the best card. Compare your choice to the DD solver's optimal play.

Apprendre

Aide-memoire — Visual cheat sheet: card strength order and values (trump / non-trump), deal points, bidding rules.

Guide des annonces — Visual strategy guide derived from the bot via ML (per-card point weights, decision rules per position, mirror rule for defense). 88-94% agreement with the NN, memorizable in minutes.

Annoncer tab

Marquer les points — Score keeper for real-life games. Pick a target score (1000-3000), add rounds with a form that computes exact FFB scores automatically (contract, coinche/surcoinche multiplier, points made, belote), and watch the live win-probability estimate update after every round. Everything lives in the browser — no server, no account.

Marquer tab

Classement

One Elo per rated entity — a human account or a bot type — updated deal by deal whenever all four seats are identifiable. Bots use a lower K: they are reference points and occupy up to three seats per game.

Build & Run

Requires stable Rust (2021 edition) and Python 3.10+.

# Engine tests (382 passing, 52 ignored)
cargo test -p colver-core

# Performance benchmark
cargo run -p colver-core --bin bench --release

# MCTS vs random demo
cargo run -p colver-core --bin mcts_demo --release -- 100

# Smart IS-MCTS vs random + vs naive demo
cargo run -p colver-core --bin smart_ismcts_demo --release -- 100

# Python bindings (via uv)
uv sync
uv run python3 -c "import colver; env = colver.Env(); print(env.reset())"

# Bot vs bot, 200 matches each way (a bot is a TOML file in arena/bots/)
cargo run --bin arena --release -- h2h web_dede web_doudou --matches 200

# Joint bid+play training (GPU, candle)
cargo run -p colver-core --bin train_joint --features dmc_train --release -- --num-envs 256 --steps 35000000

# Playgen GPU sidecar — where IS-DD gets its worlds from
cargo run -p colver-core --bin playgen_gpu_server --features gpu_server --release -- --playgen models/playgen/playgen_v2_final.bin --port 8003
export COLVER_PLAYGEN_GPU_URL=http://localhost:8003

Without $COLVER_PLAYGEN_GPU_URL, IS-DD bots fall back to constraint-uniform worlds (the web says so in the decision's stats; the arena refuses to build the bot unless the spec opts in).

AI Agents

Oracle — DD Solver (solver.rs)

Perfect-information double-dummy solver that sees all 4 hands — it cheats. Alpha-beta with transposition tables, PVS, killer moves, and card equivalence pruning. Computes the exact optimal card in ~24 ms from a full deal, ~150 us mid-game and ~1.4 us in the endgame (measured 2026-08-03, 1 thread, on a frozen corpus; the measurement spread is ~9 %, which is what tells you how many digits mean anything). Useful as an upper bound. The bench that produces those numbers ships with the repo: cargo build --release --features "parallel solver_stats" --bin bench_dd.

Dede — IS-DD (is_dd.rs)

Information Set Double-Dummy search: sample plausible deals consistent with what this seat can know, solve each one exactly with the alpha-beta DD solver, aggregate. Hard constraints (voids revealed by the play, trump ceiling, cards already gone) are facts and always apply. The sampled worlds come from a WorldSource the agent owns — playgen over the GPU sidecar by default, with a constraint-uniform sampler as the fallback. A belief network can additionally weight the sampling. IS-DD sounds like "is Dede" — hence the name.

DouDou50 — DMC Q-Network (dmc_net.rs)

DouZero-style reinforcement learning agent. A Q-network picks card plays with a single forward pass — no search tree. Default play model, trained 50M steps with the NN bidder frozen (triforge play-only phase).

Architecture: ResNet Dueling DQN 411→1024→1024→1024→32 with LayerNorm and skip connections (~2.6M parameters). Uses canonical suit encoding (no augmentation needed). Inference in pure Rust (~1ms/decision, no PyTorch needed). Strongest overall agent.

The previous model DouDou35 (415→1024³→32, legacy obs, 35M steps) is still supported for backward compatibility. DouDou = a reference to DouZero.

Playgen — world model (playgen/)

A causal transformer (10.7M params) trained to continue a deal autoregressively from the prefix one observer can see. Rolling it out reveals the hidden hands, so a rollout is a determinized world drawn from a learned posterior rather than from a uniform shuffle — that is what IS-DD samples, and what the Croyances page displays. v2 also carries a 43-way auction head, which makes it usable for mid-auction sampling (and, as a curiosity, as a bidder in its own right). It runs on CPU or CUDA; in production a sidecar (playgen_gpu_server) serves it over HTTP, ~50× faster than sampling on CPU.

Older search agents

Smart IS-MCTS (smart_ismcts.rs) — Belief-weighted Information Set MCTS with heuristic card beliefs. Naive IS-MCTS (naive_ismcts.rs) — Ensemble determinization without beliefs. Both are configurable through the bot-spec format described in docs/agents.md.

Bid V6 IS-DD — NN Bidder (bid_net.rs)

Dueling DQN 117→512→512→512→43 with score-aware v3 observation (match-score features + 4 belote bits). Trained 75M steps on real IS-DD points (not DD oracle) with belote-aware reward and full match simulation (cumulative scores, dealer rotation, reset at 2000). Beats the previous champion Bid V5 in both eval sets (55.8% with DMC play, 57.3% / +181 pts with IS-DD play). BidNet::load auto-detects hidden size and obs_dim (108 / 110 / 113 / 117).

Past versions still supported via auto-detect:

  • Bid V5 IS-DD — 113-dim score-aware obs, 25M steps on real IS-DD points
  • Bid V3 Max — 108-dim, trained on max(DMC, IS-DD) real points (20M steps)
  • Bid à Dédé (v2) — 108-dim, DD oracle reward
  • Bid à Doudou (v1) — 114→256² dueling, DouZero self-play

Interpretability: XGBoost distillation and a hidden-layer linear probe revealed that the NN's implicit scoring differs sharply from the classical hand evaluation (e.g., J atout = +11 effective, 9 = +4, A atout = +1, side A = 0 net; plus an anti-synergy J×9 = −2). Translated into a mnemonic 5-feature decision tree reaching 88-94% NN agreement. The hand space is enumerable — 472,579 distinct 8-card hands, bijectively indexed — which turns a bidder's opening policy into a finite table rather than a black box: docs/bid/interpretability/hand_classification.md.

Agent Comparison

Agent Type Speed/move Notes
Oracle (DD) DD solver (cheats) 24 ms -> 1.4 us (trick 1 -> trick 8) Perfect info upper bound
Dede (IS-DD) DD solver over sampled worlds budget (1 s in the web) Strongest search-based
DouDou50 Q-network (ResNet) <1ms Strongest overall, no search
Smart IS-MCTS Search + beliefs ~9ms Configurable budget
Naive IS-MCTS Search ~8ms Configurable budget

Note: Search-based agents get stronger with more time budget. The DMC agent uses no search — one forward pass per decision.

Bots are specs, not code paths

A bot is a TOML file describing a bidder, a card player and (for IS-DD) a world source. The arena, the web frontend and colver.Agent all read the same spec and get the same agent — there is no second implementation anywhere.

[bid]
strategy = "nn"                    # heuristic|improved|smart|maxi|nn|playgen|…
model = "models/bid_v6_isdd_resume/bid_nn_final.bin"

[play]
method = "isdd"                    # isdd|dmc|dmc_then_isdd|ismcts|smart_ismcts|oracle_dd|heuristic
time_ms = 1000

[worlds]                           # IS-DD only; defaults to the sidecar
source = "sidecar"
url = "http://localhost:8003"

Testing a new combination means writing a file, not recompiling. arena/bots/ holds three: web_dede and web_doudou are exactly the two bots colver.net plays (standard and fast modes), heuristic_baseline needs no weights at all. All three depend only on models published on the Hub. The full zoo and the accumulated results stay private — they are our measurements, not an API.

Architecture

Workspace: colver-core (pure Rust) + colver-py (PyO3/NumPy FFI) + colver-wasm (in-browser solver)

Card Representation

Bitmask system: Card = u8 (0-31), CardSet = u32 (bitmask). Layout: Spades[0-7], Hearts[8-15], Diamonds[16-23], Clubs[24-31]. Within each suit: 7, 8, 9, J, Q, K, 10, A (plain strength order). Trump strength: J > 9 > A > 10 > K > Q > 8 > 7.

Game State

GameState is Copy and ≤96 bytes (compile-time enforced) for fast MCTS cloning. Contains hands, current trick, contract, points/tricks per team, bidding state, played cards bitmask, void tracking, and belote tracking.

Action Encoding

Phase Actions Encoding
Bidding 43 total 0=PASS, 1-36=bids (9 values x 4 suits), 37-40=capot x 4, 41=COINCHE, 42=SURCOINCHE
Playing 32 total Card index 0-31 directly

Game Flow

Bidding → Playing → Done. Bidding ends after 3 consecutive passes, a surcoinche, or 4 passes (void deal). Playing runs 8 tricks of 4 cards. Card point total = 152; with dix de der = 162 (normal) or 252 (capot).

Python API

import colver

print(colver.__version__)  # "0.10.0"

# Single environment
env = colver.Env()
obs, legal_actions = env.reset()
obs, reward, done, legal_actions = env.step(action)

env.current_player()       # 0-3
env.phase()                # 0=Bidding, 1=Playing, 2=Done
env.legal_action_mask()    # numpy array (43,)
env.rewards()              # [NS_score, EW_score]
env.bid_improved()         # improved_bid action
env.deal_outcome()         # [NS_outcome, EW_outcome] binary
env.get_observation()      # 415-float observation vector
env.action_naive_ismcts(20)  # naive IS-MCTS action (20ms)
env.action_smart_ismcts(20)  # smart IS-MCTS action (20ms)

# DMC Q-network (if model weights downloaded)
model = colver.model_path()  # ~/.cache/colver/models/dmc_final.bin
if model:
    env.load_dmc_model(str(model))
    result = env.action_dmc_with_stats()  # {"best_action": 5, "q_values": [...]}

# A whole bot from a spec — same TOML the arena reads
agent = colver.Agent(spec_toml, seat=2)
agent.init_deal(env)
agent.observe(env, action)       # every action, including your own
decision = agent.decide(env)     # {"action": …, plus per-method stats}

# Playgen as an analyst: hidden-card marginals, sampled worlds, auction policy
analyst = colver.Analyst("models/playgen/playgen_v2_final.bin")
analyst.init_deal(env, observer=2)
probs = analyst.marginals(env, n_worlds=50)

Performance

Workload Throughput Latency
Play-phase rollout 1.4M/sec ~720 ns
Full-deal rollout 895K/sec ~1118 ns
MCTS game (1000 iter) vs random 8 ms
Smart IS-MCTS game (20x50) vs random 9 ms
DMC Q-Network inference <1 ms

Rules

Implements Belote Contree with 4 suits (Spades, Hearts, Diamonds, Clubs). Scoring mode: "points faits + points demandes", with the coinche (x2) and surcoinche (x3) multipliers applying to the contract value only. On a chute the defense takes the contract and every card point, whatever the real split of tricks.

Scores are exact — nothing is rounded. The FFB rounds the marque to the nearest 10; here a chute marks 162 + the contract, not 160, so the engine and the web score sheet always show the same number. See the FFB rulebook for the full official text, and docs/rules-survey/ for how ~594 published rulebooks actually differ from it.

References

Acknowledgments

Thanks to Ronan Guillou, seasoned coinche player, for his advice on the game and for being the first tester — his good sense guided many UI decisions.

License

MIT — see LICENSE. It covers all of this repository: the engine, the Python and WASM bindings, the arena, the published documents.

Model weights are not in the repository. They live on Hugging Face under their own license, and colver.download_*() fetches them from there. A model is a training artifact, not code: versioning it would add tens of megabytes to every clone for a file that changes with every campaign.

The colver.net site is not in this repository and is not under this license.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

colver-0.11.1.tar.gz (763.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

colver-0.11.1-cp310-abi3-win_amd64.whl (593.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

colver-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (718.6 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

colver-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (695.7 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

colver-0.11.1-cp310-abi3-macosx_11_0_arm64.whl (652.4 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

colver-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl (681.3 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file colver-0.11.1.tar.gz.

File metadata

  • Download URL: colver-0.11.1.tar.gz
  • Upload date:
  • Size: 763.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for colver-0.11.1.tar.gz
Algorithm Hash digest
SHA256 459c76998d953b9afa369fccda44ffcb5c538794c6e2dbd4d84078df85c0a262
MD5 d983e8d5bb09ce03823577ac456636c8
BLAKE2b-256 a29640fa5ef08d0df979a3d67a3e919c5b66b2cac9bb9367934d24aec20c6ff2

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1.tar.gz:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file colver-0.11.1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: colver-0.11.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 593.3 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for colver-0.11.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a5fccd7efef08598d65cda607265ed3a643c08941933cd1c852a731c96b12c53
MD5 fb27832e18814821e5bc6effb9e94034
BLAKE2b-256 ca0f93945527441c12bf3e2e16f1fb1bf7fad2bd61b37d1d7b3c456373a3fdb6

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1-cp310-abi3-win_amd64.whl:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file colver-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for colver-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ab4c22d69b25c901a53c9a13b46dbef349e4a4a9857597a5966a32c8ed559eb2
MD5 465f5f7c597168fea247f94f5238231d
BLAKE2b-256 f05270e7514fe9b59d73a7729cb6ddab9f12aebe8f139709e2372bce02eb6420

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file colver-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for colver-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c413830b244b5778470f755053701596260f4294d5a93f6c573bb3cdbc59ef9f
MD5 89e9dd28f55a16720d77a60c903e560b
BLAKE2b-256 6f0448c0a558d337e9bf659cc906b7d0ce9cda9a10af618e1e106c1e59a8c3e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file colver-0.11.1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for colver-0.11.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 af0d1b7bf141a61cab451969352d5e1b2e1857c809e72fc913ce7e27945e1d7e
MD5 e80de46d8489c177fd53379f9bdeff16
BLAKE2b-256 1c3160687dd25132221126e5aa0cc548bf4bbd2f38b0375df2603fca41492d2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file colver-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for colver-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 028ff020fcef8c7ca450a995328aec284321d8bb1f9df416c27f1fa500d30c8d
MD5 b2ee0ce95d12d7d90e2e4d5bc25d1dd3
BLAKE2b-256 ce9d55aa9040e4dec99706ac65f3306684df3b63397ffb5bd9e8c0073de2cb39

See more details on using hashes here.

Provenance

The following attestation bundles were made for colver-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on Avo-k/colver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page