{"item":"finer-b (batch e03-finer-solve)","credit":"All policy, filter, replica, solver (dp.py) and qm-table method (qmdp.py) are by Taylor (gtmcknight), github.com/gtmcknight/amm-sim @4812a6382311624e1506aca131ca35c378f930d9 research/solved. qt1 (QMRef), TwoComp (TC) and COMBO are IdentityMD items built on that work. This item only re-solves dp.py on a 2.5 bps lattice and swaps the resulting full qm tables into COMBO.","status":"complete: choose and report windows fully covered for all 7 policies; replica only; no contract, no engine seeds used","summary":{"C":"COMBO filter and quoting (code unchanged) reading full (uncompressed) qm tables from an independent 2.5 bps re-solve of dp.py at kappa=1e-5, replacing COMBO's QMS1 spline tables","report_C_minus_COMBO":0.093105,"report_C_minus_qt1":0.690496,"grid_gain_report_C_minus_C5":0.050018,"compression_gain_report_C5_minus_COMBO":0.043087,"reading":"On the report seeds C beats COMBO by +0.093 (se 0.008). About half is the finer grid (C-C5 +0.050 se 0.008) and about half is dropping the spline compression (C5-COMBO +0.043 se 0.008). With the true flag the grid gain disappears (Cflag-C5flag +0.005 se 0.005), so the 2.5 bps tables help only under filter error. Cflag-Flag +0.118 is mostly compression (C5flag-Flag +0.112). C-qt1 is +0.690 on the replica, which is over the +0.5 contract threshold, but most of it is COMBO's own +0.597. A contract would need the 20 MB of 2.5 bps tables compressed, and that compression costs some of the +0.093. Nothing here reaches the +3.5 board gap; the first-call error is unchanged (16.1% for C vs 16.1% for COMBO)."},"hashes":{"amm_sim_commit":"4812a6382311624e1506aca131ca35c378f930d9 (git rev-parse HEAD after checkout)","artifacts_sha256_equal_url_suffix":{"qt1":"8a6e303b662e1a5ea9bb47f31acedd3988ef65b3ddb66d074517aa59ad41ca40 OK","TC":"d3c849db2ac31e567b57e52b80b86e8c24c842e5b4125b9d75c78e3cb07115b9 OK","COMBO":"d360bea6c8c982717b7b43a8069a87013169c89ee3e4da25622db4d880b936d4 OK","QMS1":"17d249ab0c33fc44931d9b105cf3f9e3846a560bd518b67310c2a56defacdecc OK"},"extracted":{"qmref.py":"1dfc9b7a3c2237ff7a93dd9f0af54b9bdab16f2ce0a7eb00784cb4432598db92 (7739 B, matches COMBO's published hash)","twocomp.py":"9d3c1833321493fb51bbde4e1b4dabc2f8978bd6d774ee2af8dc8aed13f0f0af (matches)","combo.py":"c5b711a0b4fb4783e8879a484bf87a427171f4a11aa5eb5ec3513c24ead1a796 (matches)","blob.bin":"3ac7cb8811ecfb6a17f499aa4e9b70dd55f7fb6432b3aec3b904e11a3dece38e (10167 B, matches)","qt1 Strategy.sol fence + trailing newline":"c68887cff61180e12ba2b1ceb333edf76a830f91f63b5d775a8806fb9ec08aca (matches)"},"inputs_research_solved":{"clsdata.py":"41a72a924638e34d4ef56ba922f162e7fe60ac6c915f08d950c648151dc7b227","dp.py":"ca4e7c378d23c46c7def4716611135c471a831d15234b984fe30d58d9eec5734","fillstat.py":"a02f85e20e80f0593b9986e96cfa78f4e5f63947bd8f228a31c60af3f2503ec5","fixedcheck2.py":"de6991683b4a5f2b05b4b0d0a09e963ebc7ca1c4d7b6a4cc7602882999b08c8d","gates.py":"603280c1f595ca163ffaf2ba1ebdc7945fdb08dabae67fc53c922d39e1cce604","latt.py":"925c0fe996b19fd51fb79a85d5e4dba4bc2f5453d0a156cc1e480f65a6a00cc8","qmdp.py":"63b8c35048718c37eb0a5dae9e70849fa3af257c335e4a2e3a625c833f1dc1eb","real.py":"1305b5333731c046c3e6736cc2578eff4635c88132a39c22f5780d78aef2c81e","replica2.py":"6e37b4e61e1ffa5ffb1e43912ddb8659105989aa986eb48fcd1d7608f8dca685","stale.py":"b79b7356f7c46738ca0c5f4718ae397b67e222d8bc57cbc088896270800d5462","trace.py":"6300a33eddc091d9cb3bec5b36e23f32a541a8a2499085b9cc05d08e96b6f692","track.py":"69f49abd59e6bd62f457184cbf6ca7ea16d42bb3ef90d71c0802468ded0ba486","calib_out_2048.json":"fdf24c7aa2b604d770336a5783276da8ed4d50bca9dbcc02e98b4da58f608d26","pol_mid.json":"efbb5ee102db4d312f64565d9bf7232b6becbe02b624164f744a402bbbf2983b","qm_k1e-5.json":"5ff53e42ca87390e5f65d1caa3f7a480e67a8212fb0670274dfd562b05ba1afd"},"outputs":{"qm_k2.json (2.5 bps, kappa 1e-5, 20,241,082 B)":"cfeb051119351818473b406a8ba0aef330d300ff3c0bbd46fafd9db685500932","pol_k2.json":"5b50a083ff9d459411cc9e238af5ea70547ce2b5439bd28e8ac8ad6a198a3424","qm_k1.json (5 bps control)":"afeab9ec765609bc466d8631444afb2caa283c2bbf7c24de078e9f97511e33c2","pol_k1.json":"fafe2c68faec494c434339f78ae688bd281a3fd23f0921d0d63a39d9bd06ff04","pol_k2_VN0.npy float32 (641,25,85,85)":"11c34741a9b4bbcfe84269f96dddc3e1a77f335e491067ecce47ec8bd5a2e0c1","pol_k2_VN1.npy float32 (641,61,85,85)":"9e0e3a65787ed9519eff90a3afc254e686943ce86677ad8edea4b4c851acfadc","pol_k2_VN2.npy float32 (641,61,85,85)":"b46eaa7be271922cbd731aff832ace43c38f0ce56be6bba2256c65ff61ba2fed","pol_k2_vd.npz":"6734f516d941918e37409508e26c3589ec7bd91a195e0b0115be611d1d00ba34","pol_k1_VN0/1/2.npy":["dc602095804048829da58040ce5b40dee25b25edaeeba921f45033e9894072b6","871274b7f2ede9ee9f610c7dfaf7fe450d971259aec3cf4b74245d9cb79be0fd","7fa4b401dde383b3a37f2ba3f79edb63702ece1f4c059f8a486850cdbb32c086"]},"scripts":{"mk.py":"9db14c990f77fca7240830a5ffd89a8a2e929e851eb68f0a8a0aa8fba87ccd79","ex.py":"beba9055330de956d10e6309b6e5bc79c49b809e480fb0332f40d842d12555fe","dpg.py (generated)":"8f4711a7434bed72a5e2b95abbc1bbb900ad4555434303a6de0bdbc76d6a73bb","qmdpg.py (generated)":"a9166606857446e578d9963a7368f0bf0d5db7648f777655c26b196ee02a60b2","pol.py":"6e1eadfafc2368c05984ad92e1a75ddc387e2d1a3b851d81e3174b0cf3f15576","ev.py":"7b7db33a8a9fc02b54aae03b34b295be6d121db4a6ed55549d0f90dfcd2d8888","agg.py":"6472e6294f04ae4da9861fe95913f9e743d5acfaf6cc3092f897ad65f31a0e8b"},"freeze":"freeze.txt (sha256 of tables, solver and policy code) was written after the choose window and before any C/Cflag/C5/C5flag report run, and `sha256sum -c` passed right before the report runs"},"P_output":{"gates.py (unmodified, python3 -I, 4.4 s)":["seed   perfect-info      gaussian+plain    gaussian+qm       lattice+qm","10000  448.261189  443.455598  443.522608  443.663520","10001  576.779199  571.463409  571.623551  571.977293","10002  531.886497  525.168028  525.865859  526.411631"],"matches_README_6dp":true,"qt1 = QMRef(blob.bin) seeds 10000..10002":[443.101741,571.454483,525.908441],"qt1_matches_brief":true,"instrumented QMRef (counters only) gives the same three values; COMBO 444.19533/572.172682/526.27476, Flag 446.854161/574.179253/529.794174, C 444.312264/572.38744/526.190172, Cflag 446.583521/574.231087/529.704784, C5 444.049763/572.130756/526.372399, C5flag 446.744546/574.342963/529.622439":true},"geometry":{"rule":"DP_K=2 scales every lattice-unit constant so the physical ranges stay the same: H 5->2.5 bps; W0 160->320 (w +-800 bps, NW 641); rival band FB 6->12 (+-30 bps, NB 25); price-move support MZ 6->12 (+-30 bps, 25 nodes, sigma 9.45 bps = 3.78 units); actions AMINL -12->-24, NA 43->85 (-60..+150 bps); SQ table 1200->2400; qmdp IGMAX 60->120 (300 bps); fixed-fee rounding by H. The rival grid W2L keeps the same outer physical nodes (+-28..+-320 units = +-70..+-800 bps), is dense at 2.5 bps inside the +-30 bps band (required so phase-0 indices C2+-FB are the band), and uses 5 bps steps for 35..60 bps (the original's spacing there), so N2 49->61. Unchanged: lam 0.8, sigma 9.45, size 20 (midpoint), the 62-node lognormal size quadrature (QSTEP 0.125), the router/constant-product geometry, phase chain, refine's +-0.5-unit parabola, SLEV belief sd levels in bps, kappa 1e-5, and the filter.","W2L_k2_lattice_units":[-320.0,-260.0,-200.0,-160.0,-120.0,-100.0,-80.0,-60.0,-50.0,-40.0,-34.0,-28.0,-24.0,-22.0,-20.0,-18.0,-16.0,-14.0,-12.0,-11.0,-10.0,-9.0,-8.0,-7.0,-6.0,-5.0,-4.0,-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,14.0,16.0,18.0,20.0,22.0,24.0,28.0,34.0,40.0,50.0,60.0,80.0,100.0,120.0,160.0,200.0,260.0,320.0],"memory":"float64 VN2/VN1 2.26 GB each, VN0 0.93 GB, geometry ~3.3 GB; it ran in RAM on a 23 GB machine. Checkpoints were whole-array .npy files, not mmap."},"solver":{"k1_control":{"sweeps":110,"final_residual":1.883e-07,"tol":2e-07,"gain_per_run":536.821,"wall_s":213.6,"check":"pol_k1.json tables A0..B2 are identical to pol_mid.json; qm_k1.json is identical to qm_k1e-5.json except the scalar g (0.05368206098114671 vs ...4493)"},"k2":{"warm_start":"upsampled K=1 solution (VD0, VN0, VN2), linear in w, w2, a, b","sweeps":38,"final_residual":9.210865195008466e-07,"tol":1e-06,"gain_per_run":537.475,"chunks":"3 runs under 8 min each (checkpoint after sweeps 14 and 31)","history_[sweep,g,diff,t_in_chunk_s]":[[1,0.05372302750039012,0.0002131723484469772,73.6],[2,0.05374362850824742,0.00011396525596629736,97.0],[5,0.053745579558645215,8.485573669625435e-05,162.1],[10,0.053747287430986265,7.370112223481495e-05,267.5],[14,0.05374747786611165,6.181940228144889e-05,348.1],[20,0.053747475414500256,2.9182462355059613e-05,136.8],[25,0.05374746804574603,1.5115490775041707e-05,241.0],[30,0.05374746214289533,1.6815991300545008e-06,345.9],[31,0.05374746114448506,1.6355811613966154e-06,366.6],[35,0.053747458279296584,1.4164972208519089e-06,98.8],[38,0.053747457168878576,9.210865195008466e-07,161.4]],"nonconvergence_disclosure":"Stopped at tol 1e-6, not Taylor's 2e-7, to fit the time budget. g was stable to 1e-9 per step over the last 8 sweeps."}},"saved_value_recipe":"DP_SAVEVN=1 writes <out>_VN{0,1,2}.npy as float32 after the final sweep, plus <out>_vd.npz (VD0/1/2 float64). qmdpg.py loads them as float64. Shapes: VN0 (NW,NB,NA,NA), VN1/VN2 (NW,N2,NA,NA).","boundary_checks":{"share_of_cells_at_ask_max_150bps_for_abs_w_le_200bps":{"k2 A0/A1/A2":[0.13043,0.17605,0.17351],"k1 A0/A1/A2":[0.1358,0.19148,0.18846],"note":"mostly rows with w > 150 bps, where the a>=w clamp puts the offset above the grid top (12.5% of these rows). The rest is the same pattern as Taylor's 5 bps tables. No cell is at the -60 bps minimum."},"k2_minus_k1_offsets_at_shared_nodes_abs_w_le_200bps":{"A1":{"mean":-0.016,"mean_abs":0.316,"max_abs":46.449},"A0":{"mean":-0.022,"mean_abs":0.177,"max_abs":4.12}},"hidden_input_invariance":"qt1, COMBO, C and C5 give bit-identical edges on seeds 10000 and 10001 when the arb/p/s2/j arguments are replaced by random junk and init gets junk sigma/lam/size. Flag variants read arb by design (oracle)."},"controls":{"C5":"COMBO over full 5 bps qm tables from this item's matched re-solve (same code path, DP_K=1)","C5flag":"C5 with the flag intervention","choose":{"c5-combo":{"n":1024,"mean_diff":0.060729,"se":0.010388,"worst5":[[64568,-1.54052],[64490,-1.03388],[64938,-0.973953],[64455,-0.959079],[64064,-0.926744]],"won":595},"c-c5":{"n":1024,"mean_diff":0.0252,"se":0.010616,"worst5":[[64963,-1.12064],[64505,-1.020526],[64305,-1.019198],[64906,-0.986033],[64169,-0.960745]],"won":538},"cflag-c5flag":{"n":1024,"mean_diff":-0.000715,"se":0.007596,"worst5":[[64399,-1.236151],[64127,-1.205356],[64957,-0.8142],[64689,-0.806715],[64740,-0.730144]],"won":524},"c5flag-flag":{"n":1024,"mean_diff":0.11078,"se":0.008362,"worst5":[[64568,-1.465585],[64790,-0.622342],[64779,-0.618144],[64577,-0.59272],[64926,-0.581852]],"won":678},"combo-qt1":{"n":1024,"mean_diff":0.609605,"se":0.019401,"worst5":[[64101,-2.776983],[64845,-1.163868],[64374,-1.023434],[64795,-0.983171],[64555,-0.946189]],"won":875},"flag-qt1":{"n":1024,"mean_diff":3.112983,"se":0.030987,"worst5":[[64322,0.08756],[64509,0.148183],[64593,0.208364],[64109,0.570966],[64636,0.581355]],"won":1024}},"report":{"c5-combo":{"n":2048,"mean_diff":0.043087,"se":0.00755,"worst5":[[11519,-1.95316],[12015,-1.737633],[11303,-1.240779],[11786,-1.196135],[10486,-1.158438]],"won":1146},"c-c5":{"n":2048,"mean_diff":0.050018,"se":0.007569,"worst5":[[10146,-1.787537],[11918,-1.322533],[11857,-1.31236],[11555,-1.269918],[10546,-1.086704]],"won":1144},"cflag-c5flag":{"n":2048,"mean_diff":0.005157,"se":0.005324,"worst5":[[10322,-1.186981],[11837,-0.888953],[11659,-0.784132],[11490,-0.703725],[10957,-0.703417]],"won":1055},"c5flag-flag":{"n":2048,"mean_diff":0.112491,"se":0.006068,"worst5":[[12006,-1.419035],[10357,-0.999878],[10208,-0.97118],[10633,-0.894121],[10928,-0.845014]],"won":1376},"combo-qt1":{"n":2048,"mean_diff":0.597391,"se":0.013388,"worst5":[[10146,-3.552497],[11062,-2.334849],[11808,-1.822738],[10519,-1.782691],[11376,-1.750296]],"won":1753},"flag-qt1":{"n":2048,"mean_diff":3.16751,"se":0.022386,"worst5":[[11062,-1.300795],[10146,-0.016155],[11519,0.095586],[11376,0.277364],[10141,0.297378]],"won":2046}}},"selection":"One candidate with no free parameters. Rule: keep C if choose C-COMBO > 0. It was +0.0859 (se 0.0116), so C was kept and the tables frozen. Cflag uses the same tables and settings. Report seeds were never used to choose.","choose_64000_65023":{"c-combo":{"n":1024,"mean_diff":0.085929,"se":0.011606,"worst5":[[64568,-2.190324],[64490,-1.133895],[64941,-1.068947],[64963,-1.028675],[64968,-0.997393]],"won":605},"c-qt1":{"n":1024,"mean_diff":0.695534,"se":0.018731,"worst5":[[64101,-2.357622],[64795,-1.332618],[64447,-1.084982],[64322,-0.887698],[64654,-0.780477]],"won":915},"cflag-flag":{"n":1024,"mean_diff":0.110065,"se":0.00933,"worst5":[[64568,-1.604286],[64399,-1.183067],[64926,-1.098143],[64885,-0.87088],[64501,-0.80617]],"won":685},"cflag-combo":{"n":1024,"mean_diff":2.613443,"se":0.028758,"worst5":[[64901,-0.713067],[64003,-0.30474],[64854,-0.068567],[64203,0.151262],[64132,0.159005]],"won":1021},"cflag-qt1":{"n":1024,"mean_diff":3.223048,"se":0.030864,"worst5":[[64322,0.169377],[64703,0.647146],[64636,0.650538],[64593,0.751501],[64509,0.773035]],"won":1024}},"report_10000_12047":{"c-combo":{"n":2048,"mean_diff":0.093105,"se":0.007779,"worst5":[[11918,-1.680414],[11693,-1.332896],[11064,-1.206534],[10105,-1.156878],[11370,-1.123656]],"won":1255},"c-qt1":{"n":2048,"mean_diff":0.690496,"se":0.013667,"worst5":[[10146,-3.969523],[10519,-1.989222],[11062,-1.976732],[11808,-1.475022],[10236,-1.446322]],"won":1813},"cflag-flag":{"n":2048,"mean_diff":0.117648,"se":0.006745,"worst5":[[12006,-1.669774],[10208,-1.012153],[11540,-0.956997],[10555,-0.877744],[10417,-0.845104]],"won":1352},"cflag-combo":{"n":2048,"mean_diff":2.687768,"se":0.02094,"worst5":[[11701,-1.01869],[11693,-0.699166],[10578,-0.359125],[11519,-0.350863],[11911,-0.157355]],"won":2042},"cflag-qt1":{"n":2048,"mean_diff":3.285159,"se":0.022562,"worst5":[[11062,-0.740595],[10146,0.277233],[11967,0.291949],[10519,0.306947],[11693,0.448411]],"won":2047}},"seed_coverage_and_row_hashes":{"choose":{"qt1":{"n":1024,"complete":true,"mean":535.720495,"rows_sha256":"8e091478a398e5c3c4095f5611b472ef3f0e104a18a959e8400812f294402f3d"},"combo":{"n":1024,"complete":true,"mean":536.3301,"rows_sha256":"1885f8072407b8180b85996ab9115cb434b9fd711d574b0dad05f61c1d0fa56d"},"flag":{"n":1024,"complete":true,"mean":538.833479,"rows_sha256":"1bac6f3c175af6743d2edf70a6a7b4500bb5f62855b620101f166fdd3e7fd2d3"},"c":{"n":1024,"complete":true,"mean":536.416029,"rows_sha256":"474e5d59b0443e5dbb4c66dacd80c136b7e15a52177603dee23c62dabc269a93"},"cflag":{"n":1024,"complete":true,"mean":538.943543,"rows_sha256":"032446a7d0b914812a1dac9f62bd13fa08c11c4c6ceee8e968e3abf8ce6ab93d"},"c5":{"n":1024,"complete":true,"mean":536.39083,"rows_sha256":"efa1f4289a80574ef366e58bede0df3963811971f1e50e9f964860973d375d8a"},"c5flag":{"n":1024,"complete":true,"mean":538.944259,"rows_sha256":"ce62a3db515e82eb9c7fc60ca3ad732981415292d10a99f711465f2ca080172e"}},"report":{"qt1":{"n":2048,"complete":true,"mean":533.262831,"rows_sha256":"d970ed59a12450860818cda274687e3706e3794b193376f8aca8b18a84ca5d7d"},"combo":{"n":2048,"complete":true,"mean":533.860222,"rows_sha256":"62cd7deea74835a60c08ade1e287c351ab56d0d70faa35bf7322f0bb062135a5"},"flag":{"n":2048,"complete":true,"mean":536.430341,"rows_sha256":"87177bc3e1cc794110e53606725b2d32fe80f7c36267a8eb27e4847d5342a74e"},"c":{"n":2048,"complete":true,"mean":533.953327,"rows_sha256":"1f666116596f01039c06b99c2e96c4b214d9252e24b58c2e70eb42e945032420"},"cflag":{"n":2048,"complete":true,"mean":536.547989,"rows_sha256":"b6982c72a76653f34840a553f631d7765eed330a0a7ae1ef03eed15214a59bb8"},"c5":{"n":2048,"complete":true,"mean":533.903309,"rows_sha256":"52304ad1ceec50446821cc53401b271d18cb5390e72ce371e74a997a1608f619"},"c5flag":{"n":2048,"complete":true,"mean":536.542832,"rows_sha256":"57802dbf854db828088355fc08f7734620a1b142f1937f95c860d30b18ac184c"}},"row_hash_rule":"sha256 of ''.join(f'{seed},{edge!r}\\n') over sorted seeds"},"first_call_errors":{"definition":"at each step's first own trade (dt>=1): is_arb=(pi>0.5) differs from the replica's true arb flag","choose":{"qt1":{"wrong":1239361,"total":7197347},"combo":{"wrong":1154223,"total":7201469},"flag":{"wrong":0,"total":7192654},"c":{"wrong":1152163,"total":7206117},"cflag":{"wrong":0,"total":7201882},"c5":{"wrong":1150113,"total":7194163},"c5flag":{"wrong":0,"total":7185615}},"report":{"qt1":{"wrong":2487830,"total":14374445},"combo":{"wrong":2318251,"total":14382447},"flag":{"wrong":0,"total":14364018},"c":{"wrong":2315083,"total":14392271},"cflag":{"wrong":0,"total":14382255},"c5":{"wrong":2312590,"total":14367658},"c5flag":{"wrong":0,"total":14349520}}},"cross_checks":"Report COMBO-qt1 +0.597391 se 0.013388 (1753/2048 won) equals the COMBO artifact's published row exactly.","params":{"lam":0.8,"sigma_bps":9.45,"size":20,"kappa":1e-05,"DP_K":2,"DP_AMINL":-24,"DP_NA":85,"DP_TOL":1e-06,"S_levels_bps":[0,4,8,12,16,20,26,34],"replica":"replica2.run(seed, policy) defaults, 10000 steps"},"flag_intervention":"ComboFlag: inserted `if self.FLAG: pi = float(bool(arb))` right after `pi = la / (la + lr) ...` in COMBO's dt>=1 block, before is_arb, the posterior, rival, phase and quote updates. Other callbacks are unchanged. Flag=ComboFlag(blob), Cflag=ComboFlag(full k2 tables). Oracle-only diagnostics.","regeneration":{"commands":["git clone https://github.com/gtmcknight/amm-sim && git checkout 4812a6382311624e1506aca131ca35c378f930d9","python3 -I ex.py dl w   # extract qmref.py, twocomp.py, combo.py, blob.bin from the 4 artifacts (hashes above)","uv venv --python 3.12 venv; uv pip install numpy numba   # numpy 2.5.4, numba 0.68.1","python3 -I mk.py amm-sim/research/solved solve   # writes dpg.py, qmdpg.py from dp.py/qmdp.py","DP_K=1 DP_SAVEVN=1 DP_AMINL=-12 DP_NA=43 DP_CKPT=k1/ck venv/bin/python dpg.py solve 0.8 9.45 20 k1/pol_k1.json   # 214 s","DP_K=1 DP_AMINL=-12 DP_NA=43 venv/bin/python qmdpg.py k1/pol_k1.json k1/qm_k1.json 1e-5   # 11 s","DP_K=2 DP_SAVEVN=1 DP_AMINL=-24 DP_NA=85 DP_TOL=1e-6 DP_WARM=k1/pol_k1.json DP_CKPT=k2/ck DP_BUDGET=330 venv/bin/python dpg.py solve 0.8 9.45 20 k2/pol_k2.json   # repeat (resumes from checkpoint, exit 3) until SOLVED; 3 chunks, ~13 min total","DP_K=2 DP_AMINL=-24 DP_NA=85 venv/bin/python qmdpg.py k2/pol_k2.json k2/qm_k2.json 1e-5   # 78 s","for m in qt1 combo flag c cflag c5 c5flag: python3 -I ev.py $m 64000 65024 4; then python3 -I agg.py 64000 65024 ...; freeze; python3 -I ev.py $m 10000 12048 4; agg.py 10000 12048 ..."],"timings":"each 1024-seed screen with 4 workers took about 1-2 min, with two screens running at once on 8 cores"},"source_patch":{"mk.py":"import sys,pathlib\nsrc=pathlib.Path(sys.argv[1]); out=pathlib.Path(sys.argv[2])\nt=(src/'dp.py').read_text()\ndef rep(a,b):\n    global t\n    assert t.count(a)==1,a; t=t.replace(a,b)\nrep(\"H = 5e-4\\nW0 = int(os.environ.get('DP_NW', '160'))\",\n\"KS = int(os.environ.get('DP_K', '1'))         # lattice refinement: H = 5 bps / KS; every lattice-unit constant scaled by KS\\nH = 5e-4 / KS\\nW0 = int(os.environ.get('DP_NW', str(160 * KS)))\")\nrep(\"W2L = np.array([-v for v in _out[::-1]] + list(range(-12, 13)) + _out, dtype=np.float64)\",\n\"_mid = [v * KS for v in range(7, 13)] if KS > 1 else []   # 5 bps spacing kept outside the dense band (35..60 bps)\\n_dense = list(range(-6 * KS, 6 * KS + 1)) if KS > 1 else list(range(-12, 13))\\nW2L = np.array([-v * KS for v in _out[::-1]] + [-v for v in _mid[::-1]] + _dense + _mid + [v * KS for v in _out], dtype=np.float64)\")\nrep(\"FB = 6 \", \"FB = 6 * KS \")\nrep(\"MZ = 6 \", \"MZ = 6 * KS \")\nrep(\"for n in range(0, 1200)])\", \"for n in range(0, 1200 * KS)])\")\nrep(\"fixed_fee_l=int(round(fee / 5.0))\", \"fixed_fee_l=int(round(fee / (5.0 / KS)))\")\n# warm start + checkpoint\nrep(\"def solve(lam, sigma_bps, size_mean, fixed_fee_l=-1, tol=2e-7, max_sweeps=600, verbose=True):\",\n\"def solve(lam, sigma_bps, size_mean, fixed_fee_l=-1, tol=float(os.environ.get('DP_TOL', '2e-7')), max_sweeps=int(os.environ.get('DP_MAXSW', '600')), verbose=True):\")\nrep(\"\"\"    VD0 = np.zeros((NW, NB)); VN0 = np.zeros((NW, NB, NA, NA))\n    VN2 = np.zeros((NW, N2, NA, NA))\n    g = 0.0\"\"\",\"\"\"    VD0 = np.zeros((NW, NB)); VN0 = np.zeros((NW, NB, NA, NA))\n    VN2 = np.zeros((NW, N2, NA, NA))\n    g = 0.0\n    CK = os.environ.get('DP_CKPT'); it0 = 0; hist = []\n    if CK and os.path.exists(CK + '_state.json'):\n        st = json.load(open(CK + '_state.json')); it0 = st['it']; hist = st['hist']; g = st['g']\n        VD0 = np.load(CK + '_VD0.npy'); VN0 = np.load(CK + '_VN0.npy'); VN2 = np.load(CK + '_VN2.npy')\n        if verbose: print(f'resume at sweep {it0}', flush=True)\n    elif os.environ.get('DP_WARM'):\n        VD0, VN0, VN2 = warm(os.environ['DP_WARM'])\n        if verbose: print('warm start from', os.environ['DP_WARM'], flush=True)\n    budget = float(os.environ.get('DP_BUDGET', '1e9')); diff = 1e9\"\"\")\nrep(\"\"\"    for it in range(max_sweeps):\n        S = step_end\"\"\",\"\"\"    for it in range(it0, max_sweeps):\n        S = step_end\"\"\")\nrep(\"\"\"        if diff < tol: break\n    return dict(\"\"\",\"\"\"        hist.append([it + 1, float(g), float(diff), round(time.time() - t0, 1)])\n        if diff < tol: break\n        if time.time() - t0 > budget and CK:\n            np.save(CK + '_VD0.npy', VD0); np.save(CK + '_VN0.npy', VN0); np.save(CK + '_VN2.npy', VN2)\n            json.dump(dict(it=it + 1, hist=hist, g=float(g)), open(CK + '_state.json', 'w'))\n            print(f'CHECKPOINT sweep {it+1} diff {diff:.3e}', flush=True); sys.exit(3)\n    if CK: json.dump(dict(it=it + 1, hist=hist, g=float(g), done=True, final_diff=float(diff)), open(CK + '_final.json', 'w'))\n    return dict(\"\"\")\nrep(\"def refine(VN, IA, IB):\", '''def warm(path):\n    \"\"\"upsample a KS=1 solution (VD0, VN0, VN2 saved by DP_SAVEVN) onto this lattice: linear in w, w2, a, b (lattice units scale by KS).\"\"\"\n    z = np.load(path.replace('.json', '_vd.npz')); vd0 = z['VD0']\n    vn0 = np.load(path.replace('.json', '_VN0.npy')).astype(np.float64); vn2 = np.load(path.replace('.json', '_VN2.npy')).astype(np.float64)\n    W2c = np.array([-v for v in _out[::-1]] + list(range(-12, 13)) + _out, dtype=np.float64)\n    def ax(n_f, x):   # fractional index on a uniform coarse axis\n        p = np.clip(x, 0, n_f - 1); i = np.minimum(p.astype(np.int64), n_f - 2); return i, p - i\n    iw, fw = ax(vd0.shape[0], (np.arange(NW) - W0) / KS + 160)\n    ib_, fb_ = ax(vn0.shape[1], (np.arange(NB) - FB) / KS + 6)\n    ia_, fa_ = ax(vn0.shape[2], (AMINL + np.arange(NA)) / KS + 12)\n    j2 = np.zeros(N2, np.int64); f2 = np.zeros(N2)\n    for k in range(N2):\n        v = W2L[k] / KS\n        if v <= W2c[0]: j2[k] = 0; f2[k] = 0.0\n        elif v >= W2c[-1]: j2[k] = len(W2c) - 2; f2[k] = 1.0\n        else:\n            j = int(np.searchsorted(W2c, v, side='right') - 1); j = min(j, len(W2c) - 2); j2[k] = j; f2[k] = (v - W2c[j]) / (W2c[j + 1] - W2c[j])\n    def up4(A, i1, f1):\n        A = A[iw] * (1 - fw)[:, None, None, None] + A[iw + 1] * fw[:, None, None, None]\n        A = A[:, i1] * (1 - f1)[None, :, None, None] + A[:, i1 + 1] * f1[None, :, None, None]\n        A = A[:, :, ia_] * (1 - fa_)[None, None, :, None] + A[:, :, ia_ + 1] * fa_[None, None, :, None]\n        A = A[:, :, :, ia_] * (1 - fa_)[None, None, None, :] + A[:, :, :, ia_ + 1] * fa_[None, None, None, :]\n        return A\n    V0 = vd0[iw] * (1 - fw)[:, None] + vd0[iw + 1] * fw[:, None]; V0 = V0[:, ib_] * (1 - fb_) + V0[:, ib_ + 1] * fb_\n    return V0, up4(vn0, ib_, fb_), up4(vn2, j2, f2)\n\n\ndef refine(VN, IA, IB):''')\nrep(\"for j in range(3): np.save(out.replace('.json', f'_VN{j}.npy'), r['VN'][j].astype(np.float32))\",\n\"for j in range(3): np.save(out.replace('.json', f'_VN{j}.npy'), r['VN'][j].astype(np.float32))\\n            if os.environ.get('DP_SAVEVN64'): np.save(out.replace('.json', '_VN2f64.npy'), r['VN'][2])\")\nout.joinpath('dpg.py').write_text(t)\nq=(src/'qmdp.py').read_text()\nfor a,b in [(\"import dp\\n\",\"import dp as dp\\n\"),(\"IGMAX = 60 \",\"IGMAX = 60 * dp.KS \")]:\n    assert q.count(a)>=1,a; q=q.replace(a,b,1)\nq=q.replace(\"import dp as dp\\nfrom dp import\",\"import dpg as dp\\nfrom dpg import\")\nassert 'import dpg as dp' in q\nout.joinpath('qmdpg.py').write_text(q)\n","pol.py":"\"\"\"Policies for finer-b. Credit: Taylor (gtmcknight) -- replica2, Gaussian filter, fee rule, dp/qmdp solver\n(github.com/gtmcknight/amm-sim @4812a638 research/solved); qt1 (QMRef), TwoComp and COMBO are IdentityMD items on it.\nVariants: qt1, COMBO, Flag (oracle), C = COMBO over full qm tables from the 2.5 bps solve, Cflag (oracle),\nC5 / C5flag = matched control over full tables from the 5 bps re-solve. Instrumentation only counts first-call errors.\"\"\"\nimport os, sys, json, pathlib\nHERE = pathlib.Path(__file__).resolve().parent; W = HERE.parent / 'w'\nSRC_TC = (W / 'twocomp.py').read_text(); SRC_CO = (W / 'combo.py').read_text()\ndef patch(t, a, b):\n    assert t.count(a) == 1, a; return t.replace(a, b)\n# instrument qt1 (QMRef) and TwoComp-derived first-call classification; no state change\ntc = patch(SRC_TC, \"pi = la / (la + lr) if la + lr > 0 else 0.; is_arb = pi > .5\",\n           \"pi = la / (la + lr) if la + lr > 0 else 0.; is_arb = pi > .5; self.nfirst = getattr(self, 'nfirst', 0) + 1; self.nwrong = getattr(self, 'nwrong', 0) + (is_arb != bool(arb))\")\nco = patch(SRC_CO, \"from twocomp import\", \"from twocomp_i import\")\nco = patch(co, \"            pi = la / (la + lr) if la + lr > 0 else 0.\\n            is_arb = pi > .5\\n\",\n           \"            pi = la / (la + lr) if la + lr > 0 else 0.\\n            if self.FLAG: pi = float(bool(arb))   # oracle diagnostic: true flag right after the likelihood\\n\"\n           \"            is_arb = pi > .5\\n            self.nfirst = getattr(self, 'nfirst', 0) + 1; self.nwrong = getattr(self, 'nwrong', 0) + (is_arb != bool(arb))\\n\")\nco = patch(co, \"class Combo(TwoComp):\\n\", \"class Combo(TwoComp):\\n    FLAG = False\\n\")\nimport types\nm1 = types.ModuleType('twocomp_i'); exec(compile(tc, 'twocomp_i', 'exec'), m1.__dict__); sys.modules['twocomp_i'] = m1\nm2 = types.ModuleType('combo_i'); exec(compile(co, 'combo_i', 'exec'), m2.__dict__)\nQMRef, Combo = m1.QMRef, m2.Combo\nclass ComboFlag(Combo): FLAG = True\n\nclass FullT:\n    \"\"\"full (uncompressed) qm tables from qmdpg.py output, in the attribute layout QMRef expects\"\"\"\n    def __init__(self, path):\n        d = json.load(open(path))\n        self.P = dict(S=d['S'], W0=d['W0'], NW=d['NW'], H=float(d['H_bps']), FB=d['FB'], W2L=[float(v) for v in d['W2L']])\n        self.A = {t: d['A' + t] for t in ('0c', '1s', '1c', '2s', '2c')}; self.B = {t: d['B' + t] for t in ('0c', '1s', '1c', '2s', '2c')}\ndef full(path):\n    key = 'full:' + path\n    if key not in QMRef._cache: QMRef._cache[key] = FullT(path)\n    return key\nBLOB = str(W / 'blob.bin')\nQK2 = str(HERE.parent / 'solve' / 'k2' / 'qm_k2.json'); QK1 = str(HERE.parent / 'solve' / 'k1' / 'qm_k1.json')\ndef make(mode):\n    if mode == 'qt1': return QMRef(BLOB)\n    if mode == 'qt1raw':\n        import importlib; sys.path.insert(0, str(W)); return importlib.import_module('qmref').QMRef(BLOB)\n    if mode == 'combo': return Combo(BLOB)\n    if mode == 'flag': return ComboFlag(BLOB)\n    if mode == 'c': return Combo(full(QK2))\n    if mode == 'cflag': return ComboFlag(full(QK2))\n    if mode == 'c5': return Combo(full(QK1))\n    if mode == 'c5flag': return ComboFlag(full(QK1))\n    raise ValueError(mode)\n","ev.py":"\"\"\"Paired replica screen on Taylor (gtmcknight)'s replica2 (unmodified run defaults, 10000 steps).\nusage: python3 -I ev.py MODE START STOP WORKERS   -> state/MODE.jsonl (seeds already present are skipped)\"\"\"\nimport sys, json, pathlib, multiprocessing as mp\nHERE = pathlib.Path(__file__).resolve().parent\nsys.path.insert(0, str(HERE)); sys.path.insert(1, str(HERE.parent / 'amm-sim' / 'research' / 'solved'))\nimport replica2 as R, pol\nMODE = sys.argv[1]\ndef one(seed):\n    p = pol.make(MODE); r = R.run(seed, p)\n    return dict(seed=seed, edge=r['edge'], nfirst=getattr(p, 'nfirst', 0), nwrong=getattr(p, 'nwrong', 0))\nif __name__ == '__main__':\n    a, b, nw = int(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4])\n    st = HERE / 'state'; st.mkdir(exist_ok=True); f = st / f'{MODE}.jsonl'\n    done = set(json.loads(l)['seed'] for l in f.open()) if f.exists() else set()\n    todo = [s for s in range(a, b) if s not in done]\n    with mp.Pool(nw) as P, f.open('a') as out:\n        for r in P.imap_unordered(one, todo, chunksize=4):\n            out.write(json.dumps(r) + '\\n'); out.flush()\n    print(MODE, a, b, 'ran', len(todo))\n","agg.py":"\"\"\"aggregate paired screens. usage: python3 -I agg.py START STOP mode...\"\"\"\nimport sys, json, math, hashlib, pathlib\nst = pathlib.Path(__file__).resolve().parent / 'state'\na, b = int(sys.argv[1]), int(sys.argv[2]); modes = sys.argv[3:]\nD = {}; out = {'window': [a, b - 1], 'modes': {}, 'pairs': {}}\nfor m in modes:\n    rows = {}\n    for l in (st / f'{m}.jsonl').open():\n        r = json.loads(l)\n        if a <= r['seed'] < b: rows[r['seed']] = r\n    seeds = sorted(rows); D[m] = rows\n    h = hashlib.sha256(''.join(f\"{s},{rows[s]['edge']!r}\\n\" for s in seeds).encode()).hexdigest()\n    out['modes'][m] = dict(n=len(seeds), complete=seeds == list(range(a, b)), mean=round(sum(rows[s]['edge'] for s in seeds) / len(seeds), 6),\n                           first_call_errors=dict(wrong=sum(rows[s]['nwrong'] for s in seeds), total=sum(rows[s]['nfirst'] for s in seeds)), rows_sha256=h)\ndef pair(x, y):\n    s = sorted(set(D[x]) & set(D[y])); d = [D[x][k]['edge'] - D[y][k]['edge'] for k in s]; n = len(d); mu = sum(d) / n\n    sd = math.sqrt(sum((v - mu) ** 2 for v in d) / (n - 1))\n    w = sorted(zip(d, s))[:5]\n    return dict(n=n, mean_diff=round(mu, 6), se=round(sd / math.sqrt(n), 6), worst5=[[k, round(v, 6)] for v, k in w], won=sum(v > 0 for v in d))\nfor x, y in [('c', 'combo'), ('c', 'qt1'), ('cflag', 'flag'), ('cflag', 'combo'), ('cflag', 'qt1'), ('c5', 'combo'), ('c', 'c5'), ('cflag', 'c5flag'), ('c5flag', 'flag'), ('combo', 'qt1'), ('flag', 'qt1')]:\n    if x in D and y in D: out['pairs'][f'{x}-{y}'] = pair(x, y)\nprint(json.dumps(out))\n"},"limitations":["Replica only. Replica edges are not board scores, and no engine seed was used.","K=2 converged to 9.2e-7, not 2e-7 (disclosed above).","qm_k2.json is 20 MB. It is not delivered; the regeneration commands and its SHA256 are. A contract would need it compressed, and that compression would give back part of the gain.","VN arrays were held in RAM with whole-array checkpoints, not mmap.","Boundary check: a 46 bps max |K2-K1| offset difference at some shared node shows the tables differ locally; mean |diff| is 0.3 bps.","The arb/retail call is not improved: first-call error is about 16.1% for both C and COMBO."]}