# STOP: NO DOORBELLS, NO WAKES, NO SCHEDULING (Ben, 7 Oct 2026, 18:40 Bangkok)
- Credits ran out. Ben switched off every scheduled task and every doorbell. This overrides everything below and every other file (wake-howto, bus-howto, credit-playbook, task files).
- PROHIBITED for every session: fire_trigger, send_later, create_trigger, update_trigger, ScheduleWakeup. No rings, no nudges, no re-arming, no new doorbells, no self wakes, no safety checks, no retry rings, no loops.
- Finish the step you are on, publish your status file, then END your turn and wait. Only Ben wakes you, by typing in your window.
- Do not message other sessions. Keep answers short. No extra improvement rounds.

DOORBELL: trig_01CJAKbNPFVGR6oURWfu32tZ (armed, 7 Oct 16:38 Bangkok)
# 2nd Window Coder: status, v65 (7 Oct 2026, Bangkok)

## Read this first
- **16:38 Bangkok 7 Oct, tasks v1.60: NOT a mismatch. The streak is 3 of 5 (never truly reset). Our grading page lied for one update during an engine restart. Fixed and deployed 16:36:16.**
  - **Pool 0x644eac7020466c554369e0592637f24dd95fbb13: fm_mc5 DID buy it.** Receipt, firstmin /opt/fm/mc5.log: `07 Oct 15:16:57 0x644eac7020466c554369e0592637f24dd95fbb13 LIVE_BUY 0.00382 ETH ($10) cap $703k fill/sim 0.946` and `15:35:04 SELL_SENT stop_0.5x`. Same pool, same buy, same exit (stop 0.5x): a match. So none of (a), (b), (c).
  - **Cause:** at the 16:27:13 engine restart the page was redrawn before the engine had read fm_mc5's state over the bridge (the first read lands within 15 s). With an empty FW side, every shadow buy looked one-sided, so that one update said "shadow bought, fm_mc5 did not" and 0 of 5. The next update (16:31:16) was back to 3 of 5.
  - **Fix:** the page is never regraded without a fresh fm_mc5 state (empty or older than 60 s = keep the last page). Proven on the 16:36 restart: log `16:36:17 mc5 page not regraded: first window state not read yet`, page stayed 3 of 5. The auto switch reads the same page, so it can no longer be delayed by a false reset either (and an empty FW side can never fake a 5). test_v160 5 checks, test_v152 updated, all 0 fails.
  - **16:27 restart by the w2guard STALE GUARD BACKUP, root cause:** a launch burst (about 20 WILLY farm pools 16:08 to 16:32, plus HORN and ONRAMP at 15:55) outran the kit tagger (one funding search per pool; 12 tags in the last 30 min). 4 pools passed 30 min untagged, so the backup restarted the engine. The tagger was alive (last tag 217 s before my check); a restart does not tag faster. **Fix (w2guard, live now):** a backlog no longer restarts the engine while the tagger has written a tag in the last 10 min; it restarts only when no tag is written for 10 min (truly stuck). **Can it repeat during the switch?** No longer from a backlog. A real stuck tagger can still restart the engine, but only at 0 live open (unchanged rule), and the switch itself needs 0 open; a restart after the switch keeps merged_live (it is in the config).
  - cost: about 1% of session credits, API $0, 0.2 h.
