{
 "previous": "2026-09-29-research-deployed",
 "setup": {
  "date": "2026-09-29",
  "agent": "claude -p, model claude-opus-5-5, the same on both sides (Claude Code 2.1.285 on the MCP side, 2.1.284 on the parquet side)",
  "harness": "scripts/run_research_agents.py unchanged since P4-A18 (byte for byte, checked with cmp on both hosts): system prompt replaced (published in results.json), no settings sources, no CLAUDE.md, no MCP servers except the one declared, permission prompts off. Fresh work directories, so no agent found an earlier run's scripts",
  "tools_both_sides": "Bash, and a Python with duckdb 1.5.6, pandas 3.0.6, pyarrow 25.0.1, numpy 2.5.3 (the same pinned environment as A20; Python 3.14 on the MCP side, 3.12 on the parquet side)",
  "mcp_side": "market-data-mcp as deployed on its serving host at 2026-09-29 22:07 CEST: every installed module is byte-identical to upstream 96efb79, which adds withheld_by_floor (bars, trades, volume) and extremum_warning to run_query and trims describe_dataset for one instrument. Tool definitions are byte-identical to A20's (tools.json), so only the responses changed. Run from the installed entry point over stdio with MDMCP_MODE=public: 1-minute bars, bars with fewer than 3 trades withheld",
  "raw_side": "the same parquet copy A20 used (hard-linked, not re-copied): the 12 datasets the tasks touch, 2026-09-20..28, from the serving host, in the delivered {venue}/{type}/parquet/YYYY/MM/DD/HH-HH.parquet layout",
  "raw_side_bytes": 5213305568,
  "raw_side_memory_cap": "whole agent process tree capped at 6 GB, as before",
  "hosts": "MCP side: the agents ran on the same analysis host as A20's MCP side and reached the server over stdio on the serving host. Parquet side: the serving host, as in A20, because the analysis host was running another lane's multi-hour job (one heavy job at a time). Precondition checked before the parquet side: analysis host 25 GB available, memory pressure zero, no sealed-research heavy unit running; serving host 33 GB available, memory pressure about 3% (some, 60 s). The parquet side ran on the same host as last time, so its wall times are comparable to A20's; the MCP side's are not comparable to the parquet side's. Tokens compare everywhere",
  "tokens": "the API's own usage counts, Claude tokenizer. processed = sum over every API call of input + cache reads + cache writes + output",
  "cost_usd": "as reported by the CLI at list price",
  "reference": "A15/A20's reference scripts on the same bytes, plus three new ones in reference/: t2_tiebreak.py (T2 maxima under explicit same-millisecond order, with and without the floor), t3_vol_floor.py (1-minute realised vol by the MCP agent's own definition, with and without the floor), withheld_probe.py (withheld_by_floor per instrument from the deployed server)",
  "tie_order": "CORRECTION TO A15/A20's T2 REFERENCE. Several fills often share one millisecond, and a minute's close is the last of them. The earlier reference broke ties by trade id. On Hyperliquid the id is not a sequence: at 13:31:58.930 on 09-27 one taker order filled 29 times in the same millisecond, walking up the book 85,028 -> 85,040 in the archive's row order and in no order at all by id. Row order is fill order. Under fill order Pacifica's largest dislocation is -11.05 bp at 13:31 (not -10.58 bp at 13:33) and ApeX's is -5.68 bp at 08:44 (not -5.60 bp at 07:12); edgeX and dYdX do not move. The parquet agent in this run chose fill order on its own and matches exactly",
  "floor_and_t2": "Under fill order the floor removes NONE of the four T2 maxima: with and without it the answer is identical for every venue (reference/t2_tiebreak.json). The case the server's extremum_warning cites (a 2-trade Pacifica minute) exists only under trade-id order. The floor still costs T2 one thing: dYdX lead-lag, where it withholds 277 of dYdX's 409 trading minutes and leaves 34 usable return pairs",
  "variance": "One run per cell. A20 measured the parquet side's own run-to-run swing at up to about 1.5x with nothing changed; only moves larger than that are counted. This run's parquet side moved 0.69x-1.05x against A20, inside that band",
  "withheld_by_instrument": [
   {
    "window": "2026-09-21..28",
    "instrument": "hyperliquid/trades:BTC",
    "bars_kept": 10077,
    "bars_withheld": 0,
    "trades_kept": 2406078,
    "trades_withheld": 0,
    "volume_kept": 246523.02896,
    "volume_withheld": 0.0,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-21..28",
    "instrument": "edgex/trades:BTCUSDC",
    "bars_kept": 10079,
    "bars_withheld": 1,
    "trades_kept": 826369,
    "trades_withheld": 2,
    "volume_kept": 35316.548,
    "volume_withheld": 0.01,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-21..28",
    "instrument": "apex/trades:BTCUSDT",
    "bars_kept": 10080,
    "bars_withheld": 0,
    "trades_kept": 165722,
    "trades_withheld": 0,
    "volume_kept": 24895.711,
    "volume_withheld": 0.0,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-21..28",
    "instrument": "pacifica/trades:BTC",
    "bars_kept": 6955,
    "bars_withheld": 2942,
    "trades_kept": 80611,
    "trades_withheld": 5240,
    "volume_kept": 16155.34616,
    "volume_withheld": 163.65358,
    "pct_bars_withheld": 29.7,
    "pct_trades_withheld": 6.1,
    "pct_volume_withheld": 1.0
   },
   {
    "window": "2026-09-21..28",
    "instrument": "dydx/trades:BTC-USD",
    "bars_kept": 1885,
    "bars_withheld": 2320,
    "trades_kept": 15247,
    "trades_withheld": 3262,
    "volume_kept": 662.808,
    "volume_withheld": 27.4641,
    "pct_bars_withheld": 55.2,
    "pct_trades_withheld": 17.6,
    "pct_volume_withheld": 3.98
   },
   {
    "window": "2026-09-21..28",
    "instrument": "paradex/trades:BTC-USD-PERP",
    "bars_kept": 1221,
    "bars_withheld": 194,
    "trades_kept": 14130,
    "trades_withheld": 274,
    "volume_kept": 122.85006,
    "volume_withheld": 5.02399,
    "pct_bars_withheld": 13.7,
    "pct_trades_withheld": 1.9,
    "pct_volume_withheld": 3.93
   },
   {
    "window": "2026-09-21..28",
    "instrument": "nado/trades:2",
    "bars_kept": 9299,
    "bars_withheld": 464,
    "trades_kept": 261162,
    "trades_withheld": 695,
    "volume_kept": 9984.1123,
    "volume_withheld": 13.0149,
    "pct_bars_withheld": 4.8,
    "pct_trades_withheld": 0.3,
    "pct_volume_withheld": 0.13
   },
   {
    "window": "2026-09-27",
    "instrument": "hyperliquid/trades:BTC",
    "bars_kept": 1440,
    "bars_withheld": 0,
    "trades_kept": 175800,
    "trades_withheld": 0,
    "volume_kept": 14529.77049,
    "volume_withheld": 0.0,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-27",
    "instrument": "edgex/trades:BTCUSDC",
    "bars_kept": 1440,
    "bars_withheld": 0,
    "trades_kept": 63737,
    "trades_withheld": 0,
    "volume_kept": 1344.725,
    "volume_withheld": 0.0,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-27",
    "instrument": "apex/trades:BTCUSDT",
    "bars_kept": 1440,
    "bars_withheld": 0,
    "trades_kept": 18490,
    "trades_withheld": 0,
    "volume_kept": 3490.477,
    "volume_withheld": 0.0,
    "pct_bars_withheld": 0.0,
    "pct_trades_withheld": 0.0,
    "pct_volume_withheld": 0.0
   },
   {
    "window": "2026-09-27",
    "instrument": "pacifica/trades:BTC",
    "bars_kept": 801,
    "bars_withheld": 610,
    "trades_kept": 7239,
    "trades_withheld": 1078,
    "volume_kept": 1449.85402,
    "volume_withheld": 27.68117,
    "pct_bars_withheld": 43.2,
    "pct_trades_withheld": 13.0,
    "pct_volume_withheld": 1.87
   },
   {
    "window": "2026-09-27",
    "instrument": "dydx/trades:BTC-USD",
    "bars_kept": 132,
    "bars_withheld": 277,
    "trades_kept": 1422,
    "trades_withheld": 362,
    "volume_kept": 100.6532,
    "volume_withheld": 3.0012,
    "pct_bars_withheld": 67.7,
    "pct_trades_withheld": 20.3,
    "pct_volume_withheld": 2.9
   },
   {
    "window": "2026-09-27 day",
    "instrument": "paradex/trades:BTC-USD-PERP",
    "no_data": true
   },
   {
    "window": "2026-09-27",
    "instrument": "nado/trades:2",
    "bars_kept": 1225,
    "bars_withheld": 126,
    "trades_kept": 23132,
    "trades_withheld": 187,
    "volume_kept": 643.85435,
    "volume_withheld": 3.02325,
    "pct_bars_withheld": 9.3,
    "pct_trades_withheld": 0.8,
    "pct_volume_withheld": 0.47
   }
  ],
  "withheld_count_vs_volume": "Measured by the market-data-mcp lane on the deployed server, dydx/trades over two hours: BTC-USD 47.5% of trades withheld against 5.4% of volume, ETH-USD 21.1% against 9.7%. Over this run's week, per instrument: dYdX BTC-USD 17.6% of trades against 3.98% of volume, Pacifica BTC 6.1% against 1.0%, Paradex BTC-USD-PERP 1.9% against 3.93%. Never summed across instruments: volume is in each instrument's own base unit",
  "previous_note": "This run re-measures both routes after the server began stating what its three-trade floor withheld. The previous run measured the same routes before that change."
 },
 "predictions": [
  {
   "task": "t1",
   "registered": "T1 stays correct and cheap.",
   "outcome": "met",
   "evidence": "Correct on both routes. 165k tokens through the MCP against 297k over the parquet: still the cheaper route. Against A20's 127k it is 1.31x, inside the 1.5x noise band, so the win holds and did not measurably change."
  },
  {
   "task": "t3",
   "registered": "T3 improves, because it is a sum and totals are addable.",
   "outcome": "missed",
   "evidence": "The sum improved exactly as predicted: all seven notionals are now right, because the agent read withheld_by_floor and added the withheld volume back (dYdX $58.6M against $58.5M; A20's agent was 4% short). The grade did not improve: it is still partly wrong, because the floor also biases realised vol, which is not a sum. Pacifica came back 43.8% against 36.4% and dYdX 88.5% against 68.0% on the same definition. The prediction's mechanism worked; the task outcome it predicted did not happen."
  },
  {
   "task": "t2",
   "registered": "T2 stays partly wrong, with the best available outcome being an honest refusal.",
   "outcome": "met, for a reason other than the one registered",
   "evidence": "Still partly wrong, and the one cell the floor genuinely blocks (dYdX lead-lag, 34 usable pairs) was correctly declined. But the extremum the prediction was about is not a floor limit: under fill order the floor removes none of the four maxima. What is left wrong (Pacifica's value, ApeX's minute) comes from how the server picks a bar's close among fills sharing a millisecond, which is fixable, not policy."
  }
 ],
 "tasks": {
  "t1": {
   "reference": "APR, BTC / ETH: Hyperliquid 11.1 / 12.4, edgeX 6.7 / 10.95 time-weighted (7.1 / 10.95 sampled at its 42 settlements; rate is per 4 h), Extended 7.6 / 11.3, Pacifica 10.0 / 10.95. Nado, on the serving host's copy, to one significant figure: BTC 2, ETH 8 (a 24 h rate carried forward over a change-only feed). Best carry: long BTC on Nado, short BTC on Hyperliquid, about +10% APR. Unchanged from A20: funding is not touched by the trade floor.",
   "bytes_needed": 2100911213
  },
  "t2": {
   "reference": "CORRECTED this run (fill order within a millisecond; see setup.tie_order). Correlation peaks at lag 0 for edgeX (0.96) and ApeX (0.92): no leader at 1 minute. Hyperliquid leads Pacifica (lag +1 about 0.30) and dYdX (lag +1, weaker, on about 197 returns). Largest dislocations: edgeX -5.51 bp 06:27, ApeX -5.68 bp 08:44, Pacifica -11.05 bp 13:31, dYdX +66.36 bp 14:29 (one order sweeping the book inside one millisecond). The floor withholds none of these four minutes.",
   "bytes_needed": 901415597
  },
  "t3": {
   "reference": "Notional: Hyperliquid 20.87B (73.8%), edgeX 2.99B, ApeX 2.11B, Pacifica 1.38B, Nado about 0.8B (one significant figure, the serving host's copy), dYdX 58.5M, Paradex 10.9M (only 28 h of data in the window). Realised vol about 36-37% on the liquid venues; dYdX and Paradex higher from thin trading. Added this run: on back-to-back minutes only (the MCP agent's definition) the full data gives Pacifica 36.4% and dYdX 68.0%; dropping minutes of fewer than 3 trades gives 43.8% and 88.5% (reference/t3_vol_floor.json).",
   "bytes_needed": 3112394355
  },
  "s1": {
   "reference": "84,600.71 (175,800 trades)",
   "bytes_needed": 587883959
  },
  "s2": {
   "reference": "About $50M to one significant figure, on the serving host's copy (product 2; product 1 is spot). Both routes and the reference agree on the exact figure, which is in results and transcripts.",
   "bytes_needed": 8939310
  },
  "s3": {
   "reference": "26.6% (0.2661)",
   "bytes_needed": 245563216
  },
  "k1": {
   "reference": "84,600.71"
  },
  "k2": {
   "reference": "About $50M, as s2"
  },
  "k3": {
   "reference": "26.6%"
  }
 },
 "runs": {
  "t1_mcp": {
   "verdict": "correct",
   "note": "Four get_funding calls plus checks. Hyperliquid 11.12/12.40, edgeX 6.65/10.95, Extended 7.59/11.26, Pacifica 10.02/10.95 % APR for BTC/ETH, and Nado BTC about 2%, ETH about 8% on the serving host's copy (the agent quoted the Nado range across copies and said why). Best trade long Nado, short Hyperliquid BTC, about +10% APR (it said 9.6%). Stated each interval. 165k tokens against 127k in A20 (1.31x, inside the noise) and 297k for the parquet agent: the funding win holds."
  },
  "t1_raw": {
   "verdict": "correct",
   "note": "Time-weighted every rate, carried Nado's change-only feed forward, converted edgeX from 4 h and Nado from 24 h. Same figures as the MCP agent; Nado about 2% BTC on the serving host's copy. 297k tokens against 319k in A20."
  },
  "t2_mcp": {
   "verdict": "partly wrong",
   "cells": [
    {
     "cell": "lead-lag edgeX",
     "grade": "correct"
    },
    {
     "cell": "lead-lag ApeX",
     "grade": "correct"
    },
    {
     "cell": "lead-lag Pacifica",
     "grade": "correct"
    },
    {
     "cell": "lead-lag dYdX",
     "grade": "correctly declined",
     "why": "Said it cannot be determined from 34 usable return pairs, and tabled the 277 dYdX minutes the floor withheld. This is the one T2 cell the floor genuinely blocks."
    },
    {
     "cell": "dislocation edgeX",
     "grade": "correct"
    },
    {
     "cell": "dislocation ApeX",
     "grade": "partly wrong",
     "why": "-5.60 bp at 07:12 against -5.68 bp at 08:44. Hyperliquid's last millisecond of 08:44 holds 11 fills walking 84,706 to 84,716 in fill order, and the server's close is one of the middle ones. Not the floor."
    },
    {
     "cell": "dislocation Pacifica",
     "grade": "partly wrong",
     "why": "Right minute (13:31), value -10.70 bp against -11.05 bp: the server's Hyperliquid close for 13:31 is a middle fill of a 29-fill sweep. The agent warned this maximum might sit in a withheld minute; that caution was reasonable but it was not the cause."
    },
    {
     "cell": "dislocation dYdX",
     "grade": "correct"
    }
   ],
   "note": "Lead-lag right for edgeX, ApeX and Pacifica, and dYdX's lead correctly declined: the floor withholds 277 of its 409 trading minutes and the agent said 34 pairs cannot decide it, naming the withheld minutes. That is the fourth grade, earned on the one cell the floor genuinely blocks. Dislocations right for edgeX and dYdX (+66.36 bp at 14:29). Pacifica is the right minute with the wrong value (-10.70 against -11.05 bp) and ApeX the wrong minute by 0.08 bp: both come from how the server picks a close among fills sharing a millisecond, not from the floor, which withholds none of the four maxima under fill order. 614k tokens against 309k in A20: dearer by more than the noise, from 15 model calls against 7, each re-reading the conversation (the tool output it received was smaller, about 113k characters against 128k); 4.6x the parquet agent."
  },
  "t2_raw": {
   "verdict": "correct",
   "note": "Deduplicated on trade id and, on its own, kept same-millisecond fills in file order (fill order) rather than id order: edgeX -5.51 bp 06:27, ApeX -5.68 bp 08:44, Pacifica -11.05 bp 13:31, dYdX +66.36 bp 14:29, matching the corrected reference exactly. Hyperliquid leads Pacifica and dYdX (the latter on 197 returns, weaker). 134k tokens against 193k in A20 (0.69x, inside the noise)."
  },
  "t3_mcp": {
   "verdict": "partly wrong",
   "cells": [
    {
     "cell": "notional and share, all seven venues",
     "grade": "correct",
     "why": "Read withheld_by_floor and added the withheld volume back at the week's average price. A20's agent was 4% short on dYdX and Paradex."
    },
    {
     "cell": "realised vol Hyperliquid, edgeX, ApeX",
     "grade": "correct"
    },
    {
     "cell": "realised vol Pacifica, dYdX",
     "grade": "partly wrong",
     "why": "43.8% and 88.5% against 36.4% and 68.0% on the agent's own definition over all minutes. Removing the floor's minutes from the parquet reproduces the agent's figures to the pair (5,217 and 774 pairs). Attributed to thin trading, not to the floor."
    },
    {
     "cell": "consistency and outliers",
     "grade": "correct",
     "why": "dYdX and Paradex named as the outliers, from thin trading; it also called Pacifica high at 1 minute, which the full data does not show."
    }
   ],
   "note": "The sum is fixed: every notional and share is right, dYdX $58.6M against $58.5M and Paradex $10.9M, Pacifica 1.38B, Nado about 0.8B on the serving host's copy, because the agent read withheld_by_floor and added the withheld volume back. The vol half is now what the floor costs: Pacifica 43.8% against 36.4% and dYdX 88.5% against 68.0% on the agent's own definition (back-to-back minutes), because a minute with 3 or more trades is a busier, more volatile minute; the parquet reproduces both figures exactly once the floor's minutes are removed. A withheld total cannot repair a second moment, and nothing said so in terms the agent acted on: extremum_warning fired on 14 of the 17 query results it received, because it triggers on any ORDER BY. 963k tokens against 707k in A20 (1.36x, inside the noise); 2.9x the parquet agent."
  },
  "t3_raw": {
   "verdict": "correct",
   "note": "Deduplicated across file boundaries, excluded Pacifica settlement prints and Paradex unwind transfers, flagged Paradex's 28 hours. Notional matches the reference, Nado about 0.8B on the serving host's copy; vol with prices carried forward, Pacifica 35.9%, dYdX 39.9%. 328k tokens against 338k in A20."
  },
  "s1_mcp": {
   "verdict": "correct",
   "note": "84,600.71 from the same 175,800 trades. 49k tokens against 167k in A20 (0.29x, a real move): describe_dataset for one instrument now answers in about 9,000 to 12,000 characters, against 47,004 last time. Still dearer than the parquet agent's 39k."
  },
  "s1_raw": {
   "verdict": "correct",
   "note": "84,600.71 from 175,800 trades."
  },
  "s2_mcp": {
   "verdict": "correct",
   "note": "About $50M on the serving host's copy, the same figure to the dollar as the reference. It used hourly bars (nothing withheld) and cross-checked the minute bars, whose shortfall it matched to withheld_by_floor exactly: 187 trades, about 3 BTC. 193k tokens against 280k in A20 (0.69x, inside the noise); the parquet agent spent 65k."
  },
  "s2_raw": {
   "verdict": "correct",
   "note": "About $50M on the serving host's copy, the same figure to the dollar as the reference."
  },
  "s3_mcp": {
   "verdict": "correct",
   "note": "26.6% (0.2662). 82k tokens against 55k in A20 (1.48x, just inside the noise) and 74k for the parquet agent."
  },
  "s3_raw": {
   "verdict": "correct",
   "note": "26.6% (0.2662); dropped 14 trades duplicated across files."
  },
  "k1_mcp": {
   "verdict": "correct",
   "note": "84,600.71 in one call."
  },
  "k2_mcp": {
   "verdict": "correct",
   "note": "About $50M in one call, on the serving host's copy; see s2."
  },
  "k3_mcp": {
   "verdict": "correct",
   "note": "0.2661 in one call."
  }
 }
}