Files
winning-wallet-finder_github/HANDOFF.md
T

93 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Session handoff — 2026-07-08 (rev 2: Phase 1 COMPLETE)
Self-contained pickup for a fresh session. Read [README.md](README.md) gotchas
111, [FINDINGS.md](FINDINGS.md), and [LIVE_ROLLOUT.md](LIVE_ROLLOUT.md) first.
Project memory (`polymarket-resolution-truth`, `polymarket-us-expansion`) has
deeper history; the repo is authoritative.
## Where things stand (all green)
- **Live paper bot**: Fly.io app `wwf-copybot`, region `arn` (Stockholm),
push mode. Following **Set D** (2026-07-08): LSB1, imwalkinghere, Kruto2027,
42021, 0xbadaf319, BikesAreTheBikes — 6 moderate-bet volume wallets chosen by
simulation ($27.8k / +2680% 30d backtest). `flyctl logs --app wwf-copybot`.
- **P&L is honest end-to-end** (sharps All-Time = realized track record +
abandoned-loser fold-in; Open P&L = in-flight exposure — see rev 1 in git
history for the full derivation).
- **Ledger reconciles** (`ledger_drift` 0.00, self-checked every heartbeat AND
after every trade — see below).
- **Daily pipeline** (launchd 08:00) runs the corrected code; exits cache
incremental (86/96 wallets `complete`).
## DONE 2026-07-08 (this session) — the proper fix + Phase 1 closeout
**Orphan/cash-debit seam CLOSED (Option A, commit 167a0b9).** The mechanism
that created the $+36.35 drift orphan is fixed, not just guarded:
- `on_wallet_activity` now records EVERY drained buy fill: the tok-match keeps
`_record_lag` (real lag/slippage); leftovers get `_record_untracked_buy`
(bet record synthesized from the fill, conds from the position, audit line
with `"untracked":true`). `reconcile_exits`' drain does the same instead of
discarding returned buys.
- `check_book()` asserts the invariant **after every trade and at boot**:
every `my_pos` token ⇒ bet record + conds entry + cash debited. Records and
conds self-correct in place. The cash leg heals ONLY at boot
(`check_book(heal_cash=True)`, called after `bot.seed()`) and ONLY when
`ledger_drift` matches ONE un-vouched position's cost+fee within
max($0.10, 1%) — vouched = fills-ledger BUY line for the token, or a real
`_record_lag` record (`their_price` set). A drift that matches nothing stays
a loud `⚠ LEDGER DRIFT`, never papered over.
- Supporting plumbing: `my_pos` entries carry `cond` (engine stamps it on
OPEN/ADD); fills-ledger BUY lines carry `token`; `_synth_bet` (shared with
`write_feed`) estimates the fee with the same `taker_fee` formula
`_drain_fills` charges, so a synthesized record over correctly-debited cash
closes to drift 0 — and a never-debited orphan shows drift = cost+fee
exactly, which is what the heal keys on.
- Tested: 6-case harness (untracked booking, synth+conds, matching heal,
non-matching refusal, vouched exclusion, multi-orphan refusal) all pass;
dry-run against the real state was a clean no-op (drift $0.0055, nothing
touched). Deployed; heartbeats clean.
**Phase 1 is 8/8 DONE** (LIVE_ROLLOUT.md): 1.1 feed separation, 1.2 env
secrets, 1.3 live deps in the worker image (py-clob-client==0.34.6 +
web3==7.16.0 in fly.Dockerfile, import-verified via `flyctl ssh console`),
1.4 on-chain cash anchor, 1.5 fatal geocheck, 1.6 exit retries, 1.7 config
sync, 1.8 dashboard REAL MONEY section (jaxperro `trading/index.html` commit
871e56e — fourth board chip + section reading `live/copybot_live_real.json`,
shared `copybotSection()` renderer, ledger drift/adjustments surfaced on both
books, verified against a mode:"live" feed copy and the 404 NOT STARTED
empty-state; `?rmFeed=`/`?botFeed=` query params override feeds for testing).
## Next: Phase 2 — funding (USER ONLY)
Everything before real money is done. Per LIVE_ROLLOUT.md: fund the live
wallet (test size, rule 0.6 caps stay at $5/trade · $25/day · $30 exposure),
then Phase 3 preflight (`preflight_live.py`), Phase 4 supervised first fill,
Phase 5 edge-case matrix. The typed-phrase interlock (rule 0.7) is the human
checkpoint — never automated.
## Standing to-dos (user-only or external)
- **ROTATE THE LEAKED ALCHEMY KEY.** A real key briefly hit the public repo
(`config.live.example.json`, removed from HEAD but in git history). Generate a
new key at dashboard.alchemy.com, then update `alchemy_key` in the local
gitignored `config.json` AND the `ALCHEMY_RPC_URL` Fly secret
(`flyctl secrets set ALCHEMY_RPC_URL=...`). Blocks nothing but is a live key.
- Delete the stopped Railway project `magnificent-kindness` when comfortable
(saves the idle spend; the Fly worker fully replaced it).
## Operational quick-reference
- Change the follow set: edit `live/copybot.paper.json` `wallets`, then
`./live/deploy_bot.sh` (validates → pins floors → syncs Alchemy webhook →
restarts Fly → confirms banner). `backtest.json` should mirror it.
- Backtest any set: `python3 live/portfolio.py --wallets 0xa,0xb --days 30
--out /tmp/t.json`.
- Never keep 2 Fly machines (2 book-writers): `flyctl scale count 1`.
- Cache is single-writer; don't run cache-touching scripts while the daily
pipeline or a regen is running.
- Bot commits its own state/feed every few minutes — always
`git pull --rebase --autostash` before pushing.
- Image changes (fly.Dockerfile) need `flyctl deploy --remote-only`; code-only
changes just need a push + `flyctl apps restart` (start.sh clones main).