Skip to content

hotfix(citable): quorum guard against mostly-draft aggregator cache - #631

Merged
Flotapponnier merged 1 commit into
mainfrom
hotfix/citable-aggregator-quorum
Jun 22, 2026
Merged

hotfix(citable): quorum guard against mostly-draft aggregator cache#631
Flotapponnier merged 1 commit into
mainfrom
hotfix/citable-aggregator-quorum

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Problème

Sur prod, 24 des 26 benches renvoient status=insufficient via /api/citable alors que /api/stat/<slug> renvoie status=live avec leader et value pour les mêmes slugs.

Vérifié juste maintenant (12:58 UTC) sur openchainbench.com:

slug /api/stat /api/citable
bridge-quote-latency live, 338.984, leader=Mobula insufficient
l1-finality live, 397, ss=567k insufficient
perp-fees live, 0.304, ss=28800 insufficient
(24 / 26 dans le même cas)

Cause

Les deux chemins de chargement appellent loadBenchmarkUnfilteredCached(slug), mais le cache aggrégateur all-benchmarks-v13 est indépendant du cache per-bench bench-unfiltered-v10.

Au premier hit /api/citable après un cold start, l'aggrégateur fan-out 26 requêtes Prom parallèles. Sous burst, plusieurs throw → draftPlaceholderForSpec → mixed set 2 live / 24 placeholders. Le throw AllBenchmarksDraftError actuel ne se déclenche QUE si literalement 0 bench est live, donc 2/26 passe → set caché 60s. Les hits suivants /api/stat populent le per-bench cache avec live, mais l'aggregator cache reste sur le mixed set.

Fix

  • aggregateBenchmarks throw désormais quand moins de la moitié des specs déclarées live (en YAML) produisent un bench live dans le run courant. Floor de 4 pour ne pas tripper en test fixtures.
  • Cache key bumped all-benchmarks-v13v14 pour flush le snapshot poisoned actuel.
  • prod-deploy.yml warm explicitement /api/citable, /api/llm-context, /api/mcp après deploy, pour que l'aggregator cache parte chaud.

Tests

Ajouté coverage:

  • Mostly-draft (2 live / 10) → throw AllBenchmarksDraftError
  • Half live (5/10) → passe sans throw
  • Sous le floor (1/3 live) → comportement legacy préservé
bun test src/lib/spec.test.ts
15 pass / 0 fail

Test plan

  • Merge → CI deploy auto via prod-deploy.yml
  • Vérifier curl https://openchainbench.com/api/citable | jq '[.benchmarks[] | select(.status=="live")] | length' retourne ≥ 13 (sur 26)
  • Vérifier que la warm-up step log 200 /api/citable dans le workflow summary

- Aggregator throws AllBenchmarksDraftError when <50% of live specs
  produce a live bench (was: only when 0/N live). Prevents a mixed
  set like 2/26 live being cached for 60s while /api/stat returns
  live for the same slugs.
- Bumped all-benchmarks cache key v13 to v14 to flush the current
  poisoned snapshot on prod.
- Warm /api/citable, /api/llm-context, /api/mcp explicitly on
  prod deploy so the aggregator cache starts hot.
- Added tests for the new quorum threshold.
@Flotapponnier
Flotapponnier merged commit 6390d5e into main Jun 22, 2026
1 check failed
Flotapponnier added a commit that referenced this pull request Jun 22, 2026
…HF Space description (#654)

Two fixes bundled because both must land for the next prod-deploy to succeed.

loadBenchmark fell back to loadAllBenchmarks (strict) when the per-slug
cache miss happened. The strict aggregator throws AllBenchmarksDraftError
when the quorum guard from #631 trips, which crashes next build during
any Prom blackout. Both fallback sites now use loadAllBenchmarksSafe,
which substitutes draft placeholders for the same blackout. Behavior at
runtime is unchanged when Prom is healthy.

HF Space short_description was 86 chars, HF rejects anything > 60.
Shortened to 46.
@Flotapponnier
Flotapponnier deleted the hotfix/citable-aggregator-quorum branch July 17, 2026 14:43
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