Skip to content

fix: audit batch — answer YAMLs, bench math, compare FAQ, JSON-LD - #1131

Closed
Flotapponnier wants to merge 10 commits into
devfrom
fix/audit-batch-2026-07-12
Closed

fix: audit batch — answer YAMLs, bench math, compare FAQ, JSON-LD#1131
Flotapponnier wants to merge 10 commits into
devfrom
fix/audit-batch-2026-07-12

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Summary

Consolidated fixes from a six-agent deep audit run.

Answer YAMLs (6 files) — same class of bug as PR #1130. Removed {{best_name}} / {{best_p50}} tokens where the underlying bench dimension does not match the question's named cohort.

  • which-crypto-oracle-is-the-most-accurate — oracle-deviation bench is per USD pair, not per oracle; token would surface "XRP/USD leads across Chainlink, Pyth, Binance, Coinbase" (nonsense)
  • drpc-vs-publicnode-vs-1rpc — rpc-capabilities bench has 15 providers including chain-officials (Binance/Base/Avalanche); token surfaces "Binance leads" on a page framed as dRPC vs PublicNode vs 1RPC. Also 1RPC delisted 2026-07-09.
  • alchemy-vs-quicknode-vs-infura-latency — rpc-keyed-latency has 6 providers; token can surface Chainstack/Ankr/Helius on the head-to-head page.
  • which-bridge-has-the-cheapest-usdc-fee — cohort list was wrong (missing Across, Near Intents).
  • cheapest-bridge-usdc-to-base — cohort list named Stargate/Squid/Socket which don't exist in the bench.
  • which-perp-dex-has-the-lowest-fees — cohort missing Paradex, Extended, Polymarket.

Bench YAMLs (6 files)

  • gas-estimation|predicted, realized||predicted - realized| (3 spots, math notation).
  • l1-finalitylag_seconds = headTimestamp, finalizedTimestamp → subtraction.
  • rpc-capabilities — drop 1rpc provider block; methodology already flagged it delisted.
  • base-rpc, bnb-rpc — remove "Merkle" from seo_intro (delisted 2026-07); update provider count.
  • megaeth-rpc — abstract said "4 providers", only 3 actually listed.

Compare page — FAQ template rendered "a s value" / "a count value" because ${unit} was interpolated bare. Now shows real numbers via fmtUnit(p50, unit) for both providers. Added Dataset.identifier to satisfy Google rich-result requirement.

Answer page JSON-LD — added Article.image pointing at the bench OG route (Google Article rich-result blocker).

Chain sub-page JSON-LD — added TechArticle.datePublished (was missing, only dateModified present).

Test plan

  • pnpm typecheck clean
  • merge to dev, verify staging renders all 6 answer pages without tokens
  • verify /compare/codex-vs-mobula FAQ answer text
  • verify /answers/{slug} JSON-LD includes image
  • verify /benchmarks/network-fees/base JSON-LD includes datePublished
  • cherry-pick to main + vercel --prod

Florent Tapponnier and others added 10 commits July 12, 2026 15:15
ship monad-rpc + megaeth-rpc to prod (cherry-pick)
* coherence batch: hyperliquid profile name, fraxtal frxETH, data-dated as-of, sub-ms precision, KV read retry

* fix answers grammar fallback + live ticker SSR

Two audit fixes that touch the SSR HTML crawlers cache:

* /answers pages showed 'The current leader currently leads Solana
  transaction landing latency at measured live (p50, 24h)' when the
  referenced bench had no defensible leader. The per-token fallback in
  cleanLeftoverTokens rewrote {{best_name}} to 'The current leader'
  inside sentences whose YAML grammar assumed a proper-noun subject,
  producing broken output that Perplexity + Bing were picking up
  verbatim.

  Fix: detect the (no leader) AND (source uses live tokens) case at
  the page level and swap the whole short_answer / intro / methodology
  / limitations / FAQ set with a canned 'data pending' fallback that
  reads naturally in every downstream surface (meta description,
  JSON-LD Article.description, LLM grounding trace). Fallback is
  benchmark-scoped so the copy stays specific instead of reading like
  a generic error page. Applied on generateMetadata too so the SERP
  snippet never publishes the broken sentence.

