Worker T4, 2026-09-26 00:37 to 00:52 Beirut. Brief: briefs/T4-discovery.md. Everything here is planning and measurement; no production file, service or cron was touched. All numbers from our stores come from scripts in scripts/T4-*.py, run against a read-only copy of events.sqlite taken at 00:37 (data/events.sqlite) and read-only opens of the signal-room and watchtower files. Outputs are saved beside them in data/T4-*.md so every table below can be regenerated with one command.
| script | command | output |
|---|---|---|
| sources, overlap, lag | python3 -W ignore scripts/T4-sources-overlap.py --days 14 > data/T4-sources-overlap.md |
data/T4-sources-overlap.md |
| base rates per admitter | python3 -W ignore scripts/T4-base-rates.py > data/T4-base-rates.md |
data/T4-base-rates.md |
| social capture, casual mentions | python3 -W ignore scripts/T4-social-capture.py > data/T4-social-capture.md |
data/T4-social-capture.md, data/T4-casual-candidates.jsonl (490 rows) |
| ticker ambiguity, resolver outcomes | python3 scripts/T4-ticker-ambiguity.py > data/T4-ticker-ambiguity.md |
data/T4-ticker-ambiguity.md |
Web research (caller expansion list, terms of service, DexScreener search behaviour) was done by a sub-worker with WebSearch/WebFetch only; its notes are in data/T4-web-research.md and every claim from it carries an evidence grade. Our own stores are grade A where a script is named.
T4-sources-overlap.md)$TICKER; 26% name a token only as a bare word ("Musebook", "Agrippa", "levercat"), 2% carry position language with no token at all ("I got out", "stay put in position"), 33% are chatter. The current detector reads 31% of messages; stance lives almost entirely in the other 69%. (A, T4-social-capture.md)T4-ticker-ambiguity.md)An admitter is anything that can put a token on the look list. Admission is cheap (the list is "curated, not tight"); what is expensive is watching the token after admission (price polling, tape, holdings, sweep). So every admitter has an admission rule and a cost of watching.
| admitter | what a credible signal is | proposed admission rule | false-positive risk | cost of watching the source | base rate from our stores |
|---|---|---|---|---|---|
| Telegram caller channel (formatted calls and chat) | a named token (address, or ticker resolved unambiguously) posted by a channel with a scored history; stronger when the post carries a stated position ("aped", "bought more") rather than a shill line | admit on first call by a watch-now channel; admit on a casual mention only if the extractor resolves the token with confidence >= 0.8 and stance is bullish or the caller states a position; never admit on a promo or referral post | high: paid promos (MetaWin, trading-bot referrals appear in Sugar), vamp and copycat tickers, re-calls of tokens already run; 78% of calls resolve by ticker, the weaker route | t.me/s preview polling: one HTTP GET per channel per 5 min, ~290 GET/day/channel, ~6 KB/day stored per channel at 30 msgs/day; LLM extraction ~$1/day at 20 channels (§3.5) | 275 marked calls: any-mark >= +20% 30%, >= +50% 18%, >= 2x 12%; median best mark +5.5%, median 24 h mark -10.1%. Per channel below |
| X account | same as caller, plus reach; a post by an account with a scored history, or a mention cluster across several scored accounts within an hour | admit on a scored account's post naming a resolvable token; admit on 3+ distinct watched accounts inside 60 min even if unscored | very high: engagement farming, paid posts, bots; X search via xAI returns model-summarised posts, not raw | dark: xAI credits exhausted since 09-18; official X API pricing in §6 | 5,272 posts captured 09-14 to 09-18, no outcome join done; none since |
| Tracked wallet (own on-chain watch, Robinhood Chain today) | a buy by a wallet in the proven set, from the chain itself, with size | admit on any buy >= $100 by a proven-set wallet; tier by wallet grade | low on identity (it is the chain), medium on meaning (small buys, farming, bundles) | own RPC; Robinhood public RPCs; one poll lane already running; BSC and Solana would need per-chain watchers | 6,802 buys on 1,118 tokens in 14 days; in the tracked-buy outcomes it is always co-attributed with Fomo (below) |
| Fomo-profiled trader | a buy alert from Fomo for one of our 119 tracked traders, with size; theses are a separate, later signal | admit on any tracked-trader buy >= $500 (Fomo reports USD size); thesis posts raise the light but do not admit alone | medium: copy-trade traps (trader buys to sell into followers), size games | Fomo plan, 2.5M credits/month, already paid | 1,806 tracked buys with outcomes: h1 max >= +20% 28%, h6 42%, h24 57%; >= 2x at h24 17%. Solana h24 >= 2x 20%, BSC 10%, Robinhood 17% |
| Own tape anomaly (first-hour buyer surge, repeat-wallet cluster, liquidity add) | on our own chain tape: distinct new buyers per minute above the pool's own baseline, or a cluster of wallets that co-bought earlier winners | admit when distinct buyers in 10 min >= 3x the pool's trailing median and >= 25, liquidity >= $10K | medium: bundles and sybil swarms look like surges; the recurring-wallet effect measured 0.10 vs 0.27 is unaudited | runs on the tape we already collect for BSC (continuous since 09-18) and Solana (restarted 09-25) | not measured in this pass (no labelled surge events exist yet); T5 and T6 own it |
Per-channel caller base rates, point marks (A, T4-base-rates.md §A):
| channel | call rows | priced, on time | any mark >= +20% | >= +50% | >= 2x | median best mark | median 24 h mark |
|---|---|---|---|---|---|---|---|
| PowsGemCalls | 183 | 129 | 36% | 20% | 15% | +5.8% | -12.7% |
| sugarydick (Sugar) | 154 | 106 | 26% | 16% | 8% | +5.7% | -6.3% |
| overdose_gems_calls | 38 | 19 | 37% | 26% | 26% | +13.7% | +2.7% |
| columbus_trades | 28 | 16 | 6% | 6% | 0% | -0.2% | -50.8% |
| Casonshrine | 9 | 5 | 0% | 0% | 0% | +2.0% | -1.6% |
Pooled by mark, the shape is what the 09-11 call-timing study found for Fomo flags: flat at 15 min and 1 h (median 0.0% and -0.7%), then a fat right tail and a falling median (4 h -4.8%, 24 h -10.1%, but 10% of calls sat at 2x or more at the 24 h mark). The look list is useful because of the tail; the median call loses.
Screened-in versus screened-out (the discovery screen: mcap under $5M, age under 3 days, covered chain): passed calls reached >= +20% at a mark 38% of the time (n=37) against 28% for refused (n=263); at 2x it reverses (8% vs 11%). n=37 does not support a conclusion; the screen is not shown to add anything yet.
14 days to 2026-09-25 21:32Z, distinct tokens, first sighting per family (A, T4-sources-overlap.md):
| pair | tokens in both | first family was A | first was B | median lag, h | p25 | p75 |
|---|---|---|---|---|---|---|
| Fomo buy / wallet watch buy | 227 | 55 | 172 | 1.3 | 0.0 | 26.1 |
| Fomo buy / caller call | 63 | 51 | 12 | 32.5 | 4.0 | 104.7 |
| Fomo buy / Fomo thesis | 278 | 222 | 56 | 8.5 | 0.4 | 39.6 |
| wallet watch / caller call | 26 | 24 | 2 | 50.5 | 14.6 | 126.8 |
| wallet watch / thesis | 113 | 89 | 24 | 37.4 | 4.3 | 93.4 |
| caller call / thesis | 50 | 20 | 30 | 34.9 | 3.0 | 107.1 |
Per caller channel, was a tracked trader or wallet already in before the call:
| channel | tokens called | Fomo buy before | wallet buy before | either before | tracked buy only after (within 24 h) | median lead of the earlier buyer |
|---|---|---|---|---|---|---|
| PowsGemCalls | 53 | 28 | 15 | 32 | 2 | 18.8 h |
| sugarydick | 44 | 23 | 8 | 25 | 1 | 64.2 h |
| overdose_gems_calls | 7 | 2 | 1 | 3 | 0 | 13.6 h |
| columbus_trades | 5 | 2 | 2 | 2 | 0 | 59.9 h |
| Casonshrine | 3 | 1 | 0 | 1 | 0 | 17.5 h |
Reading. The ordering is consistent: own wallet watch, then Fomo alert, then thesis, then caller. Two cautions. First, "before" is inside the 14-day window only; a token first bought a month ago counts as "no tracked buy before". Second, these channels and our Fomo roster sit in the same Robinhood and Solana community (Pow and Sugar both reference their Fomo positions in chat), so the traders and the callers are partly the same people seen through two pipes. The product consequence is a field, not a filter: on every situation, show "who was already in, and how long before the first public call". That is view 2 of the 09-25 synthesis and it is computable today.
Method: web sources only (no Telegram client, no x.com), by a research sub-worker; full notes with every URL in data/T4-web-research.md. The backbone is Call Analyser (t.me/CallAnalyser, 49,658 subscribers per TGStat on 2026-09-26, A), a curated feed that reposts calls from "qualified call channels only" with a per-channel CPW score out of 1000 and a per-call ROI, and covers Solana, Robinhood Chain and Arc. Subscriber counts are TGStat snapshots of 2026-09-26 unless marked. Evidence grades in the "track record" column grade the evidence, not the caller: no candidate has a neutral, audited win rate; everything published is peak-multiple (entry market cap to later high), which flatters callers (C). Our own shadow scoring decides promotion.
Format: F formatted (address + mcap per call, regex-parsable), C conversational, M mixed, ? not seen.
| channel | chains in our data | msgs/day | format | our marks: any >= +20% / 2x (n) | recommendation |
|---|---|---|---|---|---|
| PowsGemCalls | Robinhood, Solana, Base | 29.7 | C (9% address) | 36% / 15% (129) | keep; the richest stance source we have |
| sugarydick (Sugar) | Solana, Base, BSC, Robinhood | 10.2 | M | 26% / 8% (106) | keep; filter promos (MetaWin, bot referrals) |
| overdose_gems_calls | Solana, Arc | 0.7 | F ($TICKER 71%) | 37% / 26% (19) | keep, low volume |
| columbus_trades | Robinhood, Arc | 2.0 | M | 6% / 0% (16) | keep on probation; median 24 h mark -51% |
| Casonshrine | Robinhood | 0.4 | C | 0% / 0% (5) | keep as commentary (warnings), not as an admitter |
| sweep bot feeds: scoutrobinhood, scoutbsc, memescopeai, dogehomes, memelottery2024, GentleCatCalls, cassandra_oracle, alexandros145 | RH, BSC, Solana | 40 to 480 | F | not scored (sweep keeps mentions, no marks) | parse, mark and score like callers; scoutbsc self-reports peak multiples, ignore its recaps |
| 14 dead sweep entries (based_eth_bot, MemeGem_0, BSCSDSQ, ceaser_calls, entry_sniper, QuantzAlphaX, Signalsblog, ...) | 0 | remove: 167 to 186 consecutive failures, never returned a message |
| # | name | handle | chain focus | size (TGStat) | track-record evidence (grade) | format | tier |
|---|---|---|---|---|---|---|---|
| 1 | Call Analyser | t.me/CallAnalyser | SOL, RH, Arc, BSC | 49,658 | aggregator; per-call ROI and per-channel CPW (A) | F | watch now (as a meta-source: discovery and convergence) |
| 2 | MadApes Calls | t.me/mad_apes_call | SOL, RH, ETH | 80,218 | frequent high-ROI Call Analyser listings, peak-based (B) | F | watch now |
| 3 | Gambles MadApes | t.me/mad_apes_gambles | SOL, ETH, RH | 100,710 | self-reported recaps only (C) | F | watch now, labelled "gambles" |
| 4 | LION CALLS | t.me/LionCALL | SOL, RH, BSC, Base | 90,439 | CPW 523 (A); cross-promotes its own bots (C) | F | watch now, promo flag |
| 5 | Astral's Gambles | t.me/ASTRAL_GAMBLES | SOL, RH | not on TGStat | CPW 522 to 526, several listings (A) | M | watch now |
| 6 | BrodyCalls | t.me/BrodyCalls | SOL | not on TGStat | CPW 554 (A) | F | watch now |
| 7 | Insider Calls | t.me/inside_calls (verify handle) | SOL | about 25.9K (B) | highest CPW seen, 722 (A); "no paid channels" in bio (B) | ? | watch now after handle check |
| 8 | Doxxed GEM Club | t.me/DoxxedChannel | SOL, BSC, ETH | 17,232 | CPW 548 (A) | C (EN/CN) | watch now (BSC and Chinese coverage) |
| 9 | EZ Money's Gems | t.me/EZMoneyCalls | RH, SOL, Arc, NEAR | 25,869 | Robinhood $SIN +83% and +26% via Call Analyser (A); "DM for promotions" (A) | C | watch now (Robinhood), promo flag |
| 10 | Kobe's Gambles | t.me/kobesgambles | ETH, RH, SOL | 16,020 | forwards x4 to x11 achievements (B) | F | watch now |
| 11 | Gabbens Calls | t.me/GabbensCalls | SOL, RH, multi | 10,804 | SpyDefi x1000 in 2024 (B) | C | watch now |
| 12 | Dream Calls 100x | t.me/DreamCalls100x | SOL, BSC, RH, ETH | 10,782 | Robinhood $DRIVE scored 60/100 (A) | C | watch now |
| 13 | Luigi's Alpha Calls | t.me/luigiscalls | BSC, SOL, RH | 8,357 | listed Sep 2026 (A) | C | watch now (BSC) |
| 14 | Mark Degens | t.me/MarkDegens | BSC, SOL | 23,695 | listed Sep 2026 on BSC (A) | M | watch now (BSC) |
| 15 | SpiderCrypto Trading Journal | t.me/spidersjournal | BSC, SOL, ETH | 32,896 | listed Sep 2026 on BSC (A) | C | watch now (BSC) |
| 16 | decu (Kolscan KOL with public Telegram) | via kolscan.io profile | SOL | n/a | wallet 81 W / 37 L, +126.6 SOL on the 09-26 daily board (A) | wallet + TG | watch now: score calls against the caller's own wallet |
| 17 | Call Analyser (SOL only) | t.me/CallAnalyserSol | SOL | 26,052 | CPW table (A) | F | watch later (redundant with #1) |
| 18 | MEMENTO / ALPHA | t.me/mementomonkalpha | SOL | unknown | CPW 561 (A) | ? | watch later |
| 19 | CarnageCalls | t.me/carnagecalls (gambles: t.me/CarnagecallsGambles) | SOL, ETH | 6,633 (gambles) | CPW 545 (A); one +410% call (B) | C | watch later |
| 20 | Maniac Degen Apes | t.me/maniacapes | SOL | 10,868 | CPW 474 (A) | M | watch later |
| 21 | Apes Anonymous | t.me/caesars_gambles | SOL, ETH | 15,770 | CPW 461 (A); "average X of 50" self-claim (C, implausible) | M | watch later |
| 22 | Shyroshi Gambles | t.me/SHYROSHIGAMBLES | RH, SOL | unknown | Robinhood call at $108K mcap (A) | ? | watch later |
| 23 | Thoth / Explorer Gems | t.me/explorer_gems | RH, SOL, ETH | 1,521 | CPW 480 (A); sub-$20K Robinhood calls | F | watch later (very early calls) |
| 24 | The Caller | t.me/thecallercrosschain | SOL, RH | 7,633 | old SpyDefi x176 (B) | C | watch later |
| 25 | ALIEN'S ALPHA CALLS | t.me/aliensalphacalls | RH | unknown | Robinhood call +4% (A) | ? | watch later |
| 26 | Luca Apes | t.me/Luca_Apes | RH, SOL, TON | 2,374 | Robinhood listing (A) | C | watch later |
| 27 | frontrun or zero | t.me/frontrunorzero | Base, SOL, ETH | 2,352 | Base listing (A) | C | watch later (only Base caller found) |
| 28 | Cook or Die | t.me/Shitscooksbyharrison | BSC | unchecked | BSC listing (A) | ? | watch later (BSC) |
| 29 | Kartel (Картель) | t.me/tradcryptos | SOL, HyperEVM | unchecked | CPW 653 on one call (A) | ? | watch later (Russian-language) |
| 30 | Prints Printing Press, Whale Coin Talk Gambles, Moon or Rekt, Terp's X100, Archerr | t.me/printspress, t.me/WCTCalls, t.me/MoonOrRektJourney, t.me/TERPS_X100_CALLS, t.me/Archerrgambles | SOL | unchecked | listed by Call Analyser (A), nothing else | ? | watch later |
| 31 | Capri Calls | t.me/CapriCalls | 9 chains | 40,002 | CPW 616 (A); CEO plus a marketing team, presale focus (C) | F | skip (or keep as a known-promo detector) |
| 32 | Crypto Gems 1000X, Crypto Eagle Gems, Python Call, ChinapumpWXC / ZORO Chinese Calls | various | SOL | unchecked | listed only; naming and style typical of paid shill rings (C) | ? | skip |
| 33 | Solana100xCall, SOLANA MEME COINS CALLS, Whale's Crypto Calls, Spaceman Callz, Crypto Dragon Calls | various | SOL | ~15K (B) and various | self-claims, "promotion inquiries" in bios (C) | F | skip |
| X1 | Ansem | @blknoiz06 | SOL | about 1M (B) | market-moving; now has his own token (B) | C | watch later (conflicted) |
| X2 | Orangie | @orangie | SOL | 388K (B) | impersonation risk, one official TG (B) | C | watch later, only via the TG linked from his X |
| X3 | Cented | @Cented7 | SOL | n/a | Kolscan 102 W / 112 L, +110 SOL daily (A) | wallet | watch as a wallet, not a caller |
| X4 | Kolscan KOLs with Telegram links (Pain, Mitch, cap, EustazZ, Zef, MACXBT, Rilsio, slingoor, Jijo, zhynx, Lynk, GK, Wugi and others) | kolscan.io profiles | SOL | n/a | daily W/L and PnL on Kolscan (A) | TG unknown | watch later: pull TG handles, score what they call against what their wallet did |
| X5 | Murad | @MustStopMurad | SOL, ETH | >1M (B) | long-horizon holder (B) | C | skip (wrong horizon) |
| X6 | X accounts of Telegram callers above (@madapescall, @TheLionCALLS, @TradeWithKobe, @0xGabbens, @SpiderCrypto0x) | same operators | skip, read the Telegram side |
First wave (16 plus Call Analyser as meta-source): #1 to #16. That adds six BSC-capable and ten Robinhood-capable sources to our five. Add in batches of five with a 7-day read-only probation each (health, volume, promo share, first marks) before calls admit.
Honest gaps (C): there is no Robinhood-only caller channel of any size; Robinhood calls come from Solana callers who added it, and Call Analyser is the best live source of them. English-language BSC callers are thin; the BSC meme scene runs on Chinese-language X accounts and groups found through GMGN, chain.fm and ave.ai (B, PANews 2025-03). A Chinese-language intake is a separate decision.
Trackers and APIs that could replace or cross-check our own scoring (details and URLs in the notes):
| tracker | what it scores | API | use for us |
|---|---|---|---|
| Call Analyser (A) | Telegram caller channels, per call and per channel | none public, bots only | discovery, convergence across channels we do not read |
| SpyDefi (A) | "thousands of Telegram KOLs": consistency %, average X, calls | none public | reputation cross-check; its achievement posts are peak-multiple marketing |
| Kolscan (A) | named Solana KOL wallets, realized PnL, W/L, links to X and TG | none; terms ban scraping | identity bridge: caller handle to wallet |
| MadeOnSol (A) | 1,100+ named Solana KOL wallets, Robinhood endpoints, "coordination" (3+ KOLs converge) | yes: free 200 req/day delayed, EUR 43/month 10K/day | cheapest licensed KOL-wallet feed for Solana and Robinhood; evaluate as a wallet admitter |
| GMGN OpenAPI (A) | wallet tags (KOL, smart money, sniper, bundler), reads incl. Robinhood and BSC | yes, key-based; pricing not stated | wallet labels for the tape admitter |
The caller poller (watchtower/callers.mjs, every 5 min by cron) reads each channel's public web preview t.me/s/<handle> (no bot, no join, no account), stores every message as an msg event in events.sqlite, and runs a regex detector: EVM 0x + 40 hex, Solana base58 32-44 with mixed case and digits, and $TICKER. Anything the regex finds is priced on DexScreener and becomes a call row with four marks. The social sweep (signal-room/social-sweep, every 10 min) reads 40 channels' first preview page and keeps only messages that match a live token (by address, cashtag, or the bare word for symbols that are not plain English); 14 of the 40 channels return nothing (private, bots, or not channels) and have failed 167 to 186 times in a row.
Messages per channel per day, 14 days, whole-chat corpus (A, T4-social-capture.md §1):
| channel | 14-day total | per day | busiest day |
|---|---|---|---|
| PowsGemCalls | 416 | 29.7 | 84 (09-16) |
| sugarydick | 143 | 10.2 | 23 (09-19) |
| columbus_trades | 28 | 2.0 | 10 (09-16) |
| overdose_gems_calls | 10 | 0.7 | 2 |
| Casonshrine | 6 | 0.4 | 4 |
What each message carries, all 1,557 messages held:
| channel | messages | contract address | $TICKER only |
bare known symbol only | position language only | nothing token-like | media only |
|---|---|---|---|---|---|---|---|
| PowsGemCalls | 1,070 | 9% | 16% | 25% | 2% | 38% | 10% |
| sugarydick | 306 | 12% | 35% | 31% | 3% | 16% | 4% |
| overdose_gems_calls | 45 | 7% | 71% | 13% | 0% | 9% | 0% |
| columbus_trades | 76 | 30% | 7% | 25% | 0% | 36% | 3% |
| Casonshrine | 60 | 7% | 13% | 28% | 0% | 42% | 10% |
| all | 1,557 | 10% | 21% | 26% | 2% | 33% | 8% |
"Bare known symbol" is a word that equals a symbol in our token table (1,758 symbols of 3+ characters, minus a common-English stop list), so it over-counts ("MAGIC", "HIGHER", "WALLET" slip through) and under-counts names that never entered our table. Read it as "about a quarter of messages name something that may be a token without a $ or an address".
The sweep's 40 channels, latest preview page on disk (a 20-message snapshot, A, T4-social-capture.md §2) split into three kinds, which matters for design:
$TICKER. They need a parser, not an LLM. scoutbsc also posts its own "hit 17X, called $455K to $7.7M, peak since the call" follow-ups: a self-reported scorecard with survivorship bias built in.All public posts from our store, none carries a contract address or a $TICKER, so the current detector drops every one (A, data/T4-casual-candidates.jsonl). Links are the public post URLs. Grouped by what the extractor must do.
Stance on a named token (name as a plain word):
Stance with the token only in context (the referent is an earlier message or the image):
What the sample teaches the design:
One derived row per (message, token reference). The raw message stays the primary record.
| field | type | notes |
|---|---|---|
msgEventId |
text | the events.sqlite id of the raw msg row this derives from |
channel, postTs, seenTs |
text | copied for query convenience |
refIndex |
int | 0..n for messages naming several tokens |
refText |
text | the literal span naming the token ("levercat", "$STONK", "it") |
refKind |
enum | address / cashtag / ticker_word / name / pronoun_context / image_only (image_only is recorded and left unresolved: contract in a screenshot is out of scope) |
resolution |
object | {chain, address, symbol, method, candidates, confidence}; method one of address_exact, channel_recent, watchlist, dexscreener_search, unresolved; see §4 |
callType |
enum | formal_call / casual_mention / update / exit_note / warning / promo / question / recap (self-reported "hit 5x" posts) |
stance |
enum | bullish / neutral / bearish / exited / unknown |
position |
enum | entered / added / holding / trimmed / exited / none_stated / unknown |
statedMcapUsd |
number or null | "aped at 1.5m" becomes 1,500,000; range midpoint if a range |
confidence |
0..1 | model's own, calibrated on the eval set (§3.6) |
evidenceSpan |
text | the exact quoted substring that carries the stance (must be a substring of the raw text; rows failing the substring check are rejected) |
contextUsed |
array | msg ids the extractor saw as context |
model, promptVersion, extractedAt, inputTokens, outputTokens |
provenance and cost | |
escalated |
bool | true if the Sonnet-class pass produced this row |
Stance and position are separate on purpose. "Musebook looks pretty bottomed" is bullish with no stated position; "Musebook I am no longer in but I see the alignment" is exited and still bullish. A flip detector that watches only stance would miss the second; one that watches only position would miss the first.
claude-haiku-4-5). Input: a frozen system prompt with the schema, 20 labelled examples and the rules below (about 1,500 tokens, cached); per message the channel's previous 8 messages in compact form, the reply-to message, and the channel's resolved tokens of the last 7 days as a short table (symbol, name, chain, address prefix, last mention time), about 700 tokens uncached. Output: a JSON array of reference rows using structured outputs, about 150 tokens.claude-sonnet-5) runs only when stage 1 returns any row with confidence < 0.6, or refKind in (pronoun_context, name) with more than one candidate, or callType in (exit_note, warning) (because those feed the flip detector and a false exit is the costly error). Same input plus the previous 20 messages. Expected escalation rate 10 to 15% (C, to be measured on the eval set).unknown rather than infer stance from tone alone; a question is not a stance; a relayed buy ("moneylord bought in") is callType=update with the third party named, not the caller's own position; promos and referral posts are promo with stance unknown; never invent an address.Prices from the Claude API reference bundled with our tooling, cached 2026-06-24 (B): Haiku 4.5 $1 input / $5 output per million tokens; Sonnet 5 $2 / $10. Cache reads are billed at a fraction of input (B, 0.1x assumed; verify on the pricing page before budgeting). Batch API halves cost but adds up to hours of latency, so it is for backfills and the eval set, not live.
| item | basis | per message | per day at 20 human channels |
|---|---|---|---|
| messages reaching stage 1 | 20 channels x 25 msgs/day (Pow 30, Sugar 10, others 1 to 5; assume expansion channels are chattier) x 60% after stage 0 | 300 | |
| stage 1 Haiku | 700 uncached in, 1,500 cached in, 150 out | $0.0016 | $0.48 |
| stage 2 Sonnet on 15% | 45 msgs x (2,500 in, 250 out) | $0.0075 | $0.34 |
| total | about $0.80/day, $25/month (C, estimate) |
At 40 channels and 50 messages a day each (a busy week), the same arithmetic gives about $3/day. The cost is not the constraint; eval quality is. A cap of $5/day with a ledger like the sweep's cost-ledger.jsonl is enough.
data/T4-casual-candidates.jsonl plus the 486 address/ticker messages are the pool.unresolved), callType, stance, position, evidence span. Disagreements are discussed and the resolved label kept; inter-annotator agreement (Cohen's kappa on stance) is reported. Expect about 3 hours of human time.exited and bearish (they drive the flip detector); recall >= 0.75. Promo classification precision >= 0.95. Calibration: among rows with confidence >= 0.8, precision >= 0.9.Follow the events.sqlite standard already in place:
source = watchtower-callers:["<channel>","msg",null], raw JSON blob, sha256, receivedAt, and availableAt (populate it; the audit found it null on 91% of rows).caller-extract/<promptVersion> with kind = mention, originalSourceId = the raw msg event id, token/tokenAddress/chain filled from the resolution, actor = channel, and the full extraction row as the raw blob. Quality field derived_llm. A rerun under a new prompt version is a new source name; nothing is overwritten.caller_stance(channel, tokenKey, at, stance, position, statedMcapUsd, confidence, eventId) rebuilt from the derived events for fast reads by the page.Per (channel, token) the timeline is the ordered list of derived rows with stance, position, stated mcap, and the price at that time from our own stores. On the situation page it renders as one line per caller: dots coloured by stance on a shared time axis under the price chart, a hollow dot for "mentioned, no stance", a cross for exit.
Flip detection, first version, deliberately conservative:
| event | rule | shown as |
|---|---|---|
| exit | a row with position = exited or trimmed, confidence >= 0.8, for a token the channel was bullish/entered/holding on within the last 14 days |
"Pow says they are out (09-18 18:35), after calling it 09-16" |
| flip to bearish | the latest two rows within 72 h include one bearish or warning with confidence >= 0.8, and the channel's previous stance on the token (within 14 days) was bullish |
"Cason turned cautious on PONS" |
| cooling | a bullish channel has not mentioned the token for 3x its own median gap between mentions of that token, and the token is still on the look list | grey text, not a light |
| re-entry | entered or added after an exited |
shown, not a light |
Guards: flips need two independent rows or one explicit exit (single ambiguous bearish lines do not flip); rows from the escalated pass only for exits; every flip carries its evidence span and post link so a reader can check it in one click. Thresholds are starting points to tune on the eval set and on the first month of live data. How often a flip precedes a drawdown is measurable later by joining flips to our own price path; that is a T6-style study, not assumed here.
The problem in our own data: 15% of the 1,911 symbols in our token table map to two or more addresses, 112 across chains (SI 10, AGI 9, GME 8, JOLLY 8, FLY 7). The resolver in callers.mjs already does the right first thing (DexScreener search, exact symbol match, rank by 24 h volume not liquidity because spoofed liquidity ranks first, require liquidity >= $20K and >= 100 txns, flag ambiguous when the runner-up has >= 40% of the leader's volume); 20 of 234 ticker resolutions were flagged ambiguous, and those were still priced and marked.
Proposed resolution ladder, stop at the first rung that resolves:
/latest/dex/search?q=), rate limit and result cap in §6 and the research notes. Filter exact symbol, chain in the channel's chain prior, liquidity >= $20K, 24 h txns >= 100, pair age consistent with the message (a token "aped yesterday" is not a pair created an hour ago). Unique survivor: 0.8. Leader with >= 3x the runner-up's 24 h volume: 0.7 and flag ambiguous. Otherwise unresolved.candidates; do not admit; do not price. Show nothing publicly. If the same unresolved reference recurs across two or more channels in 24 h, surface it on the internal admin page for a human pick.Rules that prevent wrong matches: never resolve a symbol of three characters or fewer through rung 4 alone; never cross chains the channel has never talked about without an address; plain English words (PICK, HIGHER, WALLET, MAGIC) never resolve below rung 2; "that dog coin" style descriptions without a name stay unresolved unless rung 2 has exactly one candidate matching the description words, and then at 0.6, which is below the admission threshold. Chains we do not cover (Base, Ethereum, Arc, NEAR: 56 of 300 priced calls) are resolved and stored but marked chain_uncovered, so the page can say "called on Base, outside what we watch" instead of dropping it.
Each admitter source gets an expected cadence, a stall rule and a dark-state text. Cadence is measured from our own history (the table in T4-sources-overlap.md and sources in events.sqlite), not declared.
| source | expected cadence (from history) | stall rule | state today (2026-09-25 21:32Z) | what the page shows when dark |
|---|---|---|---|---|
| Fomo alerts | 400 to 1,200 buys/day, never a silent hour in 14 days | no event for 30 min in 08:00 to 02:00 UTC, or poll error 3x | live, last event 6 min before snapshot | "Fomo trader feed paused since HH:MM. Trader buys are not being added." |
| Own wallet watch (Robinhood) | 250 to 800 buys/day | no event for 60 min, or RPC error 3x | live | "Wallet watch paused since HH:MM (RPC)." |
| Caller channel, per channel | per-channel gap distribution between posts, computed from the msg history (Pow posts about 30 a day, Cason a few a fortnight) | poll failed 3x (fetch error, as the sweep counts), or no new post for 5x the channel's own p90 gap; distinguish "channel silent" (poll ok, no posts) from "we are blind" (poll failing) | all 5 polls ok; Cason silent 6.7 days, OverDose 2.5 days (silent, not blind) | "Cason: no posts since 09-19 (channel quiet, we are reading it)." vs "Sugar: we cannot read this channel since HH:MM." |
| Sweep channels | as above | as above | 26 of 40 ok; 14 have never returned a message (167 to 186 consecutive failures): remove them from the list, they are not sources | same |
| X | none since 09-18 21:05Z | already dark | dark, 7 days (xAI credits exhausted) | a persistent line on every social field: "X: not read since 18 Sep. Social counts are Telegram only." Never a zero. |
| Marks (price at 15 m / 1 h / 4 h / 24 h) | every 5 min run | a mark more than 15 min late | live | mark shown with its lateness |
Rules:
note pattern ("absence here is not absence on Telegram").source_health already exists; its lastPollCompletedAt is the heartbeat), read by the page. One small status strip per situation lists which admitters were readable over the situation's life.t.me/s/ shows about 20 latest messages. A channel posting more than 20 messages between polls loses messages. At 5-minute polling this only bites bot feeds (dogehomes ~480/day is 1.7 per 5 min, fine; a burst of 20 in 5 min would drop). Record messages on page and the id gap between polls; a gap in message ids is a measured loss, shown on the admin page.Quotes fetched 2026-09-26 by the research sub-worker; URLs and fuller extracts in data/T4-web-research.md Part B. Not legal advice; where a clause is ambiguous for our use it says unclear and names the clause.
How we read today matters: callers.mjs and the social sweep fetch the public web preview t.me/s/<channel> over plain HTTPS. No Bot API, no MTProto user client (Telethon), no account.
| route | what it can read | terms that bind it | reading for us |
|---|---|---|---|
| Bot API bot | only chats the bot was added to; a bot cannot passively read a third-party public channel unless made admin (C, general knowledge, not re-verified) | Bot Platform Developer Terms 4.3: "You agree not to use your TPA to collect, store, aggregate or process data beyond what is essential for the operation of your services. Always prohibited uses include any form of data collection aimed at creating large datasets, machine learning models and AI products, such as scraping public group or channel contents." (A, telegram.org/tos/bot-developers) | not a usable route for reading callers; fine for our own alert posting |
| User client (MTProto, Telethon) | anything the account can see, full history | API Terms: third-party clients must not "interfere with the basic functionality of Telegram"; "You are prohibited from using, accessing or aggregating data obtained from the Telegram platform to train, fine-tune or otherwise engage in ... artificial intelligence, machine learning models" (A, core.telegram.org/api/terms); enforcement is loss of API access after a 10-day notice | an unattended account feeding a multi-user product is not described as permitted anywhere (C); ban risk falls on the account and api_id |
| Public web preview t.me/s/ (what we do) | the latest ~20 posts of public channels | the general ToS and the Content Licensing and AI Scraping terms: "Access to user-generated content for any purpose other than ordinary, legitimate, and intended use of the Telegram platform as its user is prohibited." and "Telegram firmly prohibits the scraping, indexing, harvesting, aggregation or use of data obtained from its platform to train, fine-tune, validate or otherwise engage in the development, enhancement, benchmarking or deployment of artificial intelligence, machine learning models and similar technologies." (A, telegram.org/tos/content-licensing) | unclear. The preview is a public page meant to be read, but "scraping ... aggregation" is named, and the AI clause reads literally onto running an LLM over channel text ("deployment of AI") and onto building a labelled eval set ("validate", "benchmarking"). |
What this means for the design in §3 (C, our reading):
API Terms (docs.dexscreener.com, last updated 2023-08-18, A): commercial use allowed "subject to the limitations"; no product "whose primary purpose is to compete directly with DEX Screener"; no "selling, marketing, licensing" of the API services; no ownership of the data obtained. No attribution clause and no clause on derived values found (A for absence). Reading (C): using search to resolve a ticker and prices for marks inside a companion is fine; republishing raw pair data or a price feed is not. Credit "data: DexScreener" where their numbers show. This matches the 09-25 synthesis: raw prices not ours, derived fields only.
What similar products do (A unless marked):
| product | how names get there | disclaimer printed |
|---|---|---|
| Kolscan | curated and opt-in: KOLs apply with a wallet ($100K+ PnL) (B) | terms: "We do not guarantee the accuracy, completeness, or timeliness of the information"; "informational purposes only and should not be used for financial or investment advice"; footer only, not on the board |
| GMGN | "KOL" label only for accounts that connected a verified X account (opt-in); other labels behavioural and anonymous (Smart Money, Sniper, Paper Hand) | risk warnings; "fame is not profit" (B) |
| Call Analyser | "listing qualified call channels only"; channels apply for listing; public CPW score per channel | "NFA & DYOR" |
| SpyDefi | lists KOL channels with consistency % and average X; channels forward its achievement posts as marketing | "your capital is at risk", "previous performance doesn't guarantee future results" |
| Sect Bot | group admins add the bot to rank their own members (opt-in) (B) | not checked |
Disputes found: a 12-signature petition to ban Kolscan (Change.org, 2025-03-14, A), no effect found; MachiBigBrother v. ZachXBT (libel, W.D. Texas, filed 2023-06-16, A via CoinDesk), reportedly dropped after the words "embezzled" and "stolen" were edited out (B). No case of a caller suing a numeric leaderboard was found (C, absence in one search pass). The lesson is consistent: exposure comes from characterising conduct, not from publishing reproducible numbers.
Proposed rules for Caverio:
Days are working days for one builder (Bolo) with Vesper reviewing; estimates, C.
| step | what | depends on | days |
|---|---|---|---|
| 1 | Source hygiene: drop the 14 dead sweep channels; populate availableAt on caller msg rows; per-channel silent-vs-blind health using the existing source_health table; dark-state strings on the page (X dark line first) |
nothing | 0.5 |
| 2 | Dedupe and promo filter (text hash per channel per 24 h; per-channel promo patterns); bot-feed parsers for the formatted feeds kept | 1 | 0.5 |
| 3 | Eval set: draw 200 messages, labelling file, two labellers, kappa | 2 (draw from cleaned pool) | 1 (half of it human time) |
| 4 | Extractor v1: stage 0/1/2 pipeline, structured outputs, derived events in events.sqlite, cost ledger with $5/day cap, backfill all 1,557 held messages via Batch API | 3 for tuning, can start in parallel | 1.5 |
| 5 | Resolver ladder (§4) as a shared module used by both the regex path and the extractor; Solana mint validation | 4 | 1 |
| 6 | Tune on eval set until targets in §3.6 are met; freeze prompt v1 | 3, 4, 5 | 0.5 to 1 |
| 7 | caller_stance table, timeline component data, flip detector with the §3.8 rules; admin page for unresolved recurring references |
6 | 1 |
| 8 | "Who was already in" field per situation (the §1.2 join, live) and caller admission rules into the look list | 5 | 0.5 |
| 9 | Caller expansion: add the watch-now channels from §2 in batches of five, each with a 7-day read-only probation (health, volume, promo share) before its calls admit | 1, 2 | 0.5, then ongoing |
| 10 | Scorecards per channel from marks (internal first; public only after §6 decisions) | 8, T6 win definition | 1 |
Total to a working intake with stance and flips: about 7 to 8 working days. The first visible product value (dark-source honesty, "who was already in", casual mentions admitted) lands by day 4.
.backup at 00:37).Status: DONE