Promote dev to main: Serialized onboarding, bench scoring fixes, 001 node reference - #2269
Open
Flotapponnier wants to merge 313 commits into
Open
Flotapponnier wants to merge 313 commits into
Flotapponnier wants to merge 313 commits into
Conversation
…ovider+chain logos
feat(speedtest): prefill validation + logos polish
…, Speedtest-style gradient dial
feat(speedtest): pro live dial (concurrent probes + gradient gauge)
fix(speedtest): no em dashes in copy
…lish feat(speedtest): responsive + design polish
…nks, llms.txt entry, footer link
feat(speedtest): SEO/GEO findability pass
feat(speedtest): red stop button at section bottom
feat(speedtest): dedicated social card
fix(speedtest): satori-compatible OG card
feat: crowdsourced RPC latency world map
…ing, zoom-adaptive labels
feat(map): search + compare + smart viewport
feat(map): clickable areas + history panel
feat(map): near me + pin with nearest results
fix(speedtest): fail-open prefill check
…owing all-chain totals
fix(bench-205): apples-to-apples Solana scoping
Wires serialized.xyz into metadata-coverage (004) and wallet-labels (008), the two benches where their endpoints map 1:1 to the existing scoring rule. Both providers throttle client-side at ~16 rps: Serialized enforces a hard 40 req/s burst cap and an unthrottled worker pool turns coverage into a rate-limit artifact (measured 77% -> 37%). Adds the registry entry, logo and a full onboarding audit documenting the apples-to-apples numbers and two scoring flaws the tests exposed in our own benches (logo presence vs resolution on 004, name-service strings counted as entity labels on 008). Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The harnesses emit provider="serialized" but the leaderboards are driven by the explicit providers block in each spec, so the series never rendered. Adds the block for both benches, same query shape as the incumbents. Validated with SpecSchema.safeParse across all 218 specs; every formula stays under the 240-char cap that silently drops a spec. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nsfer through a hop vault discarded every leg and sent the 2 % fee into pool on routed swaps); the Relay column only where a bridge was used; pooled components over the rows that carry them, published when they hold half the flow; applyLearned honours DISCOVER_DENY; copy and tooltips (#2514) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…g: noindex (#2515) Search Console "Crawled, currently not indexed" (326 URLs, 2026-09-19): about 200 are opengraph-image / twitter-image / icon URLs fetched from og:image meta tags (compare pairs, benches, products, chains), about 60 are /api/stat, /api/badge, /api/og and /api/llm-context, a handful are compare pages already noindex, static chunks and feeds. Google fetched each and had to decide; none is a page. - src/lib/og-response.tsx wraps ImageResponse with X-Robots-Tag: noindex; the 30 construction sites in 17 files (metadata image routes, /api/og, share cards, icons) go through it. Metadata routes ignore next.config headers(), hence the wrapper. - next.config headers(): /api/:path* carries X-Robots-Tag: noindex. robots.txt stays fully open, so GPTBot, ClaudeBot and PerplexityBot keep fetching the citable JSON; noindex is not a fetch block. The remaining entries of the report are the compare pairs (noindex by design, they move to "Excluded by noindex"), /benchmarks/perp-fees/SOL (already 308 to lowercase), and two indexable pages Google judged thin on the old template (/products/cow, /benchmarks/bitcoin-rpc). Verified locally: /api/stat, /api/badge, /compare/x/opengraph-image, /benchmarks/x/opengraph-image/default, /products/x/opengraph-image, /icon, /opengraph-image all answer the header. tsc, eslint, bun test. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e parent bench instead of 404; a missing bench stays 404 (Search Console 2026-09-19: network-fees/{gram,blast,optimism,stellar}) (#2516)
Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw
Co-authored-by: Flotapponnier <florent@mobula.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Gram, Optimism, Blast and Scroll back in the cohort, Sui on GraphQL; harness source in the repo (#2517) The six chains were pulled on 2026-07-02 (#828) because their USD figures looked 100 to 1000x too low. Reading the fetchers: the arithmetic was right, the figures were real. Stellar is 100 stroops (0.00001 XLM), and an OP Stack transfer's L2 execution is a few thousand wei. What made the rollup numbers misleading was the documented omission of the L1 data posting fee, which on Optimism, Base and Blast is the larger of the two components a wallet charges. That omission also understated Base and Mantle, which stayed in the table. Harness (harnesses/transaction-fee, previously only on the VPS under /opt/ocb, now versioned here where the spec's source link already pointed): - ChainConfig.L1Fee: "opstack" (GasPriceOracle 0x42..0F getL1Fee on a serialized 113 byte EIP-1559 transfer: Optimism, Base, Blast, Mantle), "scroll" (L1GasPriceOracle 0x53..02), "arbitrum" (eth_estimateGas on a native transfer returns 21000 plus the L1 calldata component; each tier is scaled by estimated / 21000). zkSync Era, Linea, Taiko and Robinhood Chain embed the data cost in the gas price and declare none. An L1 call failure fails the sample instead of publishing execution only. - Avalanche (C-Chain, plain EVM), Stellar (horizon fee_stats), Gram (0.005 GRAM observed) and the three rollups re-declared. - Sui: the public fullnodes retired JSON-RPC ("migrate to gRPC or GraphQL"); reference gas price now from graphql.mainnet.sui.io. Sui had been silent (120 parse errors an hour). - PORT env for local runs. Spec: 21 providers, per-chain explainers for the six, formulas and methodology describe the L1 fee per rollup family, the "Are the L2 numbers complete? Not yet" FAQ now says what is included where, counts are {{count}}, description mentions the L1 fee. per_chain_explainer cap 20 -> 30. Deployed on the VPS (ocb-transaction-fee, env kept in /run/ocb/.env.transaction-fee): 22 chains scraped, no fetch errors. Values at deploy: Stellar $0.000002, Blast $0.000004, Optimism $0.00002, Avalanche $0.00015, Base $0.00035, Arbitrum $0.0013, Scroll $0.0059, Gram $0.007, Sui $0.0066, Ethereum $0.036, TRON $0.099. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-user account takes it on part of them: terminal read 0, other 100); stale component gauges deleted per entry; product KPIs gated on the headline; value in and value out in USD on the audit table; Relay page budget 60 for a deploy's gap; copy (#2518) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…k minus source block), not the 5 s status poll (#2520) * bridge-execution-latency (261): settlement latency read on-chain (destination block timestamp minus source block timestamp) instead of the wall clock to a 5-second status poll Every provider's execution latency was time.Now() after a loop that slept 5 s between status calls, plus the provider's indexing lag: a fill under 5 s always read 5.x s. The table showed Mobula 5.29 s, Relay 5.53 s, LI.FI 5.82 s, which is the poll cadence, not the bridges. - onchain_latency.go: TxBlockTime(chain, hash) reads the including block's timestamp (EVM receipt + header, Solana getTransaction blockTime, 6 short retries for RPC lag); settlementLatency() replaces ExecutionLatencyMs on a settled result with destination minus source block time when both hashes resolve, keeps the wall clock in ObservedLatencyMs, and reports the method. - Destination hashes: Relay v3 txHashes (inTxHashes as the source fallback), LI.FI receiving.txHash (received kept as fallback), Mobula toTxHash (already parsed), 1Click swapDetails.destinationChainTxHashes. - Metrics: bridge_exec_latency_ms carries the on-chain value; bridge_exec_observed_ms keeps the old figure for comparison; bridge_execution_latency_fallback_total counts settled executions that had to keep the wall clock. - Spec: methodology, subtitle, description, formulas and findings say "source block to destination block"; the history bullet documents the change and the fallback. go vet, go build, go test ./... pass. To deploy: rebuild ocb-bridge-monitor on the VPS between two scheduled executions. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * bridge-monitor: Mobula's settled payload names the destination fill `fillTxHash` (toTxHash kept as fallback); checked on today's two settlements: SOL->Base deposit block 10:00:03, fill block 10:00:05 = 2 s on-chain against 5.3 s from the poll; ARB->SOL same second Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw --------- Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cap 10); the purge log names its variables; pump.fun fee vaults out of the unattributed list; In $ on EVM sells includes the gas paid apart; hub per-chain badge on every pooled row; copy (gas coins at Coinbase spot, USDC deposits on FOMO, intervals overlap, thresholds, purge and deny variables documented) (#2521) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…00 ms watch), block delta as cross-check, EXEC_RUN_ON_START (#2522) * bridge-execution-latency: millisecond settlement latency from a two-ended 100 ms watch (destination credit observed minus source inclusion observed), block-timestamp delta kept as the cross-check; EXEC_RUN_ON_START for a one-off validation cycle Block timestamps (previous commit) are honest but whole-second: a sub-second fill reads 0 s and Base moves in 2 s steps. The harness now observes both ends itself, on one clock, every 100 ms on the keyed RPCs: the recipient balance from before the broadcast (first read above the pre-execution balance = creditAt) and the deposit's inclusion from the broadcast (receipt on EVM, signature status on Solana = confirmedAt). bridge_exec_latency_ms = creditAt - confirmedAt, detection lag at most one interval plus one RPC round-trip on each end. Order of preference in settlementLatency: watch, watch-broadcast (source watcher missed), blocks (timestamp delta), poll (old wall clock). The block delta is always published as bridge_exec_onchain_ms and must agree with the watch to within one destination block; bridge_exec_observed_ms keeps the poll figure; the fallback counter now counts only "poll". EXEC_RUN_ON_START=3 fires one $3 tier 20 s after start, for validation and for repopulating the 24h window after the polluted series are deleted from Prometheus; unset in normal operation. go vet, go build, go test pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * bridge-execution-latency spec: methodology describes the 100 ms two-ended watch as the published figure, the block delta as cross-check, and the Prometheus reset of the poll-era series Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw --------- Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…mily, same swap event with the sender in topic 1, filtered on the wallets it funded through Relay); HyperEVM deliveries valued at Hyperliquid's HYPE mid and a HyperEVM tab (#2524) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…racters (validate was red on dev after c17b354) (#2523) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… other, 138 bps); pump.fun's A7hAgCz vault listed; Axiom's tip on ERC20-paid buys (value equal to the tip) no longer in terminal; a pool under -100 bps on a multi-pool route is an implausible split; discovery never adopts a wallet seen on two platforms; /metrics served before the Relay seed; hop cost on four.meme; metadata failures not cached; product page keeps its own row; copy (#2525) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…zed-cost dropped the two bridges that beat their quote and crowned the wrong leader); negative USD reads "-$0.0038" (#2526) liveResults() kept a row only when p50 > 0, a guard meant for legacy zero placeholders. On bridge-realized-cost (slippage vs quote, where a bridge that settles better than it quoted is negative by design, and the FAQ says so) Mobula at -$0.0038 and LI.FI at -$0.00008 vanished from the ranking, the API and the TL;DR, and Relay at $0.000003 was crowned. - load.ts marks every row built from real aggregates availability: "live". - liveResults(): a "live" row passes on any finite p50; rows without the flag (older blobs) keep the > 0 rule, so nothing regresses until the worker republishes. - fmtUnit: negative USD formats as -$0.0038 (was $-0.0038). Local render: Mobula leads at -$0.00381, then LI.FI, Relay, Near Intents. tsc, bun test 255. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nch recurses; typecheck was red on dev after #2526) (#2527) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…te, hub tooltip) instead of reading as unresponsive; the HyperEVM tab waits for a product priced there; EVM_DAILY_TARGET default 1000; copy on which rows price the gas coin where (#2528) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…se gauges and a 7-day window (p50/p90/p99 were one execution), method label and full fallback accounting, real freshness from a persisted last-execution time, RPC keys out of the log, Near Intents quoted fee, stuck deposits in the success denominator, ticket dimension the site could not render removed, realized fee panel (#2529) ocb-bench-audit on bridge-execution-latency (staging, 9135212): NOT READY, 4 blockers, 5 majors. Blocker 1 (and major 4): bridge_exec_latency_ms, slippage, gas, realized output and fees were last-value gauges that persisted for days; quantile_over_time over them returned the last execution (p50 = p90 = p99 on every row) and the "24h" panels averaged Thursday's $30 legs into Saturday. They are now pulses: set once per execution, deleted after 75 s (2 to 3 scrapes), so every execution weighs the same in a range query. The recording rules move to a 7-day window (ocb:*:p50_7d ..., plus :last, fees and onchain), and the specs read them: one execution per corridor per day makes a 24h quantile meaningless. n = round(increase(success + reverts + stuck)[7d]). Blocker 2: the amount_usd dimension was in the specs but the variant API and the tab strip never carried it, so the "$30" view was the pooled view under a formula that claimed a selection. Dimension removed from both specs; copy says $3 and $30 are pooled (label kept in Prometheus). Blocker 3: freshness_metric pointed at a histogram family (no bare series) and the loader fell back to "now", so a dead harness read "updated 4 min ago" forever. New prometheus.freshness_timestamp_metric (schema + load.ts): a persistent gauge whose value is the unix time of the last run; bridge_last_execution_timestamp_seconds is set on every terminal execution and persisted in /state/last-execution.json so a restart re-exposes it (seeded on the VPS with today's 18:36 cycle). With no run recorded the bench reads epoch, never "now". Blocker 4: tx_executor logged the three keyed RPC URLs at start; hosts only now. The keys themselves stay valid until rotated (Alchemy dashboard, owner action: docker log history holds them). Major 1: bridge_exec_latency_ms carries a method label (watch, watch-broadcast, blocks, poll); the fallback counter counts every non-watch method with the same label; the spec says so. Solana source inclusion is stamped from `processed` so a relayer acting on processed cannot credit before our stamp and push the leg to the broadcast fallback. Major 2: stuck deposits enter the success denominator and n; FAQ and outcome bullet updated. Major 3: Near Intents sets QuoteFeeUSD from the 1Click quote, and the slippage gauge is published only when a quoted fee exists (it was the whole realized fee before). Major 5: "Realized fee" panel (ocb:bridge_fees_usd:avg_7d) on both benches, amount sent minus amount received on-chain. Minors: cohort named as four in title, description and intro; findings wording; shortHash guard on the success log line; histogram help text. Deployed: rules reloaded on ocb-prom (promtool: 13 rules), harness rebuilt (log shows hosts only, last-execution times restored), 7-day recording series present for the 12 corridors. validate 236, tsc, bun test 255, go vet/build/test. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…x), not the raw unix time; prom.scalar keeps 6 significant digits and rounded 18:36:50 to 17:46:40 (#2530) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sell straight through Uniswap, 2 of 2 sellers among 14 recent buyers, the rest still holding): the hold is permanent, the copy says so (#2531) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ies now aggregate the recorded cells, region pinned to EU-West, meme route and execution-path quotes excluded, mean fixed, Mobula timed like the others and keyed by header, Near Intents' fixed 3 s wait disclosed (#2532) ocb-bench-audit on bridge-quote-latency-solana (and confirmed on the production bridge-quote-latency page): - Blocker: the recording rules keep (bridge, region, chain, amount_usd) and the spec queries selected on bridge only, so histogram_quantile(...{bridge="mobula"}) returned 39 series and prom.scalar took result[0], which Prometheus orders by Go map iteration. The live production page read Mobula p50 31 / p90 57 / p99 4172 ms and Near Intents p99 108 below p90 4700: a different cell on every materialization. Every p50/p90/p99 query is now histogram_quantile(q, sum by (le) (...)), mean is sum(rate_sum)/sum(rate_count) (the previous clamp_min(count_rate, 1) floored a per-second rate to 1 and printed ms per second, 300x too small), success is avg(...), n is round(sum(increase)). Verified on the VPS Prometheus: one series, Mobula 43.7 / 345.8 / 982.6 ms, mean 118.3. - Region pinned to eu-west on every headline query: the us-east probe is live (the copy said paused) and was part of the random draw; sgp is down. Copy corrected on both specs. - Rules (infrastructure/monitoring/prometheus/recording_rules/ ocb_bridge_quote.yml, source of truth for the VPS file that was only on the host, and ocb_bridge_quote_solana.yml) exclude the R4 TRUMP to BRETT meme route the same loop quotes (it pooled a cross-asset swap into the Base USDC cells: Mobula 34.6 ms USDC-only vs 139.3 pooled) and the $3 / $30 execution-path quotes. - Harness: execution-path quote latency goes to its own histogram (bridge_exec_quote_latency_ms); Mobula's stopwatch stops after the body is read like the five other providers; the Mobula key travels in the Authorization header instead of the query string (a transport error wrapped the full URL into the log and Slack); the quote histogram gains 500 ms buckets between 1 and 5 s. - Near Intents: its dry quote waits a fixed 3 s solver window (quoteWaitingTimeMs: 3000), so its row measures that wait; disclosed in the methodology and the finding, the "bimodal, sub-100 ms" claim removed. Robinhood coverage bullet (four providers quote it now) and the Across / Near Intents coverage (Base and Arbitrum only, our maps) corrected. Deployed: rules reloaded (promtool 6 + 5), harness rebuilt, Mobula quotes verified with header auth. validate 236, go vet/build/test. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…finition (ticket minus quoted output), realized cost published only from the on-chain read, realized fee in bps of the ticket from an execution-only metric, stale threshold and window wording follow the spec, pre-pulse history purged (#2533) ocb-bench-audit on bridge-realized-cost: NOT READY, 4 blockers, 7 majors. - Blocker 4: Mobula's slippage was a constant negative offset at every ticket (-$0.0015 on Base at $3 and at $30) because its quoted fee summed TotalFeeUsd + GasFeeUsd, gas the realized fee (ticket minus landed) can never contain; Relay and LI.FI derived theirs from the output. Every bridge now uses ticket minus the output the quote promised (QuotedOutputUSD), so both sides of the subtraction are defined the same way. Gas we pay stays its own panel. - Blocker 3 and major 2: the "Realized fee" panel read bridge_fees_usd, which the quote loop also writes at $5/$50/$300 and on off-triangle routes (LI.FI $0.417 shown against $0.032 executed), and the realized output panel was a ticket-mix number. New execution-only pulses bridge_exec_realized_fee_usd and bridge_exec_realized_fee_bps; the panel is "Realized fee (bps of ticket)"; the output panel is gone. - Major 1 and 3: fee, output and slippage pulses are published only when the destination balance delta was read (RealizedOnChain); a failed leg no longer publishes the quote's projection as "landed" and a fallback is counted in bridge_realized_fallback_total instead of an exact zero. - Blocker 1: the 7-day window still held the pre-pulse persistent samples (about 2,880 per old execution against 3 per new one), so no new execution could move a median before 2026-09-26. Deleted from Prometheus for the execution cost series and the retired 24h rules; the benches read empty until the 10:00 UTC cycle tomorrow. - Major 4: LiveIndicator takes staleAfterSec from the bench (prometheus.expected_freshness_seconds, carried on Benchmark as expectedFreshnessSec), so a daily bench is not "Stale" 23 hours a day. - Major 5: Benchmark.window (prometheus.window) drives the Results caption, the infobox "Leader (7d)" and the citation suffix instead of a hardcoded 24h. - Copy: quoted-fee definition, gating, cohort of four, 7-day findings. Rules reloaded (14), harness redeployed. validate 236, tsc, eslint, bun test 255, go vet/build/test. Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…LANA_RPC comma-separated, Helius appended, public node last; the next endpoint on a rate limit or a transport error instead of a sleep): production runs Chainstack's shared node first, Alchemy's free app for the overflow, Helius third; Robinhood Chain gets Chainstack behind QuickNode (#2535) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ghbour screen, no neighbourhood read when the exact mid is known), FAIL_SCAN_BLOCKS per chain, NATIVE_POLL_EVERY ticks; production moves to 150 draws a day per row, no sandwich, fail-rate blocks bnb 3 / base 2 / ethereum 1 / robinhood 0, EVM logs every 3 ticks: about 27,000 calls a day instead of 146,000 (#2536) Claude-Session: https://claude.ai/code/session_01L4rjxemTvgRwrCG6D2iK5D Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…te, not on a positive quoted fee (Mobula Sol to Base quoted the full ticket back and its +$0.003 slippage was skipped) (#2537) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…03 name the live leader and number; the fee FAQ and the three bridge answers drop the claims the harness never measured ($1000/$10000 buckets, 10x, 100 to 400 ms, three regions, Ethereum to Base); the USDC-to-Base answer reads the Sol to Base cell; answers get compare links and citation meta, bench pages and the /bridge hub list their answers; the hub hides region columns whose variant is stale (US/SGP showed 2026-09-09 figures) and shows an as-of line; products meta uses short bench labels; compare pages dedupe the FAQ, date from the newest run and carry the count in the title; ad hoc compare pairs enter the sitemap; validator lints answers placeholders and typed cohorts (#2538) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… metric ("faster on quote latency") instead of the lowercased bench title (#2539)
Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw
Co-authored-by: Flotapponnier <florent@mobula.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…channel, bench and harness health, Dune) (#2540) * crm: internal dashboard on Railway (traffic from PostHog with an AI-referral channel, bench and harness health, Dune credits); a fixed list of 11 HogQL queries per hourly refresh writes a snapshot the pages read, so the PostHog query budget stays under 1 % of the organisation's 2400/hour Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * crm, review round 1: crm/ excluded from the site's tsconfig and eslint (the root typecheck pulled it into the Vercel build) with its own CI job; sessions are random, signed with a separate secret, listed on the volume and revoked on logout, login limited per client; snapshot cache, refresh mutex and PostHog budget on globalThis with mtime re-reads (instrumentation and routes are separate bundler layers); history append-only and tolerant of a torn line; bench health from index.json so expired chain RPC benches show instead of vanishing; exact AI/search 7 d uniques in the KPIs; page and referrer rows ranked on either week so losses survive the LIMIT Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * crm, review round 2: the login limiter keys on the last forwarded hop with a global cap and evicts idle keys; session writes serialised with unique temp files; one referrer rule for the SQL KPIs and the TS channel table (Google and Bing country hosts count as search on both sides); sitemap body parse guarded; Dune sub text keys on the recorded error Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw --------- Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
) * posthog: three custom events (outbound_click by delegated listener, copy with kind/bench, search with the query and the result picked) so the CRM measures what the traffic turns into; crm: Actions page (outbound hosts, copies per bench, search queries), four more HogQL queries per hourly refresh (15 total) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * posthog events, review: config snippets on /mcp tagged mcp_config with their name, the badges catalog copy tagged embed with format and bench, track() typed per event, action labels rendered Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw --------- Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ariable; vercel pull hands sensitive env vars back as the literal "[SENSITIVE]" and that string shipped as the PostHog token since 2026-08-24 (#2542) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… set (#2544) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…5 % of the org budget), manual cooldown 5 min, next refresh shown in the header (#2546) Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw Co-authored-by: Flotapponnier <florent@mobula.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Staging state on
devsince 2026-09-05, reviewed at https://staging-openchainbench.vercel.app.What this promotes
Serialized (serialized.xyz) as a provider
Bench integrity fixes, all as separate series so history is preserved
logo_resolved(HEAD-checks the logo instead of scoring URL presence) and bench 008wallet_labels_accurate_total(scores against the curated hint instead of "any non-generic name")head_lag_ref_seconds: a node subscription we hold, matched by txHash. The spec has promised archive nodes in three places; the harness computed against each provider's own timestampAudit doc
docs/methodology/serialized-onboarding-audit.mdv1.3 (#2264, #2265): every number, every correction, two methodology defects in our own benches, a verified 5.2x BONK mispricing traced to a pool-ranking unit bug on their side.What merging to main does beyond the site
The three Railway head-lag services (
Aggregator east usa,Agg eu west,agg sgp) build frommain, rootharnesses/aggregator-head-lag. After this merge, trigger a fresh git build on each (serviceInstanceDeployV2);SERIALIZED_API_KEYis already set on all three.Agg eu westhas three failed snapshot-upload deploys since 2026-09-05 14:32 (lstat …/harnesses: no such file or directory), arailway upfrom a directory without the harness path; a git build replaces it.Known state at promotion time
api.sim.dune.comno longer resolves).🤖 Generated with Claude Code
https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA