---
name: alert-bot-fleet-3
description: Continuation of the alert bot fleet change log from 6 Sep 2026, after alert-bot-fleet-2.md hit its size cap. Read all three whenever a bot, alert, tracker or watcher comes up.
sources: [cowork]
aliases: [alert bots part 3, ubermwatch, 0XUBERM ALERT]
---
Continues [[alert-bot-fleet-2]] and [[alert-bot-fleet]]. Same droplet, same rules.

## THE HOOKED FALSE BUY, 6 Sep 2026, and the classifier rewrite it forced
- [stated] Ben, on a "BOUGHT $226.62 of HOOKED" alert from 0XUBERM ALERT: "This used to be a scam token. Make sure that this is really a buy. I don't think it is. Double check, triple check." **He was right. It was not a buy.**
- What the transaction actually was, tx 0xc669692378b6baa14f460732dcd73afcc84e9ad1fd001ba8a6190c5f9a2436da: contract 0xe5eac6b2143c7d6eb2e242fc1c8e43b24eef4d46, driven by 0x207e4c519f84c0adc5a45ae2d2e341d2d6ef76f7, made **seven** small WETH buys of HOOKED on the v2 pair 0x8a91b2827987deafa5bf7e9e039615b976de0943 and sent each output to a **different wallet**, his among them (5,406,084.74 tokens). A promoter buying bags and gifting them to KOLs to bait a shill. His wallet paid nothing.
- Second tell, independent: his HOOKED balance reads **zero** with no outgoing transfer ever, so the contract emits Transfer events it does not honour.
- **WHY THE OLD CODE CALLED IT A BUY:** the inherited rh-tracker treated "any Uniswap Swap event anywhere in the receipt" as proof of a trade (it logged `trade (swap-event)`), plus a weaker rule for "any quote-asset transfer anywhere in the tx". In a 42-log batch those fire on a stranger's leg. **Both rules are now deleted.** This bug is in every clone of /opt/dinerodom/tracker.py, so it is present in dinerodom, rhtracker, rhtracker-base, ansem-rh, earlybirds and strongtrader too. **Port the fix into them.**
- **THE RULE THAT REPLACED THEM, verified across ten of his transactions: he trades through fomo, and fomo settles every fill through ONE contract, 0xb92fe925dc43a0ecde6c8b1a2709c170ec4fff4f.** Every real buy has that contract as the immediate SENDER of the coin; every real sell has it as the immediate RECIPIENT; the HOOKED gift came straight from a Uniswap pair. His own wallet never pays inside the transaction (a relayer, e.g. 0xf70da97812cb96acdf810712aa562db8dfa3dbef, pays from his deposited balance), which is exactly why "did he pay?" cannot be answered from his own legs. Config key **`settlement_contracts`** now carries it.
- Fallback for a trade routed some other way: `matched_trade()` in pnl.py requires the swap amounts in the transaction to ADD UP to the wallet's token delta within 15%. This also handles split routes a naive single-pool match misses: RSRV, 6 Sep, was 1,898,169 tokens bought across four pools in one transaction. The HOOKED spray fails the test because the pool's swaps account for three times what he received (all seven recipients), which is the arithmetic signature of a spray.
- Third guard, cheap and independent: **a "buy" that leaves the wallet holding zero of the token is not a buy** and is dropped with a log line. Catches fake-Transfer contracts.
- Also fixed in pnl.py: `swap_sides()` now decodes **v2 (amount0In/1In/0Out/1Out) and v3 (int256 pairs)** Swap events, not only v4.
- Replay over the last 400,000 blocks after the change: **14 trades, all with reason `fomo-settlement`, 72 transfers, HOOKED excluded.** An over-strict interim version (swap amounts only) would have silently lost three real AI buys, because fomo buys carry no recognised Swap topic at all: the fill happens on a custom AMM (0xb3d0e42a8618c020142767d4a5983f4df22da938, Swap topic 0x87d25816ca01...) that is not in SWAP_TOPICS.
- Test harnesses left on the droplet: `/tmp/test_classify.py` (four known cases, HOOKED must be TRANSFER and three AI trades must be TRADE) and `/tmp/replay.py` (whole window, prints every kept trade with its reason). **Run both after any change to classify().**
- **THE GENERAL LESSON for every wallet tracker: a swap in the transaction proves someone traded, not that THIS wallet traded.** The question is always whether value left this wallet or its agent. Answer it by the identity of the counterparty, or by arithmetic, never by the presence of an event.
- **A SECOND, TRADEABLE SIGNAL falls out of this:** a token arriving at a KOL wallet from a promoter spray is a paid-shill setup. Those are worth SEEING, labelled as gifts, not as buys. They still alert as transfers, which is the right place for them.

