Emission window detector

The watcher diffs each run against a saved market baseline and emits four alert types (NEW_COIN, PROFIT_SPIKE, HASH_BID_SPIKE, RENTAL_PRICE_MOVE), the signals where mining briefly beats everything else.

Why windows matter

On a consumer GPU, steady-state mining loses to inference and rental (see the oracle numbers in the README). Mining only becomes interesting during emission windows: a new PoW chain's first days, an actor overpaying for hashpower, a price pump before difficulty catches up. The watcher exists to catch those windows within one cron interval.

How it works

bun run src/watch-cli.ts (logic in src/watch/detect.ts):

  1. Fetches three sources concurrently, each failure tolerated independently: WhatToMine coins.json (BTC/day per hash per coin/algo), NiceHash simplemultialgo (BTC/day per hash per algorithm), and Vast.ai p25 asks for RTX 4090, RTX 3080 and RTX 3060.
  2. Builds the current snapshot and saves it to data/snapshot.json.
  3. If no previous snapshot existed, it stops there: "baseline initialized", run again to start detecting.
  4. Otherwise it diffs current vs previous and appends alerts to data/alerts.jsonl (JSONL, one alert per line: ts, type, subject, detail, optional ratio).

Thresholds (constants in src/watch/detect.ts): SPIKE = 1.5 (a 1.5x jump vs baseline) for profitability and hash bids, RENTAL_MOVE = 0.3 (plus or minus 30% on the p25 ask).

The four alert types

NEW_COIN: new mineable coin

A coin/algo key present on WhatToMine that was absent from the baseline. This is the "Tari/Nockchain/Quai day one" signal: fresh PoW listings are where early hashrate earns outsized emissions before difficulty adjusts. Each detection also appends a pre-filled registry draft to data/review-queue.jsonl for a human pass before the coin can enter the scorer registry (see docs/scorer.md).


{ "ts": "...", "type": "NEW_COIN", "subject": "TARI/randomx", "detail": "nouveau coin minable detecte sur WhatToMine, evaluer la fenetre d'emission" }

PROFIT_SPIKE: profitability jump on a known coin

BTC/day per hash for a known coin at 1.5x or more vs baseline: a price pump or a nethash drop. Either way, revenue per hash jumped and the window closes as hashrate migrates in.


{ "ts": "...", "type": "PROFIT_SPIKE", "subject": "QUAI/kawpow", "detail": "profitabilite x1.82 vs derniere baseline", "ratio": 1.82 }

HASH_BID_SPIKE: someone overpaying for hashpower

A NiceHash algorithm's paying at 1.5x or more vs baseline: a buyer is bidding above market for that hash. This is the Qubic pattern: in 2025 Qubic bought RandomX hashpower on NiceHash at above-market rates to point it at its own chain, briefly making hash sellers the best-paid actors on the algo. When this alert fires, selling hashpower can transiently beat every other destination.


{ "ts": "...", "type": "HASH_BID_SPIKE", "subject": "RANDOMXMONERO", "detail": "paying NiceHash x2.40: un acheteur surencherit sur ce hash", "ratio": 2.4 }

RENTAL_PRICE_MOVE: GPU rental market move

The Vast.ai p25 ask for a tracked GPU moved 30% or more in either direction. Up: demand surge, reprice your listings (the rental driver prices at p25 minus 2%). Down: rental may have lost the primary slot to another destination.


{ "ts": "...", "type": "RENTAL_PRICE_MOVE", "subject": "RTX 4090", "detail": "p25 ask 0.312 -> 0.418 $/h", "ratio": 1.34 }

Cron usage

The watcher is designed for a ~15 minute cron:


*/15 * * * * cd /path/to/effective-intelligence && /path/to/bun run src/watch-cli.ts >> data/watch.log 2>&1

Telegram push

If data/agent.json contains a telegram block (botToken, chatId), each run with alerts pushes a summary through the Telegram Bot API (src/watch/notify.ts): one line per alert, message truncated at Telegram's 4096-char cap (the full log stays in data/alerts.jsonl). Without config the push is silently skipped; failures never break the watch run.