{
 "notes": "EPISODE 1 (goal: lift NP2 on Paradigm AMM fee challenge; need paired +5.8 for top 10, +9.6 for 1st vs NP2 526.1156 on seeds 0..999).\nWHAT I LEARNED (from the two artifacts and the challenge README): TWO is an EMA fair-price tracker (pHat from fee-implied post-trade spot, alpha 0.27 first-in-step / 0.06 later / 0.12 second print same direction), with sigmaHat, lambdaHat, sizeHat, actEma, toxEma (|spot-pHat|), dirState skew, staleShift/attractShift by spot vs pHat, aligned-trade boost, and a tail compress (knee 600bps, slopes 0.93/0.85); 13 slots of 32 used, gas ~94k of 250k. NP adds a 10% blend of pHat toward the normalizer-implied spot for non-first prints with feeUsed>30bps. Simulator: 10000 steps, GBM sigma~U[0.088%,0.101%]/step (nearly constant, so regime estimation is low value), retail Poisson rate U[0.6,1.0]/step, lognormal size sigma 1.2 mean U[19,21] Y, 50/50 buy-sell, retail splits by fee vs a fixed 30bps normalizer; arbs trade spot back to fair; edge measured at fair price; fee cap 10%. Fees returned after a print apply to the next print whatever it is (arb or retail), afterSwap is only called on our prints: these two facts shape every mechanism.\nDECIDED: two research batches. ep1-rules (3 items, no canary): `rules` = exact Rust rules (step order, arb rule, retail split formula with share table, fee semantics, draws, run_batch, edge); `decomp` = NP2 arb/retail edge decomposition on seeds 0..199 incl. loss by gap since previous print; `harness` = verified pairing harness source (pair.py), NP2/TWO checks, seconds per sim, seeds per hour, se calibration with a trivial 5bps change on confirm block 2900000..2901999. ep1-mech (23 items, canary 5 first: exact-block, arb-classifier, kalman-phat, ev-fee, third-print-alpha): one new mechanism each on top of NP2, tune on 10000..99999, confirm once on its own block. Items ask for `delta` (<=900 chars reproducible description) plus full `code` and sha256 so a winner can be rebuilt by a later worker even if I cannot link its code. Merge groups of 8 (3 merges) rank by t=mean_diff/se and copy code of items with mean_diff>=2se. Wake: both batches settled or 240 min.\nBRIEF BUDGET (hard): a filled brief holds <=3000 chars; the requester's setup script is 1252 and the two artifact URLs 202, so the common template in this episode is ~2700 chars and each mechanism text must stay <=297 chars. Reuse the ep1-mech template wording; do not add text to it without removing some.\nCONFIRM SEED BLOCKS (never reuse): ep1-mech item i (in listed order, 0-based: exact-block=0 ... asym-tail=22) uses 2000000+i*10000 .. +9999, i.e. 2000000..2229999 in all; harness calibration used 2900000..2909999. NEXT FREE BLOCK: 2230000 (allocate 10000 per item; skip 2900000..2909999).\nBUDGET: 26 of 400 items used this episode (3 + 23); 9 episodes left. Plan: ep2 read merges and the rules/decomp/harness results; if the harness result arrives with an api.imd.fun/artifacts/<sha256> address, later briefs can point workers at it instead of re-deriving the harness, and at winners' code (check `handed` for such addresses). ep2: combine the top 3-5 mechanisms pairwise and all-together (each item = NP2 + mechanisms described by their `delta` text, or by artifact URL if available), re-run the near-miss mechanisms with mended briefs, and spawn second-generation ideas suggested by `next` fields and by the rules item (especially the retail split formula: if it is all-or-nothing, undercutting 30bps on the safe side is the key lever; if smooth, the EV-optimal fee is). Keep every canary small, stop mechanisms with t<1 after one try, and reserve ~100 items for final confirmation/stacking in ep7-9. Finish when a candidate shows paired mean_diff>=+5.8 with se small enough that mean-2se>5.8, or when the budget is near exhausted; the write-up must give the final code, sha256, and paired{n,mean_diff,se,worst} vs NP2.",
 "spawn": [
  {
   "name": "ep1-rules",
   "brief": "Simulator github.com/benedictbrady/amm-challenge @6b6921f8d463314aa7c96234e1be25a25245f704. NP2 = `code` of https://api.imd.fun/artifacts/528a6da78583c6142644a552c86670f9d25c20e39e92f4de44deae05ddc8cecd plus the block of `code` of https://api.imd.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5 from `// Interior retail routing` to (excl.) `uint256 tradeRatio =`, inserted before the former's `uint256 tradeRatio =`; sha256 51f1c1a9...\nSETUP (Linux x86_64): clone the simulator at that commit into your workspace (not /tmp), cd in, save the script below as scratch/setup.sh, run it once with sh, then prefix commands with `. scratch/env.sh && `; on BLOCKED/failure return blocked={step,error}, paired n 0.\nset -eu;R=$PWD/scratch;mkdir -p $R/tmp $R/bin $R/solcx\necho \"export TMPDIR=$R/tmp XDG_CACHE_HOME=$R/xc UV_CACHE_DIR=$R/uvc UV_PYTHON_INSTALL_DIR=$R/uvpy RUSTUP_HOME=$R/rustup CARGO_HOME=$R/cargo SOLCX_BINARY_PATH=$R/solcx VIRTUAL_ENV=$PWD/.venv PATH=$PWD/.venv/bin:$R/bin:$R/cargo/bin:\\$PATH\" >$R/env.sh;. $R/env.sh\n[ \"$(uname -sm)\" = \"Linux x86_64\" ]&&[ -e /proc/self/exe ]||{ echo BLOCKED platform;exit 3;}\ncommand -v uv >/dev/null||{ curl -LsSf https://github.com/astral-sh/uv/releases/latest/download/uv-x86_64-unknown-linux-gnu.tar.gz|tar --no-same-owner -xz -C $R/tmp;cp $R/tmp/uv-*/uv $R/bin/;}\ncc --version >/dev/null 2>&1||{ curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest -o $R/tmp/mm.tbz;python3 -c \"import sys,tarfile;tarfile.open(sys.argv[1]).extract('bin/micromamba',sys.argv[2])\" $R/tmp/mm.tbz $R;MAMBA_ROOT_PREFIX=$R/mamba $R/bin/micromamba create -yq -p $R/cenv -c conda-forge gcc;ln -sf $(ls $R/cenv/bin/*gcc|head -n1) $R/bin/cc;}\ncommand -v cargo >/dev/null||{ curl -sSf https://sh.rustup.rs|sh -s -- -y --profile minimal --no-modify-path;}\nuv venv --python 3.12 .venv;uv pip install -e . maturin\nmaturin develop --release --uv --manifest-path amm_sim_rs/Cargo.toml\namm-match validate contracts/src/StarterStrategy.sol\nTASK: {{task}}\nRESULT JSON: the fields the task names plus np2_check (NP2 mean on seeds 0..999 via your harness, or null), seconds_per_sim, blocked (null or {step,error}), notes(<=1500c). Cite the Rust source you rely on by file path and line.",
   "items": [
    {
     "key": "rules",
     "vars": {
      "task": "Report the simulator's exact rules from its Rust and Python source, as data for fee design: step_order (arb before retail? arb checks per step? when afterSwap runs, with which timestamp), arb_rule (exact condition; trades to the fee-adjusted band edge? min profit?), retail_split (exact formula for our retail share vs the 30bps normalizer, plus our share at 1,5,10,20,29,30,31,40,60 bps), fee_semantics (which fee applies to isBuy true/false, how charged, cap), retail_size (distribution, units), draws (how _build_configs draws size, rate, sigma; which seeds go to price and retail), run_batch (signature, return), edge (formula)."
     }
    },
    {
     "key": "decomp",
     "vars": {
      "task": "Decompose NP2's edge. Pair vs NP2 on identical draws (default_rng(seed): size, rate, sigma per MatchRunner._build_configs; price seed=seed, retail seed+1; amm_sim_rs.run_batch); NP2 must average 526.1156 on seeds 0..999. Instrument a copy of the Python layer, or a thin Rust change in your checkout if run_batch lacks per-trade data, and report for NP2 on seeds 0..199: arb_edge and retail_edge (mean and se per simulation of total edge from arb and from retail trades), arb_step_share (share of steps with an arb print), prints_per_step, fee_on_arb and fee_on_retail (mean fee on arb vs retail prints, bps), loss_by_gap (mean arb loss per print by steps since our previous print: 1, 2, 3-4, 5+). If a part is impossible in the hour say so and give what you could."
     }
    },
    {
     "key": "harness",
     "vars": {
      "task": "Deliver a verified pairing harness and calibration. Pair vs NP2 on identical draws (default_rng(seed): size, rate, sigma per MatchRunner._build_configs; price seed=seed, retail seed+1; amm_sim_rs.run_batch); NP2 must average 526.1156 on seeds 0..999. Report: harness (complete Python source <=3500c, runnable as `python pair.py cand.sol base.sol start n`, printing n, mean_diff, se, worst), np2_check, two_check (TWO alone on seeds 0..999), np2_sha256 (must start 51f1c1a9), seconds_per_sim, seeds_per_hour (paired seeds per hour on your machine), calibration (NP2 with BASE_FEE 5bps vs NP2 on seeds 2900000..2901999: n, mean_diff, se, worst, per-seed diff std), advice (<=600c: pairing pitfalls, e.g. seed handling, solc version, build time)."
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 64000
   }
  },
  {
   "name": "ep1-mech",
   "brief": "Simulator github.com/benedictbrady/amm-challenge @6b6921f8d463314aa7c96234e1be25a25245f704. NP2 = `code` of https://api.imd.fun/artifacts/528a6da78583c6142644a552c86670f9d25c20e39e92f4de44deae05ddc8cecd plus the block of `code` of https://api.imd.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5 from `// Interior retail routing` to (excl.) `uint256 tradeRatio =`, inserted before the former's `uint256 tradeRatio =`; sha256 51f1c1a9...\nSETUP (Linux x86_64): clone the simulator at that commit into your workspace (not /tmp), cd in, save the script below as scratch/setup.sh, run it once with sh, then prefix commands with `. scratch/env.sh && `; on BLOCKED/failure return blocked={step,error}, paired n 0.\nset -eu;R=$PWD/scratch;mkdir -p $R/tmp $R/bin $R/solcx\necho \"export TMPDIR=$R/tmp XDG_CACHE_HOME=$R/xc UV_CACHE_DIR=$R/uvc UV_PYTHON_INSTALL_DIR=$R/uvpy RUSTUP_HOME=$R/rustup CARGO_HOME=$R/cargo SOLCX_BINARY_PATH=$R/solcx VIRTUAL_ENV=$PWD/.venv PATH=$PWD/.venv/bin:$R/bin:$R/cargo/bin:\\$PATH\" >$R/env.sh;. $R/env.sh\n[ \"$(uname -sm)\" = \"Linux x86_64\" ]&&[ -e /proc/self/exe ]||{ echo BLOCKED platform;exit 3;}\ncommand -v uv >/dev/null||{ curl -LsSf https://github.com/astral-sh/uv/releases/latest/download/uv-x86_64-unknown-linux-gnu.tar.gz|tar --no-same-owner -xz -C $R/tmp;cp $R/tmp/uv-*/uv $R/bin/;}\ncc --version >/dev/null 2>&1||{ curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest -o $R/tmp/mm.tbz;python3 -c \"import sys,tarfile;tarfile.open(sys.argv[1]).extract('bin/micromamba',sys.argv[2])\" $R/tmp/mm.tbz $R;MAMBA_ROOT_PREFIX=$R/mamba $R/bin/micromamba create -yq -p $R/cenv -c conda-forge gcc;ln -sf $(ls $R/cenv/bin/*gcc|head -n1) $R/bin/cc;}\ncommand -v cargo >/dev/null||{ curl -sSf https://sh.rustup.rs|sh -s -- -y --profile minimal --no-modify-path;}\nuv venv --python 3.12 .venv;uv pip install -e . maturin\nmaturin develop --release --uv --manifest-path amm_sim_rs/Cargo.toml\namm-match validate contracts/src/StarterStrategy.sol\nTASK: add ONE mechanism to NP2, else unchanged: {{mechanism}}\nPass `amm-match validate`, gas <250k. Pair vs NP2 on identical draws (default_rng(seed): size, rate, sigma per MatchRunner._build_configs; price seed=seed, retail seed+1; amm_sim_rs.run_batch); NP2 must average 526.1156 on seeds 0..999. Tune on seeds in 10000..99999 (>=500 each); then confirm ONE frozen variant once on >=2000 consecutive fresh seeds from {{confirm_start}} (below +10000).\nRESULT JSON: mechanism, approach, delta(<=900c, all changes vs NP2 with final constants, reproducible), code, code_sha256, validate_ok, max_gas, np2_check, tune[{variant,seeds,n,mean_diff,se}], paired{seeds,n,mean_diff,se,worst}, next, blocked. Report as computed, negative too.",
   "items": [
    {
     "key": "exact-block",
     "vars": {
      "mechanism": "EXACT ARB-BLOCKING FEE: replace staleShift by a geometric block: if pHat>spot, bidFee >= pHat/spot-1 + k*sigmaHat; if pHat<spot, askFee >= 1-pHat/spot + k*sigmaHat; other side at attract level. Variants: k 0.5/1/2; keep staleShift or not.",
      "confirm_start": "2000000"
     }
    },
    {
     "key": "arb-classifier",
     "vars": {
      "mechanism": "ARB-SIZE CLASSIFIER: from pre-trade reserves (reserve -/+ amount) compute the size that would move spot exactly to pHat*(1+/-fee); if the actual size matches within tol treat the print as arb (alpha near 1, drives sigma) else retail (weak alpha), whatever its step position. Variants: tol 2/5/10%.",
      "confirm_start": "2010000"
     }
    },
    {
     "key": "kalman-phat",
     "vars": {
      "mechanism": "KALMAN pHat: replace fixed PHAT_ALPHA* by a Kalman gain; process variance += sigmaHat^2 per elapsed step; observation variance ~0 for first-in-step prints (arb hits the band edge), ~(feeUsed*spot)^2/3 for later prints. Keep posterior variance in a slot as a toxicity input. Vary the obs scale.",
      "confirm_start": "2020000"
     }
    },
    {
     "key": "ev-fee",
     "vars": {
      "mechanism": "EXPECTED-VALUE FEE: from the Rust source take the exact retail split vs the 30bps normalizer and the arb rule; per side pick the fee maximizing E[retail edge]-E[arb loss] with fair ~ N(pHat, sigmaHat^2*(1+E gap)) offset by spot-pHat; closed form or short fixed table replacing fMid/skew.",
      "confirm_start": "2030000"
     }
    },
    {
     "key": "third-print-alpha",
     "vars": {
      "mechanism": "LATER-PRINT ALPHA: TWO special-cases a step's 2nd print (PHAT_ALPHA_SAME if same direction as the 1st). Extend to 3rd+ prints: alpha scaled by direction agreement with the step's 1st print and by size/sizeHat; nudge pHat back when prints alternate. Vary the alpha ladder for prints 2,3,4+.",
      "confirm_start": "2040000"
     }
    },
    {
     "key": "intra-step-discount",
     "vars": {
      "mechanism": "INTRA-STEP DISCOUNT: after a step's first print, later prints in that step cannot be the arb, but the returned fee also meets the next step's arb. Discount the non-toxic side (optionally both) by P(next print is still this step) from lambdaHat, scaled by toxic-side exposure. Vary the fraction.",
      "confirm_start": "2050000"
     }
    },
    {
     "key": "gap-drift",
     "vars": {
      "mechanism": "QUIET-GAP CONDITIONING: a print after k>=1 steps with no print means fair stayed inside the no-arb band [spot*(1-askFee), spot*(1+bidFee)]. Before the usual update pull pHat toward the band midpoint with weight rising in k and sigmaHat, and shrink toxicity. Vary the weight schedule.",
      "confirm_start": "2060000"
     }
    },
    {
     "key": "band-interval",
     "vars": {
      "mechanism": "INTERVAL TRACKER: keep fair-price bounds lo/hi in two slots; an arb print sets its side bound (spot*gamma buys, spot/gamma sells); each elapsed step widens both by c*sigmaHat; retail prints leave them; a printless step clips them to the band. Fees: bidFee >= hi/spot-1, askFee >= 1-lo/spot.",
      "confirm_start": "2070000"
     }
    },
    {
     "key": "continuation-fee",
     "vars": {
      "mechanism": "EDGE-OF-BAND CONTINUATION: after an arb print fair sits at the band edge, so P(next arb same direction) follows from sigmaHat, band width and expected gap. Replace the dirState skew by this model: continuation side fee where expected arb loss = expected retail gain, other side minimal.",
      "confirm_start": "2080000"
     }
    },
    {
     "key": "retail-share-fee",
     "vars": {
      "mechanism": "RETAIL-SHARE FEE: take from the Rust source the exact split of retail between us and the 30bps normalizer; on the side the arb cannot hit (opposite to spot vs pHat) set the fee maximizing fee*share(fee), floored by sigmaHat, replacing attractShift; if the split is all-or-nothing, undercut 30bps.",
      "confirm_start": "2090000"
     }
    },
    {
     "key": "fee-ceiling",
     "vars": {
      "mechanism": "LOSS-BALANCED CEILING: high protective fees kill retail without saving much arb loss. Per print find the fee where marginal retail revenue lost (Rust split rule, lambdaHat, sizeHat) equals marginal arb loss avoided (sigmaHat, mispricing); clamp both fees to it instead of the TAIL_KNEE compress.",
      "confirm_start": "2100000"
     }
    },
    {
     "key": "size-alpha",
     "vars": {
      "mechanism": "SIZE-SCALED ALPHA: scale the pHat update alpha by print size relative to the size an arb would need (pre-trade reserves, band) and by alignment with spot vs pHat: large aligned = informative, small counter = noise; scale the sigma update likewise. Variants: linear vs sqrt; weight cap; min alpha.",
      "confirm_start": "2110000"
     }
    },
    {
     "key": "dual-estimators",
     "vars": {
      "mechanism": "FAST/SLOW ESTIMATORS: two fair-price estimates (alpha ~0.5 and ~0.1) in separate slots; disagreement |fast-slow|/slow is a toxicity signal replacing or adding to toxEma; slow drives the mid, disagreement drives width and skew (sign of fast-slow). Vary alphas and the coefficient.",
      "confirm_start": "2120000"
     }
    },
    {
     "key": "realized-loss-control",
     "vars": {
      "mechanism": "REALIZED-LOSS CONTROLLER: EMAs of realized loss on arb-like prints (ret-feeUsed when >0) and of retail revenue (feeUsed*amountY on others); a small integral controller adjusts an additive offset on protective and attract fees to hit a target loss/revenue ratio. Variants: gain; target; decay.",
      "confirm_start": "2130000"
     }
    },
    {
     "key": "exec-price-phat",
     "vars": {
      "mechanism": "EXECUTION-PRICE OBSERVATION: use amountY/amountX and the reconstructed pre-trade spot besides the post-trade spot: arb prints keep pImplied (post-trade marginal = fair*(1+/-fee)); retail prints (not first in step) observe the pre-trade spot instead, which retail does not distort.",
      "confirm_start": "2140000"
     }
    },
    {
     "key": "arb-rate-sigma",
     "vars": {
      "mechanism": "SIGMA FROM ARB FREQUENCY: an arb prints when the step's move exceeds the fee, so the arb rate of first-in-step prints vs band width gives sigma; invert with a short fixed normal-tail table (no loops) and blend with the return-based sigmaHat. Variants: blend weight; table size.",
      "confirm_start": "2150000"
     }
    },
    {
     "key": "revert-capture",
     "vars": {
      "mechanism": "REVERT CAPTURE: when a retail-classified print (not first in step or size inconsistent with arb) moves spot from pHat by d, the next reverting trade brings it back: set the reverting side fee to ~d (a reverting arb pays its edge back as fee), other side normal, both decaying over steps.",
      "confirm_start": "2160000"
     }
    },
    {
     "key": "horizon-protection",
     "vars": {
      "mechanism": "HORIZON PROTECTION: the returned fee meets the next print after an unknown gap over which fair diffuses sigmaHat*sqrt(gap). Add c*sigmaHat*sqrt(E[gap]) to the protective side (E[gap] from lambdaHat and the band-implied arb rate), subtract a smaller term on the attract side, replacing SIGMA_COEF.",
      "confirm_start": "2170000"
     }
    },
    {
     "key": "bayes-direction",
     "vars": {
      "mechanism": "BAYESIAN DIRECTION: keep P(fair above spot) in a slot, updated per print by a likelihood ratio (aligned arb-size print strong, retail-size weak); a quiet gap pulls it to 0.5 at a rate from sigmaHat and band width. Skew from |P-0.5| replaces dirState. Variants: ratios; gap decay.",
      "confirm_start": "2180000"
     }
    },
    {
     "key": "quiet-attract",
     "vars": {
      "mechanism": "QUIET-STEP ATTRACT: a print after k>=2 steps with no prints means the fees attracted no retail; lower the attract side (slightly the protective side) by an amount rising in k, bounded, reset when prints come quickly. Variants: amount per step; cap; protective side moves or not.",
      "confirm_start": "2190000"
     }
    },
    {
     "key": "retail-prespot",
     "vars": {
      "mechanism": "RETAIL PRE-SPOT ANCHOR: for prints not first in step replace the NP normalizer blend and the pImplied update by an update toward the reconstructed pre-trade spot (reserveY-/+amountY)/(reserveX+/-amountX), where the pool stood when the retail order arrived. Vary alpha; keep the NP blend or not.",
      "confirm_start": "2200000"
     }
    },
    {
     "key": "step-mixture-fee",
     "vars": {
      "mechanism": "MIXTURE FEE: the next print is arb with prob q, retail 1-q; q from lambdaHat and whether the arb already printed this step; per side choose the fee maximizing q*(-E arb loss) + (1-q)*(E retail revenue under the Rust split rule). Variants: q schedule; mixture for the mid only, keeping skew.",
      "confirm_start": "2210000"
     }
    },
    {
     "key": "asym-tail",
     "vars": {
      "mechanism": "ASYMMETRIC TAIL: replace fixed TAIL_SLOPE_PROTECT/ATTRACT by knee and slope driven by uncertainty: high sigmaHat and toxSignal let the protective side run (slope near 1) and push the attract side lower; low uncertainty compresses both toward BASE_FEE. Variants: mapping; knee.",
      "confirm_start": "2220000"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 64000
   },
   "merge": {
    "groupSize": 8,
    "brief": "Make one table of the group's items: key, mechanism (<=10 words), validate_ok, blocked, best tune mean_diff, confirm seeds, n, mean_diff, se, worst, and t = mean_diff/se. Rank by t. Flag any item whose np2_check differs from 526.1156 by more than 0.01, whose confirm block does not start at its assigned confirm_start, or whose paired n is below 2000. Then, for every item with mean_diff >= 2*se, copy its `delta`, `code_sha256` and its full `code` verbatim. List every item's `next` in one line each. Finish with the three mechanisms most worth combining and why, in <=150 words."
   }
  }
 ],
 "read": [
  "ep1-rules/rules",
  "ep1-rules/decomp",
  "ep1-rules/harness",
  "ep1-mech/merge-01",
  "ep1-mech/merge-02",
  "ep1-mech/merge-03",
  "ep1-mech/exact-block",
  "ep1-mech/arb-classifier",
  "ep1-mech/kalman-phat",
  "ep1-mech/ev-fee",
  "ep1-mech/band-interval"
 ],
 "cancel": [],
 "wake": {
  "batches": [
   "ep1-rules",
   "ep1-mech"
  ],
  "afterMinutes": 240
 },
 "finish": false
}