---
name: alert-bots
description: Ben's Telegram alert bot fleet - ten services on one droplet that watch wallets, X accounts, Telegram channels and GitHub repos and push alerts to his Telegram. Use whenever a bot, alert, tracker or watcher comes up - "is the bot running", "I stopped getting alerts", "add a wallet to the tracker", "why did I get this message", "mute that bot", "restart it", or when a screenshot of a Telegram alert is pasted. Also load before creating any new alert bot, because the fleet has a fixed home and a duplicate running elsewhere silently doubles every alert.
---

# Ben's alert bot fleet

Ten services. All on one droplet. All alerting into one Telegram chat.

## Before anything else

Run the control tool. It answers most questions in one call:

```
~/botctl/botctl status
```

Bot names are `crashbot tonalert gramwatch xalert rhtracker ansemtracker
basewatch bwbot kookwatch watchdog`.

```
~/botctl/botctl status            every bot: live, enabled, uptime, log age, muted
~/botctl/botctl log <bot> [n]     last n lines (default 25)
~/botctl/botctl restart <bot>     also stop / start; 'all' works
~/botctl/botctl mute <bot>        and unmute - hot-read, no restart
~/botctl/botctl config <bot>      config with tokens fingerprinted, never printed
~/botctl/botctl watches           what each bot is actually watching
~/botctl/botctl ping              proves every bot token still authenticates
```

`botctl` runs on Ben's Mac and reaches the droplet over SSH. It is the only
place the full registry lives. If it disagrees with memory, believe `botctl`.

## The one rule that matters

**Everything runs on the droplet. Nothing runs on the Mac.**

The Mac holds abandoned copies of five of these bots in `~/crash-bot`,
`~/gramwatch`, `~/ton-alert`, `~/x-alert`, `~/rh-tracker`. Their launchd
plists are parked in `~/bots-mac-disabled/` and must stay parked. A second
copy of a bot uses the same Telegram token and posts into the same chat, so
it duplicates every alert while looking perfectly healthy from either side.

This is not hypothetical. On 2026-08-26 the Mac `crash-bot` was updated to 9
wallets and started, while the droplet copy ran the old 3-wallet config -
both posting as `@crash_accum_bot`. Symptom: duplicate alerts on the three
shared wallets and stale coverage on the six new ones.

**Before editing any bot, confirm which host it runs on.** `botctl watches`
and `references/registry.md` both answer this. Editing a Mac copy changes
nothing, silently.

## The fleet

| Bot | Telegram | Watches |
|---|---|---|
| `crashbot` | `@crash_accum_bot` | 9 Solana wallets in the Crash cluster |
| `tonalert` | `@crashtonbuy_bot` | Crash's TON wallet, jetton buys/sells |
| `gramwatch` | `@bk_gramwatch_bot` | Gram wallet launch - channels + wallet-core repos |
| `xalert` | `@xalertben_bot` | `brozinkerbell`, `forginvestments` on X |
| `rhtracker` | `@bk_rhwatch_bot` | Robinhood Chain swing wallet |
| `ansemtracker` | `@bk_ansem_tracker_bot` | 3 Ansem Solana wallets |
| `basewatch` | `@bk_basewatch_bot` | Solana DEX sweep for based charts |
| `bwbot` | `@bk_basewatch_bot` | Command bot for basewatch |
| `kookwatch` | own bot | kook's paid-group buy calls |
| `watchdog` | `@crash_accum_bot` | Restarts and reports on the other nine |

Eight distinct bot tokens, one chat. Two pairs share a token: `basewatch`
with `bwbot`, and `watchdog` with `crashbot` - so a watchdog message and a
Crash wallet alert arrive in the same thread and look like one bot.

Per-bot detail - thresholds, wallet lists, config paths, poll intervals - is
in `references/registry.md`. Host and SSH detail is in
`references/hosts-and-access.md`.

## When Ben says he stopped getting alerts

Work in this order. Each step has been the real answer at least once.

1. `botctl status` - is the unit active, and how old is its log?
2. Is it **muted**? `status` flags it. Muting is hot-read and silent.
3. Is the **threshold** hiding it? `crashbot` at `min_usd 1000` says nothing
   about a $600 buy. `botctl config <bot>` shows the numbers.
4. Is the **source** down rather than the bot? A bot can be perfectly alive
   and blind - see `references/failure-modes.md`.
5. Only then suspect the bot itself.

Silence is not evidence of quiet. It is evidence of nothing until steps 1-4
are cleared.

## When adding a wallet or account to a bot

Edit the config on the **droplet**, never the Mac copy. Most bots hot-read
their config each cycle, so no restart is needed - but `crashbot` takes a
baseline snapshot per wallet at startup, so a newly added wallet needs a
restart before it will ever alert.

```
~/botctl/botctl config crashbot     # see current shape
# edit /opt/crash-bot/config.json on the droplet
~/botctl/botctl restart crashbot    # posts a startup notice listing all wallets
```

`crashbot` confirms its own config on every start by pushing the full wallet
list to Telegram. That notice is the proof an edit landed. If it does not
arrive, the edit did not take effect - do not report the change as done.

## Known open gap

`tonalert` watches one TON wallet, `0:4e1dda8f...`. The wallet cluster found
in the wallet hunt - `0:ae4ec802` holding ~$330k of UTYA and `0:9631c9fc`
holding ~$25k of CHERRY - is **not covered**. `tonwatch.py` takes a single
`wallet` string, so covering the cluster needs a code change, not a config
edit. Raise this when TON coverage comes up; do not assume the cluster is
watched.
