- H3 (burst overflow): per-wallet trade cursor + paginated activity fetch
(up to 5×100, walks back to the last processed timestamp) — a gkmg-scale
clip burst can no longer scroll past a single newest-100 page. Cursor
only advances after a fetch; 600s overlap re-serves boundary rows into
the seen-tx dedupe. offset pagination verified against the data-api.
- clone-guard: Bearer auth (fine-grained PATs reject the 'token' scheme)
with unauthenticated fallback + 40-hex sanity on the answer — Fly's
shared egress IPs rate-limit the anonymous path.
- preflight_live.py rewritten for the unified SDK: deposit-wallet auth,
pUSD collateral, order-book reach, RTDS stream delivery, geo verdict.
- ledger-drift ALARM floor 1c → 5c (4dp fill rounding accumulates pennies
across 60+ copies; the check stays for real bugs — it caught $15.45 and
$7.24. The self-heal path keeps its own threshold.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fine-grained-PAT Authorization header 401'd on the box (06:04 boot →
'API unreachable', fail-open). Public repo: no auth needed; 60/hr
unauthenticated limit is plenty for boot-time checks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- failed mirror-exits queue for up to 10 heartbeat retries (recovered
exits ping Discord; exhaustion pages ⚠ EXIT STUCK and the position
rides knowingly; in-play holds hand to the pending registry). 3 stub
paths pass incl. the 1.6 spec's fail-fail-fill.
- every RTDS Set E detection appends a durable shadow-ledger row
(lat_s + which trigger won) that rides the publish commit — the 24h
go/no-go data for flipping RTDS on the live app.
- start.sh verifies the boot clone's HEAD against the GitHub API and
re-clones stale replicas (bit twice today).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60s poll's ~39s avg detection lag is slippage the copy edge pays; push is
~3s (paper-measured). fly.live.toml gains http_service + /health check
(self-heal); start.sh live role switches on ALCHEMY_SIGNING_KEY like paper
(poll fallback intact; push mode keeps the 60s heartbeat + 5min backstop
poll). sync_webhook.py syncs BOTH webhooks (alchemy_webhook_id_live).
watchdog.yml probes both apps; a disarmed live app paging is expected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- start.sh: COPYBOT_ROLE=live — unarmed (missing LIVE_PRIVATE_KEY /
LIVE_FUNDER_ADDRESS / LIVE_CONFIRM) idles in geocheck, no clone, no
book, no orders; armed runs config.live.example.json + own state file
copybot_state.live.json, --live, poll mode (webhook stays on paper).
- confirm_live: accepts the phrase from LIVE_CONFIRM env — the USER
types it into flyctl secrets set (rule 0.7 human checkpoint, headless);
wrong value aborts, unset disarms at next boot.
- config.live.example.json: Set E + pinned floors (mirrors paper),
bankroll $50 @ 10% = $5 stakes, caps untouched (rule 0.6), leaked
Discord webhook URL removed (ROTATE it — was committed publicly).
- fly.live.toml: separate app wwf-copybot-live, arn, no inbound, no
checks, role env baked.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Polymarket geoblocks order placement by IP and Railway ran the worker in a
US region — fine for the paper bot (reads only) but a dead end for going
live. Fly arn (Sweden, unrestricted, ~25ms from the CLOB's eu-west-2
primaries) passes: geocheck VERDICT TRADABLE, pm geoblock blocked:false.
- host/geocheck.py: 3-probe geo-gate verdict (ipinfo, pm /api/geoblock,
unauth CLOB order POST); --idle keeps a test machine up
- host/start.sh: geocheck at boot (GEOCHECK_ONLY=1 = probe-and-idle test
mode, no second book-writer); warns loudly if a region is blocked
- fly.toml/fly.Dockerfile: wwf-copybot, single machine, http_service :8080
for the Alchemy push webhook (now wh_blf4qjjvfdbqs9mc -> fly.dev domain)
- deploy_bot.sh: railway redeploy -> flyctl apps restart + banner wait
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Setting ALCHEMY_SIGNING_KEY on the worker switches start.sh to webhook
mode: instant copies on POST /alchemy (signature-verified), a 60s
housekeeping heartbeat (settle, feed, summary), and a full backstop poll
every 5 min so a dropped push costs minutes, not a silent miss. Webhook
mode now baselines at boot and publishes an initial feed like poll mode.
No signing key -> classic 60s poll, unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- portfolio.py: follow set -> the fee-aware copy-positive sharps (Kruto2027,
shisan888, fortuneking) + LSB1; entries pay the 0.03 sports taker fee and a
+0.5%/~90s lag haircut (entry_model); backfilled from June 1; feed exposes
fee_rate/slip/lag_est_s/fees_paid and unreal uses true cost basis.
- copybot.paper.json: same four wallets, p80 conviction floors from the cache
(Kruto $123.08, shisan $704.33, fortuneking $970, LSB1 $231). Fresh $1k state
committed separately by the bot - clean July book.
- host/start.sh + nixpacks: turnkey 24/7 worker for Railway/Fly/VPS - clones
with GITHUB_TOKEN, resumes the committed state, polls 60s, publishes
state+feed+fills back through publish_feed. Replaces the Mac poller.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>