Feed-health pass over KOL_FEEDS:
- raoulpal: stale Substack (last 2024-05) → Real Vision podcast feed
- dampedspring: paywalled (0 entries) → free "Damped Spring 101" Substack
- unchained: Cloudflare 403 → canonical Megaphone podcast feed
- lynalden: Cloudflare 202 → FeedBurner mirror
- glassnode: recovered via httpx http2=True (was 403 on HTTP/1.1)
- browser User-Agent + Accept headers on feed fetch
- removed dead feeds with no active replacement: placeholder,
dragonfly, niccarter, eugene
- pin h2==4.3.0 (required by http2=True)
All 25 remaining feeds verified fetching real body content; newest
post per feed ≤88d. Bundles in-flight KOL-module work already in the
working tree (kol_x ingest, migration 027, tests).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- /positions/hl/{wallet} was unauthenticated — knowing a wallet address alone
exposed that wallet's live Hyperliquid positions + already_adopted status.
Its docstring claimed "same trust model as /positions/open", but that route
IS signed. Now requires the same view signature (view_positions/view_user,
allow_replay). The Telegram /adopt path calls list_hl_positions() directly,
so it's unaffected.
- HL API key masked hint was inconsistent: set_hl_api_key returns the real
key's last 6 chars ("...abc123"), but get_user returned 6 chars of
sha256(encrypted_blob) — a different string. After a reload the suffix
changed, making users think their key was altered. get_user now decrypts
only to take the real last 6 chars (matching save), with a neutral
"…(set)" fallback if decryption fails.
72 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Batch of the pre-launch audit campaign (BUG-01…14 plus three new features):
Pricing / TP-SL protection
- Add app/services/hl_price_feed.py: supplemental HL allMids poller for
HL-native assets (HYPE, PURR) not listed on Binance. Pumps price_store +
tp_sl_monitor.on_price_tick so bot trades on these assets keep full
stop-loss / take-profit / trailing protection instead of max-hold only.
- Wire feed into main.py lifespan (startup task + graceful shutdown cancel).
Telegram
- Add format_trump_mention + PATH B in _dispatch: crypto-relevant Trump
posts with no directional signal (relevant=True, signal=hold) now alert
the public channel only (no per-subscriber noise).
- Rate limiter (slowapi) on the API; assorted bot/digest fixes.
KOL on-chain
- seed_kol_wallets.py: KOL_FEEDS coverage cross-check; reversibly deactivate
orphaned wallets (handle not in KOL_FEEDS → can never produce divergence)
so the scanner stops burning cycles on them.
Tests / misc
- Fix brittle test_macro_ahr999_uses_same_formula_as_scanner: mock now uses
realistic ms timestamps so the in-progress-day drop fires, matching the
fetcher's bar count (was 0.3179 vs 0.3178 off-by-one).
- Refresh stale notify_signal comment in truth_social.py.
Frontend reduce-action type fix lives in the sibling repo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
schemas.py:
- Add paper_mode: bool = False to UserResponse so frontend can distinguish
paper vs live subscribers and skip HL API key requirement accordingly
api/user.py:
- Return paper_mode=bool(sub.paper_mode) in GET /user/{wallet}
- Fix elif-chain bug in settings validation: two independent `if` blocks
instead of elif so both TP and SL ranges are checked when trump_enabled
- Conditional validation: TP/SL required only when trump_enabled=True;
daily_budget_usd optional at all times
- Persist trump_enabled / macro_enabled from PUT /user/{wallet}/settings
services/bot_engine.py:
- Remove daily_budget_usd from required fields check — it is optional
(null = no cap). Previous code silently skipped ALL trades for users
who cleared their daily budget cap.
alembic/versions/025_module_toggles.py:
- Add trump_enabled, macro_enabled columns to subscriptions table
tests/test_production_readiness.py:
- Sync test_open_positions_requires_signed_wallet_read to patch
verify_signed_request_any (the function now used) instead of
verify_signed_request; update expected call kwargs accordingly
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. hyperliquid.open_position now returns effective_leverage. HL clips
the requested leverage to each asset's max (e.g. memes capped at 3×)
and silently applied the lower value; we were discarding that. For
System-2 this meant sys2_protective_stop_pct was computed against the
REQUESTED leverage, so the "inside-liquidation" full-close rung was
actually well inside an 8.5% stop while the real liquidation sat ~33%
away — strategy intent broken. bot_engine now reads the effective
value back, recomputes the protective stop + derisk ladder against
it, and freezes the correct values into BotTrade.eff_* / .leverage.
2. circuit_breaker.clear_trip now clears BOTH systems by default. The
sys2 column was never reachable from any reset path — a sys2 trip
forced users to wait the full 24h lockout even after explicit
human re-arm.
3. /api/user/.../manual-window and /auto-trade re-arm endpoints now
clear sys1 AND sys2 CB on the same human ack. Symmetry with
check_and_trip / is_tripped which already supported both systems.
4. telegram.py deep-link map: btc_bottom_reversal + funding_reversal
alerts now point at /en/macro instead of the now-404 /en/btc.
5. (Already landed: _sys2_mode UnboundLocalError fix in bot_engine —
restated here for the audit trail.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- New migrations for daily_budget, active_window, and bottrade snapshot
- Add trumpstruth scraper and price_impact_monitor service
- Expand bot_engine, hyperliquid, recovery, and tp_sl_monitor logic
- Update API/schemas/models for new features
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>