### Same day, second pass: made venue-independent, because he also trades OFF fomo
- [stated] Ben: "it doesn't have to be a FOMO contract, right? It can be off FOMO. This is a trading account also, so just make sure it's real buys and real sells that he does himself, not stuff that people sent him."
- Correct objection. A settlement-contract allowlist would go blind the day he uses a different venue. `classify()` was rewritten again as **five tests, any one of which is enough**, in order:
  1. **paid-in-tx** - his wallet has both a positive and a negative token leg. A swap however routed; a gift can never have both.
  2. **native-value** - he signed the transaction himself AND sent native ETH with it. Signing alone is not enough, because claiming a free airdrop is also signed by him.
  3. **settlement-contract** - the counterparty is in `settlement_contracts` (fomo's 0xb92fe925dc43a0ecde6c8b1a2709c170ec4fff4f). A fast path, no longer load-bearing.
  4. **swap-matched** - the swaps in the transaction add up to his fill within 15% AND he is the sole beneficiary (see below). A sell always passes, since selling is his own act.
  5. **routed-fill** - the shape test, for a venue whose Swap event is not recognised at all: real money moved (`settlement_quotes`: WETH, USDG), the coin was handed along a route, and essentially all of it ended with him.
- **THE TWO MEASUREMENTS THAT DO THE WORK, both in pnl.py, both venue-independent:**
  - `sole_beneficiary(receipt, token, wallet, min_share=0.80)`: of everything left HOLDING that coin when the transaction ends, what share is his. **Measured on his real fills: 99.0% and 98.9%, with 1% going to fomo's fee wallet 0xe5e702641ea86f4ae6cc3cdaed2b886f976be044. Measured on the HOOKED spray: 35.5%, with six strangers holding the rest.** That gap is the whole discriminator and it needs no allowlist.
  - `pass_through(receipt, token)`: how many addresses merely FORWARDED the coin inside the transaction. **A routed fill has three. A gift has zero, because it goes pool straight to recipient.**
- **VERIFICATION THAT MATTERS: the twelve-case harness `/tmp/test2.py` runs twice, the second time with `settlement_contracts` emptied.** All twelve are still correct with the fomo allowlist removed, which is the proof the logic is not fomo-specific. Do this every time a venue rule is touched: delete the shortcut and check the general rule still holds.
- Also: **USDG 0x5fc5360d0400a0fd4f2af552add042d716f1d168 added to `quote_tokens`** so the chain's stablecoin is never itself reported as a coin he bought or sold. Three sub-$10 USDG legs were being classified as trades before this.
- Final live state of 0XUBERM ALERT: two wallets, poll 2s, buys, sells and transfers all on, $100 floor, the P&L book from basis.json, and this classifier. Replay over 400,000 blocks: 22 trades, everything else transfers, HOOKED excluded.

### 6 Sep 2026, evening: REAL CASH pricing, and the full track record
- [stated] Ben asked: "what's his track record on the trading wallet. show all coins and pnl per coin." Published as the artifact **Uber M Trading Ledger** (352 coins, sortable, full addresses). Source data: /opt/ubermwatch/pnl_report.json, made by /opt/ubermwatch/report_pnl.py from basis.json + legs.json.
- **CORRECTION TO EARLIER NUMBERS IN THIS FILE.** The first backfill (802 swap-priced legs, "$95,974 realised, 11 open positions") was badly incomplete. It priced only fills that emit a standard Uniswap Swap event, and most of his fills go through fomo's custom AMM (0xb3d0e42a8618c020142767d4a5983f4df22da938) which emits none, so 2,558 of his fills were being treated as plain transfers. Also, the LIGER sale alerted at "$4,926" was really $648: DexScreener mid-price x tokens is NOT what a thin memecoin-quoted pool pays out.
- **THE FIX, and the right method for any fomo-routed wallet: read the USDG leg that passes through the settlement contract 0xb92fe925dc43a0ecde6c8b1a2709c170ec4fff4f in the same transaction.** That is the actual cash, slippage and fees included, already in dollars, no price feed at all. `settlement_value()` in pnl.py. Backfill now prices by settlement leg first (2,558 legs), swap event second (5), and drops almost nothing (1). The live tracker now uses it too, and prints "Chart said $X, real cash was $Y" whenever they differ by more than 10%. Proceeds go to the RelayDepository 0x4cd00e387622c35bddb9b4c962c136462338bc31, i.e. his fomo balance, not his wallet.
- **THE RECORD (trading wallet 0xdce001e4ec11ab58650c51ae9658accbe0f49c48, 10 Jul to 6 Sep 2026):** put in $2,985,666, taken out $3,388,422, still holding $665,561, **total P&L +$1,041,951** (+$713,041 banked, +$328,910 open). **327 coins with $100+ in: 98 winners, 227 losers, 30% hit rate.** Average winner +$14,517, average loser -$1,677, ratio 9:1. All winners +$1,422,631, all losers -$380,675. **AI alone is +$782,606, 75% of everything; without it the book is still +$259,345.** Top: AI, MOO +$143,793, BONER +$67,349, SPACEHOOD +$53,763, AGI +$33,485. Worst: Analyst -$21,241, GASOLINU -$16,146 (still held), PACK -$13,973, PYOSTR -$11,743.
- **Read for copy-trading: a right-tail record.** He is wrong 7 times in 10 and it does not matter, because he cuts at ~$1.7k and lets AI run to $783k. Copying his buys without his sizing and his willingness to sit through 96 buys and 143 sells of one coin would not reproduce this.
- Open book now: AI 2.03M ($464k), MOO 5.16M ($110k), ROBINVAULT 7.39M ($41k), ICOIN 5.59M ($26k), hoodrat ($13k), GASOLINU ($8k), PRM ($3k, bought today).
- Pipeline note: report_pnl.py takes ~8 minutes (block timestamps for 352 coins). Run it detached with setsid; the ssh call will time out otherwise.

- 7 Sep 2026: [stated] Ben, on two "RECEIVED $10,584 of BREWCAT" cards: "i don't want to see stuff he receives, only his buys and sells." **alert_transfers set to false** on 0XUBERM ALERT. This reverses the 6 Sep decision to keep transfers on for this wallet. Buys and sells only now, both directions of plain transfers silent.

## 8 Sep 2026: LAUNCHWATCH sent a BUY on FUN, which is not a coin. The quote-asset blind spot.
- [stated] Ben pasted the alert and said "this coin rugged few mins after this. what did the DD screen miss?"
- **The alert:** FUN, 79 min old, cap $77k, pool $118k, $129,540 in hour one ($5,017 in the first 15 min then $124,522 more), "-0% on the hour, holding at 91% of the hour's high", pool turned over 1x.
- **FUN 0xF9d30A05A63d795e3eF37b34143f33b2cBEf0f14 is not a memecoin. It is money.** tickr.fun (tickrfun.gg, x.com/tickrdotfun_rh) is a "pair anything with anything" launchpad on Robinhood Chain: you name a coin, name any ticker to price it in, **and a brand new pairing unit is created in the same transaction.** Somebody launched TICKR paired against a ticker called FUN, so FUN was minted into existence as the unit of account.
- **Proof it could never move:** every 5-minute candle from its first (20:20 UTC 7 Sep) to now opens and closes at $1.00. h24 price change +0.05%. 6 decimals, supply 49,634 and shrinking as people redeem. Wicks to $1.09 are swap slippage, not price.
- **What actually rugged was TICKR 0x51d553Efd2E8D772AEe6d602A9ea26C56c9a6942**, the real coin on the other side: -78% on the day against ETH, pool down to $319. FUN itself just had its supply and pool halve (cap $77k to $45.8k, pool $118k to $50k) as people redeemed out, which on a chart reads as a collapse.
- **THE FOUR TELLS THE SCREEN ALREADY HAD IN HAND:**
  1. **pool > market cap.** $118k pool against a $77k cap is a ratio of 1.53. A real launch on this chain runs 0.05 to 0.5 (SNOWBALL measured 0.46 live). A pool worth more than the whole token means the token IS the liquidity. **The alert printed both numbers side by side and drew no conclusion.**
  2. **the flat price WAS the tell and the bot read it as strength.** "-0% on the hour, holding at 91% of the hour's high" is what a peg looks like. `MIN_OFF_HI` has no floor on realised volatility, so a pegged instrument scores as maximum conviction.
  3. **the quote filter was a hardcoded list.** `QUOTES = {"weth","usdg","usdc","usdt","dai","eth"}` at line 66, applied at line 228. FUN was created ten minutes before the pool, so it could never be on that list. **tickr.fun manufactures a new quote asset on every single launch, so a static allowlist is structurally the wrong shape of defence.**
  4. **wrong DexScreener endpoint.** The bot called `tokens/v1/robinhood/{ca}`, which returns ONLY pools where the token is the BASE. FUN sits on the quote side of TICKR/FUN, so that pool was invisible to it. `latest/dex/tokens/{ca}` returns every pool including quote-side ones, same cost, one call. **Verified both endpoints on FUN: v1 returned 1 pair, latest returned 2 including TICKR/FUN.**
- **THE PATCH: APPLIED AND VERIFIED LIVE 8 Sep 2026 00:31 UTC.** Backup at /opt/launchwatch/launchwatch.py.bak-quoteasset-20260908-003121. Syntax OK, first post-patch cron run 00:33:14 clean, zero tracebacks. Harness /tmp/t3b.py on the droplet: **FUN blocked ("quote side of 1 pool(s)"), USDG blocked ("price flat +0.00%"), SNOWBALL passes (ratio 0.46), TICKR passes (ratio 0.02).** Re-run it after any change to CHECK 3b. Note USDG did NOT trip the quote-side test (DexScreener returns limited pairs for it) and was caught by the flat-price test instead, which is the point of layering three independent reads.
- **THE PATCH (source /tmp/lw_patch.py in the Cowork container).** Inserts CHECK 3b after the mcap/liq fetch in /opt/launchwatch/launchwatch.py, swaps the endpoint to `latest/dex/tokens`, and hard-rejects on any one of: (a) token appears as `quoteToken` in any pool, (b) liq/mcap > 0.9, (c) |move - 1| < 0.015. Blocked rows are logged to blocked.jsonl like the scam veto. Also relabels the `<code>` address block as "contract:" because it sat directly under the "deployer:" line and read as the deployer (the value was always the CA and always correct, only the placement was misleading).
- **THE GENERAL LESSON, and it generalises past this bot: an allowlist of known infrastructure cannot defend against infrastructure that is created on demand.** Ask the structural question instead: is anything pricing itself in this token. If yes it is money, not a trade. One field on a call the bot was already making.
- Droplet reminder: LAUNCHWATCH is /opt/launchwatch/launchwatch.py (357 lines), no systemd unit of its own; lwserve.service serves its scorecard. Reach the droplet from Cowork via Desktop Commander on the Mac: `ssh -i ~/kookwatch/id_kookwatch root@159.223.88.168`. Large patches go over as one base64 blob piped to `base64 -d`, since there is no scp path from the container.

## 8 Sep 2026: PAR UPDATE, the first EMAIL service in the fleet
- [stated] Ben: "Send me a daily email with usage stats, and also check if any of the revenue comes back to the token. Also, give me updates on the burns. Anything that accrues value should also be in the daily update email. Create a new bot for it. It's called PAR update."
- **`/opt/parupdate/parupdate.py` on kookwatch, cron `0 1 * * *` UTC (08:00 Bangkok), sqlite at `/opt/parupdate/parupdate.db`, config `/opt/parupdate/config.json`, log `/opt/parupdate/run.log`.** Backup of v1 at `parupdate.v1.bak.py`. Covers PAR `0x507B6F349a80114097A67B8b4677367acC15b220`, see [[par-family]].
- Sections: MARKET (cap, price, liq, vol, holders with day-over-day delta, buys/sells) · USAGE (launches 24h vs 48h vs 7d, launch trend, trades delta, platform ETH volume and PAR's share of it, multipair count, biggest community token and the $1M trigger) · BURN (tokens, % of supply, USD, expected-vs-actual, annualised as % of cap, cumulative) · **DOES REVENUE COME BACK TO THE TOKEN**, five explicit routes with a live yes/no each.
- The five accrual routes it answers every day: protocol fee TOKEN half **BURNED** (measured as fee-wallet transfers to `0x0` in the window) · protocol fee QUOTE half **LEAVES THE TOKEN** (fee-wallet ETH balance and its daily delta) · **fee share to PAR holders ON/OFF** (`feesToHolders` on PAR's own launch record, currently OFF while 23 community launches use it) · **fee wallets selling PAR YES/NO** (transfers into the PoolManager or a known router) · **deployer launch bag MOVED/UNMOVED** (the 10,000,308 PAR at `0x0071ac8dbf95770c089fbd52af4bd5a63293b040`). It also lists any NEW protocol fee recipient that appears in the launches feed.
- **EMAIL NEEDS A KEY AND THAT IS THE ONE THING BEN HAS TO DO. SMTP is dead on this droplet: ports 25, 465, 587 and 2525 are ALL BLOCKED outbound (DigitalOcean).** Verified. HTTPS mail APIs are reachable (api.resend.com 200, api.mailgun.net 200, api.postmarkapp.com 302, sendgrid and brevo 404 on the bare path). So delivery is Resend over HTTPS: paste a key into `resend_api_key` in the config and it sends to `benkorsa@gmail.com`. **Any future "email me X" request on this droplet hits the same wall, so do not re-test SMTP.**
- **Telegram is wired as a permanent fallback so the digest is never silent**: it reuses the coinbench bot token and chat 357464289. Note the coinbench config nests them under a `telegram` object (`config["telegram"]["bot_token"]`), not at the top level like the older bots.
- **Design rule enforced in `analyse()`, and it matters: the burn is NEVER a buy signal on its own.** Burn = 0.25% of PAR's own volume, so "145% of market cap per year" is just today's volume restated and it falls exactly when volume falls. BUY fires only on a structural change (PAR's own `feesToHolders` flips on, a community token clears $1M, or launches re-accelerate). SELL fires only if the deployer bag moves or a fee wallet sells into a pool. Everything else is HOLD.
- Verified live 8 Sep 01:30 UTC: HOLD, cap $1,836,622, holders 4,134, launches 32 in 24h against 90 the day before, burn 3,763,506 PAR (0.376%, $7,316) against $6,011 expected at the 0.25% ratio, fee wallets burned 1,420,385 PAR and sold zero, deployer bag unmoved. Telegram sent, email skipped for the missing key.
- Traps fixed on the first run: Blockscout holders returned 0 on a single try, so it now retries six times with backoff across both the v2 and v1 endpoints; and `getLogs` bisects on any failure so a range cap can never silently drop burn events.
- **v3, same day: Ben asked for it shorter and in five-year-old words.** `render()` was rewritten to four blocks and about 25 lines: **MONEY THAT COMES BACK TO YOU · IS ANYONE USING IT · PRICE · BAD SIGNS (all should say no)**, with the action word and one plain sentence on top. Jargon is gone from the output entirely (no "protocol fee", no "accrual", no "quote half"): the team's cut reads "Team kept 36.0 ETH, none of it is yours", the trigger reads "it needs to reach $1,000,000 for this to work", and the burn line carries "(this only lasts while people keep trading PAR)" so the 145%-of-cap number can never be read as a floor. Backups `parupdate.v1.bak.py`, `.v2.bak.py`, `.v3.bak.py`. **This is the house style for every recurring output now: blocks with plain-English headers, a yes/no checklist for the risks, and no term he would have to look up.**
- Delta guard added after a first run printed "People holding 4,134 (+4,134 today)": a `delta()` helper returns None whenever the previous snapshot's value was zero or missing, so a cold start never fakes a day-over-day move. Same class of error as scoring a partial day.

## 8 Sep 2026: IGNITION, and the reason LAUNCHWATCH has never fired an alert
- [stated] Ben: "i want to catch the next ones. develop a filter and framework to see them before they pop. recheck it 3 times before you present it. There were literally fourteen 10-xes yesterday from sub $1M to up to $50M. Literally one 10x per hour." He listed SOCK, LUCKY, LUNA, MINI, ROUTE, 4STOCK, FAB, GAGE, MARLIN, LAPTOP, RSTR, CATGPT, AA, STOCKHOOKS, KELF.
- **THE ROOT CAUSE OF MISSING ALL FOURTEEN, and it is not the thresholds. LAUNCHWATCH makes ONE rate-limited GeckoTerminal call per candidate with `CYCLE_BUDGET = 120.0`, so it scores 8 to 13 of an ~800-deep queue per cycle, while `MIN_AGE, MAX_AGE = 60, 180` minutes means a coin is only eligible for two hours.** The queue drains in days, the window is two hours, so ~98% of launches age out never having been looked at. run.log shows "cleared the filter: 0" on every cycle for as long as it has run. **The screen was not too strict. It was never run.** Whenever a bot "fires nothing", check its throughput against its queue depth BEFORE touching a threshold.
- **THE FIX AND THE GENERAL LESSON: DexScreener `latest/dex/tokens/{a1,a2,...}` takes THIRTY addresses per call and returns m5/h1/h6/h24 volume, txns, priceChange, liquidity, marketCap, pairCreatedAt and socials.** That is everything a launch screen needs. Whole queue per cycle: **37 calls, 2.4 seconds**, measured live. Never build a per-token loop against a rate-limited API when a batch endpoint exists.
- **NEW SERVICE `/opt/launchwatch/ignition.py`, cron `*/2 * * * *` with flock, alerts into the existing coinbench Telegram chat.** State `ignition_state.json` (6h re-cool per coin), age cache `ignition_ages.json` (probes 900 unknown-age tokens per cycle then only ever queries coins under 120h old, which is what keeps the 16,268-token seen.json tail from costing 544 calls a cycle). Verified live: first cycle 7 hits, second cycle 1.
- **THE FILTER, fitted on 469 Robinhood Chain tokens / 4,498 hourly decision points over the 120h to 8 Sep, forward window 24h.** Base rate of a >=5x move from any hour of any coin: **8.34%**.
  - **TIER B (plan around this one): mcap < $800k, price +60% in the hour, hour volume >= $25k. 30% hit, 3.6x lift, 8.0 alerts/day, median forward 2.34x.** Holds out of sample: 30.8% older half / 28.6% newer half.
  - **TIER A (size up, but n=11): the above plus hour volume >= $60k and volume >= 3x the trailing 6h hourly rate. 55% hit, 6.6x lift, 2.2 alerts/day, median forward 6.85x.**
  - Hard rejects: mcap/liq > 300 (fake depth), and flat price while quoted by 3+ pools (a peg).
- **THE SHAPE FINDING, which is the actual framework: the 10x does not start at launch.** SOCK slept 11 hours on falling volume before its bar; FAB 6; MARLIN 7; RSTR bled -78% over 12 hours then went 38x off the low. Hourly volume strips for all 13 are in the artifact. So the game is NOT sniping block zero, it is watching already-listed, still-cheap, still-boring coins for the ignition hour. **After the ignition hour has already CLOSED, median remaining upside across the 10 winners it fires on was 4.1x** (FAB 22.5x, RSTR 12.3x, SOCK 7.4x, MINI 7.2x, LAPTOP 4.5x, STOCKHOOKS 3.7x, CATGPT 2.7x, MARLIN 2.3x, AA 2.0x, 4STOCK 1.9x).
- **IT CANNOT CATCH LAUNCH-CANDLE ROCKETS. ROUTE, LUCKY and GAGE never printed a qualifying hour** because the whole first leg happened inside the opening bar. Those need minute resolution and an execution bot, not a Telegram message. Say this every time; do not oversell the filter.
- **THE THREE RECHECKS EACH FOUND A REAL BUG. Keep doing this.**
  1. **Forward-window truncation.** Coins near the end of the sample had fewer than 24 bars ahead, so their upside scored as zero and the newer half looked like the edge had died. Requiring a full 24 forward bars moved the base rate 4.4% -> 8.3% and made both halves agree. **Any forward-return study must drop rows without a complete forward window.**
  2. **The quote-asset veto from the FUN fix would have killed 6 of the 13 winners.** 4STOCK is the quote side of 21 pools and still did 40x; GAGE, RSTR, SOCK, MINI and CATGPT all quote at least one. **The tell for a peg is a FLAT PRICE, not being used as a quote.** Rule is now `asquote >= 3 AND |pc_h6| < 3%`. This is a correction to the 8 Sep FUN patch note above: do not port the raw quote-side veto anywhere else.
  3. **A 2x take-profit destroys the edge.** Hit rate was measured on the max price in the next 24h, which no real exit captures. Simulating buy-at-signal with 6% round-trip friction: tier A returns **1.35x mean at a +100% target and 2.89x mean at a +400% target** (64% win rate); tier A+B 1.24x and 1.79x; control (buy every hour of every coin) 0.97x and 1.08x. **The filter finds them, the target decides whether you get paid. Do not take 2x.**
- **KNOWN BIAS, state it whenever these numbers are quoted:** the universe comes from LAUNCHWATCH's seen.json filtered to coins DexScreener still lists, so coins that died completely are missing. That flatters the base rate and probably the rule with it.
- **WHAT THEY WERE, which earned no statistical gate but is the strongest qualitative thread: 8 of the 14 were plumbing between tokenised stocks and memes** (SOCK baskets of stocks, 4STOCK stocks onchain, GAGE borrow against stocks, STOCKHOOKS programmable stock assets, CATGPT stock rewards, FAB mine NVDA, LAPTOP quoted against SGOV, LUCKY quoted against GOOGL). Quote-is-a-stock alone was only a 1.3x lift over five days. Treat it as a reason to take a bigger swing on an alert, never as a filter.
- **Chain coverage gap: the scanner is Robinhood Chain only.** SOCK and 4STOCK were BNB, MINI and CATGPT were Solana. The same three numbers work on any chain DexScreener covers; it is a config change.
- Artifact "The Ignition Hour": https://claude.ai/code/artifact/b61ca22e-a6d2-4cd9-b601-5c51692d3920
- Backtest code left in the Cowork container at /tmp/hunt (bt3.py features+grid, ver.py the three passes, pass3.py the realistic-exit simulation, winrule.py the winner replay). Droplet backup of the pre-veto-fix scanner: /opt/launchwatch/ignition.py.bak-asquote.

## 8 Sep 2026: CEOFOLLOW, built for the CEO engagement thesis ([[ceo-engagement-thesis]])
- **`/opt/ceofollow/ceofollow.py` on kookwatch, systemd `ceofollow.service`, log `/opt/ceofollow/ceofollow.log`, config `/opt/ceofollow/config.json`, posts as @bk_rhwatch_bot into chat 357464289.** A patched copy of the retired `/opt/followwatch` (DFarmer watcher, still retired, untouched). Registered in the Mac botctl registry (16 bots) and in the watchdog UNITS table (the watchdog unit is `watchdog-bots.service`, not `watchdog.service`).
- Watches the live X follow lists of 37 accounts: Vlad Tenev, Andrew Dudum, Natan Benish, LONG, Dan Gallagher, Johann Kerbrat, Elon Musk, Ryan Cohen, Novogratz, Saylor, Michael Dell, Matthew Prince, Baszucki, Jeff Thompson, Sam Tabar, Dylan Field, RJ Scaringe, Allaire, Phong Le, Brian Armstrong, Nadella, Pichai, Cook, Spiegel, Jassy, Nunes, Krishna, Lisa Su, Bourla, Adam Aron, Netflix, Micron CEO, Snowflake CEO, Uber CEO, spez, Hims official, GameStop official. Alerts on EVERY new follow (these people follow rarely: Dudum 8, Cohen 1, LONG 1) with the existing DexScreener token resolution.
- **THE COST TRAP, and the design that avoids it: twitterapi.io charges $0.18 per 1K users returned by followings, tiered to 3 credits per user on small pages.** The original followwatch pulled a 200-row page every poll; on 37 accounts every 2 minutes that is about $600/day. ceofollow instead calls `user/info` (one credit, field `following` is the live count) on a per-account interval (`every`: 120s for Vlad, Dudum, Natan, Elon, Cohen, Novogratz, Saylor, Dell; 180 to 600s for the rest) and only pulls a 20-row followings page when the count ROSE. Full 200-row resync every 24h. Baselines are quiet (`quiet_baseline`) so 37 "armed" cards were not sent. Estimated cost about $3/day.
- Known blind spot: a follow and an unfollow inside one poll interval nets to zero on the count and is missed until the 24h resync. Acceptable.
- Verified live 16:30 UTC: user/info returns `following: 8` for AndrewDudum and page 1 of his followings lists bonercoinlong first; baselines vladtenev 889, Natan_benish 2,799, elonmusk 1,404, novogratz 4,729, saylor 801, all quiet.
- **REMOVED 9 Sep 2026 at Ben's instruction.** [stated] Ben: "Remove that bot that's watching live follows of CEOs. I'm not interested in that." Service stopped, disabled, unit file deleted, directory kept as `/opt/ceofollow.RETIRED-20260909-045451`, row removed from the watchdog UNITS table and from the Mac botctl registry (16 bots). No process left. Do not rebuild a CEO follow watcher unless he asks again.

## 8 Sep 2026: CHJOKKA ALERT, a clone of ubermwatch for @chjokka
- [stated] Ben: "Create a Telegram bot separate for him only. Name it after his name... only alerts buys and sells and not if somebody drops him something or if he moves something."
- **`/opt/chjokkawatch` on kookwatch, unit `chjokkawatch.service`, log `/opt/chjokkawatch/chjokkawatch.log`, bot @bk_chjokka_bot (created via BotFather from Ben's Telegram Web session in Chrome; Ben's chat with it was started the same way, which is required before a bot can post), chat 357464289.** tracker.py, pnl.py, backfill.py, report_pnl.py, bookreport.py copied verbatim from ubermwatch (same five-rule classifier, same real-cash pricing, same P&L book); tag CHJOKKA; `alert_transfers` false; `min_usd` 50; poll 2s. Wallet `0xa8ab5a838b50c14cfc5c3e788c37c77140481c41`, see [[chjokka-wallet]]. Registered in /opt/botctl/registry.json, the Mac ~/botctl/registry.json (17 bots) and the watchdog UNITS table. Proof-of-life sent 20:00 UTC.
- Backfill book: only 18 of his ~110 tokens priced, realised $349,267, one open (PRM). He trades off fomo through routers, so most legs have no settlement leg and the swap pricing in backfill.py only catches standard Swap events. Alerts still classify buy vs sell correctly (rules 1, 2 and 4 do not need pricing); the "avg entry" lines will be thin for him until backfill prices router fills.
- Telegram Web driving notes: `type` does not land in Telegram inputs, `key` with space-separated characters does ("/ n e w b o t Return"; "slash" and "underscore" are typed literally, use the raw characters). Hash URLs (#-100...) do not open chats; search then click, or click a t.me link inside a message. Token moved to the droplet as a char-code list into token.txt then settoken.py, never printed. **Mistake to not repeat: my config dump masked only a top-level `bot_token`, the real one sits under `telegram.bot_token`, so ubermwatch's token was echoed in a tool result. Mask `["telegram"]["bot_token"]`.**


