{
  "notes": "EPISODE 4 (2026-11-07). STATE: r1 code wave still running (2 accepted: vol-estimate, public-replica; 11 running; NO trunk). writeups settled (github, social). theory (1), anchors2 (4), r1x (4) running. Nothing refused. DECIDED: (1) PROMOTION 1: best = YQ replica (r1/public-replica), sha256 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4, byte-identical to github.com/jiayaoqijia/amm-challenge-yq commit 3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d contracts/src/Strategy.sol (fetch via raw.githubusercontent.com at that commit: any worker can, so the best travels without a trunk). Paired vs StarterStrategy on 100000..101999: +154.69, se 0.95, n 2000, worst +74.78 (seed 101573): clears 2 se. Scores: 0..999 = 524.6271111458843 (se 2.78); 100000..101999 = 524.1942870525012 (starter 369.50130143736396). Calibration 900000..909999: pending (r2-measure/yq-calib). Round 1 (r1 + r1x) has a promotion. (2) Round 2 started as research batches (no trunk needed): 27 items in 6 batches of <=5 (no canary hold); 51 of 600 used. Every build item: toolchain first, return `blocked` with score.n 0 if the simulator cannot run (requester asked for `python3 --version` first; phrased as 'run the install and validate, fail fast' because a brief asking about the worker's machine is refused, see ep2 anchors); fetch YQ by URL + sha; tune only on 0..99999; confirm paired vs YQ on the EPISODE-4 FRESH BLOCK 400000..401999 (n 2000) inside the item; score on 0..999; result JSON per objective plus `delta` (exact edits from YQ, <=1500 chars) so a later brief can rebuild a winner as 'YQ + delta' without the trunk.\n\nR2 ITEMS (key: idea). r2-deep-a: alpha-first (first-in-step alpha up to exact reset), running-means (1/n means for sigma/lambda/size), sigma-arbs (sigma from first-print implied prices over elapsed), lambda-fix (retail intensity from non-first prints; refit LAMBDA/FLOW), tune-asym (stale/dir/boost block). r2-deep-b: tune-base (BASE/LAMBDA/FLOW/ACT block), tune-tox (tox + tail block), recenter (geometric recentering instead of additive stale shift), tune-decay (gap decay, additive decay, tox cap after silence), retail-alpha (later-print alpha and gate). r2-fresh-a: norm-spot (model the 30 bps pool's spot, undercut the attract side), phase (tight after first-in-step print, wide after later prints), arb-class (arb label by band-edge consistency), kalman (variance-tracked pHat), silence (clamp pHat into the band that stood during silent steps). r2-fresh-b: linear-cma (8-coefficient linear policy, CMA-ES), warmup (fixed pair for the first N callbacks), vol-redo (requester: r1/vol-estimate rerun, also vs starter on 100000..101999). r2-simplify: ablate (deliver minimal YQ), yq-lite (<=8 slots, 8 constants), linear-stale (5-constant linear stale model), freeze-est (sigma/lambda/size frozen at midpoints). r2-measure: yq-calib (900000..909999; 0..999 must equal 524.6271111458843), yq-replicate (vs starter on 400000..401999; 100000..101999 must equal 524.1942870525012 / 369.50130143736396: determinism check), pub-chenghua (ChengHua926 d34a5199, claims 525.81), pub-shl0k28 (9c4be0b6, claims 525.08), pub-elizabeth (7156ff03, new 2026-11 code).\n\nSCOREBOARD vs YQ (paired, n 2000, from r1/public-replica): dipankar WinningV5 -232.88 se 1.18 (seeds 2000..3999); dipankar SigmaAdaptive -5.05 se 0.04 (4000..5999) though its README claims 526.54: public claims are unreliable, only our paired numbers count. r1/vol-estimate: n 0, unmeasured (requester: never rank an n=0 item; rerun it). Board 2026-11-07 (official API, 743 entries, 1000 sims each): 528.399 @0xMai, 528.323 @Ponxter, 528.258 @KaihuaQIN, 528.206 @pxmwxd_eth, 528.099 @aaaapsouuu; 10th = 524.66. YQ's author claims 523.21 on the board vs our 524.6 local: local is within ~1.5 of the board, a calibration score near 528 is in range. Gap to close: about +4 over YQ.\n\nLEARNED (writeups/github, writeups/social; cite in the write-up): nearly every public repo is the YQ family (fee-band pHat, tox, stale asymmetry) with other parameters; nobody public is near 528. Dipankar SigmaAdaptive has bugs (sigma term divided by WAD twice; lambda observation pinned at cap). Bruno I. (rank 44, LinkedIn index only): ~95% of edge from stale-price directional protection, ~82% of cross-sim variance from arrival rate, a linear model beat regime switching. Algebra (rank 9 of 654, medium.com/@crypto_algebra): environment estimation + probabilistic first-in-step arb; no code. HackMD note has the band edges reversed. Not implemented anywhere public (round-3 fresh ideas): censored Bayesian fair-price posterior; router-censored joint lambda/size inference; closed-form expected-edge maximisation including next-step arb cost; value-of-information quoting; offline-distilled finite-horizon policy. Pinned commits: writeups/github.\n\nCARRIED FORWARD: seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs: numpy default_rng(seed) draws mean size, rate, sigma; Rust price seed = seed, retail seed = seed+1); other ranges via amm_sim_rs.run_batch with explicit seeds. Tune only on 0..99999; fresh block for episode e = e*100000..e*100000+1999 (ep5 = 500000..501999); promote only when paired mean_diff >= 2 se, n >= 2000, on the episode's fresh block vs the current best; requester's calibration set 900000..909999 is report-only, never used to choose; say when the best reaches 525/527/528 there. Simulator: 10000 steps; GBM sigma U(0.000882,0.001008) fixed per sim; arb each step leaves spot at the band edge (AMM bought X: p = spot*(1-bid); sold X: p = spot/(1-ask)); Poisson(U(0.6,1.0)) retail, lognormal mean U(19,21) Y sigma 1.2, 50/50, router splits vs fixed 30 bps AMM; fees aside; silence = no arb. Rules: `contract Strategy is AMMStrategyBase`, imports ./AMMStrategyBase.sol + ./IAMMStrategy.sol only, slots 0..31, 250000 gas, solc 0.8.24 viaIR, max fee 10%, no loops over history. Trunk plan (r1/layout) unchanged: best/, candidates/<key>/, tools/pair.py, tools/README.md; once r1 merges, a code wave item with scope [\"best/**\"] writes the promoted file from its URL or 'YQ + delta'. Never ask a worker about its machine (ep2 anchors refused). A brief is <=3000 chars (the r2 template alone ~2300): a non-public best travels as 'YQ + delta' or through the trunk. Timing: ~0.1 s per simulation per file; 2000 paired = ~7 min; 10000 sims = ~20 min.\n\nNEXT EPISODE (5): 1) Read r2-*/*. Drop items with score.n or paired.n 0 (rerun the idea later; not a failure). Scoreboard per item: paired mean_diff and se vs YQ on 400000..401999, code_sha256, score on 0..999, delta. Promote the largest mean_diff >= 2 se; if several clear, round 3's first deepen item combines them in one file, confirmed on 500000..501999. 2) yq-calib / yq-replicate: check bit-identity (524.6271111458843 on 0..999; 524.1942870525012 / 369.50130143736396 on 100000..101999); if not identical, say in every brief that absolute scores differ across machines and only in-item paired numbers count. Record YQ's calibration mean + se: the first best-file calibration number for the write-up. 3) anchors2 (vanilla/starter calibration), r1x (vs starter on 300000..301999), theory, remaining r1 items: add to the scoreboard; an r1 item beats YQ only if its diff vs starter on 100000..101999 exceeds 154.69 by 2*sqrt(se^2 + 0.95^2); re-measure promising ones vs YQ in round 3. 4) Spawn round 3 (30-40 items, batches of <=5, names r3-*): 40% deepen the new best (combine positive r2 changes; their `next` lines), 30% fresh (the 'not implemented anywhere' list), 15% simplify, 15% measure (replicate the promoted gain by another worker on 500000..501999; calibration of the new best). Fresh block 500000..501999. Same template as r2, the new best as YQ URL + delta (or its own public URL). 5) If r1 merged, use code waves only if they settle in < 3 h. Stop rule: two rounds in a row with no promotion, or episode 10 (write-up). Budget after this episode: 549 items, 6 episodes; plan 40-60 items a round from round 3.",
  "spawn": [
    {
      "name": "r2-deep-a",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge, round 2: one idea, one complete Strategy.sol, measured paired. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .`, `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm) and `amm-match validate` on the reference. If that cannot work within a few minutes, return at once with `blocked` set to the reason and score.n 0, never an untested strategy. Current best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol (sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4; 524.63 on seeds 0..999). Facts from the Rust source: 10000 steps; fair price p is a GBM, per-step sigma fixed per simulation in U(0.000882,0.001008); each step an arbitrageur trades each AMM if profitable, leaving spot exactly at the band edge under the fees quoted before that trade (AMM bought X: p = spot*(1-bidFee); sold X: p = spot/(1-askFee)); then Poisson(lambda in U(0.6,1.0)) retail orders, lognormal size (mean U(19,21) Y, sigma 1.2), 50/50 side, each split by a router between us and a fixed 30 bps AMM so marginal prices equalise; fees kept aside. isBuy = AMM buys X; timestamp = step; a gap between timestamps means no arb hit us. Seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs); amm_sim_rs.run_batch with explicit seeds for other ranges. Tune ONLY on seeds 0..99999. Confirm the final file on the fresh block 400000..401999 (n=2000) paired against YQ on identical seeds inside this item: mean and se of the per-seed differences, 5 worst seeds. Score it on seeds 0..999. Never run seeds 900000..909999. YOUR IDEA ({{key}}): {{idea}} Rules: `contract Strategy is AMMStrategyBase`, imports only ./AMMStrategyBase.sol and ./IAMMStrategy.sol, slots 0..31, <=250000 gas per call, no loops over history, max fee 10%, passes `amm-match validate`. Budget one hour in all. Result JSON: approach, tried (each variant with its tuning-seed paired diff and se), next (3 lines), code (full final .sol), code_sha256, delta (exact edits from YQ that rebuild your file, <=1500 chars), score {n, mean_edge, se, seed_start}, paired {reference: 'YQ 00fae418', seed_start: 400000, n, mean_diff, se, worst: [{seed, diff}]}, seconds_per_simulation, validate_ok, blocked (null or reason), citations.",
      "items": [
        {
          "key": "alpha-first",
          "vars": {
            "key": "alpha-first",
            "idea": "Deepen YQ: the first callback at a new timestamp is usually the arbitrage trade, whose fee-band inverse gives p exactly. Grid PHAT_ALPHA {0.26, 0.5, 0.75, 1.0} (1.0 = exact reset); for 1.0 also test widening the gate to 3*max(10*sigmaHat, 0.03). Pick on tuning seeds, confirm the one best on the fresh block. Keep everything else as YQ."
          }
        },
        {
          "key": "running-means",
          "vars": {
            "key": "running-means",
            "idea": "Deepen YQ: sigma, lambda and mean size are constant within a simulation, so EWMAs (SIGMA_DECAY 0.824, LAMBDA_DECAY 0.99, SIZE_BLEND_DECAY 0.818) keep forgetting. Replace each by a running mean (1/n weight with n in a slot, blended in after a short warm-up) for sigmaHat, lambdaHat, sizeHat; test each alone and all three together; deliver what gains."
          }
        },
        {
          "key": "sigma-arbs",
          "vars": {
            "key": "sigma-arbs",
            "idea": "Deepen YQ: sigmaHat is an EWMA of |implied return| that mixes retail impact into volatility. Estimate sigma from consecutive first-in-step implied prices only: accumulate (relative change)^2 / elapsed steps as a running variance, sigmaHat = integer sqrt. Then re-fit SIGMA_COEF and SIGMA_TOX_COEF on a 3x3 grid (the true sigma spans only 0.000882..0.001008, so the mapping may need a steeper slope)."
          }
        },
        {
          "key": "lambda-fix",
          "vars": {
            "key": "lambda-fix",
            "idea": "Deepen YQ: lambdaHat counts own fills per elapsed step, which includes arb prints and is censored by the router (a public write-up says arrival rate explains most cross-simulation variance). Estimate retail intensity from prints that are not first-in-step plus first prints whose implied move is below sigmaHat/2, as a running mean over elapsed steps; mean size from amountY on those prints. Re-fit LAMBDA_COEF (include negative values) and FLOW_SIZE_COEF on a 4x3 grid."
          }
        },
        {
          "key": "tune-asym",
          "vars": {
            "key": "tune-asym",
            "idea": "Deepen YQ: coordinate search over the asymmetry block only: STALE_DIR_COEF {5000..9000 bps}, STALE_ATTRACT_FRAC {0.9..1.4}, DIR_COEF {0..40 bps}, DIR_TOX_COEF {0..200 bps}, TRADE_TOX_BOOST {0..5000 bps}. Two passes, n=500 paired per evaluation on tuning seeds, then n=2000 fresh confirmation of the final set. Report the full sweep table in tried."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 64000
      }
    },
    {
      "name": "r2-deep-b",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge, round 2: one idea, one complete Strategy.sol, measured paired. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .`, `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm) and `amm-match validate` on the reference. If that cannot work within a few minutes, return at once with `blocked` set to the reason and score.n 0, never an untested strategy. Current best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol (sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4; 524.63 on seeds 0..999). Facts from the Rust source: 10000 steps; fair price p is a GBM, per-step sigma fixed per simulation in U(0.000882,0.001008); each step an arbitrageur trades each AMM if profitable, leaving spot exactly at the band edge under the fees quoted before that trade (AMM bought X: p = spot*(1-bidFee); sold X: p = spot/(1-askFee)); then Poisson(lambda in U(0.6,1.0)) retail orders, lognormal size (mean U(19,21) Y, sigma 1.2), 50/50 side, each split by a router between us and a fixed 30 bps AMM so marginal prices equalise; fees kept aside. isBuy = AMM buys X; timestamp = step; a gap between timestamps means no arb hit us. Seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs); amm_sim_rs.run_batch with explicit seeds for other ranges. Tune ONLY on seeds 0..99999. Confirm the final file on the fresh block 400000..401999 (n=2000) paired against YQ on identical seeds inside this item: mean and se of the per-seed differences, 5 worst seeds. Score it on seeds 0..999. Never run seeds 900000..909999. YOUR IDEA ({{key}}): {{idea}} Rules: `contract Strategy is AMMStrategyBase`, imports only ./AMMStrategyBase.sol and ./IAMMStrategy.sol, slots 0..31, <=250000 gas per call, no loops over history, max fee 10%, passes `amm-match validate`. Budget one hour in all. Result JSON: approach, tried (each variant with its tuning-seed paired diff and se), next (3 lines), code (full final .sol), code_sha256, delta (exact edits from YQ that rebuild your file, <=1500 chars), score {n, mean_edge, se, seed_start}, paired {reference: 'YQ 00fae418', seed_start: 400000, n, mean_diff, se, worst: [{seed, diff}]}, seconds_per_simulation, validate_ok, blocked (null or reason), citations.",
      "items": [
        {
          "key": "tune-base",
          "vars": {
            "key": "tune-base",
            "idea": "Deepen YQ: coordinate search over the base-fee block only: BASE_FEE {1..6 bps}, LAMBDA_COEF {0..24 bps}, FLOW_SIZE_COEF {3000..7000 bps}, ACT_COEF {50000..130000 bps}, ACT_BLEND_DECAY {0.97..0.995}. Two passes, n=500 paired per evaluation on tuning seeds, then n=2000 fresh confirmation of the final set. Report the full sweep table in tried."
          }
        },
        {
          "key": "tune-tox",
          "vars": {
            "key": "tune-tox",
            "idea": "Deepen YQ: coordinate search over the toxicity and tail block only: TOX_COEF, TOX_QUAD_COEF, TOX_CUBIC_COEF, SIGMA_TOX_COEF (each x0.5..x2), TOX_BLEND_DECAY {0.03..0.15}, TOX_DECAY {0.85..0.97}, TAIL_KNEE {300..800 bps}, TAIL_SLOPE_PROTECT and TAIL_SLOPE_ATTRACT {0.85..1.0}. Two passes, n=500 paired per evaluation on tuning seeds, then n=2000 fresh confirmation. Report the sweep table."
          }
        },
        {
          "key": "recenter",
          "vars": {
            "key": "recenter",
            "idea": "Deepen YQ: replace the additive stale shift (STALE_DIR_COEF*toxEma, x1.124 on the attract side) by exact geometric recentering: with spot = reserveY/reserveX choose fees so the band edges sit at pHat*(1-h) and pHat*(1+h): bidFee = 1 - pHat*(1-h)/spot, askFee = 1 - spot/(pHat*(1+h)), each floored at a small minimum fee; h = h0 + h1*sigmaHat + h2*toxEma on a small grid. Keep the rest of YQ."
          }
        },
        {
          "key": "tune-decay",
          "vars": {
            "key": "tune-decay",
            "idea": "Deepen YQ: the gap-decay block (DIR_DECAY 0.8, ACT_DECAY 0.7, SIZE_DECAY 0.7, TOX_DECAY 0.91, ELAPSED_CAP 8, applied once per new timestamp). Test (a) a grid on each decay and the cap, (b) additive decay (subtract a fixed amount per elapsed step, as dipankar's SigmaAdaptive does) as an alternative, (c) on a print after k>1 silent steps cap toxEma at the half-band width, since no arb hit us so |spot-p| stayed inside the band. Deliver the best combination."
          }
        },
        {
          "key": "retail-alpha",
          "vars": {
            "key": "retail-alpha",
            "idea": "Deepen YQ: later-in-step prints are retail and their fee-band inverse is a noisy fair-price observation. Grid PHAT_ALPHA_RETAIL {0, 0.02, 0.05, 0.1} and the gate GATE_SIGMA_MULT {5, 10, 20} x MIN_GATE {0.01, 0.03, 0.06}; also test updating sigmaHat only from first prints whose implied move exceeds 0.5*sigmaHat (arb-like). Pick on tuning seeds, confirm the best on the fresh block."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 64000
      }
    },
    {
      "name": "r2-fresh-a",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge, round 2: one idea, one complete Strategy.sol, measured paired. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .`, `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm) and `amm-match validate` on the reference. If that cannot work within a few minutes, return at once with `blocked` set to the reason and score.n 0, never an untested strategy. Current best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol (sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4; 524.63 on seeds 0..999). Facts from the Rust source: 10000 steps; fair price p is a GBM, per-step sigma fixed per simulation in U(0.000882,0.001008); each step an arbitrageur trades each AMM if profitable, leaving spot exactly at the band edge under the fees quoted before that trade (AMM bought X: p = spot*(1-bidFee); sold X: p = spot/(1-askFee)); then Poisson(lambda in U(0.6,1.0)) retail orders, lognormal size (mean U(19,21) Y, sigma 1.2), 50/50 side, each split by a router between us and a fixed 30 bps AMM so marginal prices equalise; fees kept aside. isBuy = AMM buys X; timestamp = step; a gap between timestamps means no arb hit us. Seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs); amm_sim_rs.run_batch with explicit seeds for other ranges. Tune ONLY on seeds 0..99999. Confirm the final file on the fresh block 400000..401999 (n=2000) paired against YQ on identical seeds inside this item: mean and se of the per-seed differences, 5 worst seeds. Score it on seeds 0..999. Never run seeds 900000..909999. YOUR IDEA ({{key}}): {{idea}} Rules: `contract Strategy is AMMStrategyBase`, imports only ./AMMStrategyBase.sol and ./IAMMStrategy.sol, slots 0..31, <=250000 gas per call, no loops over history, max fee 10%, passes `amm-match validate`. Budget one hour in all. Result JSON: approach, tried (each variant with its tuning-seed paired diff and se), next (3 lines), code (full final .sol), code_sha256, delta (exact edits from YQ that rebuild your file, <=1500 chars), score {n, mean_edge, se, seed_start}, paired {reference: 'YQ 00fae418', seed_start: 400000, n, mean_diff, se, worst: [{seed, diff}]}, seconds_per_simulation, validate_ok, blocked (null or reason), citations.",
      "items": [
        {
          "key": "norm-spot",
          "vars": {
            "key": "norm-spot",
            "idea": "Fresh mechanism on YQ's estimators: model the 30 bps competitor. Its spot stays within [p*0.997, p/0.997] and is pushed to the near edge whenever p moves 30 bps past it; track a modelled normalizer spot sN from pHat and the sign of the last implied move. Per side, if undercutting its marginal price (sN/0.997 ask, sN*0.997 bid) by a margin m still executes better than pHat for us, quote that undercut (floored); else quote YQ's protective fee. Tune m and the floor."
          }
        },
        {
          "key": "phase",
          "vars": {
            "key": "phase",
            "idea": "Fresh mechanism on YQ's estimators: quote by phase within a step. After a first-in-step print (the arb has just happened, p is known, no further arb this step) quote tight on both sides: half-spread h_fast around pHat by geometric recentering. After a later-in-step print the next callback may be the next step's arb: quote a wider band h_slow plus YQ's stale protection. Grid h_fast {5..20 bps} x h_slow {25..60 bps}; also test a third phase for prints after k>=2 silent steps."
          }
        },
        {
          "key": "arb-class",
          "vars": {
            "key": "arb-class",
            "idea": "Fresh mechanism on YQ: classify each first-in-step print as arb or retail by consistency, not size. Reconstruct the pre-trade spot from post-trade reserves and amounts (fee-aside update per amm_sim_rs/src/amm/cfmm.rs). An arb print starts outside the band around the previous pHat and lands exactly on the new band edge; label arb when its implied p is within a tolerance of that edge. Arb -> pHat exact reset and sigma update; retail -> pHat untouched, lambda/size update. Tune the tolerance."
          }
        },
        {
          "key": "kalman",
          "vars": {
            "key": "kalman",
            "idea": "Fresh mechanism, built on YQ: replace the fixed alphas (0.26/0.05) and the shock gate by a Kalman filter on the fair price: variance v grows by (pHat*sigmaHat)^2 per elapsed step; a first-in-step print is an observation with small noise r1, a later print with large noise r2; gain = v/(v+r); reject when innovation^2 > 16*(v+r). Store v in a slot. Grid r1, r2; also add c*sqrt(v)/pHat as a widening term."
          }
        },
        {
          "key": "silence",
          "vars": {
            "key": "silence",
            "idea": "Fresh mechanism, built on YQ: use silent steps as evidence. On a print after k>1 elapsed steps, no arb hit us for k-1 steps, so p stayed inside the band quoted then: clamp pHat into [spotPrev*(1-bid), spotPrev/(1-ask)] (store the previous post-trade spot and quotes), and count those steps as zero own retail fills in lambdaHat. Also test a discount on return after silence (0..4 bps per silent step, cap 8 steps). Deliver what gains."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 64000
      }
    },
    {
      "name": "r2-fresh-b",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge, round 2: one idea, one complete Strategy.sol, measured paired. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .`, `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm) and `amm-match validate` on the reference. If that cannot work within a few minutes, return at once with `blocked` set to the reason and score.n 0, never an untested strategy. Current best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol (sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4; 524.63 on seeds 0..999). Facts from the Rust source: 10000 steps; fair price p is a GBM, per-step sigma fixed per simulation in U(0.000882,0.001008); each step an arbitrageur trades each AMM if profitable, leaving spot exactly at the band edge under the fees quoted before that trade (AMM bought X: p = spot*(1-bidFee); sold X: p = spot/(1-askFee)); then Poisson(lambda in U(0.6,1.0)) retail orders, lognormal size (mean U(19,21) Y, sigma 1.2), 50/50 side, each split by a router between us and a fixed 30 bps AMM so marginal prices equalise; fees kept aside. isBuy = AMM buys X; timestamp = step; a gap between timestamps means no arb hit us. Seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs); amm_sim_rs.run_batch with explicit seeds for other ranges. Tune ONLY on seeds 0..99999. Confirm the final file on the fresh block 400000..401999 (n=2000) paired against YQ on identical seeds inside this item: mean and se of the per-seed differences, 5 worst seeds. Score it on seeds 0..999. Never run seeds 900000..909999. YOUR IDEA ({{key}}): {{idea}} Rules: `contract Strategy is AMMStrategyBase`, imports only ./AMMStrategyBase.sol and ./IAMMStrategy.sol, slots 0..31, <=250000 gas per call, no loops over history, max fee 10%, passes `amm-match validate`. Budget one hour in all. Result JSON: approach, tried (each variant with its tuning-seed paired diff and se), next (3 lines), code (full final .sol), code_sha256, delta (exact edits from YQ that rebuild your file, <=1500 chars), score {n, mean_edge, se, seed_start}, paired {reference: 'YQ 00fae418', seed_start: 400000, n, mean_diff, se, worst: [{seed, diff}]}, seconds_per_simulation, validate_ok, blocked (null or reason), citations.",
      "items": [
        {
          "key": "linear-cma",
          "vars": {
            "key": "linear-cma",
            "idea": "Fresh approach: a compact linear policy fit offline. Reuse YQ's estimators (pHat, sigmaHat, lambdaHat, toxEma), drop its fee formula. Per side: fee = c0 + c1*d_protect + c2*d_attract + c3*tradeRatio + c4*min(elapsed,8) + c5*firstInStep + c6*sigmaHat + c7*lambdaHat, clamped, with d = |spot-pHat|/pHat on the protect or attract side. Fit the 8 coefficients by Nelder-Mead or CMA-ES (pip install cma), 300 paired sims per evaluation on tuning seeds; confirm on fresh."
          }
        },
        {
          "key": "warmup",
          "vars": {
            "key": "warmup",
            "idea": "Deepen YQ: estimates are poor during the first steps. Add a warm-up policy: for the first N callbacks (grid N {0, 20, 50, 100, 200}) quote a fixed pair (grid {25, 30, 35, 40} bps, symmetric, and asymmetric from the stale sign) while the estimators run; after N switch to YQ's quotes. Also test initial guesses at the parameter midpoints (sigma 0.000945, lambda 0.8, size 0.002)."
          }
        },
        {
          "key": "vol-redo",
          "vars": {
            "key": "vol-redo",
            "idea": "Round-1 idea re-run (its first run had no simulator): a volatility-adaptive fee. At each new timestamp take the fair price implied by the previous quote (bid side: reserveY*(1-bid)/reserveX; ask side: reserveY/(reserveX*(1-ask))), EWMA (15/16) its squared relative change when below 1%, map the variance linearly to a base fee 34..50 bps between 7.78e-7 and 1.016e-6, add a 2 bps reserve-imbalance skew. Also pair it against contracts/src/StarterStrategy.sol on seeds 100000..101999; improve it if time allows."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 64000
      }
    },
    {
      "name": "r2-simplify",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge, round 2: one idea, one complete Strategy.sol, measured paired. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .`, `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm) and `amm-match validate` on the reference. If that cannot work within a few minutes, return at once with `blocked` set to the reason and score.n 0, never an untested strategy. Current best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol (sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4; 524.63 on seeds 0..999). Facts from the Rust source: 10000 steps; fair price p is a GBM, per-step sigma fixed per simulation in U(0.000882,0.001008); each step an arbitrageur trades each AMM if profitable, leaving spot exactly at the band edge under the fees quoted before that trade (AMM bought X: p = spot*(1-bidFee); sold X: p = spot/(1-askFee)); then Poisson(lambda in U(0.6,1.0)) retail orders, lognormal size (mean U(19,21) Y, sigma 1.2), 50/50 side, each split by a router between us and a fixed 30 bps AMM so marginal prices equalise; fees kept aside. isBuy = AMM buys X; timestamp = step; a gap between timestamps means no arb hit us. Seeds: `amm-match run --simulations N` = seeds 0..N-1 (MatchRunner._build_configs); amm_sim_rs.run_batch with explicit seeds for other ranges. Tune ONLY on seeds 0..99999. Confirm the final file on the fresh block 400000..401999 (n=2000) paired against YQ on identical seeds inside this item: mean and se of the per-seed differences, 5 worst seeds. Score it on seeds 0..999. Never run seeds 900000..909999. YOUR IDEA ({{key}}): {{idea}} Rules: `contract Strategy is AMMStrategyBase`, imports only ./AMMStrategyBase.sol and ./IAMMStrategy.sol, slots 0..31, <=250000 gas per call, no loops over history, max fee 10%, passes `amm-match validate`. Budget one hour in all. Result JSON: approach, tried (each variant with its tuning-seed paired diff and se), next (3 lines), code (full final .sol), code_sha256, delta (exact edits from YQ that rebuild your file, <=1500 chars), score {n, mean_edge, se, seed_start}, paired {reference: 'YQ 00fae418', seed_start: 400000, n, mean_diff, se, worst: [{seed, diff}]}, seconds_per_simulation, validate_ok, blocked (null or reason), citations.",
      "items": [
        {
          "key": "ablate",
          "vars": {
            "key": "ablate",
            "idea": "Simplify YQ by ablation: remove one component at a time (cubic tox, trade-aligned boost, tail compression, directional skew, stale shift, activity term, sigma-tox term, lambda term, flow-size term), each measured paired vs YQ with n=1000 on tuning seeds; report the table (component, mean_diff, se) in tried. Deliver YQ minus every component whose removal is neutral or positive (mean_diff > -1 se), confirmed on the fresh block."
          }
        },
        {
          "key": "yq-lite",
          "vars": {
            "key": "yq-lite",
            "idea": "Simplify: reimplement YQ's core in at most 8 slots and 8 constants: fee-band pHat (first-print alpha, gate), toxEma = |spot-pHat|/pHat, a flow base (constant + lambda*size term), the stale asymmetry (protect side + c*tox, attract side - c'*tox) and one tail cap. Retune the 8 constants coarsely on tuning seeds; report the loss or gain vs YQ."
          }
        },
        {
          "key": "linear-stale",
          "vars": {
            "key": "linear-stale",
            "idea": "Simplify: a linear stale-price model (a public rank-44 write-up reports ~95% of its edge from stale-price directional protection and a linear model beating regime switching). fee_protect = a + b*|spot-pHat|/pHat, fee_attract = max(f, a - c*|spot-pHat|/pHat), both + d*tradeRatio; pHat from YQ's fee-band inverse with its gate. Five constants tuned by coarse grid on tuning seeds; measure vs YQ."
          }
        },
        {
          "key": "freeze-est",
          "vars": {
            "key": "freeze-est",
            "idea": "Simplify: freeze YQ's hidden-parameter estimators at the parameter midpoints: sigmaHat = 0.000945, lambdaHat = 0.8, sizeHat = 0.002 (constants, never updated), keeping pHat, tox, dir and act dynamic. Measure the loss vs YQ paired; then freeze one of the three at a time. If a freeze is neutral (within 1 se) deliver the frozen version; report the table."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 64000
      }
    },
    {
      "name": "r2-measure",
      "mode": "research",
      "brief": "Paradigm AMM fee challenge: a measurement item, no new strategy, no tuning. Toolchain first: clone github.com/benedictbrady/amm-challenge into a fresh empty directory, check out 6b6921f8d463314aa7c96234e1be25a25245f704, run `pip install -e .` and `maturin develop --release` (or `--uv`; needs Rust, Python>=3.10, numpy, py-solc-x, pyrevm). If that cannot work within a few minutes, return at once with `blocked` set to the reason and every n 0. Reference best = YQ: fetch https://raw.githubusercontent.com/jiayaoqijia/amm-challenge-yq/3e9dc7d5a6192c88b562a0f8d9c172ca566ec94d/contracts/src/Strategy.sol ; its sha256 must be 00fae418c49cd681ad0879c6f96ebed0163fab5a660b38030f11e6947a39afd4 ; `amm-match validate` it. Seeds: `amm-match run --simulations N` uses seeds 0..N-1 (MatchRunner._build_configs: numpy default_rng(seed) draws mean size, rate, sigma; Rust price seed = seed, retail seed = seed+1); for any other range call amm_sim_rs.run_batch with explicit seeds built the same way, in seed order, chunked. TASK ({{key}}): {{what}} Statistics: mean, se = sd/sqrt(n), 5 worst seeds; a paired comparison is the mean and se of the per-seed differences on identical seeds, both files run inside this item. Give the first 10 per-seed edges of every file to 6 decimals. If a 10000-seed run cannot finish in 40 minutes, stop at a 1000-multiple prefix and say which. Result JSON: task, files [{name, url, commit, sha256, validate_ok}], runs [{file, seed_start, n, mean_edge, se, first10}], paired [{a, b, seed_start, n, mean_diff, se, worst: [{seed, diff}]}], seconds_per_simulation, matches_expected (per stated expectation: true/false and your value), blocked (null or reason), citations (URLs with commit hashes).",
      "items": [
        {
          "key": "yq-calib",
          "vars": {
            "key": "yq-calib",
            "what": "Score YQ on the requester's calibration set: seeds 900000..909999 in order (10000 simulations, default config): mean edge, se, first 10 per-seed edges. Also run YQ on seeds 0..999: an earlier worker found mean 524.6271111458843; report whether yours matches to 6 decimals (this checks that runs are reproducible across workers)."
          }
        },
        {
          "key": "yq-replicate",
          "vars": {
            "key": "yq-replicate",
            "what": "Replicate the current best's gain: YQ paired against the repository's contracts/src/StarterStrategy.sol on seeds 400000..401999 (n=2000): mean_diff, se, 5 worst. Also run both on seeds 100000..101999: an earlier worker found YQ 524.1942870525012 and the starter 369.50130143736396 there; report whether yours match to 6 decimals."
          }
        },
        {
          "key": "pub-chenghua",
          "vars": {
            "key": "pub-chenghua",
            "what": "Measure a public candidate: https://github.com/ChengHua926/amm-challenge at commit d34a5199c59a4c44d5336a25f1436b4ae1f21104, file contracts/src/Strategy.sol (named no_cubic; the repo's scratch/results/best_params_baseline.json records 525.806 on 1000 sims with a cubic coefficient 2.0). Validate (the contract must be named Strategy; rename only if needed); pair it against YQ on seeds 400000..401999 (n=2000); score it on 0..999. If the params file differs from the Solidity constants, also build that parameterised variant and measure it the same way. Include each file's sha256."
          }
        },
        {
          "key": "pub-shl0k28",
          "vars": {
            "key": "pub-shl0k28",
            "what": "Measure a public candidate: https://github.com/shl0k28/amm-challenge at commit 9c4be0b64479ebb41c5cb5dd7082007130a155a2, root file Strategy.sol (first-small-print arb filter; its research_log.md claims 525.08 on 1000 sims). Validate (contract must be named Strategy; rename only if needed); pair it against YQ on seeds 400000..401999 (n=2000); score it on 0..999. Include its sha256."
          }
        },
        {
          "key": "pub-elizabeth",
          "vars": {
            "key": "pub-elizabeth",
            "what": "Measure a public candidate: https://github.com/eliizabethzhang/market-making-challenge at commit 7156ff039f0ecd9ad62328664d997a762cf02cf0, file contracts/src/Strategy.sol (15-slot YQ variant with a sigma-dependent fee cap, published 2026-11-02, no public score). Validate (contract must be named Strategy; rename only if needed); pair it against YQ on seeds 400000..401999 (n=2000); score it on 0..999. Include its sha256."
          }
        }
      ],
      "output": {
        "format": "json",
        "maxBytes": 32000
      }
    }
  ],
  "read": [
    "r2-deep-a/alpha-first",
    "r2-deep-a/running-means",
    "r2-deep-a/sigma-arbs",
    "r2-deep-a/lambda-fix",
    "r2-deep-a/tune-asym",
    "r2-deep-b/tune-base",
    "r2-deep-b/tune-tox",
    "r2-deep-b/recenter",
    "r2-deep-b/tune-decay",
    "r2-deep-b/retail-alpha",
    "r2-fresh-a/norm-spot",
    "r2-fresh-a/phase",
    "r2-fresh-a/arb-class",
    "r2-fresh-a/kalman",
    "r2-fresh-a/silence",
    "r2-fresh-b/linear-cma",
    "r2-fresh-b/warmup",
    "r2-fresh-b/vol-redo",
    "r2-simplify/ablate",
    "r2-simplify/yq-lite",
    "r2-simplify/linear-stale",
    "r2-simplify/freeze-est",
    "r2-measure/yq-calib",
    "r2-measure/yq-replicate",
    "r2-measure/pub-chenghua",
    "r2-measure/pub-shl0k28",
    "r2-measure/pub-elizabeth"
  ],
  "cancel": [],
  "wake": {
    "batches": [
      "r2-deep-a",
      "r2-deep-b",
      "r2-fresh-a",
      "r2-fresh-b",
      "r2-simplify",
      "r2-measure"
    ],
    "afterMinutes": 300
  },
  "finish": false
}