* Home page live ticker rendered 'Reconnecting' in the SSR HTML
  because the SSE connection is client-only. Googlebot cached a
  snapshot with the module apparently broken. Fix: always render 'Live'
  in the label so the SSR text reads as a healthy live module; the dot
  color still reflects the actual connection state (green pulse when
  connected, muted grey when not) so client users still see when the
  stream is genuinely down. aria-label on the muted dot preserves a11y.

Verified:
  pnpm typecheck: clean
  eslint on modified files: 0 errors
  bun test src/lib: 64 pass 0 fail
  No changes to /api/citable, /api/llm-context, JSON-LD shapes or any
  existing behaviour when the bench has live data.

---------

Co-authored-by: Florent Tapponnier <contact@mobula.io>
Follow-up to #1121 addressing the review agent's two blocking findings:

* /answers hub page was not covered by the pending-data guard. When the
  referenced bench had no defensible leader, the Solana card and any
  other pending row still surfaced 'The current leader currently leads
  Solana transaction landing latency at measured live (p50, 24h)' as
  its short_answer preview. Fix: mirror the detail-page guard on the
  hub loop. Same import list, same swap logic, same benchDataPendingFallback
  scoped to each row's referenced bench.

* Pending detail pages rendered empty <h2>Frequently asked questions
  and <h2>What this number does not tell you sections with no items
  below, reading as UI dead space and emitting <ul>/<dl> shells with
  no content. Fix: hide both sections when their arrays are empty.

Verified:
  pnpm typecheck: clean
  eslint on modified files: 0 errors
  bun test src/lib: 64 pass 0 fail
  No changes to behaviour when the bench has live data (both sections
  render normally, hub preview shows the real short_answer).

Co-authored-by: Florent Tapponnier <contact@mobula.io>
Old file was a wordmark including 'CHAINSTACK' text, ~9.7 KB. Replaced
with the official icon-only mark pulled from
chainstack.com/wp-content/themes/chainstack/img/chainstack-logo-blue.svg,
1.2 KB, blue (#007BFF), viewBox 0 0 109 109. Matches the shape used on
their own homepage today and lines up better with the other provider
icons in the leaderboard.

Co-authored-by: Florent Tapponnier <contact@mobula.io>
…1128)

time.Duration.Milliseconds() returns int64 and truncates every probe
under 1 ms to zero. QuickNode is measured via the Mobula shared paid
fleet whose endpoints are peer-adjacent to the harness (short RTT +
HTTP keep-alive), so a significant share of successful probes returned
in ~0.3 to 0.9 ms and were recorded as 0 ms in Prometheus. The 24h
aggregate on the BNB + US-East cell landed at effectively 0 ms and
rendered as 'QuickNode leads at 0 ms' on
/benchmarks/rpc-keyed-latency?chain=bnb&region=us-east.

Fix: latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6. Same
wall-clock delta, real precision preserved down to microsecond
granularity. Every other provider stays within noise (their probes
were already above 1 ms so the truncation never bit them).

Requires a Railway harness rebuild + redeploy to take effect on
staging and production (bench 069 runs on Railway, not the shared
worker VPS). The materialized store will catch up on the next 24h
window after redeploy.

