{
 "notes": "EPISODE 4 (2026-11-10). 16 results read; 58 items used before this episode, 18 spawned now (76 of 240), 16 episodes left. Unreturned since episode 1: b1-ideas/idea-twohyp, b1-fresh/fresh-1 (in read again; do not wait on them).\n\nTRACK A FINDINGS. (1) Q2 CLEARS THE BAR ON 2,048 ENGINE SEEDS. a3-eng-qm2-a/-b, all 8 items accepted, both arms on 12001024..12003071, none missing: Q2 (= a2-port-qm/qm-2) minus IB pooled n 2048 mean_diff +3.0444 se 0.0325 (sum 6234.996342, sumsq 23411.221253; items 2.905..3.191; every item's sum and sumsq recomputed from its rows: all match). 19 of 2,048 seeds negative; worst -2.225 (12001701), -1.232 (12002425), -1.207 (12002099). Gas on the engine: Q2 afterSwap peak 204,917, mean 92,716; IB peak 237,142, mean 135.2k; 0 OutOfGas, 0 reverts, validate pass everywhere. Forecast was +3.14: 0.10 short, inside the 0.2 rule. +2.7 is passed by 10.6 se; expected board score about 525.0 (8th-9th). ENGINE GAS RUNS ABOVE PYREVM: Q2 mean 59,801 pyrevm against 92,716 engine (+33k every call), peak 155,745 against 204,917 (+49k); P2 the same. Size port gates by it: pyrevm peak <= 195,000.\n(2) BLEND PORTS: both a3-port-blend copies complete:true, same policy (gb.py g=1.5 on Q2's tables), cost vs fresh gauss+qm on 60000..61023 +0.2644 se 0.0163 (sum 270.718713, sumsq 348.203571; includes Q2's -0.038 compression), parity 2.8e-9 bps on 215,003 callbacks, validate pass, 0 reverts, 0 CODECOPY. pb-1 = PB (result sha 2ade1a24f75836479efeeaff574e452ff3ef5c23fd856c50bd2c1a4a10d78463, tar pb-1/, Strategy.sol inside): 21,915 runtime bytes (2,661 spare: XOR 0x40 on table bytes saved 2,526), pyrevm peak 167,214, mean 65,970. pb-2 (sha d63db308188f582d9ec3e0331369885705dca5c94ffd07ded20159c10738c576): 22,118 bytes, peak 172,801; spare. Expected PB on the engine: about +3.3 over IB, peak about 217k.\n(3) LATTICE IN THE CONTRACT IS CLOSED. a3-latt-swar: SWAR cut dt=1 peak 558k to 403k only, best accurate hybrid peaks 1.49M; an 8-word lane design is estimated, not measured, at 110-150k. The two-Gaussian mixture below gets within 0.07 of the lattice at Gaussian cost, so nothing more goes to this.\n(4) compress-sdlevels: with full rows and columns, sd levels {4, 20} bps alone cost -0.010 se 0.010 on the holdout ({4,20,34}: -0.006); one level costs -0.6 or worse. Q2 keeps 5 levels (0,4,12,20,34), so a later port can buy bytes by dropping to 2.\n\nTRACK B FINDINGS (holdout 10000..12047). mix2-1 (result sha f8a1a335228c7ce2b76273b5521a0857f7cd1b60e57aa3ec420eecc6446a64c7, mix.py, mix:MixPolicy quote=0 floor=0.00001): two Gaussians kept across steps (arb pin, cut retail prior), weights by silent-step mass, quote from the moment-matched Gaussian: +0.428 se 0.0125 vs ref/gauss_qm.json, -0.067 se 0.009 vs ref/lattice_qm.json; 3 extra slots, est. +20-60k gas on first trades (unmeasured). The pi^1.5 blend on top of it was worse (tuning +0.32 against +0.44): mix2 replaces the blend, it does not stack. fresh3-1 (sha 22819a1542e36a609ec3d02a160b4b7aaf345d26d7184ef6517abc35b85cfbfc, thrpol.py + numba fast_thr.py): COST-WEIGHTED CALL, arb called only when pi > 0.9 instead of 0.5, belief untouched: +0.323 se 0.0107 vs ref/lattice_qm.json (+4.586 vs HA), flat over 0.85..0.95, zero gas (one constant); misreads rise 16.2% to 28.9% while edge rises: the cost of each wrong call is the target, not the misread rate. blend-tune (lattice): g=2 plus blending the stored rival estimate +0.223 se 0.011 (rival blend alone +0.03 to +0.045); below 0.3. br-1 (blend + open branches): +0.118 se 0.011, 450k gas; dropped. Standing on the replica vs HA: gauss+qm +3.77; +blend +4.09; mix2 +4.20; lattice +4.26; lattice+thr +4.59; true flag +6.98.\n\nDECISIONS THIS EPISODE (18 items; A 10, B 8).\nA: a4-eng3-a and a4-eng3-b, 4 items each, 256 fresh engine seeds each on 12003072..12005119, THREE arms in the same item (IB, Q2, PB), 64-seed commands; result keys ib, q2, pb (n, sum, sumsq, rows), pb_minus_ib, q2_minus_ib, pb_minus_q2 (paired), gas, validate, valid. This takes Q2 to 4,096 paired seeds (the goal's 4,000-seed bar) and gives PB its first 2,048 against both. a4-port-mix2, 2 copies (mix-1, mix-2): mix.py ported from PB's code base (blend removed), THR a contract constant with parity at thr 0.5 and at 0.9, a bound on the silent-step loop if two components do not fit the gas, cost vs fresh gauss+qm on 60000..61023 (expect about +0.39; complete needs >= +0.25), pyrevm peak <= 195,000 incl. a forced worst case, full gate set.\nB: b4-thr, 3 items: the pi cut on gauss+qm (thr-gauss), on mix2 (thr-mix2) and on the Gaussian blend gb.py (thr-blend); each gives the tuned thr, holdout_vs_base, holdout_vs_gauss_qm, holdout_vs_lattice_qm. b4-cutfn (cutfn-1): the cut as a function of fill size, sd, dt, side, from measured per-bin costs of each wrong call, on the lattice vs the constant 0.9. b4-qm2h (qm2h-1): exact expected-value quote over the two readings using the solver's action values (needs the dp.py solve; has a must-pass check at pi 0 and 1 because idea-posterior lost 2.87). b4-flag-split (split-1): diagnostic on 60000..60511, the true flag given separately to belief pin, phase, rival update (8 combinations, at call cut 0.5 and 0.9) to say which part holds the +2.72 and how much a blind call can reach. b4-fresh4, 2 items: fresh ideas on top of lattice thr=0.9 with the full do-not-repeat list.\n\nSEED LEDGER. Engine: 12000000..12001023 used (IB, P2); 12001024..12003071 used (IB, Q2); 12003072..12005119 assigned now (IB, Q2, PB). Next free engine seed: 12005120. Replica: tuning 60000..60255, confirmation 60256..60511, port cost 60000..61023, diagnostics 60000..60511 and 61000..61255; holdout 10000..12047 once per idea.\n\nEPISODE 5 SHOULD: (1) Pool a4-eng3-a/-b. q2_minus_ib over these 2,048 seeds added to this episode's sum 6234.996342 and sumsq 23411.221253 (n 2048) gives Q2 on 4,096: at mean >= +2.7 Track A's bar is met and Q2 is the standing contract (code sha 988ef957e0f6633583384005936a94cee2816b8202feadbc2a633ee318e50c1c). pb_minus_q2 should be about +0.26 to +0.30; check PB's engine peak <= 245,000 and valid true. If PB is not at least +0.15 over Q2, spawn one trace item before trusting replica gains of the blend family. (2) Port: if a mix copy is complete:true, and thr-mix2 shows holdout_vs_base >= +0.15, spawn one small item that sets THR to the tuned value in that port, reruns parity and cost, and returns the contract; then run that contract (or the mix port at thr 0.5 if thr does not carry) on fresh seeds from 12005120 with IB and the best earlier port as arms, 8 items first (2,048 seeds), 8 more next episode. Expected: mix2 about +3.4 over IB, with thr up to +3.7 (about 525.7, 5th-7th). If both mix copies fail on gas, fall back to PB plus THR (thr-blend says what that is worth) as the next engine arm. (3) Track B: the route to first needs about +3 more than Q2, and only the flag gap is that large. Read split-1 first: if the gain sits in phase and rival (the call), put most B items on cost-aware calls and expected-value quotes (cutfn, qm2h follow-ups); if it sits in the belief pin, the gap is price information and items should go to quotes that buy pins and to anything fresh4 found. Any B result >= +0.3 over its base goes into the next port; 0.1 to 0.3 gets one tuning or stacking item; below that is dropped. From now measure B ideas on mix2 or lattice+thr as base, so gains add to what is won. (4) Budget: 164 items after this episode; engine confirmation of each new port costs 16 items for 4,096 seeds; keep 14-20 items an episode.\n\nWATCH FOR: three-arm engine items use q2/pb keys, not port; the Q2 result JSON is one object under the key qm-2; code_sha256 in results is sometimes the sha of the base64 text and sometimes of the tar, so check both; engine peak is about 50k over a port's pyrevm peak; briefs under 2,900 filled characters, no platform conditions, numbers not command text.",
 "spawn": [
  {
   "name": "a4-eng3-a",
   "brief": "Track A engine pairing: three contracts, IB, Q2 and PB, each alone against VanillaStrategy, on engine seeds {{from}}..{{to}} (256 seeds, yours alone; use no seed outside this range; never fill a missing seed). Engine: git clone https://github.com/benedictbrady/amm-challenge and check out 6b6921f8d463314aa7c96234e1be25a25245f704; from the checkout root: mkdir -p scratch && curl -LsSf https://raw.githubusercontent.com/gtmcknight/amm-sim/main/research/setup.sh -o scratch/setup.sh && sh scratch/setup.sh; prefix later commands with `. scratch/env.sh && `. If a setup step fails, return the JSON {\"key\":\"{{key}}\",\"engine\":\"blocked\",\"blocked\":{\"step\",\"error\"} } and stop. Sources: each is the JSON served at https://api.imd.fun/artifacts/<id>, and code_zb64 in it is base64, then zlib. IB: id afd5183e9ff3235334e041c00b0cd19079599a2c6464db95f8c1586712105557; its code_zb64 decodes to the Solidity source itself. Q2: id f6f4c4cccbd3fd9b0d7a4c4c329011ba1c765a10cc192b1402434033bdd10402; the JSON is one object under the key \"qm-2\"; its code_zb64 decodes to a tar, take qm-2/Strategy.sol. PB: id 2ade1a24f75836479efeeaff574e452ff3ef5c23fd856c50bd2c1a4a10d78463; its code_zb64 decodes to a tar, take pb-1/Strategy.sol. Compile each unchanged with the engine's SolidityCompiler (contract Strategy) and run amm-match validate on each. Run amm_sim_rs.run_batch(X, VanillaStrategy, configs, 8) with configs as MatchRunner._build_configs builds them, simulation i having seed {{from}}+i; four 64-seed commands per contract, twelve in all, none over 8 minutes (if a 64-seed command would pass 8 minutes use 32-seed commands and say so). A seed's score is the submission's edge. Save each block's rows under scratch/ as it finishes, so an interrupted run resumes at the next block. Result: one JSON object under 45,000 bytes: {\"key\":\"{{key}}\",\"seeds\":{\"from\",\"to\"},\"ib\":{\"n\",\"sum\",\"sumsq\",\"rows\":[[seed,edge],...]},\"q2\":{the same},\"pb\":{the same},\"pb_minus_ib\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]},\"q2_minus_ib\":{the same},\"pb_minus_q2\":{the same},\"gas\":{\"ib\":{\"peak_afterswap\",\"mean_afterswap\",\"oog\",\"reverts\"},\"q2\":{the same},\"pb\":{the same} } from gas_stats(),\"validate\":{\"ib\",\"q2\",\"pb\"},\"valid\",\"engine\":\"ok\",\"notes\"}. Row edges rounded to 6 decimals; sums and paired figures from the unrounded values. Pair only seeds that all three contracts returned and give n. valid is false on any OutOfGas, any revert, or a Q2 or PB afterSwap peak over 245,000. Numbers only: no command text and no command output in the result; notes under 800 characters.",
   "items": [
    {
     "key": "eng3-12003072",
     "vars": {
      "key": "eng3-12003072",
      "from": "12003072",
      "to": "12003327"
     }
    },
    {
     "key": "eng3-12003328",
     "vars": {
      "key": "eng3-12003328",
      "from": "12003328",
      "to": "12003583"
     }
    },
    {
     "key": "eng3-12003584",
     "vars": {
      "key": "eng3-12003584",
      "from": "12003584",
      "to": "12003839"
     }
    },
    {
     "key": "eng3-12003840",
     "vars": {
      "key": "eng3-12003840",
      "from": "12003840",
      "to": "12004095"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 48000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "a4-eng3-b",
   "brief": "Track A engine pairing: three contracts, IB, Q2 and PB, each alone against VanillaStrategy, on engine seeds {{from}}..{{to}} (256 seeds, yours alone; use no seed outside this range; never fill a missing seed). Engine: git clone https://github.com/benedictbrady/amm-challenge and check out 6b6921f8d463314aa7c96234e1be25a25245f704; from the checkout root: mkdir -p scratch && curl -LsSf https://raw.githubusercontent.com/gtmcknight/amm-sim/main/research/setup.sh -o scratch/setup.sh && sh scratch/setup.sh; prefix later commands with `. scratch/env.sh && `. If a setup step fails, return the JSON {\"key\":\"{{key}}\",\"engine\":\"blocked\",\"blocked\":{\"step\",\"error\"} } and stop. Sources: each is the JSON served at https://api.imd.fun/artifacts/<id>, and code_zb64 in it is base64, then zlib. IB: id afd5183e9ff3235334e041c00b0cd19079599a2c6464db95f8c1586712105557; its code_zb64 decodes to the Solidity source itself. Q2: id f6f4c4cccbd3fd9b0d7a4c4c329011ba1c765a10cc192b1402434033bdd10402; the JSON is one object under the key \"qm-2\"; its code_zb64 decodes to a tar, take qm-2/Strategy.sol. PB: id 2ade1a24f75836479efeeaff574e452ff3ef5c23fd856c50bd2c1a4a10d78463; its code_zb64 decodes to a tar, take pb-1/Strategy.sol. Compile each unchanged with the engine's SolidityCompiler (contract Strategy) and run amm-match validate on each. Run amm_sim_rs.run_batch(X, VanillaStrategy, configs, 8) with configs as MatchRunner._build_configs builds them, simulation i having seed {{from}}+i; four 64-seed commands per contract, twelve in all, none over 8 minutes (if a 64-seed command would pass 8 minutes use 32-seed commands and say so). A seed's score is the submission's edge. Save each block's rows under scratch/ as it finishes, so an interrupted run resumes at the next block. Result: one JSON object under 45,000 bytes: {\"key\":\"{{key}}\",\"seeds\":{\"from\",\"to\"},\"ib\":{\"n\",\"sum\",\"sumsq\",\"rows\":[[seed,edge],...]},\"q2\":{the same},\"pb\":{the same},\"pb_minus_ib\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]},\"q2_minus_ib\":{the same},\"pb_minus_q2\":{the same},\"gas\":{\"ib\":{\"peak_afterswap\",\"mean_afterswap\",\"oog\",\"reverts\"},\"q2\":{the same},\"pb\":{the same} } from gas_stats(),\"validate\":{\"ib\",\"q2\",\"pb\"},\"valid\",\"engine\":\"ok\",\"notes\"}. Row edges rounded to 6 decimals; sums and paired figures from the unrounded values. Pair only seeds that all three contracts returned and give n. valid is false on any OutOfGas, any revert, or a Q2 or PB afterSwap peak over 245,000. Numbers only: no command text and no command output in the result; notes under 800 characters.",
   "items": [
    {
     "key": "eng3-12004096",
     "vars": {
      "key": "eng3-12004096",
      "from": "12004096",
      "to": "12004351"
     }
    },
    {
     "key": "eng3-12004352",
     "vars": {
      "key": "eng3-12004352",
      "from": "12004352",
      "to": "12004607"
     }
    },
    {
     "key": "eng3-12004608",
     "vars": {
      "key": "eng3-12004608",
      "from": "12004608",
      "to": "12004863"
     }
    },
    {
     "key": "eng3-12004864",
     "vars": {
      "key": "eng3-12004864",
      "from": "12004864",
      "to": "12005119"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 48000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "a4-port-mix2",
   "brief": "Track A, the mixture port, copy {{copy}} of 2. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read its README.md. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. Start from PB (id 2ade1a24f75836479efeeaff574e452ff3ef5c23fd856c50bd2c1a4a10d78463): pb-1/ is an accepted Solidity port of real.py soft=1 with compressed qm tables; its README says how to rebuild and check it. Remove its branch blend. Port mix.py (id f8a1a335228c7ce2b76273b5521a0857f7cd1b60e57aa3ec420eecc6446a64c7), mix:MixPolicy quote=0 floor=0.00001: two Gaussians (arb pin, cut retail prior) kept across steps, quotes from their moment-matched Gaussian. 1. Reference: mix.py on PB's tables (x_c2.json) plus an option thr: the trade is the arb when pi > thr (default 0.5). 2. Gas: each silent step cuts every component, and engine gas is about 33,000 over pyrevm on every call, 50,000 at the peak. If two components do not fit, bound the loop (say one Gaussian after K silent steps) in contract and reference alike. 3. Cost: the reference against a fresh `gauss soft=1 qm=qm_k1e-5.json` run on replica seeds 60000..61023, thr 0.5. 4. Contract: THR one constant, <= 32 slots, no assembly, runtime <= 24,576 bytes, no CODECOPY data segment. Short of bytes: sd levels 4 and 20 bps alone cost -0.010 elsewhere; measure first. Gates: fees within 0.01 bps of the reference on every callback of replica seeds 10000..10019, at thr 0.5 and at thr 0.9; pyrevm afterSwap peak incl. the 21,000 intrinsic <= 195,000 there and on a forced worst case (first trade after 13+ silent steps, two live components, pi near 0.5); 0 OutOfGas, 0 revert; amm-match validate passes; report 64 stress sequences. Engine checkout: git clone https://github.com/benedictbrady/amm-challenge and check out 6b6921f8d463314aa7c96234e1be25a25245f704; from the checkout root: mkdir -p scratch && curl -LsSf https://raw.githubusercontent.com/gtmcknight/amm-sim/main/research/setup.sh -o scratch/setup.sh && sh scratch/setup.sh; prefix later commands with `. scratch/env.sh && `; if a step fails say so under blocked. Use no engine seed. Result: one JSON under 58,000 bytes: {\"key\":\"{{key}}\",\"bound_rule\",\"cost_paired\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]},\"parity\":{\"thr05\":{\"callbacks\",\"max_fee_diff_bps\"},\"thr09\":{the same} },\"gas\":{\"peak_afterswap\",\"mean_afterswap\",\"worst_case_peak\",\"oog\",\"reverts\"},\"stress_reverts\",\"validate\",\"bytes_runtime\",\"slots\",\"complete\",\"blocked\",\"code_zb64\",\"code_sha256\",\"notes\"}. complete: every gate passes and cost mean_diff >= +0.25. code_zb64: a tar of Strategy.sol, reference, generator, checks; no tables, no traces. Numbers only, no command text; notes under 1,500 characters.",
   "items": [
    {
     "key": "mix-1",
     "vars": {
      "key": "mix-1",
      "copy": "1"
     }
    },
    {
     "key": "mix-2",
     "vars": {
      "key": "mix-2",
      "copy": "2"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 60000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "b4-thr",
   "brief": "Track B, one idea on one base policy: the cost-weighted arb/retail call on {{base}}. Plain Python on the replica. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read scratch/solved/README.md, sections Harness and Rules for both; scripts run as python3 -I from that folder. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. The idea: every reference policy calls the first own trade of a step the arb when its posterior pi > 0.5; the call only picks phase 0 or phase 1 and whether the fill updates the rival spot. On the lattice filter, calling it the arb only when pi > 0.9 gained +0.323 se 0.011 on the holdout (id 22819a1542e36a609ec3d02a160b4b7aaf345d26d7184ef6517abc35b85cfbfc, thrpol.py), flat from 0.85 to 0.95: calling a retail fill the arb costs more than the reverse. Your item: the same cut on the base policy {{base}}, which is {{where}}. Add an option thr to it: only the comparison that sets is_arb changes; the belief update, and any blend weight, stay as they are. Check thr=0.5 reproduces the base within 1e-9 a seed on 8 seeds. Tune thr over 0.5..0.99 on replica seeds 60000..60255, paired against the base on the same seeds; confirm the chosen thr once on 60256..60511; then freeze and score once on 10000..12047 in four 512-seed commands, and run the base (thr 0.5) on those seeds too. Blind: a policy sees only afterSwap inputs (run.py enforces it). Never fill a missing seed; no command over 8 minutes: use smaller seed chunks if one would run longer. Result: one JSON object under 30,000 bytes: {\"key\":\"{{key}}\",\"base\",\"settings_tried\":[{\"setting\",\"n\",\"mean_diff\",\"se\"}],\"thr\",\"confirm_paired\":{\"n\",\"mean_diff\",\"se\"},\"holdout_vs_base\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]},\"holdout_vs_gauss_qm\":{the same, by pair.py against ref/gauss_qm.json},\"holdout_vs_lattice_qm\":{the same, against ref/lattice_qm.json},\"misread_rate\":{\"base\",\"mine\"},\"price_error_bps\":{\"base\",\"mine\"},\"gas_estimate\",\"code_zb64\",\"code_sha256\",\"notes\"}. code_zb64: a tar of your policy file and a short README, no tables. Numbers only: no command text or output; notes under 1,500 characters.",
   "items": [
    {
     "key": "thr-gauss",
     "vars": {
      "key": "thr-gauss",
      "base": "gauss",
      "where": "real.py's policy as run.py runs it with `gauss soft=1 qm=qm_k1e-5.json` (the policy of ref/gauss_qm.json)"
     }
    },
    {
     "key": "thr-mix2",
     "vars": {
      "key": "thr-mix2",
      "base": "mix2",
      "where": "mix.py from id f8a1a335228c7ce2b76273b5521a0857f7cd1b60e57aa3ec420eecc6446a64c7, run as `mix:MixPolicy quote=0 floor=0.00001 qm=qm_k1e-5.json` (two Gaussians kept across steps; +0.428 over Gaussian+qm on the holdout)"
     }
    },
    {
     "key": "thr-blend",
     "vars": {
      "key": "thr-blend",
      "base": "blend",
      "where": "gb.py from id 4e88413335e28582aa9e96af6520c248a03c03f6944b561bdc7cf433460e2a97, run as `gb:GaussianBlend soft=1 bw=1.5 qm=qm_k1e-5.json` (pi^1.5 log-blend of the two readings' quotes; +0.319 over Gaussian+qm on the holdout)"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 40000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "b4-cutfn",
   "brief": "Track B, one idea: the arb/retail cut as a function of the trade. Replica only; numpy and numba in a venv are allowed. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read scratch/solved/README.md, sections Harness and Rules for both; scripts run as python3 -I from that folder. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. Background: the lattice policy calls the first own trade of a step the arb when its posterior pi > 0.5; the call picks phase 0 or 1 and whether the fill updates the rival spot. A constant cut of 0.9 instead gained +0.323 se 0.011 on the holdout (id 22819a1542e36a609ec3d02a160b4b7aaf345d26d7184ef6517abc35b85cfbfc: thrpol.py for run.py, fast_thr.py a numba runner, both with option thr). Misreads rose from 16% to 29% while edge rose, so the cost of a wrong call, not its rate, is what matters. Your item: replace the constant by a cut that depends on what afterSwap shows at that trade: the fill size d = |ln(s/sp)|, the belief sd before the trade, dt since the last own trade, the side of the fill against the own displacement w, the distance of the arb reading from the belief mean. Method: on tuning seeds, with the true flag read for measurement only (clsdata.py and trace.py show how), estimate for bins of those features the edge lost by each wrong call, set the cut per bin from the two costs, keep at most 3 features and 27 bins, and compare to the constant 0.9. The policy itself stays blind. Tune on replica seeds 60000..60255, confirm once on 60256..60511, then freeze and score once on 10000..12047 in four 512-seed commands; run thr=0.9 on the same seeds for the paired gain. Blind: a policy sees only afterSwap inputs (run.py enforces it). Never fill a missing seed; no command over 8 minutes: use smaller seed chunks if one would run longer. Result: one JSON object under 30,000 bytes: {\"key\":\"{{key}}\",\"cut_rule\",\"cost_table\":[{\"bin\",\"n\",\"cost_arb_called_retail\",\"cost_retail_called_arb\",\"cut\"}],\"settings_tried\":[{\"setting\",\"n\",\"mean_diff\",\"se\"}],\"confirm_paired\":{\"n\",\"mean_diff\",\"se\"},\"holdout_vs_lattice_qm\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]} by pair.py against ref/lattice_qm.json,\"holdout_vs_thr09\":{the same, against the constant cut 0.9},\"misread_rate\":{\"base\",\"mine\"},\"price_error_bps\":{\"base\",\"mine\"},\"gas_estimate\",\"code_zb64\",\"code_sha256\",\"notes\"}. code_zb64: a tar of your policy file and a short README, no tables. Numbers only: no command text or output; notes under 1,500 characters.",
   "items": [
    {
     "key": "cutfn-1",
     "vars": {
      "key": "cutfn-1"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 40000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "b4-qm2h",
   "brief": "Track B, one idea: expected-value quotes over the two readings of a first trade. Replica only; numpy and numba in a venv. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read scratch/solved/README.md, sections Harness and Rules for both; scripts run as python3 -I from that folder. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. Background: at the first own trade of a step real.py holds two readings: the arb (price exactly lp, phase 0, rival not updated) with weight pi, and retail (price N(mt, vt), phase 1, rival updated from the fill) with weight 1 - pi. It then looks up one quote at the mixture's mean and sd, in the phase of the likelier reading. Two cheap repairs each gained about +0.3 on the holdout: a pi^1.5 log-blend of the two readings' quotes (gb.py, id 4e88413335e28582aa9e96af6520c248a03c03f6944b561bdc7cf433460e2a97) and calling the arb only above pi 0.9. Your item, the exact version: on a first trade with 0.001 < pi < 0.999 choose the ask and bid prices that maximise pi * Q0(arb state, quotes) + (1 - pi) * Q1(retail state, quotes), with Q the action values the solver saves (DP_SAVEVN=1 with dp.py; qmdp.py shows how action values are formed from the saved values and averaged over a price spread, kappa 1e-5). Express one pair of absolute quotes as offsets in each reading's own state (its w, its R, its sd). Every other call stays real.py soft=1 qm=qm_k1e-5.json. Check first: with pi forced to 0 or 1 your chooser returns the qm table quotes within one 5 bps lattice step on 1,000 recorded calls; an earlier whole-posterior chooser lost 2.87, so measure nothing before this check passes. If the solve does not finish in one command, resume it with DP_STATE and DP_SWEEPS=40 until it prints SOLVED. Tune on replica seeds 60000..60255, confirm once on 60256..60511, then freeze and score once on 10000..12047 in four 512-seed commands. Blind: a policy sees only afterSwap inputs (run.py enforces it). Never fill a missing seed; no command over 8 minutes: use smaller seed chunks if one would run longer. Result: one JSON object under 30,000 bytes: {\"key\":\"{{key}}\",\"check\":{\"calls\",\"max_offset_diff_bps\",\"passed\"},\"settings_tried\":[{\"setting\",\"n\",\"mean_diff\",\"se\"}],\"confirm_paired\":{\"n\",\"mean_diff\",\"se\"},\"holdout_vs_gauss_qm\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]} by pair.py against ref/gauss_qm.json,\"holdout_vs_lattice_qm\":{the same, against ref/lattice_qm.json},\"misread_rate\":{\"base\",\"mine\"},\"price_error_bps\":{\"base\",\"mine\"},\"gas_estimate\",\"code_zb64\",\"code_sha256\",\"notes\"}. code_zb64: a tar of your policy file and a short README, no tables. Numbers only: no command text or output; notes under 1,500 characters.",
   "items": [
    {
     "key": "qm2h-1",
     "vars": {
      "key": "qm2h-1"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 40000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "b4-flag-split",
   "brief": "Track B diagnostic, one question: where inside the policy is the true arb/retail flag worth its +2.72? Plain Python on the replica; a diagnostic, so it reads the true flag and is not a policy. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read scratch/solved/README.md, sections Harness and Rules for both; scripts run as python3 -I from that folder. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. Background: latt.py with oraclearb=1 (the true flag as pi) scores +2.72 over the blind lattice (ref/flag_qm.json against ref/lattice_qm.json). The flag enters in three places at the first own trade of a step: (a) the belief: pin the price at the arb reading or keep the cut prior; (b) the phase: tables of phase 0 or phase 1; (c) the rival spot: whether the fill updates it and sets synced. A blind change of the call alone (arb only when pi > 0.9, id 22819a1542e36a609ec3d02a160b4b7aaf345d26d7184ef6517abc35b85cfbfc, thrpol.py) gained +0.323 while leaving (a) as it was. Your item: subclass latt.py's policy so the true flag can be given to each of (a), (b), (c) separately, the others keeping the blind pi (belief) or the blind call pi > 0.5 (phase, rival). Run the eight combinations, from none (must equal latt.py within 1e-9 a seed) to all three (must equal oraclearb=1), on replica seeds 60000..60511, each paired against the blind lattice on the same seeds; repeat the eight with the blind call at pi > 0.9. Then, for (b) and (c) only, split the gain by the kind of error it repairs: retail called arb, and arb called retail, with counts per 1,000 first trades and edge per repaired call. Use no holdout seed. Never fill a missing seed; no command over 8 minutes: use smaller seed chunks if one would run longer. Result: one JSON object under 30,000 bytes: {\"key\":\"{{key}}\",\"seeds\",\"combos\":[{\"belief\",\"phase\",\"rival\",\"call_cut\",\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\"}],\"sanity\":{\"none_equals_lattice\",\"all_equals_oraclearb\"},\"by_error\":[{\"part\",\"error\",\"per_1000_first_trades\",\"edge_per_repair\",\"total\"}],\"reading\":\"three sentences: which part holds the gain and what a blind policy could reach of it\",\"code_zb64\",\"code_sha256\",\"notes\"}. code_zb64: a tar of your scripts, no tables. Numbers only: no command text or output; notes under 1,500 characters.",
   "items": [
    {
     "key": "split-1",
     "vars": {
      "key": "split-1"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 40000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  },
  {
   "name": "b4-fresh4",
   "brief": "Track B, a fresh idea, item {{n}} of 2 (the other works alone on its own idea). Replica only; numpy and numba in a venv are allowed. Solved folder: B=https://raw.githubusercontent.com/gtmcknight/amm-sim/e65314f88de945f6d055bfc2aab01c482ab6570e/research/solved; curl -LsSf $B/fetch.sh -o fetch.sh && sh fetch.sh $B scratch/solved; read scratch/solved/README.md, sections Harness and Rules for both; scripts run as python3 -I from that folder. Earlier results are JSON at https://api.imd.fun/artifacts/<id>; code_zb64 in them is base64, zlib, tar. Skip the README's list of ideas under Track B and under Open: start from the question alone. The question: the policy is blind to whether the first own trade of a step is the arb or a retail order. With the true flag the same code scores +2.72 more; the top of the board sits there. What, using only afterSwap inputs and the quotes you choose, recovers the most of it? Best so far, your base: the lattice filter with the arb called only when pi > 0.9 (id 22819a1542e36a609ec3d02a160b4b7aaf345d26d7184ef6517abc35b85cfbfc: thrpol.py for run.py, fast_thr.py a numba runner; +0.323 se 0.011 over ref/lattice_qm.json). The cost of a wrong call matters, not the misread rate (16% became 29% and edge rose). Already measured, do not repeat: finer lattice cells (0.00); per-run sigma or order rate (+0.02); router likelihood per price hypothesis (+0.09 at 1M gas); a correction trained on filter features (+0.02); quotes against the whole posterior (-2.87); revising rival and phase when a later callback flips the label (+0.08 to +0.12); a pi-weighted log-blend of the two readings' quotes (+0.18 to +0.22); a two-Gaussian belief (equal to the lattice); size, timing and exact-amount features in the classifier (no change); quote-zone masks, kappa above 1e-5, a quote-aware fill likelihood. Pick one idea, say why it should beat these, and measure it alone on top of the base. Tune on replica seeds 60000..60255 against the base, confirm once on 60256..60511, then freeze and score once on 10000..12047 in four 512-seed commands, with the base (thr=0.9) run on the same seeds. Blind: a policy sees only afterSwap inputs (run.py enforces it). Never fill a missing seed; no command over 8 minutes: use smaller seed chunks if one would run longer. Result: one JSON object under 30,000 bytes: {\"key\":\"{{key}}\",\"idea\",\"why\",\"settings_tried\":[{\"setting\",\"n\",\"mean_diff\",\"se\"}],\"confirm_paired\":{\"n\",\"mean_diff\",\"se\"},\"holdout_vs_lattice_qm\":{\"n\",\"mean_diff\",\"se\",\"sum\",\"sumsq\",\"worst5\":[[seed,diff] x5]} by pair.py against ref/lattice_qm.json,\"holdout_vs_thr09\":{the same, against the base},\"misread_rate\":{\"base\",\"mine\"},\"price_error_bps\":{\"base\",\"mine\"},\"gas_estimate\",\"code_zb64\",\"code_sha256\",\"notes\"}. code_zb64: a tar of your policy file and a short README, no tables. Numbers only: no command text or output; notes under 1,500 characters.",
   "items": [
    {
     "key": "fresh4-1",
     "vars": {
      "key": "fresh4-1",
      "n": "1"
     }
    },
    {
     "key": "fresh4-2",
     "vars": {
      "key": "fresh4-2",
      "n": "2"
     }
    }
   ],
   "output": {
    "format": "json",
    "maxBytes": 40000
   },
   "merge": {
    "groupSize": 25,
    "brief": "Keep every item's JSON whole under its key; add nothing."
   }
  }
 ],
 "read": [
  "a4-eng3-a/eng3-12003072",
  "a4-eng3-a/eng3-12003328",
  "a4-eng3-a/eng3-12003584",
  "a4-eng3-a/eng3-12003840",
  "a4-eng3-b/eng3-12004096",
  "a4-eng3-b/eng3-12004352",
  "a4-eng3-b/eng3-12004608",
  "a4-eng3-b/eng3-12004864",
  "a4-port-mix2/mix-1",
  "a4-port-mix2/mix-2",
  "b4-thr/thr-gauss",
  "b4-thr/thr-mix2",
  "b4-thr/thr-blend",
  "b4-cutfn/cutfn-1",
  "b4-qm2h/qm2h-1",
  "b4-flag-split/split-1",
  "b4-fresh4/fresh4-1",
  "b4-fresh4/fresh4-2",
  "b1-ideas/idea-twohyp",
  "b1-fresh/fresh-1"
 ],
 "cancel": [],
 "wake": {
  "batches": [
   "a4-eng3-a",
   "a4-eng3-b",
   "a4-port-mix2",
   "b4-thr",
   "b4-cutfn",
   "b4-qm2h",
   "b4-flag-split",
   "b4-fresh4"
  ],
  "afterMinutes": 150
 },
 "finish": false
}