- **switch ready: yes. The switch now runs BY ITSELF (v1.59 GO in advance).** A job on main checks every minute; the moment the shadow page shows 5 of 5 (or 8 Oct 12:40 Bangkok) AND SW + fm_mc5 have 0 live open, it does steps (a) to (c), writes the minute to w2-live-events.md and /opt/w2coder/SWITCHED. I nudge you and the FW Supervisor on my next wake (20 min cadence). Now: "waiting: streak 3 of 5".
- **16:14 Bangkok 7 Oct, tasks v1.59 + v1.58.**
  - **Auto switch (deployed 16:12):** /opt/w2coder/autoswitch.py, cron every minute. (a) bridge `fw_arm` on firstmin: refuses if fm_mc5 has a live trade, removes LIVE_MC5, waits 8 s, re-checks (a buy in flight puts LIVE_MC5 back and aborts), then creates SW_FW_ROUTE; it also refuses if LIVE_MC5 is already gone (fm_mc5 off or killed: the FW lane stays off, never armed around a FW kill). (b) merged_live true (config backup first). (c) restart at 0 live open, checks active. Any failure after (a) undoes everything (fm_mc5 trades again) and writes a SWITCH FAILED line. A mismatch resets the streak on the page, so the job just keeps waiting. Tests: test_v159 10 checks + bridge arm / abort / disarm on a fake box, 0 fails. Bridge md5 990785af65f4424dd1d4f54daab01e64.
  - **v1.58 item 1, path pick: A (GMGN route), already done.** Numbers: A was ready at 15:59 (switch ready now, waits only on 5 of 5); B needs a new wallet + Ben's funding + the D-019 fixes (done by 20:00), earliest about 20:30 (why: D-019 lands 20:00, then funding and a 10 min config flip). A wins by about 4 h. After the switch, flipping the FW lane to the D-026 self signed wallet is a config change (the key-file route is already built and tested in v1.56: `fw_route: key`, `live_keyfile_fw`), about 10 min at 0 open after the wallet is funded.
  - **v1.58 item 2, box conflict, one named risk each:** key on main = any process or person with root on main (30+ bots, feeds, public folder, M2 not done) can read the key file and drain that wallet. Engine on firstmin = 961 MB RAM shared with fm_mc5's 5 other units: an out-of-memory kill stops the engine mid-trade (2 GB swap and an OOM guard reduce, not remove it).
  - **v1.58 item 3, wallet creation:** waits on your box call (D-026 says never main; tonight's engine is on main). ETA 10 min after the call (why: generate key 600 root on that box, post only the full public address under Needs Ben). Trigger-to-fill seconds per stop are already logged on every live sell (SW: trigger to SELL_SENT and sent to mined; FW lane: trigger to filled + gmgn time).
  - cost: about 1.5% of session credits, API $0, 0.4 h.
- **switch ready: yes, missing: only the 3 GO steps below (code, route and tests are done).**
- **16:02 Bangkok 7 Oct, tasks v1.57 items 1 to 3 DONE. Deployed 15:59:00 Bangkok (0 live open, engine healthy, 116 MB).**
  - **1. GMGN route for the FW lane (D-021 v2):** FW lane = GMGN wallet 0x0184ef9b23476ed84107cc5e15485a4a7ee6b286 through gmgn-cli on firstmin only (no key anywhere on main). Main calls it through the restricted swbridge key: two new bridge commands, `fw_quote` (never trades) and `fw_swap`. fm_mc5's exact calls copied: buy ETH to token by amount at 5% slip, fill = token balance up; sell 100% at 10% slip then one more try at 30% (30% at once on stop, pull or retry), out = the wallet's ETH change; no tokens left = closed at 0. A sell that does not fill goes through the same pull rule as SW (pulled pool: booked 0x open_unsold, retried with backoff; live pool: kill after 3 tries). Gas reserve check before every FW buy (fm_mc5 rule).
  - **Bridge guards (on firstmin, md5 1e490792321a3f003e0d27195342d285):** a swap runs ONLY when /opt/fm/SW_FW_ROUTE exists AND /opt/fm/LIVE_MC5 does not (one trader per wallet), buy at most 0.2 ETH, slip 1 to 30%, ETH to one token only, fixed wallet, output secret-stripped, every call logged to /opt/fm/sw_route.log. Tested live from main: get_state OK, quote OK in 1.5 s end to end, swap refused ("not armed").
  - **Dry run running now (quote, never a swap):** every mc5 shadow buy and sell is priced on the GMGN route in a side thread, plus a route probe every 30 min. First probe 15:59:00: quote OK in 1.77 s. Line in live_status.json `fw_route`.
  - **X8 gaps closed:** kill / pause / cash out now stop FW lane buys too; the $200 combined drawdown marks BOTH lane books and fm_mc5's own open trades at a real-sale quote (was at cost); failed-sell retries run in the book that holds the trade. Ladder (D-001) and kill drops a step (D-018) were already in.
  - **2. FW-lane pools on the push watch: DONE** (was ETA 15:45; landed 15:59, why late: built together with item 1). The websocket now also watches the mc5 pools (shadow pools now, FW lane live pools after the switch) and runs the mc5 0.5x stop on the pushed swap itself (needs a 0.01+ WETH swap, same rule), instead of waiting for the 2 s log scan.
  - **3. The 3 GO steps (about 2 min, I do them on your GO at 0 live open):** (a) on firstmin `rm /opt/fm/LIVE_MC5` (fm_mc5 stops buying; it still sells what it holds) and `touch /opt/fm/SW_FW_ROUTE`; (b) `merged_live: true` in /opt/w2coder/config.json; (c) restart w2coder at 0 live open. Undo = the reverse. FW wallet holds 0.1354 ETH (about $350): enough for 24 x $10 + gas.
  - Known limit: the FW lane exit goes through GMGN (about 2 to 3 s gmgn-cli + ssh 0.5 s), so FW fills stay slower than SW's fast exit (Exec X7 measured -0.16x on one stop); a faster FW path needs Ben (Consigliere ask).
  - Tests: test_v157 27 checks, 0 fails (fake bridge, fake chain, nothing sent); all 21 older test files 0 fails (test_v156 and test_ramp updated for the GMGN default and the ladder).
  - Shadow: 3 of 5 at 15:44. I nudge you at 5 of 5.
  - cost: about 2% of session credits, API $0, 1.2 h.
- **14:48 Bangkok 7 Oct: lane line D-016 v2 + wallet routing D-021 BUILT behind the `merged_live` switch (default OFF = today's behaviour), deployed 14:45:33 (0 live open, dry sign PASS, LIVE ON).** Done ahead of the 16:15 ETA.
  - Switch ON does: the mc5 decision buys live on the FW lane (book w2_mc5_live) and its mc5 exit sells it; FW lane signs from wallet 1 (`live_keyfile_fw`, chmod 600; refuses to sign if missing, never falls back to the SW wallet), SW lane from wallet 2; one ticket per coin across both lanes (the other lane skips with a log line); every lane signal logged, ledger credits the lane that fired first; one kill switch and the $200 cap over both lanes; one nonce book and one approve set PER wallet in live.py (no nonce clash).
  - Switch OFF (now): FW lane never buys; SW behaves exactly as before. test_v156 13 checks + all 16 older test files 0 fails.
  - **What X7 must give (wiring is then minutes):** the FW wallet route. If it is a raw key: path of wallet 1's key file on main (chmod 600) -> `live_keyfile_fw`. If GMGN only (fm_mc5 trades through gmgn-cli today): I add a GMGN route for the FW lane, ETA 1 h after X7 (why: new send path + tests).
  - Open item for the switch: the mc5 stop check runs on the 2 s log scan; the push websocket covers SW live pools only. ETA 15:45 (why: about 45 min to add FW-lane pools to the push watch with a test).
  - cost: about 1.5% of session credits, API $0, 0.5 h.
- **14:45 Bangkok 7 Oct, tasks v1.55.**
  - **D-018 auto step up: LIVE (deployed 14:42:03 at 0 live open, dry sign PASS).** Every 10 min the engine reads http://159.223.88.168/hx-c9ois/fw/ramp-days.txt; WAITING, no file or no "running count N of 2" line = no step. At 2 of 2 it steps one size (D-001 ladder $10, $50, $100, $200, $300) only if the wallet holds 24 tickets + gas for the new size, else one line to Ben: "top up wallet 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 to $X" (said once per step). A streak steps once; it re-arms when the count drops under 2. Every kill path (kill check incl. the D-017 $200 combined cap, the error kill, the 3-failed-sells kill) drops one step. The live ticket and the combined cap read the ladder step. test_v155 11 checks, 0 fails; all older tests 0 fails. cost: about 1% of session credits, API $0, 0.3 h.
  - **Lane line D-016 v2 + wallet routing D-021 behind a switch (default = today's behaviour):** ETA 16:15 Bangkok (why: about 1.5 h of code and tests: a lane tag on every live row, one ticket per coin across both lanes, first-fired credit, a per-wallet nonce book and approve set in live.py, and the mc5 live path that follows the shadow's exits; X7 then only fills in the FW wallet route).
  - **M4 + M5 at 20:00 Bangkok** (why: Supervisor's slot; they do not touch the bot). M2 waits for the switch.
  - **Shadow:** honest line on http://159.223.88.168/hx-c9ois/sw/w2-mc5-shadow.md; I nudge you at 5 of 5.
- **14:35 Bangkok 7 Oct, tasks v1.54 (decisions.md ids cited).**
  - **D-022 wake rule:** fresh doorbell made (line 1). No more rings from me; I nudge the Supervisor's DOORBELL with update_trigger.
  - **Size line (D-001, D-002):** ladder $10, $50, $100, $200, $300; a step needs 2 bug free days in a row, counted only on the merged engine from its live switch, graded by FW Analyst 2 at 17:30. Today: day 0 of 2 (no switch yet). The "5 round trips within 10%" bar is dropped.
  - **D-003 v3 shadow match:** line added at the top of http://159.223.88.168/hx-c9ois/sw/w2-mc5-shadow.md: "Matched buys in a row: N of 5" (same pool, same buy/skip, same exit reason; open buys counted as pending until both sides close; any one-sided buy or different exit resets it). The bridge now carries fm_mc5's exit reason so the match is exact. Self test 15 checks, 0 fails; deployed 14:27:21 (0 live open, dry sign PASS, LIVE ON). At 5 I post here and nudge you.
  - **D-017 $200 total loss cap:** already live as the combined drawdown kill (both wallets, 20 x the larger ticket = $200 at $10; restart needs Ben or you). It will read the step from the ladder when D-018 lands.
  - **Builds before the switch (v1.54 item 3), status:** (a) lane line D-016 v2 and (b) wallet routing D-021 wait for the Exec's X7 (not published yet at 14:30): FW's fm_mc5 buys through GMGN (gmgn-cli swap), not a raw key, so "sign FW signals from wallet 1" needs X7 to say whether our engine calls GMGN for wallet 1 or holds its key. (c) is live (above). (d) D-018 auto step up: building now (ladder, 24 tickets + gas wallet check with the full-address top-up line to Ben, kill drops one step); it needs the location of FW Analyst 2's daily grade to read the bug free day count.
  - **Box for tonight (item 4): main.** Named risk of main: it also runs the feeds and 30+ bots, so a CPU or disk spike there can slow the engine (seen today: memory cap hits from my late-pool replays, fixed). Named risk of firstmin: 1 CPU and 961 MB RAM with fm_mc5 and 5 more FW units on it; an out-of-memory kill takes the live engine down (now cushioned by the 2 GB swap, still the bigger risk). Lock file on both boxes before any live buy; never two engines on one coin.
  - cost: credits about 1.5% of the session budget for this block, API $0 extra (dRPC calls inside the paid plan), 0.3 h.
- **13:55 Bangkok 7 Oct, fill watch + one fix.** No live buy or sell since 13:17; live ON, no blockers.
  - **Fix (deployed 13:52:22 at 0 live open, dry sign PASS):** two young late pools, HI (pool 0x92a4f531f82e1440d6e349bbc2ed42ba389e013f, 61,369 events) and GS (pool 0x46540a2e4b27ff778f8ec6648616660472945fc6, 14,847 events), were registered at 13:21 and 13:26 with their full history replayed; the engine hit its 300 MB memory cap for a moment (no stall over the guard limit, no trade, no gate: both pools were hours past every age gate). Now the first swap is found first (from the token's birth block, one-topic queries, adaptive chunk), and a pool that has traded for more than 3 h is registered with its true first trade and NO replay. Tests: test_v150 14 checks + all others 0 fails. Memory after restart 109 MB.
- **13:20 Bangkok 7 Oct, tasks v1.53: (a) + (b) pass tests; (c) firstmin swapfile done. Deployed 13:17:17 Bangkok at 0 live open, dry sign PASS, LIVE ON, engine healthy.**
  - **(a) mc5 signal module + shadow logging: running since 12:40:17 Bangkok (shadow start time; it survives restarts).** 13 checks, 0 fails. Grading page: http://159.223.88.168/hx-c9ois/sw/w2-mc5-shadow.md (auto every 2 min).
  - **(b) Pull fix ported (PP v45 / FW v39):** a live sell that fails on a pulled or empty pool (pool WETH under 0.1, or depth at or under the pull share of entry, or a pull exit) -> trade booked 0x as open_unsold: counts as a closed loser for the kill switch and both drawdowns, frees its open slot, buying continues, no error kill; retried with backoff 60 s doubling to 1 h, and a later fill overwrites the 0x. A sell that fails on a LIVE pool: retried every minute, kill only after 3 failed tries on that trade (was 2 errors of any kind). 13 checks, 0 fails. All older tests 0 fails.
  - **fwguard per-coin cap** now = 2 tickets of the larger ticket minus what FW holds (was a fixed $1,000). Same rule as the bridge check, so both scale with the ladder.
  - **(c) firstmin prep:** 2 GB swapfile added and on (persistent in fstab, swappiness 10 so it is only used under pressure); box had 961 MB RAM, 0 swap, 20 GB disk free. OOMScoreAdjust=-900 goes on the merged engine's unit when it is installed there (no SW unit on firstmin yet). FW's units (fmmc5, fmtrader, fmlane1, 3 PP paper books) untouched.
  - **Size line (corrected to v1.52):** 3 good days per step, counted on the MERGED engine from the switch; plus 5 round trips within 10% of paper. Today: 0 of 3 days (no switch yet), 0 of 5 round trips.
  - Next: (d) shadow day ends 8 Oct 12:40 Bangkok, graded by FW Analyst 2 + Exec X5; then (e) switch.
- **12:45 Bangkok 7 Oct, tasks v1.52 done (merge first). Deployed 12:35:53 and 12:40:17 Bangkok at 0 live open, dry sign PASS, LIVE ON. Engine healthy (beat 1 s, lag 0, memory 84 MB, FW state 3 s old).**
  - **1. Merge first: the mc5 signal module is RUNNING IN SHADOW since 12:40:17 Bangkok** (mc5shadow.py inside w2coder). It follows the mc5 spec and fm_mc5's behaviour: T0 = true first swap; check at T0 + 300 s; cap $250k to $1M; dust guard (0.001+ WETH swap, pool WETH 0.1+); seen_late after +330 s; round trip 0.80+ at FW's live ticket (read from FW state, $10); stop 0.5x on net sell value on every 0.01+ WETH swap, priced on that swap's block; 4 h time stop; pull = in-range Burn of 50%+ of in-range minted units, booked 0x. It logs the exact tx it would send (router exactInputSingle) and sends nothing. 13 self-test checks, 0 fails.
    - **Grading page for the Execution Engineer (X5), auto every 2 min:** http://159.223.88.168/hx-c9ois/sw/w2-mc5-shadow.md : every checked pool, the shadow decision and result next to fm_mc5's live fill for the same pool, plus fm_mc5 buys the shadow never checked.
    - **FW late-pool rule ported:** a Swap from a pool we never registered: our factory's WETH pool with NO Swap ever before (100k-block chunk, then 10M chunks back to block 1, one topic per query, busy pool = not new) is registered with T0 = that swap and its earlier Mint/Burn replayed. Old tokens with earlier swaps are skipped (248 checked since 12:31, all skipped).
    - Shadow day ends 8 Oct 12:40 Bangkok. Then: switch only if every shadow decision matches fm_mc5 within the X5 bars. The bug-free day count starts on the merged engine after the switch (Ben: 3 good days per step).
  - **2. Interim cap: $ cap per coin added (live).** Before a SW buy: FW's open $ in that coin + our ticket must be at most 2 x the larger ticket. With the earlier rules: 1 ticket per coin per window, one combined drawdown kill (20 x the larger ticket), max 6 open combined, fail closed on stale FW state. FW live wallet noted: 0x0184ef9b23476ed84107cc5e15485a4a7ee6b286.
  - **3. Plan, latency side by side (Exec X4, ms, median):**

    | Hop | firstmin | main |
    | --- | --- | --- |
    | Sequencer sendRaw, warm | 217 | 216 |
    | Sequencer sendRaw, cold | 718 | 705 |
    | Public read, warm | 268 | 245 |
    | dRPC read, warm | 5 | 5 |
    | dRPC websocket head age | 0.17 s | 0.15 s |

    Same region, same edges: the move does not cost latency. Keep-warm on the sell connections is now 60 s (Exec: they stay open 90 s idle).
  - **4. firstmin hard condition (before the merged engine moves there, NOT done yet):** add a 2 GB swapfile and set OOMScoreAdjust=-900 on the engine unit. fm_mc5 runs on that box, so I do this only after FW says yes (one line in fw-to-sw.md is enough) or Ben resizes the box to 2 GB. No backfills or research ever on firstmin; scoreboard, halfc and health stay on main.
  - **Merge plan (updated):** shadow day (running) -> X5 grade -> FW yes on the swapfile -> copy engine + venv + key (chmod 600, never printed) + guard timers to firstmin -> main's live switch off and firstmin's on in the same minute (lock file checked before every live buy on both boxes; never two live engines on one coin) -> fm_mc5 off -> FW's ramp count and our bug-free day count restart.
  - Pool universe count since 1 Oct: the research-box pull is still running (rewritten to skip pools that first swapped before our engine existed); next status.
- **12:35 Bangkok 7 Oct, tasks v1.51 + v1.50 done. Combined cap with the first window is LIVE (deployed 12:26:46, final 12:31:00 Bangkok, 0 live open, dry sign PASS, LIVE ON). Merge plan written below. Engine healthy (beat 1 s, lag 0, stale [], FW state 0 s old).**
  - **v1.51.1 Combined cap (live now).**
    - Bridge: a new restricted ssh key on main (swbridge@main) whose ONLY permitted command on firstmin is /opt/fm/sw_bridge.py (forced command, no shell, no pty, no forwarding; tested: `cat /etc/passwd` -> denied). It can do 3 things: read FW live state from /opt/fm/mc5.db (read only, FW's own open/closed definitions incl. the PULL_UNSOLD rule), write /opt/fm/exposure_ext.json, write /opt/fm/sw_state.json.
    - Every 15 s a background thread reads FW state and pushes SW open $ per token to /opt/fm/exposure_ext.json ({token_lower: usd}, FW's format, fm_mc5 already reads it) and SW live results to /opt/fm/sw_state.json (for FW's side of the one kill). Both files are live now.
    - Before every SW live buy: (a) FW state older than 60 s -> buy skipped, fail closed (one live-events line an hour, silent when healthy); (b) SW already holds this coin -> skip (max 1 ticket per coin PER WINDOW; a coin FW holds is NOT blocked); (c) SW open + FW open = 6 or more -> skip; (d) combined drawdown over 20 x the larger ticket -> skip.
    - Kill switch: also trips on the combined drawdown (both wallets' closed results in time order, SW open marked at a real-sale quote, FW open at cost). Today: 20 x $10 = $200.
    - Note for FW: our old cross-window rule "max $1,000 per coin across both windows" (fwguard, from v1.25) is still in place; at $10 it never binds. Say if you want it removed for the per-window rule.
  - **v1.50.1 Pool universe trap.** Ours registered pools ONLY from PoolCreated (14 h lookback at bootstrap 6 Oct 12:58, then every block). FW's pool 0xd27657e890fc13ac8a3b9f2e197bbc4ef3afe742 is not in our table. **Fix shipped:** the first Swap of any unseen address is checked once (one multicall, a few per cycle, never while a live position is open). Our factory's WETH pool + token born inside the last 74 h -> registered, its history replayed, true first swap known, it gates like any pool. Token born earlier or unknown -> skipped: it can never pass the 72 h birth rule or the 1.54 h age gate (and its history is never read).
    - **Count since deploy:** 68 unseen WETH pools have swapped since 12:31; all 68 are old tokens (births from May to early Oct), 0 young. Count since 1 Oct (all factory pools created since 1 Oct vs our table): the full pull (every factory pool created since 1 Oct, read only on research-box) is still running; the number goes in the next status. No young late pool has appeared since the fix went live.
    - **Incident during this deploy (fixed, no trade):** the first version (12:26:46) registered old pools too and read their full history. USDG (pool 0x52e65b17fb6e5ba00ed806f37afcd2daa50271ca) got registered with a fresh "first trade" and the engine stalled 4 min reading its 3 days of transfers (memory at its 300 MB cap). Fixed 12:31:00: old/unknown-birth tokens are never registered; the USDG row (55 swaps) removed; no gate, no trade, no live position at any time. This counts as a key bug: the bug-free day count restarts at 12:31.
  - **v1.51.3 Size rule (Ben): stay $10 until 2 bug-free days in a row AND 5 round trips within 10% of paper.** Today: bug-free days **0 of 2** (count runs from 7 Oct 12:31 Bangkok, after the fix above); round trips in line **0 of 5** (1 live round trip: CrawlScan, buy +1.0% vs paper, sell -14.8% vs paper; the sell was before fastexit). Kill limit already scales by itself: 10 x the current ticket ($100 now), plus the new combined 20 x the larger ticket.
  - **v1.51.2 Merge plan ("Live Desk": SW Coder + Execution Engineer). Written, not deployed.**
    1. **Base = w2coder** (fastexit, push websocket, approve at buy, stale guards, 30+ self tests). Windows become signal sources feeding ONE live book: one wallet book, one nonce book, one exposure cap, one kill switch.
    2. **mc5 signal module (from FW's spec a1-mc5-spec.md and fm_mc5.py):** universe = our factory WETH pools, one pool per token, T0 = true first Swap (our new late-pool rule gives that; FW v46 earlier-Swap check = our birth/history check). Entry check at T0 + 300 s: cap $250k to $1M on the last swap before T0 + 300 s; dust guard (one 0.001+ WETH swap moved price, pool WETH 0.1+); seen_late after T0 + 330 s -> skip. Exits: stop 0.5x on net sell value (swaps 0.01+ WETH only), time stop 4 h, pull = first Burn of 50%+ of minted liquidity units in range -> mark 0, sell anyway. No target, no trail. Book name w2_mc5; size from FW's ramp config.
    3. **PP pull fix (fm_mc5 v45, ref md5 c0210cc1676246ff10569b4e6080cdea):** a failed sell on a pulled pool -> status open_unsold, retry every minute, does NOT block new buys and does NOT trip the error kill. Ported to our live sell path for every signal source.
    4. **Shadow day:** w2_mc5 runs in SHADOW (decides and logs the exact tx it would send, sends nothing) next to the live fm_mc5 for 1 day. Graded by FW Analyst 2 against a2-ramp-v2 section 2 bars: buy within 6 s of the +5 min check, fill/model 0.995+, buy gap under +3% (median under +1.5%), trigger to SELL_SENT 5 s or less, stop slip -0.05x or better, 0 unnamed misses. fm_mc5 switches off only when every shadow decision matches.
    5. **Box:** firstmin 178.128.20.136, only after the Execution Engineer shows its sequencer latency is not worse than main's (main: 216 ms sendRaw). Move = copy /opt/w2coder + venv + key file (chmod 600, never printed) + guard timers; main's w2coder goes paper-only the same minute (never two live engines on one coin; a lock file on both boxes checked before every live buy).
    6. **Ramp count restarts at the switch** (FW's term). Order of work: (a) signal module + shadow logging, tests; (b) pull fix port + tests; (c) Exec Engineer latency check on firstmin; (d) shadow day; (e) switch. My estimate for (a)+(b): one working session; it waits for your go.
- **11:50 Bangkok 7 Oct, tasks v1.49 FAST EXITS done in one deploy: 11:48:31 Bangkok, 0 live open, dry sign PASS 11:48:34, LIVE ON. Engine healthy (beat 1 s old, lag 0, stale [], 0 errors).**
  - **Test result.** Execution Engineer's test_fastexit.py: offline 11 of 11 PASS, `--live` on main 14 of 14 PASS (websocket read only: 26 swaps on 8 pools in 20 s, decoded price = slot0 at the log's block 5 of 6). New test_v149.py: 30 checks, 0 fails. Every older test 0 fails (test_v143/144/145/147, test_mem145b, test_ramp, test_live140, test_lock141, test_guard142). test_ramp had 4 stale fails that were also in v1.47 (it assumed a $100 first ticket; the config is $10 now): the test is fixed, the engine was not wrong.
  - **1. fastexit deployed** (fastexit.py md5 91c9024e6b20fbae0f3706e6df3bd3b6, unchanged from the Execution Engineer's copy).
    - Push: the dRPC websocket gets each Swap log on the open live pools; the stop test runs on the crossing swap itself, zero calls. The engine loop wakes the moment a log lands (no 0.25 s sleep).
    - The socket runs only while a live position is open (closes 2 min after the last one; no idle dRPC traffic).
    - Fallback is automatic: socket stale (no head for 3 s) or down -> the old 0.25 s poll, now **dRPC first** (free Alchemy is capped), public second. Stale guard: a dead socket thread is restarted, a socket stale for 60 s+ writes one line to live events. Silent when healthy.
    - Send: one signed sell to sequencer + public + dRPC at once, first accept wins, local nonce book (every other tx resets it), no allowance read, simulation in parallel for the log only. Connections kept warm every 20 s while live is open: measured on main, cold 768 ms vs warm 258 ms for all three.
    - If the fast send steps aside (token not approved) or fails, the old path sells. If a late accept already sold the tokens, the engine sees the empty balance and closes the trade instead of retrying a reverting sell.
  - **2. Approve at buy time:** already live since v1.43 (approve right after the buy fills). v1.49 adds: the token is remembered as approved and the nonce is fetched right then, so the stop sell spends zero calls before signing. After a restart: one allowance read (about 5 ms), never an approve tx.
  - **3. Paper exits priced on the crossing block.** Every log-driven exit now quotes the sale on the state of the block that holds the crossing swap (eth_call at that block, cached per pool + block + amount), so every book gets the same price for the same crossing, whatever its queue order. The block is stored per closed row (`exit_qblock`). The minute timer (time exits) still uses the head. Checked on main: quotes 30 and 3,000 blocks back work (260 ms).
  - **4. Ticket cap:** 5% of gate depth, computed on every live buy and stored per trade (`ticket_cap_usd`, `R_gate`, also in the LIVE BUY line). Enforced from a $1,000 ticket (ladder step 3) on; below that it is logged only.
  - **First live exit timing after the change:** no live position since the deploy. The next LIVE SELL line will carry: fast send endpoint + seconds to accept, crossing swap block -> mined block (+N blocks), swap log arrived -> sell accepted (s). I ring you with it.
  - **For the Execution Engineer:** read access is the same as before (w2.log, live events, w2.db read only on main). Your new columns: `exit_qblock`, `ticket_cap_usd`, `R_gate`; beat field `ws` (stale, logs, head_age). One question back: does the dRPC websocket bill per pushed message? If yes, the socket-only-while-live rule keeps it small.
  - Next: v1.48.1 (size ladder step score + kill limit at 10 tickets), then v1.46 (nightly verdicts).
- **11:25 Bangkok 7 Oct, tasks v1.47 done: impact check + stale guards with a backup checker. Deployed 11:22:01 at 0 live open, dry sign PASS, LIVE ON.**
  - **1. Impact check (06:07 to 11:02 Bangkok).** One coin was gated in the window, SAI (pool 0xddefc8467c9b77e3f2c1525e0cb0f453e4408fc0), in all three gate tables. Army share was recomputed with the fixed memory (read only, script /tmp/inv147.py, output /tmp/inv147.json):

    | Gate table | Coin | Gate time (Bangkok) | Army share then | Army share now (fixed memory) | Gate verdict | Would it change? |
    | --- | --- | --- | --- | --- | --- | --- |
    | coins ($1M gate) | SAI | 07 Oct 09:52:33 | 0.0754% | 0.0754% | fail: too_old_95min (age, not army) | no |
    | coins750 | SAI | 07 Oct 09:05:25 | 0.0603% | 0.0603% | pass | no |
    | coinslg750 | SAI | 07 Oct 09:05:25 | 0.0603% | 0.0603% | pass | no |

    - **No trade was missed or wrongly taken.** The shares are identical because the coins missing from memory in that window were not among SAI's buyers' prior coins. Both limits (0.9% main, 1.5% wide/750k) are far above 0.08%.
  - **2. Stale guard (in the engine, every 60 s; silent when healthy).** Each check, what it does when it trips, and the one event line it writes (at most once an hour per issue):
    - **Army memory, loop:** the same coin picked 5 times in a row. That coin is skipped (mem_done=2) and the queue moves on.
    - **Army memory, flat:** no growth for 30 min while eligible coins wait. The memory job is run at once.
    - **Old-token coins:** now marked skipped (mem_done=2) instead of staying "waiting" forever, so a waiting count always means real work.
    - **Kit tags (srctag thread):** if the thread is dead, it is restarted. Pools older than 15 min with no tag are re-queued with their create tx (read from the PoolCreated log), at most twice per pool.
    - **Milestone tracker (kit300):** a coin whose check fails 5 times is dropped.
    - **Price heads:** an ETH price older than 10 min forces a fresh read. A block cursor more than 600 blocks behind for 3 checks writes a line (w2guard restarts at 6,000).
    - Open issues are written to the beat as `stale`.
  - **Backup checker (w2guard.py, every 2 min by timer and every 5 min by cron, read-only db):**
    - Trips on any coin waiting 45+ min for army memory, or 3+ pools older than 30 min without a kit tag.
    - Action: restarts w2coder (never with a live position open, at most once per 30 min) and writes "STALE GUARD BACKUP" to the events file.
    - Right after deploy it read 0 coins waiting and 0 untagged pools, so it stayed silent. The beat shows stale [], memory 293 coins.
  - **Files:**
    - w2.py 9188849036ff71eeb443ff1005b486b7
    - w2guard.py 725105f5081315d97e8cc910621ec36d
    - test_v147.py 4401953ed64a23221fe94f56a9afaff7
    - Backups: bak_v147/
  - **Tests:**
    - test_v147, 14 checks, 0 fails. Covers: a failing coin looped 5 times then skipped with the queue moving on, memory flat 33 min triggers the job, old token marked, dead tag thread restarted, untagged pool re-queued twice at most, old ETH price refreshed, cursor lag flagged, healthy = no event line, backup restart, backup cooldown, no backup restart with live open.
    - test_guard142, test_mem145b, test_v145, test_v144, test_v143, test_w2, test_live140, test_ramp, test_lock141: 0 fails.
  - **Next:** v1.48.1 (size ladder and step score), then v1.46 (auto-verdict).
- **11:05 Bangkok 7 Oct: army memory was stuck for 5 hours (06:07 to 11:02). Fixed, deployed 11:03:04 at 0 live open, dry sign PASS, LIVE ON.**
  - **What broke:** mem_jobs adds one coin per loop to the army memory (the wallets the army-share gate checks against). Coin blohard (pool 0xe507152250372fadb2c6cb50f2b5ff5e89dd8d21) was already in memcoin (from the daily backfill).
    - mem_add_coin returned early without marking it done. So every loop picked blohard again, logged "memory +", and returned.
    - That happened 7,980 times from 06:07 to 11:02. **No other coin entered the army memory in that window.**
  - **Effect:** gates in that window computed army share on a memory 5 hours stale. The gate's other checks and the trade path were not touched.
  - **Fix (w2.py 8735cce2abce28f2863cafcaa4e52201):** an already-stored coin is now marked done at once. Right after the restart the queue drained: ORBANCY (pool 0x4fc807391d8dd76992043950248b26a610231075) at 11:03:12, then SAI (pool 0xddefc8467c9b77e3f2c1525e0cb0f453e4408fc0) at 11:03:15, and so on.
    - Test test_mem145b.py 83e09f232faa89cb3a52f1b00356ffa6: a stored coin is marked done on the first pass, and the next coin is added on the second pass. 0 fails.
    - Regressions (v145, v144, v143, w2, live140): 0 fails. Backup: bak_v145b/.
  - **Also seen:** main rebooted at 10:45 Bangkok (now 4 CPU, 8 GB). w2coder came back by itself at 10:45:58 with dry sign PASS and LIVE ON at 10:46:22. No live position was open.
  - **New books:** w2_v3_addon5m bought its first add-on: CHONK (pool 0x8da021f34c2f2a95696c4fd842b0cd0cc4e18468) at 10:02, cap $15.26M, net buy over the last 60 min +$360, 10.2 h after the gate. w2_v3_kit300k: no milestone yet.
- **10:32 Bangkok 7 Oct, tasks v1.45: paper book `w2_v3_kit300k` (A1.27 lead, pre-registered for half C) is RUNNING.** Restart 10:29:51 at 0 live open. Nice -10 kept, dry sign PASS, LIVE ON.
  - **Universe:** every NEW v3 coin (first trade after the book started, 07 Oct 10:29:53 Bangkok, kv `kit300_start`) whose pool-create tag is Kit A or Kit B, or whose code hash is in the 3,587-byte family (srctag.KITC: 51d0e39db2ed, 2696b754c8e3, 60341fa374bf, already tagged). No age gate, no top-receiver or army filter.
  - **Fair $300k milestone:** buys made at a cap of $300k or more, summed from the swap tape, reach $15k. The dev's price jump alone does not count.
    - If the kit tag lands after the milestone, the milestone time is read back from the tape.
    - The buy is never placed in the past: it fills at max(milestone + 30 s, now).
    - Each milestone is stored in the new table `kit300` (pool, kit, code hash, fair_ts, cap, $ bought).
  - **Entry:** $1,000 paper at the first moment 30 s after the milestone. It is a real simulated fill on the pool, with the same fee and in-range depth as every other book.
  - **Exits = the live book:** 0.3x stop, 5x then kit hold for Kit A/B (50% trail, 48 h), pull, 12 h before 5x. Kit C sells all at 5x, exactly as live does. The book is in STOP_BY_BOOK, TRAIL_BOOKS and KIT_BOOKS.
  - **Overlap:** new trade column `gate_overlap` on the kit300 row is 1 if the live gate (w2_v3_wide_s03 or w2_v3_live) also took the coin. It is set at the kit300 buy and again if the live gate buys the coin later.
  - **Paper only:** no tx, no live slot (only the live entry book can buy live).
  - **Shown:**
    - Scoreboard card "Paper: kit coins at a fair $300k (w2_v3_kit300k)" (trades, open, result at $1k, average, overlap), plus `kit300k` in w2-scoreboard.json.
    - Half C line "kit coins at fair $300k (A1.27 lead)", with A1.27's reference $3,416 (A) and $14,471 (B) a day. Now 0 trades.
  - **Files:**
    - w2.py d92887680da02d57394f670276c8da09
    - scoreboard.py 01c48a3b4f1531a4cddb3394358dfc8c
    - halfc.py 10e26df469b3eabe286513cec09cca44
    - test_v145.py 8579dbe332a6c1d029e8b750168adc7c
    - Backups: /opt/w2coder/bak_v145/
  - **Tests** (droplet venv, run at nice 15):
    - test_v145, 15 checks, 0 fails. Covers: live exits, $250k buys not counted, $12k not yet fair, $16k = buy at +30 s, the table, one per coin, untagged = wait, late 3,587 tag reads the milestone from the tape, non-kit dropped, old coin skipped, Kit A with no filters, overlap mark, no live path, half C, scoreboard.
    - test_v144, test_v143, test_w2: 0 fails.
- **10:25 Bangkok 7 Oct, bus v1.3 (compute rule): checked, nothing of mine was running on main.**
  - w2coder runs at Nice -10 (drop-in /etc/systemd/system/w2coder.service.d/prio.conf, confirmed). My deploys use `systemctl restart`, which keeps the drop-in.
  - At 10:24, none of the top CPU users on main were mine. They were signer.py, daily_analysis.py, pickguard.py, reconcile.py and ppexit.py.
  - My one-off investigation script (/tmp/inv143.py, read only) ran once at 08:05 and finished.
  - From now on, any research or backtest of mine runs on research-box 152.42.241.219. On main I keep only the live engine, its guards, the hourly scoreboard and half C, and the short self-tests at deploy time.
  - No new coder tasks (tasks md5 a9714d14fce272ed328980c30b8a0155, v1.44 done). Live engine: beat age 0 s, no coin open.
- **09:51 Bangkok 7 Oct, tasks v1.44: paper book `w2_v3_addon5m` (A2.32) is ON.** Deployed 09:48:21, dry sign PASS, LIVE ON, restart at 0 live open.
  - **Which coins:** every coin the live book bought (w2_v3_live) plus its paper twin's entries (w2_v3_wide_s03, the live config: same gate, so every coin live would have bought), gated within the last 7 days. With live at one trade so far, using only w2_v3_live would mean almost no data. Config `addon_src_books` narrows it to w2_v3_live alone if you want. **Watching 2 coins now.**
  - **Entry:** on every swap of a watched coin, it checks whether this is the FIRST moment within 7 days of the gate where cap is at least $5M AND net buy $ (buys minus sells, from the swap tape) over the last 60 min is above 0. If so, a $1,000 paper buy fills 30 s later at a real simulated fill. One add-on per coin. Coins whose cross already happened before 09:48 are not back-filled.
  - **Exit:** no stop and no 5x sale. It sells on a 50% drop from the add-on peak (cap vs add-on entry cap), a liquidity pull (pool quote reserve at or under 50% of the add-on entry reserve, same R as every other book), or 7 days.
  - **No live path, no slot:** only the live entry book can buy live, and the add-on book is not it. The book does not count in live_open or the 750k_lg slot rule.
  - **Shown:**
    - Scoreboard card "Paper add-on at $5M (w2_v3_addon5m)", always shown, with add-ons, open, result at $1k, average and coins watched. It is also in w2-scoreboard.json as `addon5m`.
    - Half C row "add-on at $5M + net buying (A2.32), $1k paper", run once now: 0 trades.
  - **Files:**
    - w2.py 44c1f4794081021fb58f8eadbac481aa
    - scoreboard.py cf2cf689aa60b5af4d5955b6347181f1
    - halfc.py 470effea0ed26ee295ab6c49a085d9b7
    - test_v144.py 0dd4f4d70fe6064510c563f226c59ba8
    - Backups: /opt/w2coder/bak_v144/
  - **Tests** (droplet venv):
    - test_v144, 20 checks, 0 fails. Covers: watch list, $4.9M = no, $5.2M with net selling = no, a buy older than 60 min ignored, $5.3M + net buy = $1k at +30 s, one per coin, gated 8 d ago = not watched, no live path, holds at 5.5x, trail at 2.7x after a 5.5x peak, no price stop, pull at 40% reserve, time at 7 d, half C and scoreboard.
    - test_v143, test_live140, test_w2: 0 fails.
- **08:10 Bangkok 7 Oct, tasks v1.43 item 0 (live sell first): already shipped in the 08:06:49 deploy below.**
  - In exits_for, the paper row the live trade follows is sorted to the front, so its exit check and the live sell run before any other paper book on that pool. The rules are the same; only the order changed.
  - The fast watch also runs only that check before the rest. Test: test_v143 "exit loop: the row the live trade follows runs FIRST", PASS.
  - Restart at 08:06:49 with 0 live open (live_open 0 in the beat). Dry sign PASS, LIVE ON.
- **08:09 Bangkok 7 Oct, tasks v1.43 items 1 to 3 done and deployed (restart 08:06:49, dry sign PASS, LIVE ON). No live coin open.**
  - **1. Pre-approve: yes, the 3.6 s INCLUDED an approve tx.** The wallet nonces show it: buy nonce 4, approve nonce 5, sell nonce 6. The sell path checked the allowance, saw 0, sent the approve, waited for it to mine, and only then sent the swap.
    - **Now:** right after a live buy is recorded, the engine sends a max approve to the router. The stop sell is ONE tx. The LIVE SELL line now says either "sell was ONE tx (pre-approved)" or "sell needed an approve tx first (hash)".
    - Also cut from the hot path: the two wallet balance reads before the sell. The sell result now comes from the WETH Transfer in the sell receipt.
    - **The row the live trade follows now runs FIRST in the exit loop.** On CrawlScan, 4 paper books (s03, wide_s03, wide_ladder, regime) were quoted and closed before the kit_hold row fired the live sell.
    - Expected trigger to SELL_SENT is about 1 s (allowance read, nonce, simulation, send), next to FW's 1.4 s. This is not measured yet; the next live sell line will show it.
  - **2. Stop watch: how it was, what CrawlScan shows, what it is now.**
    - **How it was:** a live coin's price was read only from swap logs, on the main loop (poll_s 2 s, plus whatever else that loop pass did). There was no head read.
    - **CrawlScan timeline** (blocks are about 0.1 s apart):

      | Bangkok time | Block | Cap vs entry | What happened |
      | --- | --- | --- | --- |
      | 07:51:25 | 82066359 | 0.331x | swap |
      | 07:51:27 | 82066380 | **0.274x** | **one swap straight through 0.3x** (tx 0x8b3d59d971e0dd4fd0f28a565c23a950ad0fea2b5f90e4accf6fef8e924d8aa2) |
      | 07:51:28 | 82066388 | 0.294x | bounce |
      | 07:51:29 | 82066400 | 0.237x | swap; this is when the engine read the cross and fired |
      | 07:51:31 | 82066418 | 0.241x to 0.245x | two swaps |
      | 07:51:32 | 82066425 | 0.195x | another seller |
      | 07:51:33 | 82066437 | 0.195x | **our sell mined** (tx 0x9ad953b36c2c00c3d89505cc0e42160fe8156b4ec419ad3b671077d220adcf79) |

    - **Gap between the 0.3x cross and our trigger read: about 2 s** (07:51:27 to 07:51:29, about 20 blocks). The price we read, 0.274x, WAS the crossing swap. The coin gapped from 0.331x to 0.274x in one swap, so no watch could have sold at 0.3x. The 2 s of read lag plus the 4 s sell path is what cost us.
    - **Now (live_fast_watch):** while a live trade is open, the engine reads its pool at the chain head every **0.25 s** (about every 2 to 3 blocks). That is ONE multicall (slot0 + liquidity) for all live pools, free Alchemy first, public second, never the paid node.
    - If the row the live trade follows would exit at that price (stop, target, pull, 12 h, or trail when held), it runs the normal exit code at once with that state. It is the same rule and the same rows, just read sooner. With no live trade open, it makes no calls.
    - Every block (0.1 s) would be 10 calls a second, over the free limits, so 0.25 s is the setting (config `live_watch_s`).
    - **Rough estimate for CrawlScan with all of v1.43:** read at about 07:51:27.3, a one-tx sell mined around 07:51:28, near the 0.27x to 0.29x swaps instead of 0.195x.
  - **3. Kill switch: sell fills did NOT count before. They do now.**
    - The "2 fills over 10% worse than paper in a row" rule now reads buy AND sell fills in time order. A sell's gap is 1 minus live result over the paper exit row's result.
    - **Count is now 1 of 2:** the CrawlScan sell, 14.8% worse (stored on trade 24, sell_vs_paper 0.148). The CrawlScan buy was 1.0% better and does not count. The kill message now says "live fill (buy or sell)".
    - **My view: count crash sells too.** Most of the 14.8% was our own 6 s (2 s read plus approve plus queue), which this switch exists to catch. If crash gaps start tripping it after v1.43, the fix is more speed, not leaving sells out. Your call.
  - **Files:**
    - live.py ec38c7d910a406fd4010f79cbba2ecb5
    - w2.py 42e90f82ca003bf1f95baeb45efd7cb5
    - ramp.py 095e5666541712293f56c0180b380288
    - test_v143.py 1ebf32f83e411aacae3adc0c5e133073
    - test_ramp.py 59621eefb4d8ab54a640c2775f6fdc97 (its fake live module got WETH and preapprove)
    - Backups: /opt/w2coder/bak_v143/
  - **Tests** (droplet venv):
    - test_v143, 16 checks, 0 fails. Covers: one approve at pre-approve, no tx when already approved, sell = 1 tx after pre-approve and 2 txs without, live row first, sell result from the receipt, gaps in time order, CrawlScan alone = no kill, next fill 12% worse = kill, watch at 0.5x = no exit, watch at 0.25x = exits now, 0.25 s pacing, no calls with no live trade, never paid.
    - test_live140, test_w2, test_lock141, test_guard142, test_cashout: 0 fails.
    - test_ramp: the same 4 config fails it already had on the droplet before v1.40.
- **07:58 Bangkok 7 Oct, tasks v1.42 item 4: FIRST LIVE SELL done, clean. No live position open now.**
  - **CrawlScan sold on the stop at 07:51:33.** Token 0x1ec25a196c49dd3445f1fcc53c37c513af92839c, pool 0xa6caf95634d4bcffdfb535eec889c9c928ff13d5. Tx 0x9ad953b36c2c00c3d89505cc0e42160fe8156b4ec419ad3b671077d220adcf79.
  - Out 0.00072 ETH = $1.95 on the $10 ticket: **0.20x, about $8 lost.** The buy at 05:56:59 was the bot's first live buy.
  - **Speed:** trigger to SELL_SENT 3.6 s (target under 5 s, met). Sent to mined 0.2 s. No error and no kill switch. w2-ring.json wrote at once (n 1).
  - **Fill:** the trigger price was 0.274x cap and we got 0.195x, a gap of 0.079x. Sell vs paper exit (kit_hold twin, 0.229x): **-14.8%**.
  - Why the gap: the coin went through the 0.3x stop in one tick. The first stop read was already 0.27x cap at 07:51:29, and by 07:51:34 the no-stop books exited on **pull** (liquidity pulled) at 0.24x cap. So most of the gap is the market falling as we sold, not the sign path.
  - **One finding for you (no change made; live exits change only after A2.29/A3):** on that tick the engine closed 5 paper books first (07:51:29) and the live sell went out 4 s later (07:51:33). The paper sims fell 0.28x, 0.23x, 0.19x down that queue. If the live sell runs first in the exit loop, it would go out about 4 s earlier on a fast dump. Say the word and I'll ship it with a test.
  - Engine after the sell: active, beat age 1 s, live_open 0, no new "locked" lines (count still 5, all from 05:58 to 06:01). Live is still ON with a $10 ticket.
- **06:14 Bangkok 7 Oct, tasks v1.42 items 1 to 3 done, item 4 armed. CrawlScan still open, live ON.**
  - **1. Fast stall guard:** new timer w2guard-fast (every 15 s, runs `w2guard.py --fast`). While a live position is open: restart if the beat is over **45 s** old, start grace 60 s, at most one restart per 90 s. With no live position it does nothing, and the 2 min timer + cron keep the 180 s rule.
    - It never restarts in the middle of a live buy or sell: the engine writes live_busy.json during live_buy/live_sell; a marker under 120 s old blocks the restart.
    - The beat now carries live_open (CrawlScan: 1). If the beat is unreadable, the guard reads the db read only (WAL, never blocked).
    - test_guard142.py, 7 checks (60 s with live = restart, 30 s = no, no live = fast guard idle, 180 s rule kept, mid-sell = no restart, stale marker = restart): 0 fails.
  - **2. Write-lock audit, every writer to w2.db:**
    - srctag thread: fixed in v1.41 (autocommit).
    - **health.py (cron :03 every hour): same bug, fixed now.** It ran first_eth (slow RPC balance searches) for up to 12 wallets per coin inside one open write transaction. Its connection is now autocommit.
    - army_backfill.py (daily 04:17): OK, each memory insert commits right after it; the network read comes before the insert. Its engine writes go to a scratch db.
    - halfc.py, scoreboard.py: open w2.db read only, cannot lock.
    - Engine main thread: can hold its own transaction, but cannot lock itself out.
    - test_lock141.py now checks srctag, health, halfc, scoreboard, plus the lock reproduction: 0 fails.
  - **3. Labels:** LIVE BUY, LIVE SELL and both ERROR lines now print `token` and `pool`, labelled. For CrawlScan: token 0x1ec25a196c49dd3445f1fcc53c37c513af92839c, pool 0xa6caf95634d4bcffdfb535eec889c9c928ff13d5 (the 05:56:59 line showed the pool only).
  - **4. First LIVE SELL, armed:** the line now carries the tx, live buy vs paper buy %, trigger vs our fill (x of cap), **sell vs paper exit %** (when the kit_hold twin has closed first; otherwise it says so), and **trigger to SELL_SENT seconds + sent to mined seconds** (live.py now records the time the node accepted each tx). The first one is marked **FIRST LIVE SELL**, and it writes w2-ring.json at once. My watch rings you the moment it appears.
  - Files: w2.py 2b34ca630ed4d929b17cdd89240b36f3, live.py 4f8937293f24c7ad6544c5d08ed3e0e6, w2guard.py 8626a3231b415b46c8e447a6dd038755, health.py ef48b29218f6bedbe63cb44a821f6c22, test_lock141.py 5554cd144797393fb873d4c787debb77, test_guard142.py 8aaf014fa9a750557eb3cea0ec5bea45, w2guard-fast.service/.timer installed. Backups: /opt/w2coder/bak_v141/. Other tests (w2, ramp, srctag, cashout, live140): 0 fails.
  - Restart 06:11:53, dry sign PASS, LIVE ON, beat live_open=1.
- **06:06 Bangkok 7 Oct: FIRST LIVE BUY, plus a lock bug found and fixed.**
  - **First live buy:** CrawlScan, pool 0xa6caf95634d4bcffdfb535eec889c9c928ff13d5, token 0x1ec25a196c49dd3445f1fcc53c37c513af92839c. Gate 05:56:39 at $1.03M (age 8 m, receiver 5.5%, army 0.11%), filled 05:56:59 (20.9 s), $10, entry cap $1,004,910, tx 0xf4921256fed26e57b8df0890a006b8b83adbf84000d06bdd587bb0899f06df1f. Live fill vs paper fill -1.0%. The signing fix worked on the real path.
  - Still OPEN. It exits with the w2_v3_kit_hold row (stop 0.3x). Price fell fast: the 0.5x-stop paper books (w2_v3_1m, w2_v3_hold, w2_v3_rep) sold at 06:01:33 at about 0.57x. The live trade and its twins in w2_v3_wide_s03 / w2_v3_kit_hold are still open above 0.3x.
  - **Bug: right after the buy the engine stalled for 4 minutes** (05:58 to 06:01, "database is locked" x3). w2guard saw the beat 194 s old and restarted it at 06:01. No trade was lost, and no live exit was due in that window.
    - Cause: the srctag background thread (farm_funded / first_eth, which runs at every gate) wrote a row and then did slow balance searches over RPC for up to 12 wallets **inside the same open write transaction**, so the main loop could not write.
    - **Fix (v1.41, deployed 06:04):** the srctag thread's connection is now autocommit, so it never holds the write lock across a network call. srctag.py f87f8e7402a3123e6fa7ac29e73c8038 (backup bak_v140/srctag.py). New test_lock141.py reproduces the old lock and proves the fix: 0 fails. Restart 06:04:16, dry sign PASS, LIVE ON.
  - Why it matters: a 4 minute freeze while a live coin is dumping could skip the 0.3x stop. This class of freeze is now closed for the tagging thread, and w2guard still catches any other stall at 180 s.
- **00:17 Bangkok 7 Oct, tasks v1.40 item 2b done: SIGN PATH PROVEN with real transactions.** All three went through the exact live functions (`_send`, `live.buy`, `live.sell`), simulated first, status 1:
  - Wrap 0.0001 ETH to WETH: tx 0x180d617613d8d4e53f0f5b7cc2bc754911e019e6ababd584e620e303b8c95474
  - $1 buy of CHONK (token 0x717d38587504b79e2e888c860bd1569c0d5984af, pool 0x8da021f34c2f2a95696c4fd842b0cd0cc4e18468, fee 100): tx 0x144752a803ce3eda29b5a6da2d65883a1c518dc5f68d29d378f8e1aeea772636, got 268.98 tokens
  - Immediate sell (approve + swap): tx 0x1237e8b2e6280a65675efeadc72f3c63a91521e8ff95b916f8b60c88fcdf0016, back 0.000350 WETH = $0.94
  - Line written to w2-live-events.md at 00:15:33. Total cost of the proof about $0.16 (gas + spread). Wallet now 0.04079 ETH + 0.00045 WETH.
  - Script: /opt/w2coder/prove140.py (prints hashes only). Live stayed ON the whole time (00:13:12), no errors.
  - Small fix to v43: there I wrote "CHONK 0x8da0..."; that address is the POOL. The token is 0x717d38587504b79e2e888c860bd1569c0d5984af.
- **00:15 Bangkok 7 Oct, tasks v1.40 done: your hotfix is right, and now this whole class of bug is blocked. Live is ON at $10, all 12 checklist lines PASS.**
  - **1. Your fix checked:** every signing path goes through one function. I grepped all of /opt/w2coder: there is exactly one `sign_transaction(` in live code. buy, approve, sell, unwrap (WETH to ETH) and the cash-out transfer all call `_send`. Your `to_checksum_address` line was correct.
    - I moved signing into a new `_sign()` (live.py). It checksums `to`, signs, then decodes the signed bytes and checks the sender is our wallet. `_send` and the dry sign both use it, so the self-test tests the exact live code.
  - **2. Dry-sign self-test (new):** `live.dry_sign()` signs, and never sends, 5 transactions with the real key, the chain nonce and lowercase addresses on purpose: buy, approve, sell, unwrap, cash-out transfer.
    - The engine runs it at every restart, before every OFF to ON, and every 10 min while it fails. Any fail = blocker "dry-sign self-test failed", live stays OFF, one events line, and a ring.
    - Ran on the droplet at 00:11:14 and 00:13:12: PASS. Events line written.
    - **LIVE CHECKLIST item 11 = Dry-sign self-test.** The wallet line is now item 12. Re-ran `checklist.py --write` at 00:13: **ALL 12 PASS** (block in w2-live-events.md).
  - **3. Errors ring at once, 2 in a row = kill:**
    - Every LIVE BUY ERROR and LIVE SELL ERROR now: (a) writes the events line, (b) writes http://159.223.88.168/hx-c9ois/sw/w2-ring.json (count, time, text, last 20), (c) sends Ben's Telegram alert at once through alertgate (min wait 0; one message per coin and side until it is fixed, then a "fixed" line).
    - 2 errors in a row with no good buy or sell between = kill switch (new buys stop, open trades still exit by the rule). A good fill resets the count.
    - Also fixed: the old kill switch Telegram alert never sent. `import alertgate` failed silently because /opt/common was not on the path. It now goes through the same ring.
  - **Honest limit:** the droplet cannot press your doorbell itself; only a Claude session can. So: Ben's Telegram fires at once, and my fill watch now reads w2-ring.json and rings you when it changes. My watch runs every 15 min (was 30) while live is at stage 1. If you want faster, the bus.json md5 of w2-ring.json is the signal to watch.
  - **CHONK 0x8da021f34c2f2a95696c4fd842b0cd0cc4e18468, missed live fill (for A2.30):** gate 23:52:46, live buy died 23:52:51 (lowercase `to`). Paper twin: w2_v3_wide_s03 and w2_v3_kit_hold both OPEN, $500 each, entry cap $1,094,331. Not re-bought, correct.
  - **Self-tests:** test_live140.py (new, 12 checks with a throwaway key and a fake chain: proves eth_account refuses a lowercase `to` and `_sign` fixes it, dry sign never broadcasts, 2 errors kill, error then good then error does not) 0 fails. test_w2, test_srctag, test_cashout 0 fails on the droplet.
    - test_ramp: 0 fails here, 4 fails on the droplet. **The same 4 fail with the pre-v1.40 code**: the test reads the droplet's live config ($10 cap), so its $100 ramp and 10-loser drawdown asserts don't match. Not a new bug; I will pin the test config next.
    - Tests no longer write to the live w2.log (they only print). Before, test runs added lines to it.
  - Files: w2.py 145244d39a62f60a36beb29d2f8052cf, live.py 9ba3e1cfbedcd2ff09810d1258e588f8, checklist.py 272ff160058e48025fd6c9ad4497aae7, test_live140.py 774e293a6d698805e4c198e45ffeea47, test_ramp.py 820a540cacec6a31dfa280590ca2848f. Backups: /opt/w2coder/bak_v140/ and your bak_live_pre_checksum.py.
  - Live: ON since 00:13:12, ticket $10, wallet 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0.0413 ETH, no live trade yet.
- **20:52 Bangkok, tasks v1.39 answer: the live gate watcher is 0 s behind the chain. Nothing to fix.**
  - **Live path:** the engine (w2coder) reads every block itself, and the gate fires inside that same loop. At 20:50:47 its cursor was 81674625 with chain head 81674623: 0 blocks, 0 s behind. The heartbeat was 0 s old, and the newest stored swap was 2 s old.
  - **Why kitb-count.json looks 8,401 blocks behind:** its `feed_last_block` is the block of the LAST WETH pool launch (81661681), not the feed position. A direct factory log read shows only 2 PoolCreated since 81661000: the WETH one at 81661681, and one non-WETH at 81670544. Launches have simply been quiet for about 22 minutes. The counter is not behind, so I left it alone.
  - Live: ON, $10, no trade yet.
- **20:33 Bangkok, live check plus one correction.**
  - **Correction to v40:** v40 said "no gate has fired since 19:25". That was wrong: my query used a timestamp 10 hours in the future. One gate did fire:
    - CORES 0x2cdf271007c7ebb6013d55492e156031c535094f at 19:48:17. It failed on top receiver 25% (limit 0.08), at 0 minutes old, so no live buy. That is correct behaviour.
    - It is a Kit B launch, operator key 0x8876789976decbfcbbbe364623c63652db8c0904. `operator` is 0, because that contract key is under the 1 in 5 gate rate. The gate was counted for the key.
    - So the v40 line "none of the 6 keyless launches reached the gate" still holds: CORES was the one launch that did get a key.
  - **Live:** ON, $10 ticket, no blockers (live_status 20:30). No live trade yet. A second "LIVE ON" line at 20:00:35 in the events file is the restart for the srctag fix, not a new switch.
  - **Operator tag after the fix:** 1 launch since 20:00, an "old" deployer (funded over 1 h before launch), which is a correct result. No more "state pruned" misses. More launches are needed to confirm the hit rate; I re-check at 21:00.
- **20:01 Bangkok, live check plus a fix to the v1.37 operator tag.**
  - **Live:** ON since 19:25, $10 ticket, no blockers (live_status 19:57). No gate has fired since 19:25, so there is no live buy yet.
  - **Operator tag bug, fixed:** 6 of the first 7 launches after v1.37 got no key ("block scan (state pruned)"). The public node is a few blocks behind, so it refused the launch block's balance read; the old code tried 3 times in a row with no wait and no paid fallback. The same read works now (tested on the droplet: balance at 100 to 35,087 blocks back, 3 of 3 on both nodes). Now each balance read retries with a short wait, and the paid node answers on the 4th try. srctag.py 53f18e8825cd4ff9a9b3f323ed998048, test_srctag 0 failures, restarted 20:00.
    - Those 6 launches keep `operator` = 0 (no key). None of them reached the gate, so no gate learning was lost.
  - I re-check the tag hit rate at my next watch (20:30).
- **19:27 Bangkok, tasks v1.38 done. LIVE IS ON at $10 a trade** (events file: "LIVE CHECKLIST (v1.38): ALL PASS" at 19:25:38, then "LIVE ON" at 19:25:48, ticket $10, wallet 0.0413 ETH).
  - **Ticket:** `max_ticket_usd` = 10 and `ramp_steps_usd` = [10, 100, 500, 1000]. It stays $10 until you write "LIFT CAP" (self-tested: 12 good $10 trades plus a big wallet still give $10).
  - **Fund check at $10:** need = 8 x $10 + 0.005 ETH = 0.0345 ETH at ETH $2,712. The wallet holds 0.0413, so it passes. The hair-miss fallback is built: if it misses, live keeps running at $10 while liquid ETH covers 3 tickets + 0.003 ETH. The first use is logged once.
  - **LIVE CHECKLIST: all 11 lines PASS.** The full block with evidence is in w2-live-events.md. It was written before live turned on: live_auto was held off until the checklist passed.
    - Entry: wide gate, real swap from 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3. The key file derives exactly that address and is mode 600.
    - Exit: kit hold, 0.3x stop, pull, 12 h, slots 3 + 2.
    - Auto revert: armed from 17:12:27.
    - Kill switch: all four rules, plus max 3 open and the 45 s median. Not tripped.
    - Cross-window guard: mc5live.txt 69 s old, plus 0x0184ef9b23476ed84107cc5e15485a4a7ee6b286, $1k combined cap.
    - Command lines: read every minute; no payout set, so CASH OUT keeps the ETH.
    - Gas reserve 0.003 ETH: the engine checks it, and now live.buy also refuses itself.
    - Fills logged vs paper.
    - Health: heartbeat 0 s, 0 blocks behind, w2guard timer + cron.
    - Paper books never place orders.
    - Wallet and ticket, plus a quote-only $10 round trip on CLAUS 0x206211d456a3a9dbe45e13507aac5131ace9c716: PASS.
  - **Fixed before go-live (found in the audit):**
    - (a) **Orphan risk:** if the paper simulation failed right after a live buy, no paper rows existed, and live exits follow the paper rows, so the live coin would never be sold. Now the paper rows are built from the live fill. Self-test: the live position still exits on its stop.
    - (b) **Gas reserve:** it was checked only when the minute balance was fresh. live.buy now refuses any buy that would leave under 0.003 ETH.
    - (c) **"Stalled engine stops new buys":** new blocker when the engine is over 600 blocks behind the chain head or its beat is over 180 s old (on top of the 60 s late-gate rule and the w2guard restart).
    - (d) **The $10 cap:** it was below the old first step ($100), so the old code would have stayed at $100. A cap under the first step now is the ticket.
  - **Self-test, 0 failures** (test_w2, test_ramp with 9 new v1.38 checks, test_srctag, test_cashout), on the droplet too. Live config and events were byte-identical across the tests; config was changed only afterwards, by v138cfg.py.
  - Files: w2.py b255d5cd7c890bc21ec85214c45287cb, ramp.py fde53a60c3db0225dc038bfe263168d8, live.py 64145ed49fee99a229b277099e737ed3, checklist.py b0513795686a12a9d732ae5c6be097f8.
  - **Next rings:** FIRST LIVE BUY, first LIVE SELL, any KILL SWITCH. My watch reads the events file every 30 minutes, so a ring can lag by up to 30 minutes.
- **19:14 Bangkok, tasks v1.37 done. OPERATOR tag and the KIT DRIFT alarm are live. New paper book `w2_v3_opflag`. Live is unchanged.**
  - **The tag at each new v3 WETH launch** (srctag thread, every launch, not only kits):
    - It reads the deployer's first funding with a balance search back 1 h, then that block.
    - Key = the contract the funding went through when the deployer is named in its calldata (a disperse), else the sender.
    - `operator` = 1 if the key is on the watch list at that moment. The flag goes on `pool_src`, every coin row and every trade row (`operator`, `op_key`).
    - A deployer funded over 1 h before launch gets no key ("old") and `operator` 0.
  - **Watch list (`op_stats`):** seeded from a1-21-operator-wallets.json with its 25 gate keys (all 25 loaded on the droplet). Walk forward only:
    - When any coin reaches the sellable $1M gate (pass or fail), its key is added and its gate counted. This happens once per pool, at gate time.
    - Coins already tagged before the gate are never re-flagged.
    - Contract keys need at least 1 in 5 of their funded launches to have gated (A1.21 caution). Launches and gates are counted live per key: 0x84157d3d24630c297849c84d49ae7f1805c1b60f passes (34 of 155), 0x03802649e469ed5680c58dff9e65425e22d21cc5 passes, 0x8876789976decbfcbbbe364623c63652db8c0904 fails (2 of 15).
    - The other lists in the json (24 Kit A funders, 15 parents, the Kit B and 3,587-family callers) are not used as keys. A1.21's rule uses the 25 gate keys only.
  - **KIT DRIFT alarm:** when an operator = 1 coin reaches the gate with launcher code that is not Kit A, Kit B or kit_c_watch, w2-live-events.md gets one line per new code hash: "KIT DRIFT: operator on new code <hash>" (with pool, key, launcher).
    - Position manager launches (no launcher code) do not alarm. Operator A uses the plain position manager on purpose; that is not new code.
    - **Ring timing:** the droplet cannot ring you directly. My 30 minute watch reads the events file and rings you, so the worst delay is about 30 minutes.
  - **Paper book `w2_v3_opflag`:** the live book (wide + 0.3x); at 5x it holds all on the 50% trail if the code is Kit A or B, OR `operator` = 1. It never feeds the live auto revert. It is on the scoreboard and in half C.
  - **Live is unchanged:** live exits still follow `w2_v3_kit_hold` (code hash A or B only), until A2.29 and A3 pass.
  - **Self-test, 0 failures** (test_w2, test_srctag, test_ramp, test_cashout), on the droplet too. Live config and w2-live-events.md were byte-identical before and after. The tests cover:
    - Direct key and disperse key.
    - Unknown key = 0, then learned at the gate, then the next launch = 1.
    - 0x84157 flags; 0x8876 (13%) does not.
    - "old" deployer.
    - KIT DRIFT written once per hash; none on Kit B code.
    - Tags on coin and trade rows.
    - opflag holds an operator coin at 5x while kit_hold sells it all.
  - Files: w2.py 4d3b2af030fee0805eadc76829f54e64, srctag.py be2d3cc0df70803749fafafbdcb8f98c, scoreboard.py a80e37ba39a93b6abe6d75015d22a0a5, halfc.py 30594586f8050f1fd9603361fb51e09f, a1-21-operator-wallets.json 2338323e8b29914172b3c97589a242b7. Restarted 19:11 Bangkok, active. No new launch yet in the first 3 minutes, so no tagged row yet. I will confirm the first tagged launch at my next watch.
  - **Still the only live blocker:** funding. 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0 ETH and needs about 0.30 ETH.
- **18:57 Bangkok, tasks v1.36 done. Kit C WATCH is running, paper only. Live is untouched.**
  - **Tag:** `kit_c_watch` on every coin row (and every trade row). It is 1 when the launch contract's code hash is 51d0e39db2ed, 2696b754c8e3 or 60341fa374bf (the A1.20 "3,587-byte" family), else 0. `kit` stays "other" for these coins, so **live sells all at 5x** on them. Live exits still follow the `w2_v3_kit_hold` row, which holds only Kit A and Kit B. The tagger sweep fills old rows every minute.
  - **Paper book `w2_v3_kitc`:** the live book (wide gate + 0.3x stop, kit hold at 5x for Kit A and B), plus kit hold for kit_c_watch coins (all held on a 50% trail, pull or 48 h). There is no slot rule, the same as the `w2_v3_kit_hold` paper row. It never feeds the live auto revert counter (`kit_log`). It is on the scoreboard and in w2-halfC.md.
  - **First new Kit C launch:** the tagger writes one line to w2-live-events.md the first time a new launch with one of these hashes appears: "KIT C WATCH: first new launch seen", with the pool, deployer and block. Backfills never write it. My 30 minute watch reads the events file and rings you on it.
  - **Right now:** 0 Kit C launches tagged on the droplet. That fits A1.20 (none since 3 Oct 08:21 Bangkok).
  - **Self-test, 0 failures** (test_w2, test_srctag, test_ramp, test_cashout), on the droplet too. Live config and w2-live-events.md were byte-identical before and after. The tests cover:
    - Kit C coin tag = 1, Kit B tag = 0, and the tag on every trade row.
    - The kitc book holds a Kit C coin at 5x, and the 50% trail sells it.
    - kit_hold (what live follows) sells it all at 5x.
    - kit_log is untouched.
    - Exactly one event for the first new Kit C launch.
  - Files: w2.py e4056870547d9e965f744f419c37d56f, srctag.py 080f9b6a147f2e86f7d8cfc55b629e00, scoreboard.py ac9ce9b31ce452c4607fd82b9bfdcb06, halfc.py 3c08457f3c96cb37986001e34b9c9946. Service restarted 18:52 Bangkok, active.
  - **Still the only live blocker:** funding. 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0 ETH and needs about 0.30 ETH.
- **18:27 Bangkok, tasks v1.35 done. New paper book `w2_v3_750k_lg`, running now, never live.**
  - **Name clash, please note:** `w2_v3_750k` already exists (the v1.29 A2.16 cell: top receiver 0.10, wide + 0.3x exits). I kept it unchanged, so its half C row stays clean, and named the new book **`w2_v3_750k_lg`** ("live gate"). Say if you want it renamed.
  - **Gate:** the exact live gate (what puts a coin in `w2_v3_wide_s03`): age up to 3 h, army up to 0.015, top receiver up to 0.08, token born up to 72 h before its first trade, one pool per token, supply re-read, sell check. It fires when $20k sellable is bought at $750k+ instead of $1M. Own table `coinslg750`; the $1M gate state is never touched.
  - **Exit:** the live exit. Kit hold (a Kit A or B coin at 5x holds all on a 50% trail, pull or 48 h; others all out at 5x), 0.3x stop, plus the slot rule inside the book (3 open; holds past 5x ride free, up to 2). Slot skips are logged (`coinslg750.slot_skip`). The book never feeds the live auto revert counter (`kit_log`).
  - **Ticket:** a $1,000 paper buy and sell (other paper books stay at $500). Multiples are over each trade's own ticket.
  - **passed_1m (yes/no) on every trade and coin row:** "yes" the moment the coin passes the $1M live gate. "No" if it fails that gate, or has not passed 3 h 10 min after its $750k gate (the live gate's 3 h age limit means it never can).
  - **Scoreboard:** a paper card right under the live card. It shows trades, result and $ a day at $1k, and splits closed trades into coins that later passed the $1M gate vs the extra ones that never did. Also added as a row in w2-halfC.md.
  - **Self-test, 0 failures (test_w2, test_ramp, test_srctag, test_cashout), on the droplet too.** It covers: a $1k buy, the 0.3x stop, never live, passed_1m no / yes, a 9% top receiver passing the A2.16 cell but failing this gate, Kit B hold and trail, kit_log untouched, the slot rule and skip. Live config and w2-live-events.md were byte-identical before and after.
  - Files: w2.py 8fc61c774189a3545e08411b9f56d74a, scoreboard.py e0a0012709ae23f52f8a1f1fcc4609ce, halfc.py 205887944f31d67a0671f84f79191c58. Service restarted and active.
  - **Still the only live blocker:** funding. 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0 ETH and needs ~0.30 ETH. Payout address not set yet.
- **18:11 Bangkok, tasks v1.34 done. CASH OUT path is ready. Live card: "Cash out: ready (payout not set)".**
  - **How you trigger it:** the bot reads this tasks file every minute. Only standalone lines count: their own line, an optional `- ` or `**`, and no quote marks. So the quoted words in v1.34 do nothing (checked on the real file: no payout, no command).
    - `PAYOUT = 0x<40 hex>`: sets `payout_address`. The newest such line wins, and nothing else can set it. Every change is logged with the full old and new address.
    - `PAUSE <time stamp>`: stops new live buys at once; open trades run to their normal exits (kit hold, stop, pull, 48 h).
    - `RESUME <time stamp>`: undoes a PAUSE. It never undoes a CASH OUT.
    - `CASH OUT <time stamp>`, in order: (1) stops new buys; (2) sells every open live position at once (real sale, same sell path as live exits); (3) unwraps any WETH and sends all ETH minus gas for one transfer (priced at 2x) to `payout_address`, or keeps it in the wallet if none is set; (4) sets live OFF and writes every tx hash in w2-live-events.md. A failed sell sends nothing and is retried every minute; the same failure is logged only once.
    - Each command line acts once (remembered by its text). Put a time stamp on each, so a second CASH OUT is a new line.
  - **Self-test, dry (no chain, no real send), 0 failures:**
    - test_cashout.py: parsing, sell-all-then-send, no payout keeps the ETH, a failed sell sends nothing.
    - test_w2: end to end on the engine. Quoted words do nothing, PAUSE, RESUME, PAYOUT, dry CASH OUT logged with amount and address, RESUME ignored after CASH OUT.
    - On the droplet the live config and w2-live-events.md were byte-identical before and after the tests.
  - Files: w2.py md5 8f6aabbf8826a18d08d37c9f1352c43e, live.py 81c86b782d1c07c8e0b6ba8b9318ee78 (new: unwrap, send_eth, transfer_gas_eth), cmdbus.py 9bfa38f8e703cd74bdb32d16f0f1007a, scoreboard.py 758aef3c07ad2d35def6575191d9fee0.
- **17:52 Bangkok, tasks v1.33 done. Ticket capped at $100 (test), Ben's order.**
  - **Config `max_ticket_usd` = 100.** `ramp.ticket` never picks a step above it, even with $1k earned and a big wallet; the reason line reads "ticket capped at $100 (test)". It lifts only when you write "LIFT CAP".
  - **Unchanged:** kit hold exit, kill switch (drawdown over 10 x ticket, 10 losers, sell check, fill gaps), slot rule.
  - **Live card:** "Live exit: kit hold (auto revert armed). Ticket capped at $100 (test)." live_status.json 17:49 shows ticket $100 and `ticket_cap_usd` 100. Logged in w2-live-events.md.
  - **Only blocker:** the fund check. Wallet 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0 ETH and needs 0.2996 ETH (8 x $100 + gas). Once funded, live turns ON by itself.
  - **First live buy and sell** are written to w2-live-events.md the moment they happen ("FIRST LIVE BUY", "LIVE SELL", with gate time, fill time, fill vs paper, tx hashes). I watch for the first live fill every 30 minutes and ring you on it.
  - Self-tests: test_ramp adds the cap checks (0 failures); test_w2 0 failures. ramp.py md5 7f942932f7df564a62605ef3cccbb69b, w2.py 4dd5b33ee360812f7a4156615889f2ad, scoreboard.py fbd6b13655fc80a4de543e71b5041def.
- **17:22 Bangkok, tasks v1.32 done.**
  - **Yes, a self-test wrote the 17:10:33 "AUTO REVERT (K2, K1, K0)" line.** test_w2 ran on the droplet during the v1.31 deploy, and `ramp.write_event` always wrote to the live events file. The test did NOT touch the live config: it already pointed the config at a temp file, its database is a temp file, and the revert counter lives in that temp database.
    - The line is now marked "TEST, not a real revert" in w2-live-events.md, with a note under it.
    - **Right now:** `live_exit_kit_hold` = true (config, 17:12). The live table `kit_log` holds 0 rows, so the counter has 0 real kit holds. It only counts kit holds whose 5x came after `kit_hold_on_ts` (17:12:27), on real coins in the live engine; replay and test engines never count.
  - **Mechanical fix, so a test can never write a live file again:**
    - `ramp.write_event` reads its path at call time (env `W2_EVENTS`); test_w2, test_ramp and test_srctag set it to a temp file on their first line.
    - A second guard: any run whose database is not under /opt/w2coder/ (every self-test, every scratch copy) refuses to write the live events file.
    - Checked on the droplet: md5 of w2-live-events.md is the same before and after all three test files ran (0 failures each).
  - **Flow health (A1.18), new `health.py`, hourly via cron with the half C page:**
    - For every live-book coin 2 h past its gate, it reads the post-gate buys (gate to gate + 2 h, ETH-weighted).
    - Route mix: the `to` of the 60 largest buy txs (fee router, SwapRouter02, fomo router, other).
    - Fresh-wallet share: of the 12 largest signers, the share first funded under 60 min before their buy (balance search to the first-ETH block), plus the share first paid by a disperse call.
    - A daily line sits in w2-halfC.md (section "Flow health"). Two Bangkok days in a row under 25% writes an event for you.
  - **First reading (CLAUS 0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5, a test run, not stored):**
    - 67.0 ETH of post-gate buys, 100% through SwapRouter02.
    - Fresh share 0%: its 12 largest post-gate signers each bought 0.26 to 0.29 ETH. 10 of 12 were readable, and all 10 were first paid by a disperse call (0xe63d38ed) 45 to 60 h earlier.
    - Near-equal sizes from 2-day-old disperse wallets look like a pre-funded farm, not fresh retail. One coin only.
  - Files: ramp.py md5 3813c311d0ba6cd11e4a1db5f34e1975, halfc.py 2999fbf4903b1209ab48a5fc77de7c74, health.py e713c4b622126e051d6b09a0d5b2428d.
  - **Deploy note:** one package was overwritten by an older copy of the same name on the way to the droplet (caught by the md5 check). Packages now always get a new name, the same rule as the status file.
- **17:15 Bangkok, tasks v1.31 done. LIVE EXIT = KIT HOLD is ON since 17:12 (auto revert armed).**
  - **Check first (the 70 wide-list trades, sw-a2-16-wide-trades.csv, kit hold + cap):**
    - Kit tags from each pool's create tx: 16 of the 29 5x exits are kit launches (9 Kit A, 7 Kit B).
    - Each hold rebuilt from the pool's Swap logs (50% trail from the peak since entry, half-pool pull, 48 h): 12 ended on the trail; 4 Kit B holds were still running when the data ended and are counted as open to the end.
    - **Old cap (max 3 open, holds count): 4 entries skipped:** 0x0f6741982785a62e850b611cd012eb798b738037, 0x5560b76440e9b6660ab6ca8c7ae1941c92abffcf, 0x76a4c5b933c29c859fab6b3f38b540dbe7ac2aec, 0x5078092c196727b4798c5c4d583d69146bec3929.
    - **New slot rule (holds past 5x free, at most 2 on top): 1 entry skipped:** 0x76a4c5b933c29c859fab6b3f38b540dbe7ac2aec.
    - All out at 5x with the 3 cap: 0 skipped. Script /opt/w2coder/kitcap.py, output kitcap.json.
  - **Switch:** config `live_exit_kit_hold` = true. Live entries are unchanged (`w2_v3_wide_s03`). Live exits follow the `w2_v3_kit_hold` paper row: a Kit A or Kit B coin holds all at 5x; every other coin still sells at 5x.
  - **Auto revert:** each kit hold logs what selling all at 5x would have paid (table `kit_log`, real-sale quote at the 5x event) and what the hold paid. Counting from 17:12, if the last 3 finished kit holds (paper `w2_v3_kit_hold`; live follows the same rows) all ended below the sell value, the bot sets `live_exit_kit_hold` back to false by itself, writes it in w2-live-events.md, and asks you to look. It never turns it back on by itself.
  - **Slots:** a live trade whose kit-hold row is past its 5x does not use one of the 3 slots, with at most 2 such holds free; any extra counts as a normal slot. A new buy also needs wallet ETH ≥ ticket + gas. The drawdown kill switch still marks every open trade at a real sale quote.
  - **Live card:** "Live exit: kit hold (auto revert armed)" (live_status.json 17:13). Logged in w2-live-events.md at 17:12.
  - **Self-tests (test_w2: 0 failures):** sold/held both logged; 1 or 2 worse holds keep it on; the 3rd flips it off; 4 open with 3 holds past 5x uses 2 slots; with the switch off all 4 count.
  - w2.py md5 ca2b3f0733fb8efac225f4d5a796c03c, scoreboard.py 1e68aaff9c1ea1f9d499a3c7f3c49328.
  - **Fix 17:17:** the first scoreboard build of the new label dropped the whole live card (a string-format slip, caught by the card's own guard). Fixed and checked: the scoreboard now shows "Live exit: kit hold (auto revert armed)" and the Target $2,000 card.
- **17:06 Bangkok, tasks v1.30 done. Half C scorecard is live: http://159.223.88.168/hx-c9ois/sw/w2-halfC.md (+ `.json`).**
  - **Counts only gates and trades from 7 Oct 00:00 Bangkok on.** Books: live config `w2_v3_wide_s03`, `w2_v3_kit_hold`, `w2_v3_750k`, `w2_v3_regime`, `w2_v3_wide_ladder`, `w2_v3_nostop`, `w2_v3_s03`.
  - **Per book:** trades, closed, open, mean x (closed trades' real-sale quote at the exit block), $ a day at $1k, worst day, max drawdown (open trades included), open trades at a real-sale quote now. The header also counts the $1M and $750k gates.
  - **Under each book, one line for halves A / B** with the same columns, and the source of each number:
    - wide_s03 and s03: replay pass 2, $1k real swaps (2.14x / 2.04x).
    - kit_hold: Virality V8 at $1k (2.41x / 3.06x, $3,638 / $7,546 a day).
    - 750k: A2.16 grid cell (2.06x / 1.75x; $ a day is its $500 column x 2).
    - wide_ladder: replay pass 2 (2.01x / 1.42x, half B biased low).
    - regime and nostop: no per-half number exists, shown as n/a.
  - **Refresh:** cron at minute 3 of every hour. The 5-minute self-heal guard (w2guard.py) rebuilds it if it is over 2 h old, so it has two paths.
  - **Ring:** when `w2_v3_kit_hold` or `w2_v3_750k` reaches 10 closed half C trades, the script writes one event in w2-live-events.md, once per book. I ring you on it.
  - Tested on a toy database (open trades, a hold, drawdown with an open position). Files: halfc.py md5 df473d74dc8361c65120d177bdd5589a, w2guard.py a93f3850361bf63b6a895e13d88be7ff.
- **17:01 Bangkok, tasks v1.29 done. Two new PAPER books running since 16:59; live is unchanged (`w2_v3_wide_s03`).**
  - **`w2_v3_kit_hold`:** same entries and exits as `w2_v3_wide_s03`, except at the 5x hit. If the coin's `kit` (from its pool create tx, known before the gate, table `pool_src`) is A or B, it holds the WHOLE position and sells on a 50% drop from the peak since entry, a half-pool pull, or 48 h after entry. Any other kit, or no tag, sells all at 5x.
  - **`w2_v3_750k`:** its own gate, fired when $20k is bought at $750k+ market cap. Age ≤ 3 h, top receiver ≤ 0.10 (by buy count), army ≤ 0.015, token born ≤ 72 h before its first trade, sell check. Exits as `w2_v3_wide_s03`. It has its own table `coins750` and never touches the $1M gate, so a coin can be in both books.
  - **Prepared, OFF:** config `live_exit_kit_hold` (false). Set to true, live exits follow the `w2_v3_kit_hold` paper row instead of `w2_v3_wide_s03` (entries unchanged). It flips only when you write "LIVE EXIT = KIT HOLD" in the tasks file.
  - **Scoreboard:** a new card "New paper books (v1.29)" shows trades, closed, average x, $ a day at $1k for both books, and trades a day of the $750k book vs the $1M live-config book. Also in w2-scoreboard.json under `v129`.
  - **Self-tests (test_w2: 0 failures):** no kit tag sells all at 5x; a Kit B coin holds all at 5x, then sells on the 50% trail while the live book sold at 5x; the $750k gate passes at an $800k cap while the $1M gate does not fire; the 750k book opens alone and stops at 0.3x.
  - The army read was moved into one shared function (same math) so both gates use it.
  - **Live since 16:59:** w2.py md5 895c54b43d365f50b1b8198df98de1d8, scoreboard.py 0c4f0222bb82d3541727bb962af3add7. Logged in w2-live-events.md.
- **16:38 Bangkok: GO-LIVE CHECK 2 IS GREEN. All three go-live checks are green. The only blocker left is funding.**
  - **Replay pass 2 done (16:29):** every gap over 0.05x has a written cause (4 gaps, 0 unexplained).
  - **Live book `w2_v3_wide_s03` on end-of-block real swaps:**
    - at $1k: half A 2.14x (27 trades), half B 2.04x (30). Both are over 1.5x, so v1.22 (b) is met.
    - at $500: 2.20x / 2.09x. `w2_v3_s03` at $1k is the same (2.14x / 2.04x), because on these 57 main-rule coins the wide gate and the main gate agree.
  - **Other books on the same 57:**
    - `w2_v3_wide` (no stop) 2.14x (2.20 / 2.09).
    - `w2_v3_wide_ladder` 1.73x on 52 (2.01 / 1.42). The ladder's kept halves on the last coins of the tape had no full 48 h trail left before the replay ended, so its half B is biased low.
  - **The bot read it by itself:** live_status.json at 16:36 shows all three checks green. Logged in w2-live-events.md at 16:37.
  - **Blocker now:** the fund check only. Wallet 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 holds 0 ETH; it needs 0.30 ETH for $100 trades, 1.48 ETH for $500, 2.95 ETH for $1k. The moment it is funded, live turns ON by itself (Ben said GO RAMP) at the size the wallet supports.
  - Files: http://159.223.88.168/hx-c9ois/sw/w2-replay58.csv (pass 2 columns), /opt/w2coder/replay_check.json.
- **16:27 Bangkok, tasks v1.28 done. Tracking only, no size tilt.**
  - **New columns on every coin row and every trade row:** `min_to_gate` (minutes from pool creation to the gate) and `gate_hour` (hour of the gate, Bangkok).
  - Existing rows backfilled. CLAUS: 29.7 min, hour 13. Trade rows get the coin's values at entry.
  - Self-test added; test_w2 has 0 failures. Live since 16:26 (w2.py md5 c4f7f5ac2029c4cab80e7e21942b7815).
  - Replay pass 2 is at coin 51 of 58. Check 2 (b) is judged by itself when it finishes (about 16:35), then I ring.
- **16:24 Bangkok, tasks v1.27 done. `farm_funded` is live, tracking only.**
  - **Columns on every coin and trade row:** `farm_funded` and `farm_funded_n` (for example "2 of 8 sampled single-buy wallets first funded by 0x84157 (4 unreadable)").
  - **How:** at each gate the tagger thread takes up to 12 single-buy pre-gate wallets (exactly one buy before the gate, hubs and routers out, largest first). For each wallet it finds the first block where the wallet held ETH or had sent a tx, a test that never flips back. It then reads that block's tx naming the wallet. The wallet counts when that tx is sent to or from 0x84157d3d24630c297849c84d49ae7f1805c1b60f (disperse selector 0xe63d38ed). `farm_funded` = 1 when more than half of the readable wallets count. Results are cached per wallet (table `first_eth`).
  - **Limit:** this node has no call traces, so a wallet paid inside a contract call that does not name it counts as "not 0x84157". The public node also refuses some old state reads even after 4 tries; those wallets are reported as "unreadable" and left out of the share.
  - **CLAUS 0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5: farm_funded = 0** (2 of 8 readable).
    - 6 of its single-buy wallets are the 0.01 ETH bundle wallets, paid at block 81416581 through 0x8876789976decbfcbbbe364623c63652db8c0904 (selector 0x24856bc3).
    - 2 wallets were first funded by the 0x84157 disperse (blocks 79347585 and 79798751): 0x00f3585033514132fd57b3cb92e4a137e57c326c and 0xc86ce6d87c36dd20ee5851fc8ff7b8c5e6d1c614.
    - So the 0x84157 farm is real, and on CLAUS the dev's own bundle came through the other contract.
  - **Self-tests (test_srctag):** 0 failures. Covers the single-buy pick, 2 of 3 = 1, 1 of 3 = 0, and the trade row carrying the tag.
  - **Live since 16:21:** w2.py md5 530d161a69cded39052e3c53a03ff201, srctag.py ba86c380b21d2ac085a0c24fcd2db97c.
- **16:17 Bangkok, tasks v1.26 done. Kill switch fixed.**
  - **The 50% wallet rule is gone.** New live buys now stop when the running drawdown from the live peak is over 10 x the current ticket. The drawdown counts closed live trades plus open ones at a real sale quote. It is checked every minute and after every live sell, and shown in live_status.json (`drawdown_usd`, `drawdown_stop_usd`).
  - **Kept:** 10 losers in a row, a failed sell check on a held coin, two fills over 10% worse than paper, max 3 open.
  - **Size from the wallet:** need = 8 x ticket + 0.005 ETH. The ticket is the largest earned ramp step the wallet covers; steps and fill checks are unchanged.
  - **Live card:** now reads "Wallet supports up to $X a trade" ("$0, not funded yet" today).
  - **Self-tests pass:** a -4.7 ticket dip keeps trading; -10.1 tickets stops; a wallet of 8.2 x $500 picks $500, not $1k (test_ramp, test_w2: 0 failures).
  - **Live since 16:14:** w2.py md5 a6e36fa42b9625d2be0443337ce774b1, ramp.py e02c37935aed5bc493a367982ad5650b. Logged in w2-live-events.md.
  - **New wallet needs at ETH about $2,715:** $100 a trade = 0.30 ETH, $500 = 1.48 ETH, $1k = 2.95 ETH.
- **16:13 Bangkok, tasks v1.25 done. Go-live check 3 is GREEN.**
  - **Check 3** is now "one real gate filled within 30 s of the gate". CLAUS filled 20.6 s after its gate, so check 3 is green (live_status.json, 16:12). Logged in w2-live-events.md.
  - **Fill delay guard:** if the median gate to fill of the last 10 live trades goes over 45 s, new live buys stop by themselves (a blocker in the go-live list) and an event line asks you to look. The bot cannot ring you itself; my safety checks read that event and ring you.
  - **Cross-window guard (new `fwguard.py`):** before every live buy the bot reads the first window's open positions in two ways and takes the larger:
    - (a) their published state /opt/launchwatch/pub/hx-c9ois/fw/mc5live.txt (wallets on the first line, the "Open:" section, the size on the Config line, and any coin row with status open);
    - (b) the chain: the token balance of every first-window wallet, valued at a real sale quote.
  - **If they hold the coin:** our ticket = $1k minus their open cost (skipped under $20). On a live exit, if they still hold the coin, ours waits one new block before it is sent.
  - **Every trade row** (paper and live) logs `fw_overlap` (JSON: fw_holds, fw_cost_usd, fw_tokens, wallets read, state file age).
  - First-window wallet today: 0x0184ef9b23476ed84107cc5e15485a4a7ee6b286 (their test wallet, LIVE OFF, Open: none).
  - Self-tests: 0 failures (test_ramp adds 8 checks: 20.6 s passes, 31 s blocks, median stop, state file parse, $1k cap across both windows). Live since 16:11 (w2.py md5 25974226dfc0a044699716e5e377a186, ramp.py 8499810ba706917a3c105161057a1e18, fwguard.py 82f49d75007932f6f385fad9c58cffb2).
  - **Go-live blockers now:** check 2 (b) (replay pass 2 at coin 38 of 58), and funding (wallet 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 has 0 ETH; it needs 0.1156 ETH for $100).
- **16:10 Bangkok, tasks v1.24 done. Source tags are TRACKING ONLY: no skip, no rep1_pre skip.**
  - **New tags on every coin row and every trade row:** `kit` (A, B, pm, other), `funder_84157`, `farm_0x3393`, `kitb_bundle_share`.
  - **How:** a tagger thread reads each new WETH pool's create tx the moment it appears. The kit comes from the `to` address (position manager 0x73991a25c818bf1f1128deaab1492d45638de0d3 = pm) or the keccak of that contract's bytecode (0e81be52d5cf = A, 89885b75fd29 = B).
  - **Funding (Kit A and B only):** binary search on the deployer balance finds its first funding tx. This has to happen at launch, because the node keeps account state for only about 5,000 blocks. Fallback is a 150-block scan.
  - **Bundle wallets:** every other address paid in that same funding tx. `kitb_bundle_share` = their share of the pre-gate buy ETH (resolved buyers).
  - **Cost:** public RPC first, so no paid credits. Self-test `test_srctag.py`: 0 failures. Live since 16:06 (w2.py md5 820fe06af6aa139edc0989c6505fb19e, srctag.py md5 ab3309a083193750d3c5eb02df118a92).
  - **Scoreboard:** new line under the header, "Coin source last 24 h: Kit B n / Kit A n / pm n / other n". The same counts are in w2-scoreboard.json under `coin_source_24h`.
  - **First real result, CLAUS 0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5:**
    - Kit B (hash 89885b75fd29 confirmed).
    - **Funded NOT by 0x84157d3d24630c297849c84d49ae7f1805c1b60f.** Funding tx 0x2a3b8bb79d9de89ee6a0a21346c014641913f6026611676382c74dc7cd7e9bed, block 81416581, 24 blocks (2 s) before launch.
    - That tx was sent by a fresh wallet (nonce 0), 0xdef8394528c6f8bcf878d957a3e890b7bfe615a2, to the router-style contract 0x8876789976decbfcbbbe364623c63652db8c0904 (24,546 bytes, one wrap command then 10 ETH transfers).
    - 0x84157 is not in its calldata, and the node has no call traces, so `funder_84157` = 0 here. Its funding tx is stored in `pool_src` (fund_tx, fund_from, fund_to) so either route stays visible.
    - 10 bundle wallets were paid in that tx. They bought **7.6%** of pre-gate ETH on CLAUS (A1 saw 26% to 38% on 4 other Kit B coins).
- **15:59 Bangkok, tasks v1.23 done. Regime book is paper only; it is NOT wired to live.**
  - **Every 5x hit of `w2_v3_regime` is now logged** (new table `regime_log` in w2.db and a REGIME line in w2.log): prior_hold_share, n, the decision (hold or sell), the sold-at-5x value of the WHOLE position, and the held value.
  - **The result both ways:** sold at 5x is priced at the hit. Held is priced when the trail ends. On a "hold" the book's own trade gives it; on a "sell" a shadow trail (same 50% from peak / pull / 48 h) runs on the whole position. Plus = the decision paid.
  - **Scoreboard card "Regime book: hold or sell at 5x (paper only)":** 5x hits, running $ difference (decision vs the other way), switches back to sell, wrong holds, and the last 12 hits. The same numbers go in w2-scoreboard.json under `regime`.
  - Your go-live rule for it (one switch back to sell, costing about 3 wrong holds or less) can be read straight off that card. Self-tests 0 failures. Live since 15:57 (w2.py md5 ecf81a3adcf62d31afef5602bee7953f).
  - Replay pass 2 still running; check 2 (b) result comes when it ends.
- **15:54 Bangkok, tasks v1.22 done.**
  - **Check 2 yardstick:** the code already judges it your way: (a) no gap over 0.05x without a written cause (met: 0 unexplained), (b) live book `w2_v3_wide_s03` on end-of-block real swaps at $1k is 1.5x or better in BOTH halves (from replay pass 2, done about 16:30). It flips green by itself; I log it and ring. If (b) fails I ring with the numbers.
  - **Every live stop now logs the gap:** trigger cap multiple (the paper row's cap when it fired), our real fill multiple, and the gap, in the trade row (`trigger_cm`) and in w2-live-events.md. Gapping stops stay in every money number.
  - **New PAPER book `w2_v3_regime`** (V7): live gate and 0.3x stop. At the 5x hit it computes prior_hold_share = share of the last 4 days' resolved 5x trades where holding beat selling; 0.3 or more: keep ALL on a 50% trail from peak (or pull, or 48 h); else sell all; no resolved trades: sell all. "Resolved" = the trail fully closed. The trail outcome of each 5x hit is read from `w2_v3_wide_ladder` (same gate, same 0.3x stop, its kept half rides exactly that trail), so the regime book always has a counterfactual even on hits it sold. Own scoreboard card, never merged. Self-tests: no history sells all; 1 win of 2 closed (open slice and 5-day-old trade ignored) = 0.5; a fresh 5x hit then keeps all on the trail. Live since 15:53.
- **15:53 Bangkok, tasks v1.21 done (pass 2 rerunning with the live-book pricing, about 16:30).**
  - **1. Gaps over 0.05x, causes written** (`/opt/w2coder/replay_explained.json`, 26 entries, read from the replay tape):
    - 0x978177408c2f741c24ddf5ea9eb14cecbf9b3926: CONFIRMED, the out-of-range 1-tick burn (v1.7); A2 calls it a pull, my in-range rule and A3 do not; target 4.81x.
    - 0xa2508b15ab16826c720631b9afa0a90c453ae8a4: **mine is true.** The stop swap (0.593x) is the last swap in its block, the next swap is 8 blocks later at 0.600x; a real sale there gives 0.573x (A3 0.574x). The stop saves us on this coin; A2's 0.027x prices a later crash.
    - 0xc38c332012a9116dcade0c7f43b5d3c71799a9f8 and 0xba1a2d9783ebe2b76493c5c12eb9813a0e062843: entry state, as you expected. Same 5x exit swap (one buy each); my entry cap is the pool at my fill block.
    - 0x224a794031d54e49b46919ade2c55ff255dfdd97: not traded, receiver 8.3% knife-edge.
  - **2. Stops that gap on real swaps (the important one):** all three are the same thing: **a sell cascade inside ONE block.** Many separate sells through SwapRouter02 `0xcaf681a66d020601342297493863e78c959e5cb2`, one after another in a single block; our 0.6x trigger swap sits in the middle, and our own sell can only land in the next block, after the cascade:
    - 0xf5a9da666eb257c0859b47efe8c2cb6745baff94: block 80503986, 119 sells, 12.5 ETH, 0.92x to 0.59x (trigger) to 0.105x at block end; real 0.10x.
    - 0x89262fb9d6b05de797c99a927994f7c2411469d4: block 75156154, 18 sells, 8.1 ETH, 0.67x to 0.59x to 0.155x; real 0.15x.
    - 0x2a6efa703d8f1f06da07d1960711f02b1ba66f10: block 75017642, 81 sells, 10.7 ETH, 0.95x to 0.59x to 0.38x; real 0.37x.
    - No pull and no burn in any of the three blocks. 3 of 33 stops are like this; the other 30 end their block within 0.1x of the trigger. **No price stop can save these** (live gets the same block-end price); the 0.3x stop would not help either (two of the three end the block at or under 0.3x). The R model at the trigger flatters them; the real-swap pricing is the honest number.
  - **3. Pass 2** prices the live book `w2_v3_wide_s03` and `w2_v3_s03` on real swaps at $500 and $1k (CSV columns real_wide_s03_500, real_wide_s03_1000, R_wide_s03_1000, real_s03_1000, plus a per-half summary line).
  - **4. Topic check: ok.** At start both services recompute keccak of every signature they filter on and refuse to start on a mismatch. Logged 15:50: w2coder Swap, Mint, Burn, PoolCreated, Transfer; w1hot Initialize, Swap, ModifyLiquidity. A wrong hash test stops the service (self-test).
  - **Go-live check 2 now uses your v1.21 rule** and flips green by itself when (a) no gap over 0.05x lacks a cause and (b) pass 2 real-swap wide_s03 at $1k is 1.5x or better in both halves. I log and ring when it does.
- **15:49 Bangkok, replay of the 58 done (pass 1). Go-live check 2 is RED as written; I need your call on the yardstick.**
  - **Result:** 57 of 58 traded (the 58th is a knife-edge: top receiver 8.3% vs the 0.08 cap), same exit reason as the backtest on 56 of 57, main rule 2.02x (halves 2.11x / 1.94x). Books on the same 57: 0.3x stop 2.16x (2.22 / 2.11), no stop 2.14x, 0.6x 2.02x. Full block below and http://159.223.88.168/hx-c9ois/sw/w2-replay58.csv.
  - **Check 2 as written (my real-swap quote vs A2 tick walk, within 0.02x on 55+):** 32 of 57. Every one of the 26 gaps is explained in `/opt/w2coder/replay_explained.json` (0 unexplained), but explaining does not raise the count, so the gate stays red.
  - **Why the real-swap quote misses:** it is quoted on the END state of the exit block. When the coin crashes or spikes further inside that same block (common at a 5x cross or a stop), the quote moves (worst: real 0.102x vs R 0.571x). The R model at the trigger event matches the analysts much better.
  - **Same 58 on the R model:** within 0.02x of A2 on 45, of A3 on 49, of either on 51. The other 7: six are 5x exits 0.5% to 2.2% apart (which swap counts as the 5x cross), one is the knife-edge coin. On 0xa2508b15ab16826c720631b9afa0a90c453ae8a4 A2 is the outlier (A2 0.027x; mine 0.573x and A3 0.574x agree).
  - Pass 2 (adds wide, wide_s03, wide_ladder) is running, done about 16:15.
- **15:35 Bangkok, tasks v1.20 done: ramp capped at $1k (target $2k a day).** Ramp is now $100 x10, $500 x10, then $1k and stay there (config `ramp_steps_usd: [100, 500, 1000]` and code default). Wallet need at $1k: 3 x $1k + 0.005 ETH = about 1.12 ETH (shown in ETH on the scoreboard live card). New scoreboard card "Target $2,000 a day": live $ today, live 7 day average a day, paper line at the current size (worse half), each green at or above $2,000, red below. Logged in w2-live-events.md. Self-tests updated (cap holds after 100 trades; short wallet stays at $500). Also fixed a test that could overwrite the real live_status.json.
- **15:31 Bangkok, tasks v1.19 done.**
  - PAPER book `w2_v3_wide_ladder` live: same gate and 0.3x stop as the live book; at 5x sells 50%, the other 50% sells on a 50% drop from its peak, a half-pool pull, or 48 h. Own scoreboard card, never merged. Self-tests: 50% sold at 5.2x; 2.9x still held (above half of the 5.2x peak); 2.55x sold on the trail. Included in replay pass 2 (starts by itself after pass 1).
  - **Log fix:** the 15:24:56 line in w2-live-events.md was rewritten at 15:27 with the dollar amounts intact ($1M, $100, $500, $1k, $2k, $3k); events are now written from a script file, not a shell string.
- **15:26 Bangkok, tasks v1.18 done: live = wide + s03, ramp v2.**
  - New PAPER book `w2_v3_wide_s03` = the live config: wide gate ($1M sellable, top receiver 0.08, age up to 3 h, army up to 0.015, sell check must pass) + 0.3x stop set (5x, 0.3x, in-range half-pool pull, 12 h). Config `live_entry_book` and `live_exit_book` both point at it. `w2_v3_1m`, `w2_v3_nostop`, `w2_v3_s03`, `w2_v3_wide` stay paper. Re-entry is never live (live only buys on gate entries of the live book).
  - **Ramp v2:** $100 x10, $500 x10, $1k x10, $2k x10, then $3k. A step is earned when 10 trades at that size averaged live fills within 5% of paper. The wallet must cover 3 x size + 0.005 ETH; if it does not, the bot stays at the largest size it covers and keeps trading. Hard cap $3k (no $5k in code; that needs 50 trades at 1.5x and your yes). Self-tests cover each step, the cap and the wallet fallback. Kill switch unchanged.
  - **Scoreboard live card:** ramp step, ticket, next step and its wallet need in ETH, live $ a day vs the A2.18 paper line at that size. Right now: step 1 of 5, $100, next step $500 needs 0.558 ETH; paper line $299 to $454 a day.
  - Logged in http://159.223.88.168/hx-c9ois/sw/w2-live-events.md.
- **15:12 Bangkok, tasks v1.17 done: live exit = s03.** Config `live_exit_book: w2_v3_s03` set (engine re-reads config every loop, no restart). Live trades now sell when the `w2_v3_s03` paper row sells: 5x target, 0.3x stop, half-pool pull, 12 h. Kill switch unchanged. `w2_v3_1m` (0.6x) and `w2_v3_nostop` keep running as paper books. Logged in http://159.223.88.168/hx-c9ois/sw/w2-live-events.md.
- **15:13 Bangkok, tasks v1.16 done:** PAPER book `w2_v3_wide` live since 15:12, own scoreboard card. Gate: same $1M sellable and top receiver 0.08 as main, age up to 3 h, army up to 0.015 (only those two may fail, sell check must pass), exits = no-stop set (5x, half-pool pull on in-range R, 12 h). A main-rule pass also opens a wide row. Self-tests: army 1.23% opens wide only; army 2.44% opens nothing; age 2 h opens age3h + wide, never main.
  - **Replay:** pass 1 (all books but wide) is at coin 23 of 58 and is slow (about 30 s a coin on the paid node), done about 15:30. Pass 2 with the wide book starts by itself right after and overwrites w2-replay58.csv about 16:05 (pass 1 kept as replay58_pass1.json). Go-live check 2 is judged on pass 1 as soon as it lands.
- **15:01 Bangkok, tasks v1.15 done:** kill switch now trips at **10 losers in a row** (was 6), config `kill_losers: 10` plus the code default; self-tests: 9 in a row keeps trading, 10 stops. Failed sell check on a held coin, live fill over 10% worse than paper twice, wallet under 50% and max 3 open: unchanged. Scoreboard text updated.
- **14:58 Bangkok, tasks v1.14 done.** Two new PAPER books on the same gate and entry as `w2_v3_1m`: `w2_v3_nostop` (5x, half-pool pull on in-range R, 12 h, no price stop) and `w2_v3_s03` (same plus a 0.3x stop). Live since 14:57, own scoreboard cards, never merged. Self-tests: at 0.59x both stay open while the 0.6x books stop; at 0.29x the 0.3x book stops and the no-stop book holds.
  - **Live switch prepared, NOT flipped:** live exits now follow the paper row of the book named in config `live_exit_book`, today `w2_v3_1m` (0.6x stop). For v1.15 it is one config line (`w2_v3_nostop` or `w2_v3_s03`), no restart needed (config is re-read every loop). Kill switch unchanged.
  - **replay58 now carries every book:** CSV columns nostop_reason, nostop_mult, s03_reason, s03_mult, hold_mult, rep_mult, plus one summary line per book with both halves. Replay restarted 14:56 to include them, about 15 min.
- **14:56 Bangkok, tasks v1.13 done.**
  - **Army self-exclusion: checked.** The live check and the replay already skipped the coin's own pool, but not another pool of the SAME token. Now memory, study set and hubs all exclude by token (`memcoin.tok`), in the gate and in the re-entry check; rep1 memory excludes every pool of the token too. Two new self-tests: own-token memory in another pool gives army 0; the same wallets through a different earlier coin still count (control, army 10%). Live since 14:50.
  - **Buy path faster:** the live buy now goes FIRST (the gate's sell check passed seconds before), the paper fill is simulated right after and written onto the live row as live vs paper. Cut 4 calls off the live buy (no balance reads before or after: tokens come from our own receipt's Transfer logs; wallet balance comes from the minute check; gas price cached 30 s); receipt polled every 0.25 s. The router simulation before sending stays. Exits untouched.
  - **Replay bug found and fixed (it would have failed check 2):** the replay read token supply at an old block through the public RPC; some public nodes have pruned that state, the read came back empty, market cap became 0 and the gate silently never fired (coins 3 to 6 showed "no gate" at 14:47). Replay reads now go to the paid node (archive, checked at blocks 76M, 78M, 81M) with a "latest" fallback that is counted and reported. Wallet memory backfill finished (268 memory coins). Replay restarted 14:53, about 15 min, then the report compares with BOTH Analyst 2 (tick walk, go-live check 2) and Analyst 3 (A3.1 trade list). Knife-edge coins (top share within 0.005 of 0.08, army within 0.001 of 0.009, stop missed by about 1%) are listed as explained, not failures.
- **14:27 Bangkok, tasks v1.12 done: live wallet made on the droplet.** Address (public, full): **0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3**. Key made inside one python process straight into `/opt/w2coder/secret/live_key.json` (file 600, folder 700), never printed, logged or copied; the trader loads it (checked by address match only). Balance now 0 ETH. The scoreboard "Live money" card now shows the fund check next to the other two checks (red: needs 0.1142 ETH for 3 open $100 trades plus gas). Goes live by itself once funded and the other 2 checks are green.
- **14:22 Bangkok, tasks v1.9, v1.10 and v1.11 done. Live ramp is built and ARMED; it is OFF only because 3 go-live items are still red (list below).**
  - **Live state, always current:** http://159.223.88.168/hx-c9ois/sw/w2-live-events.md (one line per live buy, sell, ramp step, kill switch, ON/OFF; it is on the bus) and the "Live money" card on the scoreboard (each check green or red, refreshed every minute).
  - **Go-live checks now:** (1) entry cap at our fill: GREEN. (2) replay58 within 0.02x on 55+ of 58, every gap explained: RED, replay not finished (wallet memory backfill at block 78.1M of 81.4M, about 40 min left, then the replay runs by itself and writes `replay_check.json`; any gap I explain goes in `replay_explained.json`). (3) one real gate filled in 6 s or less: RED, only gate so far is CLAUS at 20.6 s (before the v1.8 paid RPC). Also blocking: **no key file** (see Needs Ben).
  - **Ramp (main rule `w2_v3_1m` only, one buy):** $100 for the first 10 live trades; $500 when live fills average within 5% of the paper fill; $1,000 after 30 trades with a live result of 1.5x or more. Max 3 open live trades. Before every live buy: fund check (ETH + WETH covers 3 open trades of the current ticket plus 0.003 ETH gas), the paper round trip at the fill block must show a clean sell (cost under 10%), the router call is simulated before it is sent. Pays with ETH, or with the WETH that earlier sells left in the wallet.
  - **Kill switch (automatic, holds until you or Ben clear it):** 10 losers in a row (v1.15); sell check fails on a held coin (that coin is sold at once); live fill worse than paper by more than 10% twice in a row; wallet (ETH + WETH + open positions at a real sale quote) under 50% of the value at go-live. Stops new live buys only; open live trades still exit by the rule. Also sent to Ben through alertgate.
  - **Every live trade logs:** gate time, fill time, gate to fill seconds, live fill vs paper fill, entry cap at our fill, exit reason, ETH out, result in x and in dollars, tx hashes (table `trades`, book `w2_v3_live`, and the events file).
  - Variants (`w2_v3_age3h`, `w2_v3_reentry`, `w2_v3_rep`) stay paper; all books are on the scoreboard with trade count and result.
- **14:20 Bangkok, tasks v1.9 item 1, entry cap bug (A2.11) fixed, paper and live:**
  - **Cause:** the feed pauses while a gate runs (about 20 s for CLAUS), so the pool state in memory was still the gate swap when the paper buy filled. Entry cap = that stale cap = the gate cap.
  - **Fix:** at the fill the engine reads the pool (price, liquidity) at the same block it simulates our buy on; entry cap, R for the pull guard and the "price moved between gate and fill" number all come from that read. Live: entry cap = pool state at the end of the block before our buy lands. Also fixed a second bug it hid: a swap read late from BEFORE our fill could trigger an exit; now ignored. Self-tests added (CLAUS numbers). Live since 14:20.
  - **CLAUS `0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5` recomputed:** fill state = $956,288 cap (last swap before our fill; our own fill price sits +0.98% above it, the R model says +0.97% for $495 on R $50.8k, so this is the right state). Stored cap was $1,144,067 (the gate). Analyst 2's $898,197 is the swap 1.2 s after our fill (block 81433936, $897,906), I think. New stop line $573,773. Peak after fill 1.19x. **Still a stop**, at 13:55:31 Bangkok, 0.587x of the fill cap. Value 0.566x (R model on that exit swap's real price and liquidity; the node no longer serves state that old, so no real-sale quote). Old row said stop 0.622x. Both the 1m and hold rows updated.
  - **Re-entry watch:** now armed at the fill cap ($956k, not $1.14M) until 19:55 Bangkok. Since the stop the cap topped out at $711k, so no re-entry yet under either cap.
- **14:20 Bangkok, tasks v1.9 item 2, `rep1_pre` + `w2_v3_rep` (A1.11) live:**
  - Every v3 gate logs `rep1_pre`, `rep1_n` (repeat wallets), `rep1_mem` (gated coins in memory) in `coins`. Walk-forward: only gated coins whose gate came before this gate. Router buys are followed through token transfers up to 3 hops (SwapRouter02, hubs, and any address that forwarded 90%+ of what it got before the gate); still a router after 3 hops = left out of both sides.
  - Paper variant `w2_v3_rep` = main rule plus skip if rep1_pre > 5%. Tagged rows, own scoreboard card, main book unchanged.
  - **Memory is thin today:** my gated-coin memory starts at 13:04 (1 coin, CLAUS, 830 resolved pre-gate buyers). The replay of the 58 now logs rep1_pre per trade too (walk-forward over the earlier of the 58), new columns in w2-replay58.csv.
- **14:05 Bangkok, tasks v1.8 done:**
  - **Engine on paid dRPC first** (public RPC only as fallback), own daily budget file and cap 150k calls; backfills keep their separate budget. Measured 0.26 s per call vs 1.4 s public, so a gate's handful of calls now costs about 1 to 2 s instead of 7 to 10 s. Gate to fill seconds stay on the scoreboard per trade (column "Gate to fill").
  - **Warm state:** when a coin passes $500k sellable (and is young enough to gate), its token transfers are fetched then and kept in a per-pool cache; at the $1M gate only the new blocks are fetched. The sell check stays fresh at the gate (one call, about 0.3 s), since a stale sell check is worthless.
  - **showcfg.py patched** (`/opt/common/showcfg.py`, old copy `showcfg.py.bak-v1`): masks by key name, by shape (long random strings, Telegram tokens) and inside URLs (path or query pieces that look like keys); output is first 4 characters + ****. Wallet and contract addresses stay in full. Tested on drpc_paid.json, rpc_keys.json and the watchdog config: 0 full values shown (checked by code, nothing printed).
- **14:10 Bangkok, tasks v1.7 done:**
  - **Pull guard on in-range liquidity only:** a Mint or Burn now moves active liquidity only if tickLower <= current tick < tickUpper; every Swap resets it to the Swap's own `liquidity`. Same R is used at entry. Self-test covers the 0x978177408c2f741c24ddf5ea9eb14cecbf9b3926 case (far out-of-range 1-tick burn no longer reads as a pull). Live since 14:08.
  - **Fill gap logged on every fill:** new columns `pre_fill_price`, `move_pct` (pool price move between gate and fill), `impact_pct` (our own buy), plus seconds gate to fill.
  - **CLAUS `0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5`:** the 15.6% gap was the market, not us: price fell 16.4% in the 20.6 s between gate and fill, our own impact was +1.0%. It then stopped out at 0.59x (cap) at 13:5x Bangkok.
  - **Latency gap (needs a decision):** gate to fill took 20.6 s, not the spec's 5 s. Each public RPC call costs about 1.4 s from the droplet, and a gate does several (head, logs, transfers for the army check, sell check). Fix options under "Asks for Supervisor".
  - Re-entry watches now survive a restart (rebuilt from the DB); CLAUS is being watched for a re-entry.
  - **Replay:** the wallet memory backfill is at block 73.9M of 81.4M (112 memory coins so far). The replay then runs and writes w2-replay58.csv plus a block here that compares my real-swap price with Analyst 2's tick walk on all 58 (flags any gap over 0.02x with the likely cause).
- **13:55 Bangkok:** on the bus. Doorbell created. Tasks v1.6 all done, nothing new on the list. First paper trade under the strict rule: CLAUS `0x4d8b2411255580b19a0b9fc90ed36ee15e7e1af5` (gate 13:51, $1.14M cap, age 30 min, top buyer 4.9%, army 0.02%, 82 memory coins and 57 hubs at that moment), filled 15.6% below the gate price. Wallet memory backfill at block 72.3M of 81.4M; the 58-trade replay with both pricings runs right after it and writes itself into this doc.
- **v1.6 done (13:45 Bangkok):**
  - $100 lane for crews 0x7028bab73f82dff14b199593abb76c8b6acb3aa9 and 0x2dacdf0f44d07234832799a10a7cc5c8eff0223a deleted (paper too); those coins log `skip_void_a19`; any old row is moved to book `void_a19` and kept out of every total (there were none).
  - `w1_hot` scoreboard card now leads with the pull rate (pulled within 60 s of our buy), and says paper profit is not proof.
  - Replay of the 58 now prices every trade two ways at $500 AND $2k: the R model and a real swap simulated on the archive state at the entry and exit blocks (tested on NOSH: works). Output: http://159.223.88.168/hx-c9ois/sw/w2-replay58.csv plus a summary block here.
  - **Bug found and fixed while doing it:** the exit quote ran out of gas on big token amounts (10M gas, many ticks) and returned nothing. Raised to 30M; NOSH exit now prices at 0.094 ETH (about 0.52x), in line with its 0.56x stop. Live exits use the same code, so this mattered.
- From: the 2nd Window Coder. Built to tasks v1.5 (spec A2.1 + A2.8 strict, A2.9 variants, window 1 split by crew). Everything is PAPER. Live trader built and OFF.
- **Scoreboard (phone + desktop):** http://159.223.88.168/hx-c9ois/sw/w2-scoreboard.html (data: http://159.223.88.168/hx-c9ois/sw/w2-scoreboard.json), rebuilt every 10 min.
- **Running on the droplet:** `w2coder` (v3 books), `w1hot` (C8), `w2guard` (self-heal: systemd timer every 2 min + cron every 5 min, restarts on a stale heartbeat or lag, alerts Ben only through alertgate after 3 failed restarts), `w2score` (scoreboard). Code `/opt/w2coder`.
- **Two droplet-wide problems found (need a human, they hit Price Predict too):**
  1. **Paid dRPC ran out of money at about 13:00 Bangkok and is BACK since about 13:30** (Ben topped it up). My backfills moved back onto it at 13:35 and now run about 10 times faster. PP jobs that use it should be checked for the 13:00 to 13:30 gap.
  2. **The free public RPC answers in 1.1 to 1.6 s per call from the droplet** (0.12 s from elsewhere): the box is sharing it with every service that lost dRPC. My books still work (entry within about 10 s of the gate), but backfills crawl.
- **Bug fixed that would have broken every time field:** the public RPC returns `blockTimestamp = 0x0` on logs. All times now come from real block headers (exact at anchors, linear in between, checked to within 1 s). Data collected before the fix was thrown away and rebuilt (books restarted clean at 13:04).

## Replay of the 58 strict trades (auto, 06 Oct 16:29 Bangkok)
- Target (A2.8): 58 trades, mean 1.90x, target 19, stop 34, pull 3, time 2.
- Mine: 57 of 58 traded, mean 2.02x (first half 2.11x (27), second half 1.94x (30)).
- Exit reasons: pull 2, stop 33, target 20, time 2. Same reason as the backtest on 56 of 57.
- Multiple gap per trade: median 0.005, max 4.809.
- Not traded by my engine (1): 0x224a794031d54e49b46919ade2c55ff255dfdd97 (receiver_8.3%)
- **Two pricings (v1.6), mean multiple:** $500: R model 2.10x (55), real swap 1.99x (57). $2k: R model 1.95x (55), real swap 1.85x (57).
- Per trade, both pricings and both sizes: http://159.223.88.168/hx-c9ois/sw/w2-replay58.csv
- **Live book on real swaps (v1.21):** w2_v3_wide_s03 $500: half A 2.20x (27), half B 2.09x (30); w2_v3_wide_s03 $1000: half A 2.14x (27), half B 2.04x (30); w2_v3_s03 $1000: half A 2.14x (27), half B 2.04x (30)
- Book `w2_v3_1m`: 2.02x (57); half A 2.11x (27), half B 1.94x (30)
- Book `w2_v3_nostop`: 2.14x (57); half A 2.20x (27), half B 2.09x (30)
- Book `w2_v3_s03`: 2.16x (57); half A 2.22x (27), half B 2.11x (30)
- Book `w2_v3_hold`: 1.68x (54); half A 1.89x (27), half B 1.47x (27)
- Book `w2_v3_rep`: 2.12x (48); half A 2.32x (19), half B 1.99x (29)
- Book `w2_v3_wide`: 2.14x (57); half A 2.20x (27), half B 2.09x (30)
- Book `w2_v3_wide_s03`: 2.16x (57); half A 2.22x (27), half B 2.11x (30)
- Book `w2_v3_wide_ladder`: 1.73x (52); half A 2.01x (27), half B 1.42x (25)
- **Real swap vs Analyst 2 tick walk ($500):** 57 compared, 32 agree within 0.02x, 25 do not: 0xa2508b15ab16826c720631b9afa0a90c453ae8a4 mine 0.573x vs 0.027x (stop exit); 0xf5a9da666eb257c0859b47efe8c2cb6745baff94 mine 0.102x vs 0.576x (stop exit); 0x89262fb9d6b05de797c99a927994f7c2411469d4 mine 0.150x vs 0.532x (stop exit); 0x2a6efa703d8f1f06da07d1960711f02b1ba66f10 mine 0.370x vs 0.572x (stop exit); 0x97a5d4306a99571ecce5c2448ebfad85d7a8321d mine 4.596x vs 4.785x (target exit); 0x88042d98421b4d4014910bd9ca40d3cf3a309733 mine 4.628x vs 4.766x (target exit); 0xead015725c6cc0a38cdaea04cb7933210198b830 mine 4.900x vs 5.034x (target exit); 0xc38c332012a9116dcade0c7f43b5d3c71799a9f8 mine 4.797x vs 4.907x (target exit); 0x8e41fd25e85e624560fa50ff9f117a02cd30b8b3 mine 4.889x vs 4.803x (target exit); 0x257723230c9cccf6a2df1e7cf67cffcfcf01eeb8 mine 4.844x vs 4.777x (target exit); 0xc3ba8a6f8d011881ceca8ad6e2b524232a40aa26 mine 0.500x vs 0.561x (stop exit); 0xfa1824e750f9a5bc7d253342935471b8f2709d70 mine 4.753x vs 4.811x (target exit)
  - Likely cause per spec note: a different state block (my entry/exit is the first event at or after the trigger, priced on that block's end state) or a quote near the launch floor.
- **vs Analyst 3 rebuild (A3.1, R model):** 49 of 59 agree (same exit, within 0.02x); knife-edge, explained (1): 0x224a794031d54e49b46919ade2c55ff255dfdd97 mine not traded vs A3 0.000x skip; other gaps (8): 0x978177408c2f741c24ddf5ea9eb14cecbf9b3926 mine 4.809x target vs A3 0.000x pull; 0x59b85970630dd8b808aad4257b0cdf02a8b22f90 mine 4.850x target vs A3 4.807x target; 0x0f526bdc56d1d764bd744412c1aba039c3728b76 mine 4.823x target vs A3 4.800x target; 0x6c963ce1aff02c18b2d0ef81b96df77b2f53c4ee mine 4.813x target vs A3 4.764x target; 0xba1a2d9783ebe2b76493c5c12eb9813a0e062843 mine 4.779x target vs A3 4.815x target; 0xcb142bca82c9c852ef33c5100a6f26577ad40f3c mine 1.412x time vs A3 1.386x time; 0x8cf263adfd88d72597a251908378a782a4e97aaf mine 0.574x stop vs A3 0.551x stop; 0xc38c332012a9116dcade0c7f43b5d3c71799a9f8 mine 4.797x target vs A3 4.908x target

## Task by task
| Task | State |
|---|---|
| C1 `w2_v3_1m` | LIVE paper since 13:04 (restarted clean after the time fix). All out at 5x (tasks v1.1). |
| C2 sell check | v3 and v4 versions live, run before every paper buy and every 10 min on open coins. |
| C3 split buys | built, OFF (`split_variant: false`) per v1.2. |
| C4 coin log | every gate, pass or fail, table `coins` in `w2.db`. X and crew fields stay empty until PP4/PP5 publish. |
| C5 `w2_v3_hold` | LIVE paper: 70% at 5x, 30% slice, 3x floor, ladder (new buyers last hour at least half of hour 1), pull, 7 days. |
| C1 variants (A2.9) | LIVE paper, own rows, never merged: `w2_v3_age3h` (gate at 1.54 to 3 h, same filters) and `w2_v3_reentry` (after a main-book stop: within 6 h, cap back at or above the first entry cap, 20+ new buyers since the stop, their army share 0.9% or less, one per coin). |
| C5 `w2_viral` | waiting on PP3/PP4 (fair crossings and X pull). |
| C6 live trader | built, OFF. Needs all three: `live_enabled: true`, a key file (chmod 600), C2 pass. SwapRouter02 `0xcaf681a66d020601342297493863e78c959e5cb2` verified by simulation. |
| C7 scoreboard | live, phone and desktop checked (no sideways scroll at 390 px). |
| C8 `w1_hot` | LIVE paper, rebuilt to v1.5 at 13:21. History backfill from 30 Sep running (750 pond launches). |
| Replay of the 58 strict trades | queued right after the wallet memory backfill (13 Sep to now). Result: this doc and `/opt/w2coder/replay58.json`. |

## C2 sell check
- One `eth_call` with a state override: helper code (never deployed) buys our size from the pool, then sells every token back. Token rules run for real, so honeypots and taxes show.
- Blocks the coin if the buy or sell reverts, the buy gives 0 tokens, or the round trip costs over 10%. Reason logged.
- v3 test on 28 live pools: 24 pass (cost 0.02% on 0.01% pools, 1.9% on 1% pools), 1 honeypot caught (`0xe31c757461c05c0a0ccb929b313f1a315146bd23`, revert "salg spaerret"), 3 empty pools caught.
- v4 test on 8 live native-ETH pools: 4 pass (cost = 2 x pool fee), 4 empty pools caught. About 0.12 s per check.

## C1 vs the spec (differences written down)
- As spec: gate, age (first Swap to gate swap, at most 1.54 h), token birth at most 72 h (PP `tokens.db`), receiver share by buy COUNT on Swap recipient, the $500k and $1M sellable sums.
- Army (A2.8): study set, memory and hubs only from coins whose $500k gate came before this gate; addresses counted only if touched before this gate; hubs = 20% or more of earlier coins, needs 10+; the token's own pools count as senders.
- Supply read at the gate. ETH: Coinbase spot live; replay uses the last hourly close.
- Fill and exits priced two ways, both stored: (a) the spec R model, (b) a real simulated swap of our tokens. Scoreboard shows (b). **First live gate showed why:** STONKROBBERS, R $54k said 0.9% impact, the real swap said 7.6% (concentrated liquidity is thinner at the price than the R model assumes).
- Exits checked on every pool event plus a timer.
- Feed: the books read chain logs themselves because PP1 is not up. When PP1 lands I switch the feed; nothing below it changes.

## C8 `w1_hot` (tasks v1.5)
- Pond launch only (v4, native ETH, fee 100, tick spacing 1, no hook). **c10k (the 3/5 ETH fee-10000 launches) is never traded, not even on paper.**
- Crew tag at first trade + 10 s from the funder chain (crew.db, 3 hops, must reach the creator of an earlier launch). Hot = of the crew's last 10 coins that ended before now, 5+ known and 5+ hit 3x from their 10 s price.
- **Crews 0x7028bab73f82dff14b199593abb76c8b6acb3aa9 and 0x2dacdf0f44d07234832799a10a7cc5c8eff0223a:** NOT traded (A1.9 withdrew the edge, tasks v1.6).
- **Crews A 0x92a0849f9b1e9e02363a4bd8d74a317fa6ddae92 and B/C 0x4757fc41278bd0f1b028c6dae71d381dc4558d98:** 0.0015 ETH, 10 s only, all at 2x, and **OFF until the live pull test passes** (logged as `skip_abc_waiting_live_pull_test`).
- **Other hot crews:** $20, 10 s on the tag or 35 s on the label, pull-time rule.
- Pull-time rule (crew median pull, seconds after first trade, last 10 ended coins): under 90 s all at 2x; 90 to 200 s half at 3x, rest at 10x; over 200 s all at 10x. A pulled pool pays 0. 2 h max.
- Every trade logs `pulled_60s` (pool pulled within 60 s of our buy): the live trigger chance per crew.
- Outside-buy rule: the v3 lane passed (A1.5), so its paper rows stand. Crews A and B/C failed it, so they stay off.

## Doorbell
- `trig_01DdbvEmvvqEJAc8xgZuDhka` (Doorbell: 2nd Window Coder). 30 minute safety check scheduled.

## Asks for Supervisor
- **First-window live state (v1.25):** please ask the First Window Supervisor for (1) the path of their live open-positions state, ideally a JSON file with token, pool, cost_usd and wallet per open trade, and (2) every wallet their live trader buys with. Until then the guard reads mc5live.txt plus the chain balance of 0x0184ef9b23476ed84107cc5e15485a4a7ee6b286. Its "Open:" section format is guessed (it says "none" today); a JSON file removes that guess.
- **Farm list for `farm_0x3393` (please route to Analyst 1):** the tag checks pre-gate buyers against a farm wallet set. From the blocks named in A1.14 I could only seed 5 addresses: the root, 0x03802649e469ed5680c58dff9e65425e22d21cc5, and the 3 Kit A deployers. Block 69,614,401 has no direct tx from 0x3393cab3fcfc5668b46d83b89f924c01f00aa766 (its funding is internal, and this node has no traces). Please ask Analyst 1 to publish the traced wallet list (the 5 senders, the 11 + 4 repeat wallets, and any others) as a plain text file. I load it the same minute. The tree also grows by itself: any launch funded from a farm address adds its deployer and paid wallets.
- **Kit B funder check:** CLAUS was funded through 0x8876789976decbfcbbbe364623c63652db8c0904, not 0x84157d3d24630c297849c84d49ae7f1805c1b60f. Analyst 1 may want to recheck whether 0x84157 is the funder on newer Kit B launches, or whether both routes exist.
- **Idea, your call:** the three cascade dumps all went through the same router in one block. If an analyst can tell the cascade wallets apart before the gate (same funder, same buy block), the gate could skip those coins; a stop cannot.

## Needs Ben
- **Fund this address: 0x04a057D15bd07581DC88b0a37E41EB69Ceb8C2D3 on Robinhood Chain.** **v1.33: about 0.30 ETH is all the $100 test needs** (8 x $100 + gas). More ETH does not raise the ticket until LIFT CAP. The key never leaves the droplet.

## Next
- Replay result into this doc; then explain every gap over 0.02x (go-live check 2).
- Switch feeds to PP1 / PP2 when their paths appear in sw-pp-status.md.

Version: v65, 7 Oct 2026 16:38 Bangkok, 2nd Window Coder. Latest version: http://159.223.88.168/hx-c9ois/sw/sw-coder-status.md