Co-authored-by: Florent Tapponnier <contact@mobula.io>
…wrong axis (#1130)

Both YAMLs were shipping short_answer / seo_description / faq copy that
referenced {{best_name}} and {{best_p50}}. renderTemplate resolved those
tokens against the underlying bench's global leader, but the questions
frame a head-to-head that the bench does not answer on the same axis:

* polymarket-vs-kalshi-resolution-speed referenced polymarket-resolution-delay,
  whose dimensions are market categories (Crypto / Sports / Politics),
  not venues. {{best_name}} returned the fastest category and the page
  rendered 'Crypto currently resolves faster at 11.3 min' - grammatically
  fine, factually wrong for a Polymarket vs Kalshi question. Kalshi is
  also not measured in the bench today.

  Fix: rewrite the copy to describe what the bench actually measures
  (Polymarket resolution delay per category, live onchain from UMA
  events on Polygon), state explicitly that Kalshi ingestion is pending,
  and point at the bench page for the numbers. No {{}} tokens.

* helius-vs-triton-vs-quicknode-solana referenced solana-tx-landing,
  which includes Jito bundle submission as a separate priority-lane
  comparator. {{best_name}} could name Jito, mismatching the three
  RPC providers in the question and reading as broken output.

  Fix: rewrite the copy to describe the harness methodology, name the
  three providers explicitly, and flag Jito's presence on the same
  leaderboard so a reader who lands here from Google or a LLM answer
  understands why the aggregate leader can be Jito rather than one of
  the three RPCs. No {{}} tokens.

Both YAMLs still list status: live and short_answer is above the schema
40-char floor. Related answers unchanged. No changes to any other YAML.

Verified:
  grep for {{}} tokens in both YAMLs: 0 hits
  bun test src/lib: 64 pass 0 fail
  pre-existing typecheck error on provider-registry.ts:1247 is unrelated
  (present on dev before this branch, confirmed via git stash test)

Co-authored-by: Florent Tapponnier <contact@mobula.io>
Answer YAMLs: rewrite six pages whose {{best_name}} / {{best_p50}} tokens could
resolve outside the question's named cohort (oracle-deviation is per pair not
per provider; rpc-capabilities includes 14 chain gateways; keyed RPC bench
includes Chainstack/Ankr/Helius; bridge-fee cohort was Stargate/Squid/Socket
not in bench; perp-fees added Paradex/Extended/Polymarket). Same pattern as
PR #1130.

Bench YAMLs: fix |predicted, realized| -> |predicted - realized| (3 spots in
gas-estimation), lag_seconds = a, b -> subtract in l1-finality, drop
contradictory 1RPC provider block from rpc-capabilities (methodology already
says delisted 2026-07-09), sweep stale "Merkle" references and provider
counts on base/bnb/megaeth cluster.

Compare page: FAQ template rendered "a s value" / "a count value" because
${unit} was interpolated bare. Fix by including the fmtUnit(p50, unit) for
both providers. Also add Dataset.identifier to satisfy Google's rich-result
requirement.

Answer + chain page JSON-LD: add Article.image (bench OG) on answers, add
TechArticle.datePublished on chain sub-pages.
RPC bench provider counts. 17 files stated N+1 providers while the
providers[] array held N. Sweep with a per-file actual count. Also
updates the cross-chain rpc-capabilities parent (Ethereum 8, Arbitrum 7,
Base 5, Optimism 5, Avalanche 4, BNB 4, Polygon 4, Linea+Scroll+Mantle 3
each) and its "13 audited providers" total after the 1RPC delisting.

Hyperliquid sitemap soft-404. sitemap.ts emitted every builder slug
from isHlBuilderSlug (static spec list), but /hyperliquid/[slug] 307s
to /hyperliquid when the builder has no fetchHlHistory data. 14 URLs
were polluting Google's crawl budget. Switch to isHlBuilderWithHistory
so the sitemap only lists slugs whose page can actually render.

PM cluster orphan pages. Parent bench pages for pm-api-latency,
pm-rate-limits and polymarket-resolution-delay never linked to their
per-venue and per-category sub-pages (13 orphan URLs from the audit).
Extend PerChainPagesNav to also render (a) dimension.venue entries and
(b) row-shape explainer targets outside the Blockchains category, so
the 3 PM parents now surface links to every sub-page they have.

Hyperliquid editorial polish. Hyphenate compounds ("re reads",
"End to end", "hand curated", "in memory", "per builder", "on chain"
adjectives), replace the escape-mangled "based dot app" / "pvp dot trade"
with real dotted brand names, and restore the "miniapps/hyperliquid-
frontends/local/builders.json" path that had been flattened.
@Flotapponnier

Copy link
Copy Markdown
Collaborator Author

Closing as stale (>5 days no activity). Reopen if still relevant.

@Flotapponnier
Flotapponnier deleted the fix/audit-batch-2026-07-12 branch July 17, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant