Promote dev to main: Serialized onboarding, bench scoring fixes, 001 node reference - #2269
Open
Flotapponnier wants to merge 326 commits into
Open
Flotapponnier wants to merge 326 commits into
Flotapponnier wants to merge 326 commits into
Conversation
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>
Serialized publishes its chain list at the free GET /v1/meta/chains. The same list answers both benches: they run their own indexers and do not separate asset-registry coverage from DEX-pool coverage, so the count is identical on 005 and 090 by construction. Only chains the endpoint marks status=live are counted, so a future beta or deprecated status cannot inflate the number. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ups (#2264) v1.0 claimed bench 001 references archive nodes and was therefore unaffected by provider clock disagreement. That repeated the spec instead of reading the harness: there is no archive-node reference in aggregator-head-lag at all, and the leaderboard gauge is computed from each provider's own timestamp. The spec says the opposite in three places. Also records the now-conclusive bench 067 result (verified 5 of 19 chains), probe-confirmed negative capabilities, and a verified 5.2x BONK mispricing traced to pool discovery missing the main market. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…en-security feasibility (#2265) The v1.1 text said the deep Orca pool was absent from their pool list. It is present, ranked second. The real defect is that the ranking compares liquidityNative across different quote assets without converting to USD, so a $4,347 USDC-quoted pool outranks a $75,679 SOL-quoted one because 4,346 > 728. Seven of eight pools agree on the price; rank 1 is the lone outlier and the token is priced from it. Adds section 17: token-security bench feasibility, including the provider cohort, a latency table where Mobula is last by 17x, three measured design traps, a retrospective backtest and its limits, and which fields actually carry signal. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both benches score a proxy for the thing they claim to measure. Bench 004 scores the logo field as "non-empty string", which any provider wins by construction by rewriting logos onto its own CDN at a deterministic path. The current beneficiary is Mobula, at 100% logo on every chain against 22.9/37.8/78.9 for a provider returning upstream URLs. Adds logo_resolved: HEAD the URL, fall back to a ranged GET on 403/405, cache 6h so we do not hammer third-party CDNs. Bench 008 scores a hit as "any non-generic name", which cannot tell a curated entity from a personal name-service record. Measured: 25% of Serialized's hits and 25.4% of Mobula's named something other than the curated entity. The anchor list already carries a Hint for every address and the scoring path ignored it. Adds wallet_labels_accurate_total scored against that Hint. Both land as SEPARATE series, not as redefinitions, so the published leaderboards and their history stay intact while the stricter numbers build up alongside. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… clock (#2267) The spec promises "Reference: archive nodes per chain, validated against block hashes" in three places. The harness never did that: both provider paths compute receiveTime minus the timestamp the provider itself sent. grep for archive/getBlockByNumber/blockTimestamp over the harness returns nothing. Measured consequence: on the same transaction hash, Serialized and Mobula disagree about when it happened by 707 ms on Solana and 1,000 ms on Base, so the leaderboard partly ranks where each vendor puts its clock. Adds one WebSocket subscription per monitored pool straight to a node, timestamping every swap on receipt, matched to provider emissions by transaction hash. Published as head_lag_ref_seconds beside the legacy series so the old one keeps its history while the two are compared. Validated before shipping at a 100% hash match rate on Base and Solana. That validation also surfaced the binding constraint: against public endpoints the reference node is SLOWER than the providers, so the series carries the node's own latency as an offset and must be read as a relative comparison until REF_WS_URL_<CHAIN> points at a paid node. All of this is documented at the call site. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Their trades stream is keyed by token with an optional pools filter, while the bench is keyed by pool. Subscribing by the pool's native side (SOL, WETH, WBNB) acknowledges and delivers nothing; subscribing by the side their own /v1/pool reports as `token` (USDC, BUSD, USDG) with pools=<bench pool> delivers exactly that market. Verified on all four bench pools before shipping (events with txHash: solana 4, base 10, bnb 2, robinhood 79). One connection per process, four pools multiplexed: their key allows 5 concurrent connections and this harness runs in three regions. Records both series: head_lag_seconds from their own `at`, same treatment as the incumbents, and head_lag_ref_seconds against the node reference clock matched by txHash. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…he 2025-01-01 floor (#2271) keyed-rpc-robinhood (live since 2026-08-27) and every bench added since the last regeneration emitted datePublished 2025-01-01 in JSON-LD, the FLOOR_PUBLISHED fallback in src/lib/seo/bench-dates.ts. A datePublished a year before the site existed, next to a dateModified that moves hourly, is exactly the freshness signal the file header warns about. Regenerated with scripts/generate-bench-published.mjs as documented. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…Asia-Pacific claim (#2273) Same rescoping as the main hotfix, applied to the two-region dev version: the headline still cites Singapore, the region tabs stay, every chain-wide superlative and the unsourced Asia-Pacific justification are gone. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…product URLs (dev twin) (#2275) Same two changes as the main hotfix. On dev, keyed-rpc-robinhood declares its region tabs so the payload guard is a no-op there; the sitemap filter is identical. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ditorial (dev twin) (#2277) Same change as the main hotfix. On dev, keyed-rpc-robinhood declares its region tabs so it is returned untouched; the page-level guard from the previous twin is removed. Claude-Session: https://claude.ai/code/session_01CpArutAtXuBb1BVNUDXoYA Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Reverts #2268 before it reaches main. Measured 2026-09-08: their `at` is the block timestamp exactly, so the ruler matches, but on Base every sampled trade arrives before its own block exists (11/11 received while the node head was still target-1, median 1.04 s ahead of publication). They stream sequencer preconfirmations; Mobula, Codex and GeckoTerminal read sealed blocks. That is a latency/finality trade-off, not a speed gap, and one ranking would present it as superiority. RecordHeadLag also drops negatives, so on the legacy series they would read as no data on Base while being the fastest. Audit §18.1 records the measurements, the two open questions for them (preconfirmed=false on all lead events, 0 Robinhood events in 240 s) and the conditions to reopen. Serialized stays on benches 004, 005, 008, 090. Claude-Session: https://claude.ai/code/session_01LtBjM1FhTKxiZhwzb3Y61c Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nominator (#2279) Two problems on /products/[slug], both visible on Serialized. rankPerChainForBench only holds one real per-chain fact: the leader, from bestPerChain. For every other provider it reused the unfiltered aggregate order shifted by one slot, so a chip reading "#3 on Solana" was the global rank with a chain label on it, repeated identically across every chain of the bench. That reads as a measurement and is not one. Non-leader chips are gone: a chip now means "leads this chain", and its absence means "does not lead", not "ranks lower". The chips also hid how many providers were measured on the chain. "#1 on Solana" was #1 of 2 on bench 008 while sitting next to "#3 of 8" for the aggregate. They now read "#1 of 4 on Ethereum", with the denominator taken from providersPerChain and omitted when that set is unknown rather than substituting the global count. Wins accounting is unchanged: it already counted rank === 1 entries only. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…he mix (#2280) On a bench with chain dimensions the cross-chain aggregate is a mix, not a comparison. Ranking on it alone let a provider measured on one chain that nobody else reported finish above a provider that led several contested ones. Five live benches shipped that way: rpc-capabilities Binance 1st on 1 chain, PublicNode led 6 wallet-labels-coverage XRPScan 1st on 1 chain, Serialized led 4 token-quote-coverage Jupiter 1st on 1 chain, Mobula led 2 bridge-fee Squid Router 1st on 1 chain perp-liq-rate Lighter 1st on 1 chain rankedCandidates now sorts by contested-chain wins first and uses the aggregate value only to break ties. A chain counts only when at least two providers reported on it, so an uncontested chain awards nothing: you do not win a race you ran alone. Guarded by the per-chain stashes, which materialize/load.ts populates only on the unfiltered view. A chain-filtered variant has none, so ?chain=bnb keeps ranking by value as before. providers.ts reuses the same ordering. The two surfaces disagreeing is what put "#3 of 8" next to five chain-leadership chips on the same bench row. Known and accepted: a provider with one contested win now ranks above one with none and a higher aggregate figure (TonAPI over XRPScan on 008). That is what ranking on head-to-head record means; the win count is on the row. Rule documented in methodology, section II. 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>
…olumns and labels an unpublished row Filling (threshold wording) instead of Unresponsive (probe wording); the dense layout stays inside its card instead of bleeding 80 to 128 px past it; bench 268 opts in (#2548) 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>
…), Web Vitals, time on page; site: not_found and search_no_result events (#2547) * crm: Search Console (service account, clicks/impressions/CTR/position, opportunities), Vercel log drain receiver (AI crawlers by bot and section, search bots, 404s, API and llms.txt callers, cache ratio), Core Web Vitals p75, time on page by section, searches with no result; site: not_found and search_no_result events Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw * crm, review: 404 map capped on fold, merge and read; flush swaps the day out before writing and merges it back on failure; NEXT_MANUAL_SIG_HANDLE so the shutdown flush runs; content-length guard on the drain route; one status key for Search Console; page keys folded across www/http variants 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>
…ge (funding leg, on Ethereum via Relay, Base) instead of the internal slug (basedbot-funding, fomo-ethereum, binance-wallet-base) (#2549) 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>
…etween the user's Solana and EVM wallets, both directions (18 Robinhood to Solana, 10 Solana to Robinhood in the last 50 requests), not a deposit mechanism to trade on Solana; spec, harness note, README, audit-table badge (#2550) 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>
…ws binance-wallet-bnb, -ethereum, -base showed the BW chip) (#2551) 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>
…ad of the 200 px PNG; same mark, sharp at every size (#2552) 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>
…ricing backend, GMX v2 oracle price API) instead of a Pyth Hermes proxy; hermes.pyth.network has answered 401 since 2026-08-27 and both rows were empty for 24 days; spec copy no longer assumes a near-zero deviation, it shows the measured one (#2553) 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>
…he final pool, terminal and network: routers' cuts, hop leftovers) instead of leaving it in Pool; pooled rows rank on the effective sample size; a pooled component the flow gate withholds is cleared; native fail rate from 20 sampled transactions; BasedBot's wallet set from both ends of every Relay leg; hub page cached 5 min; sampling-rate and coverage copy match production (#2554) 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>
…hed rows (#2554 set it on the held branch only) (#2555) 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>
…ee breakdown: actual execution, else the quoted gas fee) is network cost; relay = fixed + price fees + the solver's spread (#2556) 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>
… 0xdab3f5fc…, 15 bps, gas sponsored; Robinhood Chain, BNB, HyperEVM, Arc), rows pump-fun-<chain> pooled with its Solana row (#2557) 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>
…elay reports minus the app-sponsored part (the quoted userPays overstated it: 0.204 vs 0.126 $ on a pump.fun buy) (#2558) 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>
…riced (previous trade on the curve, quote = gas coin / stable / WETH / a route-bought token), ETH-quoted v4 pools priced as the gas coin when no ERC20 moved the quote, a launch's first buy rejected as launch_first_trade: Robinhood Chain draws priced 8 of 40 -> 33 of 35 fills (#2559) 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>
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