vinod-anbalagan commited on
Commit
a3b68dd
·
verified ·
1 Parent(s): aadf484

Upload 6 files

Browse files
Files changed (4) hide show
  1. app.py +356 -0
  2. build_static.py +297 -0
  3. index.html +145 -56
  4. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Multicultural Riddles Benchmark — human evaluation Space.
2
+
3
+ Self-contained Streamlit app for the Cohere Labs lead team. Recomputes the
4
+ coverage tracker and the floor-vs-ceiling leaderboard directly from Henry's
5
+ flat file on every load, so dropping a newer
6
+ `data/model_riddle_results_flat.csv` (and pushing it to the Space) refreshes
7
+ every number and chart with no code change.
8
+
9
+ Single source of truth for scores = the flat file. Every non-pending row
10
+ carries a score (human 0-3, or auto: exact_match=3, empty/placeholder=0,
11
+ idk=1). The leaderboard is computed on COMPLETE communities only, using those
12
+ scores for every row, with pending rows DROPPED (never judge-filled) — so
13
+ every value traces to the flat file with zero assumptions. Provisional until
14
+ coverage completes; every view is labelled N/44.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from datetime import datetime
20
+ from pathlib import Path
21
+
22
+ import pandas as pd
23
+ import plotly.graph_objects as go
24
+ import streamlit as st
25
+
26
+ DATA = Path(__file__).parent / "data"
27
+ FLAT = DATA / "model_riddle_results_flat.csv"
28
+ AUTO = DATA / "results_tidy.parquet" # our heuristic-judge output (static)
29
+
30
+ TOTAL_COMMUNITIES = 44
31
+ EXPECTED_MODELS = 24
32
+ RIDDLES_PER_COMMUNITY = 100
33
+ THIN_THRESHOLD = 0.20
34
+ STRICT_SCORE = 3.0
35
+ LENIENT_SCORE = 2.0
36
+ EXCLUDED_RIDDLES = {"spanish_cuba_history_016"} # Cuba: wrong v0 text, redone in v2
37
+
38
+ # Henry's model_name -> our display name (verified 24/24).
39
+ MODEL_NAME_MAP = {
40
+ "Amazon-Nova-Lite": "Amazon Nova Lite v1",
41
+ "Amazon-Nova-Micro": "Amazon Nova Micro v1",
42
+ "Deepseek-v4-flash": "DeepSeek V4 Flash",
43
+ "EuroLLM-Instruct": "EuroLLM-22B-Instruct-2512",
44
+ "GPT5.5-high": "GPT5.5 [high]",
45
+ "GPT5.5-none": "GPT5.5 [none]",
46
+ "Gemini-2.5-Flash": "Gemini 2.5 Flash",
47
+ "Gemini-2.5-Flash-Lite": "Gemini 2.5 Flash Lite",
48
+ "Mistral-Large-3": "Mistral Large 3",
49
+ "Olmo-3-32B-Think": "OLMo-3-32B-Think",
50
+ "Qwen-3.5-0.8B": "Qwen/Qwen3.5-0.8B",
51
+ "Qwen-SEA-LION-v4.5-27B-IT": "Qwen-SEA-LION-v4.5-27B-IT",
52
+ "Qwen3.5-27B": "Qwen3.5 27B",
53
+ "claude-opus-4-7": "claude-opus-4-7 [none]",
54
+ "claude-opus-4-7-thinking": "claude-opus-4-7 [thinking]",
55
+ "command-a-plus-05-2026": "Cohere Command A Plus",
56
+ "deepseek-v4-pro": "deepseek-v4-pro",
57
+ "deepseek-v4-pro-thinking": "deepseek-v4-pro-thinking",
58
+ "gemini-3.1-pro-preview": "gemini-3.1-pro-preview",
59
+ "gemma-4-31b": "Gemma 4 31B IT",
60
+ "tiny-aya-earth": "Tiny-Aya earth",
61
+ "tiny-aya-fire": "Tiny-Aya fire",
62
+ "tiny-aya-global": "Tiny-Aya global",
63
+ "tiny-aya-water": "Tiny-Aya water",
64
+ }
65
+
66
+ FLOOR_COLOR = "#9aa0a6"
67
+ CEIL_COLOR = "#3b6fb6"
68
+
69
+
70
+ @st.cache_data(show_spinner="Loading Henry's flat file…")
71
+ def load():
72
+ """Read + join once per file version; cache keyed on file mtime."""
73
+ h = pd.read_csv(FLAT, low_memory=False)
74
+ h = h[~h["riddle_id"].isin(EXCLUDED_RIDDLES)].copy()
75
+ h["model_display"] = h["model_name"].map(MODEL_NAME_MAP)
76
+ unmapped = sorted(h.loc[h["model_display"].isna(), "model_name"].dropna().unique())
77
+ if unmapped:
78
+ st.error(f"Unmapped model_name(s) in flat file: {unmapped}. "
79
+ "Numbers withheld until the name map is updated.")
80
+ st.stop()
81
+
82
+ auto = pd.read_parquet(AUTO)[["riddle_id", "model_display", "judge_verdict"]]
83
+ h["is_human"] = h["scoring_method"].eq("human_eval")
84
+ h["is_pending"] = h["scoring_method"].eq("pending_human_eval")
85
+ h["is_correct"] = h["score"].eq(STRICT_SCORE)
86
+ h["is_correct_lenient"] = h["score"].ge(LENIENT_SCORE)
87
+ m = h.merge(auto, on=["riddle_id", "model_display"], how="left")
88
+ mtime = datetime.fromtimestamp(FLAT.stat().st_mtime).strftime("%Y-%m-%d %H:%M")
89
+ return m, mtime
90
+
91
+
92
+ def coverage(h: pd.DataFrame) -> pd.DataFrame:
93
+ g = h.groupby("community")
94
+ cov = pd.DataFrame({
95
+ "human_done": g["is_human"].sum().astype(int),
96
+ "pending": g["is_pending"].sum().astype(int),
97
+ })
98
+ cov["human_eligible"] = cov["human_done"] + cov["pending"]
99
+ cov["pct_complete"] = (
100
+ cov["human_done"] / cov["human_eligible"].where(cov["human_eligible"] > 0) * 100
101
+ ).round(1)
102
+
103
+ def status(r):
104
+ if r["human_done"] == 0:
105
+ return "not_started"
106
+ if r["human_eligible"] == 0 or r["pct_complete"] >= 99:
107
+ return "complete"
108
+ if r["pct_complete"] < THIN_THRESHOLD * 100:
109
+ return "thin"
110
+ return "partial"
111
+
112
+ cov["status"] = cov.apply(status, axis=1)
113
+ return cov.sort_values(["status", "pct_complete"])
114
+
115
+
116
+ def leaderboard(m: pd.DataFrame, communities: set, strict: bool) -> pd.DataFrame:
117
+ """Floor (heuristic) vs ceiling (human/Henry) on complete communities.
118
+
119
+ Ceiling uses Henry's score for every row, pending dropped (never filled).
120
+ Floor is the heuristic judge on the very same rows.
121
+ """
122
+ col = "is_correct" if strict else "is_correct_lenient"
123
+ sub = m[m["community"].isin(communities) & ~m["is_pending"]]
124
+ ceil = sub.groupby("model_display")[col].mean().mul(100)
125
+ floor = (
126
+ sub.assign(auto=sub["judge_verdict"].eq("correct"))
127
+ .groupby("model_display")["auto"].mean().mul(100)
128
+ )
129
+ n = sub.groupby("model_display").size()
130
+ human_share = sub.groupby("model_display")["is_human"].mean().mul(100)
131
+ lb = pd.DataFrame({
132
+ "Human (ceiling) %": ceil, "Heuristic (floor) %": floor,
133
+ "n": n, "human-scored %": human_share.round(0),
134
+ }).sort_values("Human (ceiling) %", ascending=False)
135
+ lb.insert(0, "rank", range(1, len(lb) + 1))
136
+ return lb.round(1)
137
+
138
+
139
+ def community_difficulty(m: pd.DataFrame, communities: set, strict: bool) -> pd.DataFrame:
140
+ """Mean accuracy across all models per community (how hard each culture is)."""
141
+ col = "is_correct" if strict else "is_correct_lenient"
142
+ sub = m[m["community"].isin(communities) & ~m["is_pending"]]
143
+ human = sub.groupby("community")[col].mean().mul(100)
144
+ floor = (
145
+ sub.assign(a=sub["judge_verdict"].eq("correct"))
146
+ .groupby("community")["a"].mean().mul(100)
147
+ )
148
+ d = pd.DataFrame({"Human %": human, "Heuristic %": floor})
149
+ return d.sort_values("Human %").round(1)
150
+
151
+
152
+ def community_kappa(m: pd.DataFrame, communities: set) -> tuple:
153
+ """Cohen's kappa between heuristic judge and human, per community.
154
+
155
+ Computed on human-scored rows only (where both labels exist). Measures how
156
+ well strict string-matching agrees with human judgement; low kappa flags
157
+ communities where the auto-judge is unreliable (usually non-Latin scripts).
158
+ """
159
+ r = m[m["is_human"] & m["community"].isin(communities) & m["judge_verdict"].notna()].copy()
160
+ r["h"] = r["score"].eq(STRICT_SCORE)
161
+ r["j"] = r["judge_verdict"].eq("correct")
162
+
163
+ def kappa(x):
164
+ po = (x["h"] == x["j"]).mean()
165
+ ph, pj = x["h"].mean(), x["j"].mean()
166
+ pe = ph * pj + (1 - ph) * (1 - pj)
167
+ return float("nan") if pe == 1 else (po - pe) / (1 - pe)
168
+
169
+ per = r.groupby("community").apply(kappa).rename("kappa").sort_values()
170
+ overall = kappa(r)
171
+ misses = int((~r["j"] & r["h"]).sum()) # human-correct the judge missed
172
+ overcredit = int((r["j"] & ~r["h"]).sum()) # judge-correct humans rejected
173
+ return per.round(3), overall, misses, overcredit, len(r)
174
+
175
+
176
+ def hbar(series: pd.Series, xlabel: str, color: str, fmt: str = ".1f") -> go.Figure:
177
+ fig = go.Figure(go.Bar(
178
+ x=series.values, y=series.index, orientation="h",
179
+ marker_color=color,
180
+ hovertemplate="%{y}<br>%{x:" + fmt + "}<extra></extra>"))
181
+ fig.update_layout(
182
+ height=max(420, 24 * len(series)), margin=dict(l=10, r=10, t=10, b=40),
183
+ xaxis_title=xlabel, plot_bgcolor="white", font=dict(size=12))
184
+ fig.update_xaxes(showgrid=True, gridcolor="#eef0f2", zeroline=False)
185
+ return fig
186
+
187
+
188
+ def difficulty_fig(d: pd.DataFrame) -> go.Figure:
189
+ fig = go.Figure()
190
+ for i, (c, r) in enumerate(d.iterrows()):
191
+ fig.add_trace(go.Scatter(
192
+ x=[r["Heuristic %"], r["Human %"]], y=[c, c], mode="lines",
193
+ line=dict(color="#d0d3d8", width=3), showlegend=False, hoverinfo="skip"))
194
+ fig.add_trace(go.Scatter(
195
+ x=d["Heuristic %"], y=d.index, mode="markers", name="Heuristic (floor)",
196
+ marker=dict(color=FLOOR_COLOR, size=10),
197
+ hovertemplate="%{y}<br>heuristic %{x:.1f}%<extra></extra>"))
198
+ fig.add_trace(go.Scatter(
199
+ x=d["Human %"], y=d.index, mode="markers", name="Human (ceiling)",
200
+ marker=dict(color=CEIL_COLOR, size=10),
201
+ hovertemplate="%{y}<br>human %{x:.1f}%<extra></extra>"))
202
+ fig.update_layout(
203
+ height=max(420, 26 * len(d)), margin=dict(l=10, r=10, t=10, b=40),
204
+ xaxis_title="Mean accuracy across models (%)",
205
+ legend=dict(orientation="h", y=1.05), plot_bgcolor="white", font=dict(size=12))
206
+ fig.update_xaxes(showgrid=True, gridcolor="#eef0f2", zeroline=False)
207
+ return fig
208
+
209
+
210
+ def dumbbell(lb: pd.DataFrame, strict: bool) -> go.Figure:
211
+ d = lb.sort_values("Human (ceiling) %")
212
+ fig = go.Figure()
213
+ for i, (model, r) in enumerate(d.iterrows()):
214
+ fig.add_trace(go.Scatter(
215
+ x=[r["Heuristic (floor) %"], r["Human (ceiling) %"]], y=[model, model],
216
+ mode="lines", line=dict(color="#d0d3d8", width=3),
217
+ showlegend=False, hoverinfo="skip"))
218
+ fig.add_trace(go.Scatter(
219
+ x=d["Heuristic (floor) %"], y=d.index, mode="markers", name="Heuristic (floor)",
220
+ marker=dict(color=FLOOR_COLOR, size=11),
221
+ hovertemplate="%{y}<br>heuristic %{x:.1f}%<extra></extra>"))
222
+ fig.add_trace(go.Scatter(
223
+ x=d["Human (ceiling) %"], y=d.index, mode="markers", name="Human (ceiling)",
224
+ marker=dict(color=CEIL_COLOR, size=11),
225
+ hovertemplate="%{y}<br>human %{x:.1f}%<extra></extra>"))
226
+ lab = "strict (top score)" if strict else "lenient (score ≥ 2)"
227
+ fig.update_layout(
228
+ height=max(420, 26 * len(d)), margin=dict(l=10, r=10, t=10, b=40),
229
+ xaxis_title=f"Accuracy (%), {lab}", legend=dict(orientation="h", y=1.05),
230
+ plot_bgcolor="white", font=dict(size=13))
231
+ fig.update_xaxes(showgrid=True, gridcolor="#eef0f2", zeroline=False)
232
+ return fig
233
+
234
+
235
+ # ------------------------------- UI -------------------------------
236
+ st.set_page_config(page_title="Multicultural Riddles — Human Eval",
237
+ page_icon="🧩", layout="wide")
238
+
239
+ if not FLAT.exists():
240
+ st.error("data/model_riddle_results_flat.csv not found in the Space.")
241
+ st.stop()
242
+
243
+ m, mtime = load()
244
+ cov = coverage(m.drop_duplicates(["community", "riddle_id", "model_display"]))
245
+ complete = set(cov[cov.status == "complete"].index)
246
+ counts = cov.status.value_counts().to_dict()
247
+
248
+ st.title("🧩 Multicultural Riddles Benchmark — Human Evaluation")
249
+ st.caption(
250
+ f"Provisional leaderboard, live from Henry's flat file (updated {mtime}). "
251
+ "Every score traces to the flat file; pending rows are dropped, never "
252
+ "guessed. Numbers can still shift as human coverage completes.")
253
+
254
+ c1, c2, c3, c4 = st.columns(4)
255
+ c1.metric("Communities complete", f"{len(complete)} / {TOTAL_COMMUNITIES}")
256
+ c2.metric("Models", m["model_display"].nunique())
257
+ c3.metric("Human-scored rows", f"{int(m['is_human'].sum()):,}")
258
+ c4.metric("Pending", f"{int(m['is_pending'].sum()):,}")
259
+
260
+ strict = st.radio("Scoring", ["Strict (top score = 3)", "Lenient (score ≥ 2)"],
261
+ horizontal=True) == "Strict (top score = 3)"
262
+
263
+ if not complete:
264
+ st.warning("No community has complete human evaluation yet.")
265
+ st.stop()
266
+
267
+ lb = leaderboard(m, complete, strict)
268
+
269
+ tab_lb, tab_diff, tab_kappa, tab_cov, tab_map = st.tabs(
270
+ ["🏆 Leaderboard", "🌍 Community difficulty", "🤝 Judge vs human",
271
+ "📊 Coverage", "🗺️ Coverage map"])
272
+
273
+ with tab_lb:
274
+ st.subheader(f"Floor → ceiling (N={len(complete)}/{TOTAL_COMMUNITIES} "
275
+ "complete communities, provisional)")
276
+ st.plotly_chart(dumbbell(lb, strict), use_container_width=True)
277
+ st.caption("Grey = heuristic auto-judge (lower bound). Blue = human "
278
+ "judgement (upper bound). The gap is the lift from strict "
279
+ "string-matching to human scoring.")
280
+ st.dataframe(
281
+ lb[["rank", "Human (ceiling) %", "Heuristic (floor) %",
282
+ "human-scored %", "n"]],
283
+ use_container_width=True)
284
+ st.download_button("Download leaderboard (CSV)",
285
+ lb.to_csv().encode(), "human_leaderboard.csv")
286
+
287
+ with tab_diff:
288
+ st.subheader(f"How hard is each culture? (N={len(complete)}/"
289
+ f"{TOTAL_COMMUNITIES} complete communities)")
290
+ d = community_difficulty(m, complete, strict)
291
+ st.plotly_chart(difficulty_fig(d), use_container_width=True)
292
+ hardest = ", ".join(d.head(3).index)
293
+ easiest = ", ".join(d.tail(3).index)
294
+ st.caption(f"Mean accuracy across all {m['model_display'].nunique()} models "
295
+ f"per community. Hardest: {hardest}. Easiest: {easiest}. "
296
+ "Grey = heuristic floor, blue = human ceiling.")
297
+ st.dataframe(d, use_container_width=True)
298
+ st.download_button("Download community difficulty (CSV)",
299
+ d.to_csv().encode(), "community_difficulty.csv")
300
+
301
+ with tab_kappa:
302
+ st.subheader("Does the auto-judge agree with humans?")
303
+ per, overall, misses, overcredit, n = community_kappa(m, complete)
304
+ k1, k2, k3 = st.columns(3)
305
+ k1.metric("Overall Cohen's κ", f"{overall:.3f}",
306
+ help="Agreement between heuristic judge and human, on human-scored rows.")
307
+ k2.metric("Human-correct the judge missed", f"{misses:,}",
308
+ help="Answers humans scored correct but strict string-matching rejected.")
309
+ k3.metric("Judge over-credits", f"{overcredit:,}",
310
+ help="Answers the judge marked correct but humans rejected.")
311
+ st.plotly_chart(hbar(per, "Cohen's κ (judge vs human)", CEIL_COLOR, ".3f"),
312
+ use_container_width=True)
313
+ st.caption(
314
+ f"On {n:,} human-scored rows in complete communities. Low κ flags "
315
+ "communities where strict string-matching is unreliable (typically "
316
+ "non-Latin scripts and rich morphology). The judge misses far more "
317
+ f"correct answers ({misses:,}) than it over-credits ({overcredit:,}), "
318
+ "which is why the human ceiling sits well above the heuristic floor.")
319
+ st.download_button("Download per-community κ (CSV)",
320
+ per.to_csv().encode(), "community_kappa.csv")
321
+
322
+ with tab_map:
323
+ st.subheader("Coverage map")
324
+ map_img = DATA / "coverage_map.png"
325
+ if map_img.exists():
326
+ st.image(str(map_img), use_container_width=True)
327
+ st.caption("Coverage map — visualization by Pouya Sadeghi (Cohere Labs). "
328
+ "Drop an updated image at data/coverage_map.png to replace.")
329
+ else:
330
+ st.info(
331
+ "No map image yet. Add Pouya Sadeghi's coverage map as "
332
+ "`data/coverage_map.png` and it will render here, credited. "
333
+ "We can later augment it by shading each community by human "
334
+ "accuracy from the difficulty tab.")
335
+
336
+ with tab_cov:
337
+ st.subheader("Human-eval coverage by community")
338
+ order = {"complete": 0, "partial": 1, "thin": 2, "not_started": 3}
339
+ view = cov.reset_index().rename(columns={"index": "community"})
340
+ view["_o"] = view["status"].map(order)
341
+ view = view.sort_values(["_o", "pct_complete"], ascending=[True, False])
342
+ st.dataframe(
343
+ view[["community", "status", "pct_complete", "human_done",
344
+ "pending", "human_eligible"]],
345
+ use_container_width=True, hide_index=True)
346
+ chase = view[view.status.isin(["not_started", "thin"])]["community"].tolist()
347
+ if chase:
348
+ st.info("Chase list (not started / thin): " + ", ".join(chase))
349
+
350
+ st.divider()
351
+ st.caption(
352
+ "Methodology: single human annotator per riddle (no inter-annotator "
353
+ "agreement). Leaderboard restricted to communities with complete human "
354
+ "coverage; other communities excluded until done. Source of truth: "
355
+ "model_riddle_results_flat.csv (Henry). Cuba riddle "
356
+ "spanish_cuba_history_016 excluded (redone in v2).")
build_static.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Build a self-contained static dashboard from Henry's flat file.
2
+
3
+ Free HuggingFace Static Spaces cannot run Streamlit, so this precomputes every
4
+ metric (reusing app.py's exact functions) and bakes the numbers into a single
5
+ self-contained index.html with Plotly from CDN.
6
+
7
+ This is the human-evaluation layer of the benchmark: the *ceiling* (what models
8
+ actually get right when a person judges) that complements the team's full-corpus
9
+ heuristic *floor*. Views: floor->ceiling leaderboard, community difficulty,
10
+ how-models-fail error types, judge-vs-human agreement, coverage.
11
+
12
+ Refresh: drop a newer data/model_riddle_results_flat.csv, rerun this script,
13
+ push index.html. Numbers are identical to human_eval.py / app.py.
14
+
15
+ python build_static.py
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import sys
22
+ import types
23
+ from pathlib import Path
24
+
25
+ # stub streamlit and exec only app.py's compute half (before the UI marker),
26
+ # so we reuse the exact functions without running the Streamlit UI.
27
+ _st = types.ModuleType("streamlit")
28
+ _st.cache_data = lambda *a, **k: (lambda f: f)
29
+ sys.modules["streamlit"] = _st
30
+
31
+ _APP = Path(__file__).parent / "app.py"
32
+ _src = _APP.read_text().split("# ------------------------------- UI")[0]
33
+ app = types.ModuleType("app")
34
+ app.__file__ = str(_APP)
35
+ exec(compile(_src, str(_APP), "exec"), app.__dict__)
36
+
37
+ OUT = Path(__file__).parent / "index.html" # repo root: HF Static Space entry
38
+
39
+ # ordered failure/outcome buckets + colours (how models fail, from human eval)
40
+ FAIL_ORDER = ["Correct", "Partially correct", "Explicit uncertainty",
41
+ "Wrong entity", "Too broad", "Hallucinated", "Other incorrect"]
42
+ FAIL_COLORS = {
43
+ "Correct": "#1a9e76", "Partially correct": "#8fcfb8",
44
+ "Explicit uncertainty": "#4c9be8", "Wrong entity": "#e79a3c",
45
+ "Too broad": "#efc84a", "Hallucinated": "#d1552f",
46
+ "Other incorrect": "#a7adb5",
47
+ }
48
+
49
+
50
+ def records(df, index_name):
51
+ df = df.reset_index().rename(columns={df.index.name or "index": index_name})
52
+ return json.loads(df.to_json(orient="records"))
53
+
54
+
55
+ def fail_modes(m, communities: set):
56
+ """Per-model outcome/error-type breakdown (%), human-scored rows only."""
57
+ r = m[m["is_human"] & m["community"].isin(communities)].copy()
58
+
59
+ def bucket(row):
60
+ s, lab = row["score"], str(row.get("error_type_label") or "")
61
+ if s == 3:
62
+ return "Correct"
63
+ if s == 2:
64
+ return "Partially correct"
65
+ if s == 1:
66
+ return "Explicit uncertainty"
67
+ if lab.startswith("0.3"):
68
+ return "Hallucinated"
69
+ if lab.startswith("0.1"):
70
+ return "Too broad"
71
+ if lab.startswith("0.2"):
72
+ return "Wrong entity"
73
+ return "Other incorrect"
74
+
75
+ r["bucket"] = r.apply(bucket, axis=1)
76
+ import pandas as pd
77
+ piv = (pd.crosstab(r["model_display"], r["bucket"], normalize="index")
78
+ .mul(100).round(1))
79
+ for c in FAIL_ORDER:
80
+ if c not in piv.columns:
81
+ piv[c] = 0.0
82
+ piv = piv[FAIL_ORDER].sort_values("Correct", ascending=False)
83
+ return records(piv, "model")
84
+
85
+
86
+ def main() -> None:
87
+ m, mtime = app.load()
88
+ cov = app.coverage(m.drop_duplicates(["community", "riddle_id", "model_display"]))
89
+ complete = set(cov[cov.status == "complete"].index)
90
+
91
+ data = {
92
+ "meta": {
93
+ "mtime": mtime, "complete": len(complete), "total": app.TOTAL_COMMUNITIES,
94
+ "models": int(m["model_display"].nunique()),
95
+ "human_rows": int(m["is_human"].sum()), "pending": int(m["is_pending"].sum()),
96
+ },
97
+ "leaderboard": {}, "difficulty": {},
98
+ "fail_order": FAIL_ORDER, "fail_colors": FAIL_COLORS,
99
+ }
100
+ for tag, strict in [("strict", True), ("lenient", False)]:
101
+ data["leaderboard"][tag] = records(app.leaderboard(m, complete, strict), "model")
102
+ data["difficulty"][tag] = records(app.community_difficulty(m, complete, strict), "community")
103
+
104
+ per, overall, misses, overcredit, n = app.community_kappa(m, complete)
105
+ data["kappa"] = {"overall": round(overall, 3), "misses": misses,
106
+ "overcredit": overcredit, "n": n,
107
+ "per": records(per.to_frame("kappa"), "community")}
108
+ data["failmodes"] = fail_modes(m, complete)
109
+ data["coverage"] = records(
110
+ cov[["status", "pct_complete", "human_done", "pending", "human_eligible"]],
111
+ "community")
112
+
113
+ OUT.write_text(HTML.replace("__DATA__", json.dumps(data)), encoding="utf-8")
114
+ print(f"Wrote {OUT} (complete {len(complete)}/{app.TOTAL_COMMUNITIES}, "
115
+ f"kappa {overall:.3f})")
116
+
117
+
118
+ HTML = r"""<!doctype html>
119
+ <html lang="en"><head><meta charset="utf-8">
120
+ <meta name="viewport" content="width=device-width, initial-scale=1">
121
+ <title>Multicultural Riddles — Human Evaluation</title>
122
+ <script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
123
+ <style>
124
+ :root{
125
+ --ceil:#2f6f9f; --floor:#b8bfc7; --ink:#14181f; --mut:#5b6673; --line:#e7eaee;
126
+ --bg:#fbfcfd; --card:#ffffff; --accent:#2f6f9f;
127
+ --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
128
+ }
129
+ *{box-sizing:border-box}
130
+ body{font-family:var(--font);color:var(--ink);background:var(--bg);margin:0;
131
+ line-height:1.5;-webkit-font-smoothing:antialiased}
132
+ .wrap{max-width:1080px;margin:0 auto;padding:32px 24px 56px}
133
+ header{border-bottom:1px solid var(--line);padding-bottom:18px;margin-bottom:22px}
134
+ h1{font-size:24px;font-weight:700;letter-spacing:-.01em;margin:0 0 6px}
135
+ .sub{color:var(--mut);font-size:13.5px;max-width:760px}
136
+ .pill{display:inline-block;background:#eaf2f8;color:#245b82;font-size:12px;
137
+ font-weight:600;padding:3px 10px;border-radius:999px;margin-bottom:10px}
138
+ .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin:20px 0}
139
+ .card{background:var(--card);border:1px solid var(--line);border-radius:12px;
140
+ padding:14px 16px;box-shadow:0 1px 2px rgba(20,24,31,.03)}
141
+ .card .v{font-size:24px;font-weight:700;letter-spacing:-.02em}
142
+ .card .l{color:var(--mut);font-size:12px;margin-top:2px}
143
+ .tabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin:8px 0 6px}
144
+ .tab{padding:9px 14px;cursor:pointer;border:none;background:none;font-size:14px;
145
+ font-weight:500;color:var(--mut);border-bottom:2px solid transparent;margin-bottom:-1px}
146
+ .tab:hover{color:var(--ink)}
147
+ .tab.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
148
+ .toggle{display:flex;gap:6px;margin:16px 0 4px}
149
+ .toggle button{border:1px solid var(--line);background:var(--card);color:var(--mut);
150
+ font-size:13px;padding:6px 12px;border-radius:8px;cursor:pointer;font-family:var(--font)}
151
+ .toggle button.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
152
+ .pane{display:none;padding-top:10px} .pane.on{display:block}
153
+ .h2{font-size:16px;font-weight:600;margin:6px 0 2px}
154
+ .cap{color:var(--mut);font-size:12.5px;margin:8px 0 4px}
155
+ .dl{display:inline-block;margin-top:10px;font-size:12.5px;color:var(--accent);
156
+ border:1px solid var(--line);border-radius:8px;padding:5px 11px;text-decoration:none;cursor:pointer}
157
+ table{border-collapse:collapse;width:100%;font-size:13px;margin-top:12px}
158
+ th,td{border-bottom:1px solid var(--line);padding:7px 9px;text-align:left}
159
+ th{color:var(--mut);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.03em}
160
+ tr:hover td{background:#f7f9fb}
161
+ .badge{padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:600}
162
+ .complete{background:#e3f4e8;color:#1c7a3f}.partial{background:#fdf3e0;color:#9a6a12}
163
+ .thin{background:#fdeaea;color:#b23}.not_started{background:#eef0f2;color:#697}
164
+ .note{background:#f4f8fb;border:1px solid #dde8f1;border-radius:10px;padding:12px 14px;
165
+ font-size:13px;color:#2c4a63;margin-top:12px}
166
+ .foot{color:var(--mut);font-size:12px;margin-top:26px;padding-top:16px;
167
+ border-top:1px solid var(--line);line-height:1.6}
168
+ </style></head><body><div class="wrap">
169
+ <header>
170
+ <div class="pill">Human evaluation · provisional</div>
171
+ <h1>🧩 Multicultural Riddles Benchmark — Human Evaluation</h1>
172
+ <div class="sub" id="sub"></div>
173
+ </header>
174
+ <div class="cards" id="cards"></div>
175
+ <div class="tabs" id="tabs"></div>
176
+
177
+ <div id="lb" class="pane on">
178
+ <div class="h2">Heuristic floor → human ceiling</div>
179
+ <div class="toggle" id="toggle">
180
+ <button data-sc="strict" class="on">Strict (correct = top score)</button>
181
+ <button data-sc="lenient">Lenient (score ≥ 2)</button>
182
+ </div>
183
+ <div id="lbchart"></div>
184
+ <div class="cap">Grey = automatic heuristic judge (lower bound). Blue = human judgement (upper bound). The gap is the lift from strict string-matching to human scoring.</div>
185
+ <div id="lbtable"></div>
186
+ <a class="dl" id="lbdl">Download leaderboard (CSV)</a>
187
+ </div>
188
+
189
+ <div id="fail" class="pane">
190
+ <div class="h2">How models fail (human error types)</div>
191
+ <div id="failchart"></div>
192
+ <div class="cap" id="failcap"></div>
193
+ </div>
194
+
195
+ <div id="diff" class="pane">
196
+ <div class="h2">How hard is each culture?</div>
197
+ <div id="diffchart"></div>
198
+ <div class="cap" id="diffcap"></div>
199
+ </div>
200
+
201
+ <div id="kappa" class="pane">
202
+ <div class="h2">Does the auto-judge agree with humans?</div>
203
+ <div class="cards" id="kcards"></div>
204
+ <div id="kchart"></div>
205
+ <div class="cap" id="kcap"></div>
206
+ </div>
207
+
208
+ <div id="cov" class="pane">
209
+ <div class="h2">Human-eval coverage by community</div>
210
+ <div id="covtable"></div>
211
+ <div class="note" id="covnote"></div>
212
+ </div>
213
+
214
+ <div class="foot" id="foot"></div>
215
+ </div>
216
+ <script>
217
+ const D=__DATA__;
218
+ const CEIL="#2f6f9f",FLOOR="#b8bfc7";
219
+ let SC="strict";
220
+
221
+ document.getElementById('sub').textContent=`Live from the human-eval flat file (updated ${D.meta.mtime}). Every score traces to the flat file — pending rows are dropped, never guessed. This is the human ceiling that complements the team's full-corpus heuristic floor. Provisional; numbers shift as coverage completes.`;
222
+ const cards=[['Communities complete',`${D.meta.complete} / ${D.meta.total}`],['Models',D.meta.models],['Human-scored rows',D.meta.human_rows.toLocaleString()],['Pending',D.meta.pending.toLocaleString()]];
223
+ document.getElementById('cards').innerHTML=cards.map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
224
+
225
+ const TABS=[['lb','🏆 Leaderboard'],['fail','🔍 How models fail'],['diff','🌍 Community difficulty'],['kappa','🤝 Judge vs human'],['cov','📊 Coverage']];
226
+ document.getElementById('tabs').innerHTML=TABS.map((t,i)=>`<button class="tab${i==0?' on':''}" data-p="${t[0]}">${t[1]}</button>`).join('');
227
+ document.querySelectorAll('.tab').forEach(b=>b.onclick=()=>{
228
+ document.querySelectorAll('.tab').forEach(x=>x.classList.remove('on'));b.classList.add('on');
229
+ document.querySelectorAll('.pane').forEach(p=>p.classList.remove('on'));
230
+ document.getElementById(b.dataset.p).classList.add('on');window.dispatchEvent(new Event('resize'));});
231
+
232
+ const L={margin:{l:10,r:16,t:8,b:44},plot_bgcolor:'#fff',paper_bgcolor:'#fff',
233
+ font:{family:'-apple-system,Segoe UI,Roboto,sans-serif',size:12,color:'#14181f'},
234
+ xaxis:{gridcolor:'#eef0f2',zeroline:false},yaxis:{automargin:true}};
235
+
236
+ function dumbbell(el,rows,keyF,keyC,label,xlab){
237
+ const y=rows.map(label);
238
+ const segs=rows.map((r,i)=>({x:[r[keyF],r[keyC]],y:[y[i],y[i]],mode:'lines',line:{color:'#dfe3e8',width:3},showlegend:false,hoverinfo:'skip',type:'scatter'}));
239
+ const f={x:rows.map(r=>r[keyF]),y,mode:'markers',type:'scatter',name:'Heuristic (floor)',marker:{color:FLOOR,size:10,line:{color:'#9aa0a6',width:1}}};
240
+ const c={x:rows.map(r=>r[keyC]),y,mode:'markers',type:'scatter',name:'Human (ceiling)',marker:{color:CEIL,size:10}};
241
+ Plotly.newPlot(el,[...segs,f,c],{...L,height:Math.max(400,27*rows.length),xaxis:{...L.xaxis,title:xlab,range:[0,100]},legend:{orientation:'h',y:1.07}},{displayModeBar:false,responsive:true});
242
+ }
243
+ function renderLB(){
244
+ const lb=D.leaderboard[SC];
245
+ dumbbell('lbchart',[...lb].sort((a,b)=>a['Human (ceiling) %']-b['Human (ceiling) %']),'Heuristic (floor) %','Human (ceiling) %',r=>r.model,`Accuracy (%), ${SC}`);
246
+ document.getElementById('lbtable').innerHTML='<table><tr><th>#</th><th>Model</th><th>Human %</th><th>Heuristic %</th><th>human-judged %</th><th>n</th></tr>'+lb.map(r=>`<tr><td>${r.rank}</td><td>${r.model}</td><td><b>${r['Human (ceiling) %']}</b></td><td>${r['Heuristic (floor) %']}</td><td>${r['human-scored %']}</td><td>${r.n}</td></tr>`).join('')+'</table>';
247
+ const d=D.difficulty[SC];
248
+ dumbbell('diffchart',d,'Heuristic %','Human %',r=>r.community,`Mean accuracy across models (%), ${SC}`);
249
+ document.getElementById('diffcap').textContent=`Mean accuracy across all ${D.meta.models} models per community. Hardest: ${d.slice(0,3).map(r=>r.community).join(', ')}. Easiest: ${d.slice(-3).map(r=>r.community).join(', ')}. Grey = heuristic floor, blue = human ceiling.`;
250
+ }
251
+ document.querySelectorAll('.toggle button').forEach(b=>b.onclick=()=>{
252
+ document.querySelectorAll('.toggle button').forEach(x=>x.classList.remove('on'));b.classList.add('on');
253
+ SC=b.dataset.sc;renderLB();});
254
+ renderLB();
255
+
256
+ // how models fail — stacked horizontal bars, models ordered by Correct desc
257
+ (function(){
258
+ const rows=[...D.failmodes].reverse(); // plotly draws bottom-up
259
+ const y=rows.map(r=>r.model);
260
+ const traces=D.fail_order.map(cat=>({
261
+ x:rows.map(r=>r[cat]||0),y,name:cat,type:'bar',orientation:'h',
262
+ marker:{color:D.fail_colors[cat]},
263
+ hovertemplate:'%{y}<br>'+cat+': %{x:.1f}%<extra></extra>'}));
264
+ Plotly.newPlot('failchart',traces,{...L,barmode:'stack',height:Math.max(440,28*rows.length),
265
+ xaxis:{...L.xaxis,title:'Share of human-scored responses (%)',range:[0,100]},
266
+ legend:{orientation:'h',y:1.06,font:{size:11}}},{displayModeBar:false,responsive:true});
267
+ const top=D.failmodes[0],bot=D.failmodes[D.failmodes.length-1];
268
+ document.getElementById('failcap').innerHTML=`How each model's answers break down when a human judges them. <b>Hallucination (red) is the dominant failure mode and grows as capability drops</b> — from ${top.Hallucinated}% (${top.model}) to ${bot.Hallucinated}% (${bot.model}). Models almost never admit uncertainty (blue, ≤1%) — they produce a confident wrong answer instead. "Wrong entity" = right category, wrong specific answer; "too broad" = a more general answer.`;
269
+ })();
270
+
271
+ // kappa
272
+ const k=D.kappa;
273
+ document.getElementById('kcards').innerHTML=[["Overall Cohen's κ",k.overall],['Human-correct the judge missed',k.misses.toLocaleString()],['Judge over-credits',k.overcredit.toLocaleString()]].map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
274
+ const kp=[...k.per];
275
+ Plotly.newPlot('kchart',[{x:kp.map(r=>r.kappa),y:kp.map(r=>r.community),type:'bar',orientation:'h',marker:{color:kp.map(r=>r.kappa<0.4?'#d1552f':CEIL)},hovertemplate:'%{y}<br>κ %{x:.3f}<extra></extra>'}],{...L,height:Math.max(420,26*kp.length),xaxis:{...L.xaxis,title:"Cohen's κ (judge vs human)"},shapes:[{type:'line',x0:k.overall,x1:k.overall,y0:-0.5,y1:kp.length-0.5,line:{color:'#5b6673',dash:'dash',width:1.4}}]},{displayModeBar:false,responsive:true});
276
+ document.getElementById('kcap').innerHTML=`Two raters = the automatic judge and the human (not two humans — we have one annotator per riddle). On ${k.n.toLocaleString()} doubly-labelled rows. Red κ&lt;0.4 = string-matching unreliable (non-Latin scripts). Dashed line = overall κ ${k.overall}. The judge misses far more correct answers (${k.misses.toLocaleString()}) than it over-credits (${k.overcredit.toLocaleString()}).`;
277
+
278
+ // coverage
279
+ const ord={complete:0,partial:1,thin:2,not_started:3};
280
+ const cv=[...D.coverage].sort((a,b)=>ord[a.status]-ord[b.status]||b.pct_complete-a.pct_complete);
281
+ document.getElementById('covtable').innerHTML='<table><tr><th>Community</th><th>Status</th><th>% complete</th><th>human</th><th>pending</th><th>eligible</th></tr>'+cv.map(r=>`<tr><td>${r.community}</td><td><span class="badge ${r.status}">${r.status.replace('_',' ')}</span></td><td>${r.pct_complete??''}</td><td>${r.human_done}</td><td>${r.pending}</td><td>${r.human_eligible}</td></tr>`).join('')+'</table>';
282
+ const chase=cv.filter(r=>r.status=='not_started'||r.status=='thin').map(r=>r.community);
283
+ document.getElementById('covnote').textContent=chase.length?('Chase list (not started / thin): '+chase.join(', ')):'All started.';
284
+
285
+ // leaderboard CSV download
286
+ document.getElementById('lbdl').onclick=()=>{
287
+ const lb=D.leaderboard[SC],cols=['rank','model','Human (ceiling) %','Heuristic (floor) %','human-scored %','n'];
288
+ const csv=[cols.join(',')].concat(lb.map(r=>cols.map(c=>r[c]).join(','))).join('\n');
289
+ const a=document.createElement('a');a.href=URL.createObjectURL(new Blob([csv],{type:'text/csv'}));
290
+ a.download='human_leaderboard_'+SC+'.csv';a.click();};
291
+
292
+ document.getElementById('foot').innerHTML='Methodology: single human annotator per riddle (no inter-annotator agreement). Leaderboard and error types restricted to communities with complete human coverage. Source of truth: model_riddle_results_flat.csv (Henry Gagnier). Heuristic judge is reference-based string matching (no LLM). Cuba riddle spanish_cuba_history_016 excluded (redone in v2). Provisional until coverage completes.';
293
+ </script></body></html>"""
294
+
295
+
296
+ if __name__ == "__main__":
297
+ main()
index.html CHANGED
@@ -4,84 +4,173 @@
4
  <title>Multicultural Riddles — Human Evaluation</title>
5
  <script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
6
  <style>
7
- :root{--floor:#9aa0a6;--ceil:#3b6fb6;--ink:#1c1e21;--mut:#6b7280;--line:#e5e7eb}
 
 
 
 
8
  *{box-sizing:border-box}
9
- body{font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
10
- color:var(--ink);margin:0;padding:24px;max-width:1040px;margin:0 auto}
11
- h1{font-size:22px;margin:0 0 4px} .cap{color:var(--mut);font-size:13px;margin-bottom:16px}
12
- .cards{display:flex;gap:12px;flex-wrap:wrap;margin:12px 0 18px}
13
- .card{border:1px solid var(--line);border-radius:10px;padding:10px 14px;min-width:150px}
14
- .card .v{font-size:22px;font-weight:600} .card .l{color:var(--mut);font-size:12px}
15
- .tabs{display:flex;gap:6px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin-bottom:14px}
16
- .tab{padding:8px 12px;cursor:pointer;border:none;background:none;font-size:14px;color:var(--mut)}
17
- .tab.on{color:var(--ceil);border-bottom:2px solid var(--ceil);font-weight:600}
18
- .pane{display:none} .pane.on{display:block}
19
- .toggle{margin:0 0 10px} .toggle label{margin-right:14px;font-size:14px;cursor:pointer}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  table{border-collapse:collapse;width:100%;font-size:13px;margin-top:12px}
21
- th,td{border-bottom:1px solid var(--line);padding:6px 8px;text-align:left}
22
- th{color:var(--mut);font-weight:600} .foot{color:var(--mut);font-size:12px;margin-top:18px;line-height:1.5}
23
- .info{background:#eef4fb;border:1px solid #cfe0f4;border-radius:8px;padding:12px;font-size:14px;color:#274b73}
24
- .badge{padding:2px 8px;border-radius:10px;font-size:12px}
25
  .complete{background:#e3f4e8;color:#1c7a3f}.partial{background:#fdf3e0;color:#9a6a12}
26
- .thin{background:#fdeaea;color:#b23}.not_started{background:#f1f1f3;color:#666}
27
- </style></head><body>
28
- <h1>🧩 Multicultural Riddles Benchmark — Human Evaluation</h1>
29
- <div class="cap" id="cap"></div>
 
 
 
 
 
 
 
30
  <div class="cards" id="cards"></div>
31
- <div class="toggle" id="toggle">
32
- <label><input type="radio" name="sc" value="strict" checked> Strict (top score = 3)</label>
33
- <label><input type="radio" name="sc" value="lenient"> Lenient (score ≥ 2)</label>
34
- </div>
35
  <div class="tabs" id="tabs"></div>
36
- <div id="lb" class="pane on"><div id="lbchart"></div><div class="cap" id="lbcap"></div><div id="lbtable"></div></div>
37
- <div id="diff" class="pane"><div id="diffchart"></div><div class="cap" id="diffcap"></div></div>
38
- <div id="kappa" class="pane"><div class="cards" id="kcards"></div><div id="kchart"></div><div class="cap" id="kcap"></div></div>
39
- <div id="cov" class="pane"><div id="covtable"></div><div class="cap" id="covcap"></div></div>
40
- <div id="map" class="pane"><p style="font-size:14px;margin:0 0 10px">Coverage map — concept by <b>Pouya Sadeghi</b> (Cohere Labs): cultures covered per country, across 34 countries. Hover a country for its cultures.</p><div style="height:560px; width:100%;"> <div id="mapdiv" class="plotly-graph-div" style="height:100%; width:100%;"></div> <script> window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById("mapdiv")) { Plotly.newPlot( "mapdiv", [{"colorbar":{"len":0.6,"orientation":"h","thickness":14,"ticktext":["1","2","3","4","5\u201310"],"tickvals":[1,2,3,4,5],"title":{"side":"bottom","text":"Cultures covered per country"},"y":-0.12},"colorscale":[[0.0,"rgb(247,251,255)"],[0.125,"rgb(222,235,247)"],[0.25,"rgb(198,219,239)"],[0.375,"rgb(158,202,225)"],[0.5,"rgb(107,174,214)"],[0.625,"rgb(66,146,198)"],[0.75,"rgb(33,113,181)"],[0.875,"rgb(8,81,156)"],[1.0,"rgb(8,48,107)"]],"hovertemplate":"%{text}\u003cextra\u003e\u003c\u002fextra\u003e","locationmode":"country names","locations":["Indonesia","Bangladesh","Belarus","India","Bulgaria","China","United States","Hungary","Italy","Iran","Serbia","Argentina","Uganda","Peru","Nigeria","Sri Lanka","Uzbekistan","Thailand","Syria","Pakistan","Nepal","Germany","Poland","Russia","Portugal","Brazil","Cuba","Netherlands","Canada","France","Sudan","Morocco","Kenya","Egypt"],"marker":{"line":{"color":"white","width":0.5}},"text":["\u003cb\u003eIndonesia\u003c\u002fb\u003e\u003cbr\u003e3 cultures\u003cbr\u003ebugisnese_indonesia, indonesian_indonesia, mongondow_indonesia","\u003cb\u003eBangladesh\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ebengali_bangladesh","\u003cb\u003eBelarus\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ebelarusian_belarus","\u003cb\u003eIndia\u003c\u002fb\u003e\u003cbr\u003e6 cultures\u003cbr\u003ebengali_india, konkani_india, malayalam_india, marathi_india, tamil_india, telugu_india","\u003cb\u003eBulgaria\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ebulgarian_bulgaria","\u003cb\u003eChina\u003c\u002fb\u003e\u003cbr\u003e3 cultures\u003cbr\u003ecantonese_china, chinese_china, chinese_simplified_china","\u003cb\u003eUnited States\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eenglish_usa","\u003cb\u003eHungary\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ehungarian_hungary","\u003cb\u003eItaly\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eitalian_italy","\u003cb\u003eIran\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003epersian_iran","\u003cb\u003eSerbia\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eserbian_serbia","\u003cb\u003eArgentina\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003espanish_argentina","\u003cb\u003eUganda\u003c\u002fb\u003e\u003cbr\u003e2 cultures\u003cbr\u003eluganda_uganda, lumasaba_uganda","\u003cb\u003ePeru\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003espanish_peru","\u003cb\u003eNigeria\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eyoruba_nigeria","\u003cb\u003eSri Lanka\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003esinhala_sri_lanka","\u003cb\u003eUzbekistan\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003euzbek_uzbekistan","\u003cb\u003eThailand\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ethai_thailand","\u003cb\u003eSyria\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003earabic_syria","\u003cb\u003ePakistan\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eurdu_pakistan","\u003cb\u003eNepal\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003enepali_nepal","\u003cb\u003eGermany\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003egerman_germany","\u003cb\u003ePoland\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003epolish_poland","\u003cb\u003eRussia\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003erussian_russia","\u003cb\u003ePortugal\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eportuguese_portugal","\u003cb\u003eBrazil\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003ebrazilian_portuguese","\u003cb\u003eCuba\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003espanish_cuba","\u003cb\u003eNetherlands\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003edutch_netherlands","\u003cb\u003eCanada\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eenglish_canada","\u003cb\u003eFrance\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003efrench_france","\u003cb\u003eSudan\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003earabic_sudan","\u003cb\u003eMorocco\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003earabic_morocco","\u003cb\u003eKenya\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003eswahili_kenya","\u003cb\u003eEgypt\u003c\u002fb\u003e\u003cbr\u003e1 culture\u003cbr\u003earabic_egypt"],"z":[3,1,1,5,1,3,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"zmax":5,"zmin":1,"type":"choropleth"}], {"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}},"geo":{"projection":{"type":"natural earth"},"showcountries":true,"countrycolor":"#ffffff","showframe":true,"framecolor":"#888","showcoastlines":false,"landcolor":"#e5e7eb"},"margin":{"l":0,"r":0,"t":0,"b":0},"height":560,"paper_bgcolor":"#fff"}, {"displayModeBar": false, "responsive": true} ) }; </script> </div><div class="cap">Darker = more of the benchmark's cultures contributed by that country. Grey countries are not represented in the benchmark. Covers all 44 v0 cultures.</div></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  <div class="foot" id="foot"></div>
 
42
  <script>
43
- const D={"meta": {"mtime": "2026-08-07 19:55", "complete": 17, "total": 44, "models": 24, "human_rows": 63947, "pending": 18062}, "leaderboard": {"strict": [{"model": "gemini-3.1-pro-preview", "rank": 1, "Human (ceiling) %": 77.9, "Heuristic (floor) %": 65.1, "n": 1700, "human-scored %": 53.0}, {"model": "GPT5.5 [none]", "rank": 2, "Human (ceiling) %": 75.9, "Heuristic (floor) %": 60.6, "n": 1700, "human-scored %": 57.0}, {"model": "GPT5.5 [high]", "rank": 3, "Human (ceiling) %": 73.9, "Heuristic (floor) %": 59.4, "n": 1700, "human-scored %": 50.0}, {"model": "claude-opus-4-7 [thinking]", "rank": 4, "Human (ceiling) %": 64.1, "Heuristic (floor) %": 51.8, "n": 1700, "human-scored %": 61.0}, {"model": "deepseek-v4-pro-thinking", "rank": 5, "Human (ceiling) %": 61.5, "Heuristic (floor) %": 50.7, "n": 1700, "human-scored %": 64.0}, {"model": "claude-opus-4-7 [none]", "rank": 6, "Human (ceiling) %": 56.8, "Heuristic (floor) %": 46.4, "n": 1700, "human-scored %": 67.0}, {"model": "deepseek-v4-pro", "rank": 7, "Human (ceiling) %": 56.6, "Heuristic (floor) %": 46.4, "n": 1699, "human-scored %": 70.0}, {"model": "Gemini 2.5 Flash", "rank": 8, "Human (ceiling) %": 45.8, "Heuristic (floor) %": 36.2, "n": 1700, "human-scored %": 78.0}, {"model": "Mistral Large 3", "rank": 9, "Human (ceiling) %": 37.4, "Heuristic (floor) %": 29.9, "n": 1700, "human-scored %": 81.0}, {"model": "DeepSeek V4 Flash", "rank": 10, "Human (ceiling) %": 34.4, "Heuristic (floor) %": 27.4, "n": 1700, "human-scored %": 83.0}, {"model": "Gemma 4 31B IT", "rank": 11, "Human (ceiling) %": 34.2, "Heuristic (floor) %": 27.1, "n": 1700, "human-scored %": 83.0}, {"model": "Gemini 2.5 Flash Lite", "rank": 12, "Human (ceiling) %": 31.5, "Heuristic (floor) %": 25.8, "n": 1700, "human-scored %": 84.0}, {"model": "Qwen-SEA-LION-v4.5-27B-IT", "rank": 13, "Human (ceiling) %": 31.2, "Heuristic (floor) %": 25.1, "n": 1700, "human-scored %": 72.0}, {"model": "Cohere Command A Plus", "rank": 14, "Human (ceiling) %": 29.1, "Heuristic (floor) %": 23.1, "n": 1700, "human-scored %": 52.0}, {"model": "Qwen3.5 27B", "rank": 15, "Human (ceiling) %": 24.6, "Heuristic (floor) %": 19.3, "n": 1700, "human-scored %": 88.0}, {"model": "Amazon Nova Lite v1", "rank": 16, "Human (ceiling) %": 12.8, "Heuristic (floor) %": 9.6, "n": 1699, "human-scored %": 94.0}, {"model": "EuroLLM-22B-Instruct-2512", "rank": 17, "Human (ceiling) %": 11.8, "Heuristic (floor) %": 9.7, "n": 1700, "human-scored %": 95.0}, {"model": "OLMo-3-32B-Think", "rank": 18, "Human (ceiling) %": 10.4, "Heuristic (floor) %": 8.2, "n": 1699, "human-scored %": 70.0}, {"model": "Amazon Nova Micro v1", "rank": 19, "Human (ceiling) %": 6.4, "Heuristic (floor) %": 5.9, "n": 1699, "human-scored %": 88.0}, {"model": "Tiny-Aya fire", "rank": 20, "Human (ceiling) %": 6.2, "Heuristic (floor) %": 4.6, "n": 1698, "human-scored %": 97.0}, {"model": "Tiny-Aya water", "rank": 21, "Human (ceiling) %": 6.2, "Heuristic (floor) %": 4.6, "n": 1699, "human-scored %": 97.0}, {"model": "Tiny-Aya earth", "rank": 22, "Human (ceiling) %": 6.1, "Heuristic (floor) %": 4.7, "n": 1698, "human-scored %": 98.0}, {"model": "Tiny-Aya global", "rank": 23, "Human (ceiling) %": 5.7, "Heuristic (floor) %": 4.9, "n": 1698, "human-scored %": 98.0}, {"model": "Qwen/Qwen3.5-0.8B", "rank": 24, "Human (ceiling) %": 0.2, "Heuristic (floor) %": 0.3, "n": 1699, "human-scored %": 100.0}], "lenient": [{"model": "gemini-3.1-pro-preview", "rank": 1, "Human (ceiling) %": 84.7, "Heuristic (floor) %": 65.1, "n": 1700, "human-scored %": 53.0}, {"model": "GPT5.5 [none]", "rank": 2, "Human (ceiling) %": 82.1, "Heuristic (floor) %": 60.6, "n": 1700, "human-scored %": 57.0}, {"model": "GPT5.5 [high]", "rank": 3, "Human (ceiling) %": 78.8, "Heuristic (floor) %": 59.4, "n": 1700, "human-scored %": 50.0}, {"model": "claude-opus-4-7 [thinking]", "rank": 4, "Human (ceiling) %": 70.6, "Heuristic (floor) %": 51.8, "n": 1700, "human-scored %": 61.0}, {"model": "deepseek-v4-pro-thinking", "rank": 5, "Human (ceiling) %": 68.8, "Heuristic (floor) %": 50.7, "n": 1700, "human-scored %": 64.0}, {"model": "deepseek-v4-pro", "rank": 6, "Human (ceiling) %": 64.3, "Heuristic (floor) %": 46.4, "n": 1699, "human-scored %": 70.0}, {"model": "claude-opus-4-7 [none]", "rank": 7, "Human (ceiling) %": 64.2, "Heuristic (floor) %": 46.4, "n": 1700, "human-scored %": 67.0}, {"model": "Gemini 2.5 Flash", "rank": 8, "Human (ceiling) %": 53.5, "Heuristic (floor) %": 36.2, "n": 1700, "human-scored %": 78.0}, {"model": "Mistral Large 3", "rank": 9, "Human (ceiling) %": 44.7, "Heuristic (floor) %": 29.9, "n": 1700, "human-scored %": 81.0}, {"model": "DeepSeek V4 Flash", "rank": 10, "Human (ceiling) %": 43.4, "Heuristic (floor) %": 27.4, "n": 1700, "human-scored %": 83.0}, {"model": "Gemma 4 31B IT", "rank": 11, "Human (ceiling) %": 42.7, "Heuristic (floor) %": 27.1, "n": 1700, "human-scored %": 83.0}, {"model": "Gemini 2.5 Flash Lite", "rank": 12, "Human (ceiling) %": 39.9, "Heuristic (floor) %": 25.8, "n": 1700, "human-scored %": 84.0}, {"model": "Qwen-SEA-LION-v4.5-27B-IT", "rank": 13, "Human (ceiling) %": 37.9, "Heuristic (floor) %": 25.1, "n": 1700, "human-scored %": 72.0}, {"model": "Cohere Command A Plus", "rank": 14, "Human (ceiling) %": 35.9, "Heuristic (floor) %": 23.1, "n": 1700, "human-scored %": 52.0}, {"model": "Qwen3.5 27B", "rank": 15, "Human (ceiling) %": 33.4, "Heuristic (floor) %": 19.3, "n": 1700, "human-scored %": 88.0}, {"model": "Amazon Nova Lite v1", "rank": 16, "Human (ceiling) %": 18.9, "Heuristic (floor) %": 9.6, "n": 1699, "human-scored %": 94.0}, {"model": "EuroLLM-22B-Instruct-2512", "rank": 17, "Human (ceiling) %": 18.7, "Heuristic (floor) %": 9.7, "n": 1700, "human-scored %": 95.0}, {"model": "OLMo-3-32B-Think", "rank": 18, "Human (ceiling) %": 13.9, "Heuristic (floor) %": 8.2, "n": 1699, "human-scored %": 70.0}, {"model": "Tiny-Aya water", "rank": 19, "Human (ceiling) %": 12.5, "Heuristic (floor) %": 4.6, "n": 1699, "human-scored %": 97.0}, {"model": "Tiny-Aya earth", "rank": 20, "Human (ceiling) %": 12.4, "Heuristic (floor) %": 4.7, "n": 1698, "human-scored %": 98.0}, {"model": "Tiny-Aya fire", "rank": 21, "Human (ceiling) %": 12.4, "Heuristic (floor) %": 4.6, "n": 1698, "human-scored %": 97.0}, {"model": "Tiny-Aya global", "rank": 22, "Human (ceiling) %": 11.4, "Heuristic (floor) %": 4.9, "n": 1698, "human-scored %": 98.0}, {"model": "Amazon Nova Micro v1", "rank": 23, "Human (ceiling) %": 10.8, "Heuristic (floor) %": 5.9, "n": 1699, "human-scored %": 88.0}, {"model": "Qwen/Qwen3.5-0.8B", "rank": 24, "Human (ceiling) %": 1.2, "Heuristic (floor) %": 0.3, "n": 1699, "human-scored %": 100.0}]}, "difficulty": {"strict": [{"community": "mongondow_indonesia", "Human %": 5.2, "Heuristic %": 4.0}, {"community": "bugisnese_indonesia", "Human %": 6.1, "Heuristic %": 3.5}, {"community": "belarusian_belarus", "Human %": 23.4, "Heuristic %": 21.9}, {"community": "malayalam_india", "Human %": 23.6, "Heuristic %": 19.8}, {"community": "hungarian_hungary", "Human %": 24.0, "Heuristic %": 21.5}, {"community": "persian_iran", "Human %": 29.4, "Heuristic %": 24.9}, {"community": "spanish_argentina", "Human %": 30.9, "Heuristic %": 26.5}, {"community": "telugu_india", "Human %": 31.2, "Heuristic %": 22.0}, {"community": "cantonese_china", "Human %": 31.5, "Heuristic %": 20.3}, {"community": "indonesian_indonesia", "Human %": 35.5, "Heuristic %": 29.5}, {"community": "serbian_serbia", "Human %": 37.1, "Heuristic %": 19.8}, {"community": "tamil_india", "Human %": 42.0, "Heuristic %": 35.9}, {"community": "bengali_bangladesh", "Human %": 44.2, "Heuristic %": 37.4}, {"community": "bulgarian_bulgaria", "Human %": 44.3, "Heuristic %": 39.0}, {"community": "marathi_india", "Human %": 44.5, "Heuristic %": 29.1}, {"community": "italian_italy", "Human %": 46.0, "Heuristic %": 41.9}, {"community": "english_usa", "Human %": 68.4, "Heuristic %": 61.3}], "lenient": [{"community": "mongondow_indonesia", "Human %": 7.4, "Heuristic %": 4.0}, {"community": "bugisnese_indonesia", "Human %": 8.6, "Heuristic %": 3.5}, {"community": "belarusian_belarus", "Human %": 25.3, "Heuristic %": 21.9}, {"community": "hungarian_hungary", "Human %": 29.0, "Heuristic %": 21.5}, {"community": "malayalam_india", "Human %": 30.1, "Heuristic %": 19.8}, {"community": "persian_iran", "Human %": 37.2, "Heuristic %": 24.9}, {"community": "spanish_argentina", "Human %": 37.4, "Heuristic %": 26.5}, {"community": "indonesian_indonesia", "Human %": 37.7, "Heuristic %": 29.5}, {"community": "serbian_serbia", "Human %": 41.7, "Heuristic %": 19.8}, {"community": "cantonese_china", "Human %": 41.8, "Heuristic %": 20.3}, {"community": "tamil_india", "Human %": 46.4, "Heuristic %": 35.9}, {"community": "italian_italy", "Human %": 48.4, "Heuristic %": 41.9}, {"community": "bengali_bangladesh", "Human %": 49.0, "Heuristic %": 37.4}, {"community": "telugu_india", "Human %": 50.7, "Heuristic %": 22.0}, {"community": "marathi_india", "Human %": 57.5, "Heuristic %": 29.1}, {"community": "bulgarian_bulgaria", "Human %": 58.4, "Heuristic %": 39.0}, {"community": "english_usa", "Human %": 71.5, "Heuristic %": 61.3}]}, "kappa": {"overall": 0.603, "misses": 3188, "overcredit": 540, "n": 31965, "per": [{"community": "cantonese_china", "kappa": 0.096}, {"community": "serbian_serbia", "kappa": 0.212}, {"community": "marathi_india", "kappa": 0.303}, {"community": "telugu_india", "kappa": 0.314}, {"community": "mongondow_indonesia", "kappa": 0.43}, {"community": "bugisnese_indonesia", "kappa": 0.448}, {"community": "malayalam_india", "kappa": 0.48}, {"community": "bulgarian_bulgaria", "kappa": 0.551}, {"community": "tamil_india", "kappa": 0.568}, {"community": "bengali_bangladesh", "kappa": 0.582}, {"community": "indonesian_indonesia", "kappa": 0.625}, {"community": "hungarian_hungary", "kappa": 0.631}, {"community": "persian_iran", "kappa": 0.636}, {"community": "english_usa", "kappa": 0.715}, {"community": "spanish_argentina", "kappa": 0.819}, {"community": "italian_italy", "kappa": 0.823}, {"community": "belarusian_belarus", "kappa": 0.828}]}, "coverage": [{"community": "bugisnese_indonesia", "status": "complete", "pct_complete": 99.7, "human_done": 1855, "pending": 5, "human_eligible": 1860}, {"community": "bengali_bangladesh", "status": "complete", "pct_complete": 99.8, "human_done": 1707, "pending": 3, "human_eligible": 1710}, {"community": "belarusian_belarus", "status": "complete", "pct_complete": 99.9, "human_done": 1910, "pending": 1, "human_eligible": 1911}, {"community": "malayalam_india", "status": "complete", "pct_complete": 99.9, "human_done": 1928, "pending": 1, "human_eligible": 1929}, {"community": "marathi_india", "status": "complete", "pct_complete": 99.9, "human_done": 1785, "pending": 2, "human_eligible": 1787}, {"community": "bulgarian_bulgaria", "status": "complete", "pct_complete": 100.0, "human_done": 1742, "pending": 0, "human_eligible": 1742}, {"community": "cantonese_china", "status": "complete", "pct_complete": 100.0, "human_done": 1834, "pending": 0, "human_eligible": 1834}, {"community": "english_usa", "status": "complete", "pct_complete": 100.0, "human_done": 1569, "pending": 0, "human_eligible": 1569}, {"community": "hungarian_hungary", "status": "complete", "pct_complete": 100.0, "human_done": 1904, "pending": 0, "human_eligible": 1904}, {"community": "indonesian_indonesia", "status": "complete", "pct_complete": 100.0, "human_done": 1914, "pending": 0, "human_eligible": 1914}, {"community": "italian_italy", "status": "complete", "pct_complete": 100.0, "human_done": 1855, "pending": 0, "human_eligible": 1855}, {"community": "mongondow_indonesia", "status": "complete", "pct_complete": 100.0, "human_done": 2113, "pending": 0, "human_eligible": 2113}, {"community": "persian_iran", "status": "complete", "pct_complete": 100.0, "human_done": 1954, "pending": 0, "human_eligible": 1954}, {"community": "serbian_serbia", "status": "complete", "pct_complete": 100.0, "human_done": 1901, "pending": 0, "human_eligible": 1901}, {"community": "spanish_argentina", "status": "complete", "pct_complete": 100.0, "human_done": 2244, "pending": 0, "human_eligible": 2244}, {"community": "tamil_india", "status": "complete", "pct_complete": 100.0, "human_done": 1818, "pending": 0, "human_eligible": 1818}, {"community": "telugu_india", "status": "complete", "pct_complete": 100.0, "human_done": 1932, "pending": 0, "human_eligible": 1932}, {"community": "luganda_uganda", "status": "not_started", "pct_complete": 0.0, "human_done": 0, "pending": 2172, "human_eligible": 2172}, {"community": "lumasaba_uganda", "status": "not_started", "pct_complete": 0.0, "human_done": 0, "pending": 2137, "human_eligible": 2137}, {"community": "spanish_peru", "status": "partial", "pct_complete": 49.6, "human_done": 909, "pending": 923, "human_eligible": 1832}, {"community": "yoruba_nigeria", "status": "partial", "pct_complete": 63.7, "human_done": 1336, "pending": 762, "human_eligible": 2098}, {"community": "sinhala_sri_lanka", "status": "partial", "pct_complete": 74.5, "human_done": 1361, "pending": 465, "human_eligible": 1826}, {"community": "uzbek_uzbekistan", "status": "partial", "pct_complete": 76.3, "human_done": 1409, "pending": 437, "human_eligible": 1846}, {"community": "thai_thailand", "status": "partial", "pct_complete": 79.6, "human_done": 1451, "pending": 373, "human_eligible": 1824}, {"community": "arabic_syria", "status": "partial", "pct_complete": 80.7, "human_done": 1650, "pending": 395, "human_eligible": 2045}, {"community": "urdu_pakistan", "status": "partial", "pct_complete": 81.1, "human_done": 1631, "pending": 381, "human_eligible": 2012}, {"community": "nepali_nepal", "status": "partial", "pct_complete": 81.2, "human_done": 1485, "pending": 343, "human_eligible": 1828}, {"community": "chinese_china", "status": "partial", "pct_complete": 81.5, "human_done": 1725, "pending": 392, "human_eligible": 2117}, {"community": "german_germany", "status": "partial", "pct_complete": 82.8, "human_done": 1550, "pending": 321, "human_eligible": 1871}, {"community": "polish_poland", "status": "partial", "pct_complete": 83.1, "human_done": 1484, "pending": 301, "human_eligible": 1785}, {"community": "konkani_india", "status": "partial", "pct_complete": 83.8, "human_done": 1751, "pending": 339, "human_eligible": 2090}, {"community": "chinese_simplified_china", "status": "partial", "pct_complete": 85.3, "human_done": 1497, "pending": 258, "human_eligible": 1755}, {"community": "russian_russia", "status": "partial", "pct_complete": 85.9, "human_done": 1563, "pending": 257, "human_eligible": 1820}, {"community": "portuguese_portugal", "status": "partial", "pct_complete": 86.5, "human_done": 1400, "pending": 219, "human_eligible": 1619}, {"community": "brazilian_portuguese", "status": "partial", "pct_complete": 89.3, "human_done": 1175, "pending": 141, "human_eligible": 1316}, {"community": "spanish_cuba", "status": "partial", "pct_complete": 89.6, "human_done": 1477, "pending": 171, "human_eligible": 1648}, {"community": "bengali_india", "status": "partial", "pct_complete": 90.9, "human_done": 1471, "pending": 147, "human_eligible": 1618}, {"community": "dutch_netherlands", "status": "partial", "pct_complete": 91.4, "human_done": 1322, "pending": 125, "human_eligible": 1447}, {"community": "english_canada", "status": "partial", "pct_complete": 94.0, "human_done": 1841, "pending": 118, "human_eligible": 1959}, {"community": "french_france", "status": "partial", "pct_complete": 94.9, "human_done": 1334, "pending": 72, "human_eligible": 1406}, {"community": "arabic_sudan", "status": "thin", "pct_complete": 13.4, "human_done": 289, "pending": 1874, "human_eligible": 2163}, {"community": "arabic_morocco", "status": "thin", "pct_complete": 14.6, "human_done": 280, "pending": 1637, "human_eligible": 1917}, {"community": "swahili_kenya", "status": "thin", "pct_complete": 14.6, "human_done": 301, "pending": 1767, "human_eligible": 2068}, {"community": "arabic_egypt", "status": "thin", "pct_complete": 16.0, "human_done": 290, "pending": 1523, "human_eligible": 1813}]};
44
- const FLOOR="#9aa0a6",CEIL="#3b6fb6";
45
- const cap=document.getElementById('cap');
46
- cap.textContent=`Provisional leaderboard from Henry's flat file (updated ${D.meta.mtime}). Every score traces to the flat file; pending rows dropped, never guessed. Numbers shift as coverage completes.`;
 
47
  const cards=[['Communities complete',`${D.meta.complete} / ${D.meta.total}`],['Models',D.meta.models],['Human-scored rows',D.meta.human_rows.toLocaleString()],['Pending',D.meta.pending.toLocaleString()]];
48
  document.getElementById('cards').innerHTML=cards.map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
49
- const TABS=[['lb','🏆 Leaderboard'],['diff','🌍 Community difficulty'],['kappa','🤝 Judge vs human'],['cov','📊 Coverage'],['map','🗺️ Coverage map']];
 
50
  document.getElementById('tabs').innerHTML=TABS.map((t,i)=>`<button class="tab${i==0?' on':''}" data-p="${t[0]}">${t[1]}</button>`).join('');
51
  document.querySelectorAll('.tab').forEach(b=>b.onclick=()=>{
52
  document.querySelectorAll('.tab').forEach(x=>x.classList.remove('on'));b.classList.add('on');
53
  document.querySelectorAll('.pane').forEach(p=>p.classList.remove('on'));
54
  document.getElementById(b.dataset.p).classList.add('on');window.dispatchEvent(new Event('resize'));});
55
- const L={margin:{l:10,r:16,t:10,b:44},plot_bgcolor:'#fff',paper_bgcolor:'#fff',font:{size:12},xaxis:{gridcolor:'#eef0f2',zeroline:false},yaxis:{automargin:true,ticklabelposition:'outside'}};
56
- function dumbbell(el,rows,keyF,keyC,labels,xlab){
57
- const y=rows.map(labels),lo=rows.map(r=>r[keyF]),hi=rows.map(r=>r[keyC]);
58
- const segs=[];rows.forEach((r,i)=>segs.push({x:[r[keyF],r[keyC]],y:[y[i],y[i]],mode:'lines',line:{color:'#d0d3d8',width:3},showlegend:false,hoverinfo:'skip',type:'scatter'}));
59
- const f={x:lo,y,mode:'markers',type:'scatter',name:'Heuristic (floor)',marker:{color:FLOOR,size:10}};
60
- const c={x:hi,y,mode:'markers',type:'scatter',name:'Human (ceiling)',marker:{color:CEIL,size:10}};
61
- Plotly.newPlot(el,[...segs,f,c],{...L,height:Math.max(420,26*rows.length),xaxis:{...L.xaxis,title:xlab},legend:{orientation:'h',y:1.06}},{displayModeBar:false,responsive:true});
 
 
 
 
62
  }
63
- function render(sc){
64
- const lb=D.leaderboard[sc];
65
- dumbbell('lbchart',[...lb].sort((a,b)=>a['Human (ceiling) %']-b['Human (ceiling) %']),'Heuristic (floor) %','Human (ceiling) %',r=>r.model,`Accuracy (%), ${sc}`);
66
- document.getElementById('lbcap').textContent='Grey = heuristic auto-judge (lower bound). Blue = human judgement (upper bound).';
67
- document.getElementById('lbtable').innerHTML='<table><tr><th>#</th><th>Model</th><th>Human %</th><th>Heuristic %</th><th>human-scored %</th><th>n</th></tr>'+lb.map(r=>`<tr><td>${r.rank}</td><td>${r.model}</td><td>${r['Human (ceiling) %']}</td><td>${r['Heuristic (floor) %']}</td><td>${r['human-scored %']}</td><td>${r.n}</td></tr>`).join('')+'</table>';
68
- const d=D.difficulty[sc];
69
- dumbbell('diffchart',d,'Heuristic %','Human %',r=>r.community,`Mean accuracy across models (%), ${sc}`);
70
- document.getElementById('diffcap').textContent=`Hardest: ${d.slice(0,3).map(r=>r.community).join(', ')}. Easiest: ${d.slice(-3).map(r=>r.community).join(', ')}.`;
71
  }
72
- document.querySelectorAll('input[name=sc]').forEach(r=>r.onchange=e=>render(e.target.value));
73
- render('strict');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  // kappa
75
  const k=D.kappa;
76
  document.getElementById('kcards').innerHTML=[["Overall Cohen's κ",k.overall],['Human-correct the judge missed',k.misses.toLocaleString()],['Judge over-credits',k.overcredit.toLocaleString()]].map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
77
  const kp=[...k.per];
78
- Plotly.newPlot('kchart',[{x:kp.map(r=>r.kappa),y:kp.map(r=>r.community),type:'bar',orientation:'h',marker:{color:kp.map(r=>r.kappa<0.4?'#D55E00':CEIL)}}],{...L,height:Math.max(420,26*kp.length),xaxis:{...L.xaxis,title:"Cohen's κ (judge vs human)"},shapes:[{type:'line',x0:k.overall,x1:k.overall,y0:-0.5,y1:kp.length-0.5,line:{color:'#7F7F7F',dash:'dash',width:1.4}}]},{displayModeBar:false,responsive:true});
79
- document.getElementById('kcap').textContent=`On ${k.n.toLocaleString()} human-scored rows. Red κ<0.4 = string-matching unreliable (non-Latin scripts). Dashed line = overall κ ${k.overall}. The judge misses far more correct answers (${k.misses.toLocaleString()}) than it over-credits (${k.overcredit.toLocaleString()}) — why the human ceiling sits above the heuristic floor.`;
 
80
  // coverage
81
  const ord={complete:0,partial:1,thin:2,not_started:3};
82
  const cv=[...D.coverage].sort((a,b)=>ord[a.status]-ord[b.status]||b.pct_complete-a.pct_complete);
83
- document.getElementById('covtable').innerHTML='<table><tr><th>Community</th><th>Status</th><th>% complete</th><th>human</th><th>pending</th><th>eligible</th></tr>'+cv.map(r=>`<tr><td>${r.community}</td><td><span class="badge ${r.status}">${r.status}</span></td><td>${r.pct_complete??''}</td><td>${r.human_done}</td><td>${r.pending}</td><td>${r.human_eligible}</td></tr>`).join('')+'</table>';
84
  const chase=cv.filter(r=>r.status=='not_started'||r.status=='thin').map(r=>r.community);
85
- document.getElementById('covcap').textContent=chase.length?('Chase list: '+chase.join(', ')):'';
86
- document.getElementById('foot').innerHTML='Methodology: single human annotator per riddle (no inter-annotator agreement). Leaderboard restricted to communities with complete human coverage. Source of truth: model_riddle_results_flat.csv (Henry). Cuba riddle spanish_cuba_history_016 excluded (redone in v2). Provisional until coverage completes.';
 
 
 
 
 
 
 
 
87
  </script></body></html>
 
4
  <title>Multicultural Riddles — Human Evaluation</title>
5
  <script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
6
  <style>
7
+ :root{
8
+ --ceil:#2f6f9f; --floor:#b8bfc7; --ink:#14181f; --mut:#5b6673; --line:#e7eaee;
9
+ --bg:#fbfcfd; --card:#ffffff; --accent:#2f6f9f;
10
+ --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
11
+ }
12
  *{box-sizing:border-box}
13
+ body{font-family:var(--font);color:var(--ink);background:var(--bg);margin:0;
14
+ line-height:1.5;-webkit-font-smoothing:antialiased}
15
+ .wrap{max-width:1080px;margin:0 auto;padding:32px 24px 56px}
16
+ header{border-bottom:1px solid var(--line);padding-bottom:18px;margin-bottom:22px}
17
+ h1{font-size:24px;font-weight:700;letter-spacing:-.01em;margin:0 0 6px}
18
+ .sub{color:var(--mut);font-size:13.5px;max-width:760px}
19
+ .pill{display:inline-block;background:#eaf2f8;color:#245b82;font-size:12px;
20
+ font-weight:600;padding:3px 10px;border-radius:999px;margin-bottom:10px}
21
+ .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin:20px 0}
22
+ .card{background:var(--card);border:1px solid var(--line);border-radius:12px;
23
+ padding:14px 16px;box-shadow:0 1px 2px rgba(20,24,31,.03)}
24
+ .card .v{font-size:24px;font-weight:700;letter-spacing:-.02em}
25
+ .card .l{color:var(--mut);font-size:12px;margin-top:2px}
26
+ .tabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin:8px 0 6px}
27
+ .tab{padding:9px 14px;cursor:pointer;border:none;background:none;font-size:14px;
28
+ font-weight:500;color:var(--mut);border-bottom:2px solid transparent;margin-bottom:-1px}
29
+ .tab:hover{color:var(--ink)}
30
+ .tab.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
31
+ .toggle{display:flex;gap:6px;margin:16px 0 4px}
32
+ .toggle button{border:1px solid var(--line);background:var(--card);color:var(--mut);
33
+ font-size:13px;padding:6px 12px;border-radius:8px;cursor:pointer;font-family:var(--font)}
34
+ .toggle button.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
35
+ .pane{display:none;padding-top:10px} .pane.on{display:block}
36
+ .h2{font-size:16px;font-weight:600;margin:6px 0 2px}
37
+ .cap{color:var(--mut);font-size:12.5px;margin:8px 0 4px}
38
+ .dl{display:inline-block;margin-top:10px;font-size:12.5px;color:var(--accent);
39
+ border:1px solid var(--line);border-radius:8px;padding:5px 11px;text-decoration:none;cursor:pointer}
40
  table{border-collapse:collapse;width:100%;font-size:13px;margin-top:12px}
41
+ th,td{border-bottom:1px solid var(--line);padding:7px 9px;text-align:left}
42
+ th{color:var(--mut);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.03em}
43
+ tr:hover td{background:#f7f9fb}
44
+ .badge{padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:600}
45
  .complete{background:#e3f4e8;color:#1c7a3f}.partial{background:#fdf3e0;color:#9a6a12}
46
+ .thin{background:#fdeaea;color:#b23}.not_started{background:#eef0f2;color:#697}
47
+ .note{background:#f4f8fb;border:1px solid #dde8f1;border-radius:10px;padding:12px 14px;
48
+ font-size:13px;color:#2c4a63;margin-top:12px}
49
+ .foot{color:var(--mut);font-size:12px;margin-top:26px;padding-top:16px;
50
+ border-top:1px solid var(--line);line-height:1.6}
51
+ </style></head><body><div class="wrap">
52
+ <header>
53
+ <div class="pill">Human evaluation · provisional</div>
54
+ <h1>🧩 Multicultural Riddles Benchmark — Human Evaluation</h1>
55
+ <div class="sub" id="sub"></div>
56
+ </header>
57
  <div class="cards" id="cards"></div>
 
 
 
 
58
  <div class="tabs" id="tabs"></div>
59
+
60
+ <div id="lb" class="pane on">
61
+ <div class="h2">Heuristic floor → human ceiling</div>
62
+ <div class="toggle" id="toggle">
63
+ <button data-sc="strict" class="on">Strict (correct = top score)</button>
64
+ <button data-sc="lenient">Lenient (score ≥ 2)</button>
65
+ </div>
66
+ <div id="lbchart"></div>
67
+ <div class="cap">Grey = automatic heuristic judge (lower bound). Blue = human judgement (upper bound). The gap is the lift from strict string-matching to human scoring.</div>
68
+ <div id="lbtable"></div>
69
+ <a class="dl" id="lbdl">Download leaderboard (CSV)</a>
70
+ </div>
71
+
72
+ <div id="fail" class="pane">
73
+ <div class="h2">How models fail (human error types)</div>
74
+ <div id="failchart"></div>
75
+ <div class="cap" id="failcap"></div>
76
+ </div>
77
+
78
+ <div id="diff" class="pane">
79
+ <div class="h2">How hard is each culture?</div>
80
+ <div id="diffchart"></div>
81
+ <div class="cap" id="diffcap"></div>
82
+ </div>
83
+
84
+ <div id="kappa" class="pane">
85
+ <div class="h2">Does the auto-judge agree with humans?</div>
86
+ <div class="cards" id="kcards"></div>
87
+ <div id="kchart"></div>
88
+ <div class="cap" id="kcap"></div>
89
+ </div>
90
+
91
+ <div id="cov" class="pane">
92
+ <div class="h2">Human-eval coverage by community</div>
93
+ <div id="covtable"></div>
94
+ <div class="note" id="covnote"></div>
95
+ </div>
96
+
97
  <div class="foot" id="foot"></div>
98
+ </div>
99
  <script>
100
+ const D={"meta": {"mtime": "2026-08-07 19:55", "complete": 17, "total": 44, "models": 24, "human_rows": 63947, "pending": 18062}, "leaderboard": {"strict": [{"model": "gemini-3.1-pro-preview", "rank": 1, "Human (ceiling) %": 77.9, "Heuristic (floor) %": 65.1, "n": 1700, "human-scored %": 53.0}, {"model": "GPT5.5 [none]", "rank": 2, "Human (ceiling) %": 75.9, "Heuristic (floor) %": 60.6, "n": 1700, "human-scored %": 57.0}, {"model": "GPT5.5 [high]", "rank": 3, "Human (ceiling) %": 73.9, "Heuristic (floor) %": 59.4, "n": 1700, "human-scored %": 50.0}, {"model": "claude-opus-4-7 [thinking]", "rank": 4, "Human (ceiling) %": 64.1, "Heuristic (floor) %": 51.8, "n": 1700, "human-scored %": 61.0}, {"model": "deepseek-v4-pro-thinking", "rank": 5, "Human (ceiling) %": 61.5, "Heuristic (floor) %": 50.7, "n": 1700, "human-scored %": 64.0}, {"model": "claude-opus-4-7 [none]", "rank": 6, "Human (ceiling) %": 56.8, "Heuristic (floor) %": 46.4, "n": 1700, "human-scored %": 67.0}, {"model": "deepseek-v4-pro", "rank": 7, "Human (ceiling) %": 56.6, "Heuristic (floor) %": 46.4, "n": 1699, "human-scored %": 70.0}, {"model": "Gemini 2.5 Flash", "rank": 8, "Human (ceiling) %": 45.8, "Heuristic (floor) %": 36.2, "n": 1700, "human-scored %": 78.0}, {"model": "Mistral Large 3", "rank": 9, "Human (ceiling) %": 37.4, "Heuristic (floor) %": 29.9, "n": 1700, "human-scored %": 81.0}, {"model": "DeepSeek V4 Flash", "rank": 10, "Human (ceiling) %": 34.4, "Heuristic (floor) %": 27.4, "n": 1700, "human-scored %": 83.0}, {"model": "Gemma 4 31B IT", "rank": 11, "Human (ceiling) %": 34.2, "Heuristic (floor) %": 27.1, "n": 1700, "human-scored %": 83.0}, {"model": "Gemini 2.5 Flash Lite", "rank": 12, "Human (ceiling) %": 31.5, "Heuristic (floor) %": 25.8, "n": 1700, "human-scored %": 84.0}, {"model": "Qwen-SEA-LION-v4.5-27B-IT", "rank": 13, "Human (ceiling) %": 31.2, "Heuristic (floor) %": 25.1, "n": 1700, "human-scored %": 72.0}, {"model": "Cohere Command A Plus", "rank": 14, "Human (ceiling) %": 29.1, "Heuristic (floor) %": 23.1, "n": 1700, "human-scored %": 52.0}, {"model": "Qwen3.5 27B", "rank": 15, "Human (ceiling) %": 24.6, "Heuristic (floor) %": 19.3, "n": 1700, "human-scored %": 88.0}, {"model": "Amazon Nova Lite v1", "rank": 16, "Human (ceiling) %": 12.8, "Heuristic (floor) %": 9.6, "n": 1699, "human-scored %": 94.0}, {"model": "EuroLLM-22B-Instruct-2512", "rank": 17, "Human (ceiling) %": 11.8, "Heuristic (floor) %": 9.7, "n": 1700, "human-scored %": 95.0}, {"model": "OLMo-3-32B-Think", "rank": 18, "Human (ceiling) %": 10.4, "Heuristic (floor) %": 8.2, "n": 1699, "human-scored %": 70.0}, {"model": "Amazon Nova Micro v1", "rank": 19, "Human (ceiling) %": 6.4, "Heuristic (floor) %": 5.9, "n": 1699, "human-scored %": 88.0}, {"model": "Tiny-Aya fire", "rank": 20, "Human (ceiling) %": 6.2, "Heuristic (floor) %": 4.6, "n": 1698, "human-scored %": 97.0}, {"model": "Tiny-Aya water", "rank": 21, "Human (ceiling) %": 6.2, "Heuristic (floor) %": 4.6, "n": 1699, "human-scored %": 97.0}, {"model": "Tiny-Aya earth", "rank": 22, "Human (ceiling) %": 6.1, "Heuristic (floor) %": 4.7, "n": 1698, "human-scored %": 98.0}, {"model": "Tiny-Aya global", "rank": 23, "Human (ceiling) %": 5.7, "Heuristic (floor) %": 4.9, "n": 1698, "human-scored %": 98.0}, {"model": "Qwen/Qwen3.5-0.8B", "rank": 24, "Human (ceiling) %": 0.2, "Heuristic (floor) %": 0.3, "n": 1699, "human-scored %": 100.0}], "lenient": [{"model": "gemini-3.1-pro-preview", "rank": 1, "Human (ceiling) %": 84.7, "Heuristic (floor) %": 65.1, "n": 1700, "human-scored %": 53.0}, {"model": "GPT5.5 [none]", "rank": 2, "Human (ceiling) %": 82.1, "Heuristic (floor) %": 60.6, "n": 1700, "human-scored %": 57.0}, {"model": "GPT5.5 [high]", "rank": 3, "Human (ceiling) %": 78.8, "Heuristic (floor) %": 59.4, "n": 1700, "human-scored %": 50.0}, {"model": "claude-opus-4-7 [thinking]", "rank": 4, "Human (ceiling) %": 70.6, "Heuristic (floor) %": 51.8, "n": 1700, "human-scored %": 61.0}, {"model": "deepseek-v4-pro-thinking", "rank": 5, "Human (ceiling) %": 68.8, "Heuristic (floor) %": 50.7, "n": 1700, "human-scored %": 64.0}, {"model": "deepseek-v4-pro", "rank": 6, "Human (ceiling) %": 64.3, "Heuristic (floor) %": 46.4, "n": 1699, "human-scored %": 70.0}, {"model": "claude-opus-4-7 [none]", "rank": 7, "Human (ceiling) %": 64.2, "Heuristic (floor) %": 46.4, "n": 1700, "human-scored %": 67.0}, {"model": "Gemini 2.5 Flash", "rank": 8, "Human (ceiling) %": 53.5, "Heuristic (floor) %": 36.2, "n": 1700, "human-scored %": 78.0}, {"model": "Mistral Large 3", "rank": 9, "Human (ceiling) %": 44.7, "Heuristic (floor) %": 29.9, "n": 1700, "human-scored %": 81.0}, {"model": "DeepSeek V4 Flash", "rank": 10, "Human (ceiling) %": 43.4, "Heuristic (floor) %": 27.4, "n": 1700, "human-scored %": 83.0}, {"model": "Gemma 4 31B IT", "rank": 11, "Human (ceiling) %": 42.7, "Heuristic (floor) %": 27.1, "n": 1700, "human-scored %": 83.0}, {"model": "Gemini 2.5 Flash Lite", "rank": 12, "Human (ceiling) %": 39.9, "Heuristic (floor) %": 25.8, "n": 1700, "human-scored %": 84.0}, {"model": "Qwen-SEA-LION-v4.5-27B-IT", "rank": 13, "Human (ceiling) %": 37.9, "Heuristic (floor) %": 25.1, "n": 1700, "human-scored %": 72.0}, {"model": "Cohere Command A Plus", "rank": 14, "Human (ceiling) %": 35.9, "Heuristic (floor) %": 23.1, "n": 1700, "human-scored %": 52.0}, {"model": "Qwen3.5 27B", "rank": 15, "Human (ceiling) %": 33.4, "Heuristic (floor) %": 19.3, "n": 1700, "human-scored %": 88.0}, {"model": "Amazon Nova Lite v1", "rank": 16, "Human (ceiling) %": 18.9, "Heuristic (floor) %": 9.6, "n": 1699, "human-scored %": 94.0}, {"model": "EuroLLM-22B-Instruct-2512", "rank": 17, "Human (ceiling) %": 18.7, "Heuristic (floor) %": 9.7, "n": 1700, "human-scored %": 95.0}, {"model": "OLMo-3-32B-Think", "rank": 18, "Human (ceiling) %": 13.9, "Heuristic (floor) %": 8.2, "n": 1699, "human-scored %": 70.0}, {"model": "Tiny-Aya water", "rank": 19, "Human (ceiling) %": 12.5, "Heuristic (floor) %": 4.6, "n": 1699, "human-scored %": 97.0}, {"model": "Tiny-Aya earth", "rank": 20, "Human (ceiling) %": 12.4, "Heuristic (floor) %": 4.7, "n": 1698, "human-scored %": 98.0}, {"model": "Tiny-Aya fire", "rank": 21, "Human (ceiling) %": 12.4, "Heuristic (floor) %": 4.6, "n": 1698, "human-scored %": 97.0}, {"model": "Tiny-Aya global", "rank": 22, "Human (ceiling) %": 11.4, "Heuristic (floor) %": 4.9, "n": 1698, "human-scored %": 98.0}, {"model": "Amazon Nova Micro v1", "rank": 23, "Human (ceiling) %": 10.8, "Heuristic (floor) %": 5.9, "n": 1699, "human-scored %": 88.0}, {"model": "Qwen/Qwen3.5-0.8B", "rank": 24, "Human (ceiling) %": 1.2, "Heuristic (floor) %": 0.3, "n": 1699, "human-scored %": 100.0}]}, "difficulty": {"strict": [{"community": "mongondow_indonesia", "Human %": 5.2, "Heuristic %": 4.0}, {"community": "bugisnese_indonesia", "Human %": 6.1, "Heuristic %": 3.5}, {"community": "belarusian_belarus", "Human %": 23.4, "Heuristic %": 21.9}, {"community": "malayalam_india", "Human %": 23.6, "Heuristic %": 19.8}, {"community": "hungarian_hungary", "Human %": 24.0, "Heuristic %": 21.5}, {"community": "persian_iran", "Human %": 29.4, "Heuristic %": 24.9}, {"community": "spanish_argentina", "Human %": 30.9, "Heuristic %": 26.5}, {"community": "telugu_india", "Human %": 31.2, "Heuristic %": 22.0}, {"community": "cantonese_china", "Human %": 31.5, "Heuristic %": 20.3}, {"community": "indonesian_indonesia", "Human %": 35.5, "Heuristic %": 29.5}, {"community": "serbian_serbia", "Human %": 37.1, "Heuristic %": 19.8}, {"community": "tamil_india", "Human %": 42.0, "Heuristic %": 35.9}, {"community": "bengali_bangladesh", "Human %": 44.2, "Heuristic %": 37.4}, {"community": "bulgarian_bulgaria", "Human %": 44.3, "Heuristic %": 39.0}, {"community": "marathi_india", "Human %": 44.5, "Heuristic %": 29.1}, {"community": "italian_italy", "Human %": 46.0, "Heuristic %": 41.9}, {"community": "english_usa", "Human %": 68.4, "Heuristic %": 61.3}], "lenient": [{"community": "mongondow_indonesia", "Human %": 7.4, "Heuristic %": 4.0}, {"community": "bugisnese_indonesia", "Human %": 8.6, "Heuristic %": 3.5}, {"community": "belarusian_belarus", "Human %": 25.3, "Heuristic %": 21.9}, {"community": "hungarian_hungary", "Human %": 29.0, "Heuristic %": 21.5}, {"community": "malayalam_india", "Human %": 30.1, "Heuristic %": 19.8}, {"community": "persian_iran", "Human %": 37.2, "Heuristic %": 24.9}, {"community": "spanish_argentina", "Human %": 37.4, "Heuristic %": 26.5}, {"community": "indonesian_indonesia", "Human %": 37.7, "Heuristic %": 29.5}, {"community": "serbian_serbia", "Human %": 41.7, "Heuristic %": 19.8}, {"community": "cantonese_china", "Human %": 41.8, "Heuristic %": 20.3}, {"community": "tamil_india", "Human %": 46.4, "Heuristic %": 35.9}, {"community": "italian_italy", "Human %": 48.4, "Heuristic %": 41.9}, {"community": "bengali_bangladesh", "Human %": 49.0, "Heuristic %": 37.4}, {"community": "telugu_india", "Human %": 50.7, "Heuristic %": 22.0}, {"community": "marathi_india", "Human %": 57.5, "Heuristic %": 29.1}, {"community": "bulgarian_bulgaria", "Human %": 58.4, "Heuristic %": 39.0}, {"community": "english_usa", "Human %": 71.5, "Heuristic %": 61.3}]}, "fail_order": ["Correct", "Partially correct", "Explicit uncertainty", "Wrong entity", "Too broad", "Hallucinated", "Other incorrect"], "fail_colors": {"Correct": "#1a9e76", "Partially correct": "#8fcfb8", "Explicit uncertainty": "#4c9be8", "Wrong entity": "#e79a3c", "Too broad": "#efc84a", "Hallucinated": "#d1552f", "Other incorrect": "#a7adb5"}, "kappa": {"overall": 0.603, "misses": 3188, "overcredit": 540, "n": 31965, "per": [{"community": "cantonese_china", "kappa": 0.096}, {"community": "serbian_serbia", "kappa": 0.212}, {"community": "marathi_india", "kappa": 0.303}, {"community": "telugu_india", "kappa": 0.314}, {"community": "mongondow_indonesia", "kappa": 0.43}, {"community": "bugisnese_indonesia", "kappa": 0.448}, {"community": "malayalam_india", "kappa": 0.48}, {"community": "bulgarian_bulgaria", "kappa": 0.551}, {"community": "tamil_india", "kappa": 0.568}, {"community": "bengali_bangladesh", "kappa": 0.582}, {"community": "indonesian_indonesia", "kappa": 0.625}, {"community": "hungarian_hungary", "kappa": 0.631}, {"community": "persian_iran", "kappa": 0.636}, {"community": "english_usa", "kappa": 0.715}, {"community": "spanish_argentina", "kappa": 0.819}, {"community": "italian_italy", "kappa": 0.823}, {"community": "belarusian_belarus", "kappa": 0.828}]}, "failmodes": [{"model": "GPT5.5 [high]", "Correct": 74.8, "Partially correct": 9.6, "Explicit uncertainty": 0.0, "Wrong entity": 4.2, "Too broad": 3.0, "Hallucinated": 7.1, "Other incorrect": 1.3}, {"model": "gemini-3.1-pro-preview", "Correct": 65.7, "Partially correct": 12.9, "Explicit uncertainty": 0.0, "Wrong entity": 5.7, "Too broad": 2.8, "Hallucinated": 11.6, "Other incorrect": 1.3}, {"model": "GPT5.5 [none]", "Correct": 64.9, "Partially correct": 10.6, "Explicit uncertainty": 0.0, "Wrong entity": 7.6, "Too broad": 2.7, "Hallucinated": 12.9, "Other incorrect": 1.3}, {"model": "claude-opus-4-7 [thinking]", "Correct": 55.6, "Partially correct": 10.8, "Explicit uncertainty": 0.5, "Wrong entity": 14.0, "Too broad": 4.6, "Hallucinated": 12.1, "Other incorrect": 2.3}, {"model": "deepseek-v4-pro-thinking", "Correct": 45.8, "Partially correct": 11.4, "Explicit uncertainty": 0.0, "Wrong entity": 12.9, "Too broad": 5.4, "Hallucinated": 21.4, "Other incorrect": 3.1}, {"model": "claude-opus-4-7 [none]", "Correct": 42.9, "Partially correct": 11.2, "Explicit uncertainty": 0.2, "Wrong entity": 18.5, "Too broad": 5.2, "Hallucinated": 19.6, "Other incorrect": 2.4}, {"model": "deepseek-v4-pro", "Correct": 41.3, "Partially correct": 11.0, "Explicit uncertainty": 0.0, "Wrong entity": 15.5, "Too broad": 6.6, "Hallucinated": 22.4, "Other incorrect": 3.2}, {"model": "Gemini 2.5 Flash", "Correct": 31.5, "Partially correct": 9.8, "Explicit uncertainty": 0.2, "Wrong entity": 21.6, "Too broad": 6.8, "Hallucinated": 27.1, "Other incorrect": 3.0}, {"model": "Cohere Command A Plus", "Correct": 30.0, "Partially correct": 13.0, "Explicit uncertainty": 0.9, "Wrong entity": 14.0, "Too broad": 11.3, "Hallucinated": 24.7, "Other incorrect": 6.1}, {"model": "Mistral Large 3", "Correct": 23.1, "Partially correct": 9.0, "Explicit uncertainty": 0.1, "Wrong entity": 24.3, "Too broad": 9.2, "Hallucinated": 29.9, "Other incorrect": 4.5}, {"model": "Qwen-SEA-LION-v4.5-27B-IT", "Correct": 22.2, "Partially correct": 9.4, "Explicit uncertainty": 1.1, "Wrong entity": 19.0, "Too broad": 9.1, "Hallucinated": 34.0, "Other incorrect": 5.2}, {"model": "Gemma 4 31B IT", "Correct": 21.7, "Partially correct": 10.2, "Explicit uncertainty": 0.0, "Wrong entity": 20.0, "Too broad": 8.5, "Hallucinated": 34.3, "Other incorrect": 5.3}, {"model": "DeepSeek V4 Flash", "Correct": 21.0, "Partially correct": 10.9, "Explicit uncertainty": 0.1, "Wrong entity": 20.0, "Too broad": 9.3, "Hallucinated": 33.9, "Other incorrect": 4.7}, {"model": "Gemini 2.5 Flash Lite", "Correct": 18.4, "Partially correct": 10.1, "Explicit uncertainty": 0.2, "Wrong entity": 22.9, "Too broad": 9.9, "Hallucinated": 35.2, "Other incorrect": 3.2}, {"model": "Qwen3.5 27B", "Correct": 15.5, "Partially correct": 9.9, "Explicit uncertainty": 0.1, "Wrong entity": 23.5, "Too broad": 9.3, "Hallucinated": 37.2, "Other incorrect": 4.5}, {"model": "OLMo-3-32B-Think", "Correct": 8.6, "Partially correct": 5.2, "Explicit uncertainty": 0.2, "Wrong entity": 17.4, "Too broad": 14.9, "Hallucinated": 46.2, "Other incorrect": 7.5}, {"model": "Amazon Nova Lite v1", "Correct": 7.9, "Partially correct": 6.5, "Explicit uncertainty": 0.1, "Wrong entity": 21.0, "Too broad": 12.7, "Hallucinated": 47.0, "Other incorrect": 4.8}, {"model": "EuroLLM-22B-Instruct-2512", "Correct": 7.3, "Partially correct": 7.3, "Explicit uncertainty": 0.1, "Wrong entity": 16.2, "Too broad": 14.9, "Hallucinated": 47.3, "Other incorrect": 7.0}, {"model": "Amazon Nova Micro v1", "Correct": 4.4, "Partially correct": 4.9, "Explicit uncertainty": 0.3, "Wrong entity": 16.6, "Too broad": 13.2, "Hallucinated": 54.5, "Other incorrect": 6.1}, {"model": "Tiny-Aya earth", "Correct": 3.8, "Partially correct": 6.5, "Explicit uncertainty": 0.0, "Wrong entity": 19.3, "Too broad": 14.6, "Hallucinated": 47.8, "Other incorrect": 8.1}, {"model": "Tiny-Aya fire", "Correct": 3.7, "Partially correct": 6.3, "Explicit uncertainty": 0.0, "Wrong entity": 19.4, "Too broad": 14.6, "Hallucinated": 48.5, "Other incorrect": 7.4}, {"model": "Tiny-Aya water", "Correct": 3.7, "Partially correct": 6.5, "Explicit uncertainty": 0.1, "Wrong entity": 19.1, "Too broad": 14.0, "Hallucinated": 48.7, "Other incorrect": 8.0}, {"model": "Tiny-Aya global", "Correct": 3.6, "Partially correct": 5.8, "Explicit uncertainty": 0.0, "Wrong entity": 20.3, "Too broad": 14.9, "Hallucinated": 47.8, "Other incorrect": 7.7}, {"model": "Qwen/Qwen3.5-0.8B", "Correct": 0.0, "Partially correct": 1.0, "Explicit uncertainty": 0.2, "Wrong entity": 4.4, "Too broad": 10.8, "Hallucinated": 77.3, "Other incorrect": 6.3}], "coverage": [{"community": "bugisnese_indonesia", "status": "complete", "pct_complete": 99.7, "human_done": 1855, "pending": 5, "human_eligible": 1860}, {"community": "bengali_bangladesh", "status": "complete", "pct_complete": 99.8, "human_done": 1707, "pending": 3, "human_eligible": 1710}, {"community": "belarusian_belarus", "status": "complete", "pct_complete": 99.9, "human_done": 1910, "pending": 1, "human_eligible": 1911}, {"community": "malayalam_india", "status": "complete", "pct_complete": 99.9, "human_done": 1928, "pending": 1, "human_eligible": 1929}, {"community": "marathi_india", "status": "complete", "pct_complete": 99.9, "human_done": 1785, "pending": 2, "human_eligible": 1787}, {"community": "bulgarian_bulgaria", "status": "complete", "pct_complete": 100.0, "human_done": 1742, "pending": 0, "human_eligible": 1742}, {"community": "cantonese_china", "status": "complete", "pct_complete": 100.0, "human_done": 1834, "pending": 0, "human_eligible": 1834}, {"community": "english_usa", "status": "complete", "pct_complete": 100.0, "human_done": 1569, "pending": 0, "human_eligible": 1569}, {"community": "hungarian_hungary", "status": "complete", "pct_complete": 100.0, "human_done": 1904, "pending": 0, "human_eligible": 1904}, {"community": "indonesian_indonesia", "status": "complete", "pct_complete": 100.0, "human_done": 1914, "pending": 0, "human_eligible": 1914}, {"community": "italian_italy", "status": "complete", "pct_complete": 100.0, "human_done": 1855, "pending": 0, "human_eligible": 1855}, {"community": "mongondow_indonesia", "status": "complete", "pct_complete": 100.0, "human_done": 2113, "pending": 0, "human_eligible": 2113}, {"community": "persian_iran", "status": "complete", "pct_complete": 100.0, "human_done": 1954, "pending": 0, "human_eligible": 1954}, {"community": "serbian_serbia", "status": "complete", "pct_complete": 100.0, "human_done": 1901, "pending": 0, "human_eligible": 1901}, {"community": "spanish_argentina", "status": "complete", "pct_complete": 100.0, "human_done": 2244, "pending": 0, "human_eligible": 2244}, {"community": "tamil_india", "status": "complete", "pct_complete": 100.0, "human_done": 1818, "pending": 0, "human_eligible": 1818}, {"community": "telugu_india", "status": "complete", "pct_complete": 100.0, "human_done": 1932, "pending": 0, "human_eligible": 1932}, {"community": "luganda_uganda", "status": "not_started", "pct_complete": 0.0, "human_done": 0, "pending": 2172, "human_eligible": 2172}, {"community": "lumasaba_uganda", "status": "not_started", "pct_complete": 0.0, "human_done": 0, "pending": 2137, "human_eligible": 2137}, {"community": "spanish_peru", "status": "partial", "pct_complete": 49.6, "human_done": 909, "pending": 923, "human_eligible": 1832}, {"community": "yoruba_nigeria", "status": "partial", "pct_complete": 63.7, "human_done": 1336, "pending": 762, "human_eligible": 2098}, {"community": "sinhala_sri_lanka", "status": "partial", "pct_complete": 74.5, "human_done": 1361, "pending": 465, "human_eligible": 1826}, {"community": "uzbek_uzbekistan", "status": "partial", "pct_complete": 76.3, "human_done": 1409, "pending": 437, "human_eligible": 1846}, {"community": "thai_thailand", "status": "partial", "pct_complete": 79.6, "human_done": 1451, "pending": 373, "human_eligible": 1824}, {"community": "arabic_syria", "status": "partial", "pct_complete": 80.7, "human_done": 1650, "pending": 395, "human_eligible": 2045}, {"community": "urdu_pakistan", "status": "partial", "pct_complete": 81.1, "human_done": 1631, "pending": 381, "human_eligible": 2012}, {"community": "nepali_nepal", "status": "partial", "pct_complete": 81.2, "human_done": 1485, "pending": 343, "human_eligible": 1828}, {"community": "chinese_china", "status": "partial", "pct_complete": 81.5, "human_done": 1725, "pending": 392, "human_eligible": 2117}, {"community": "german_germany", "status": "partial", "pct_complete": 82.8, "human_done": 1550, "pending": 321, "human_eligible": 1871}, {"community": "polish_poland", "status": "partial", "pct_complete": 83.1, "human_done": 1484, "pending": 301, "human_eligible": 1785}, {"community": "konkani_india", "status": "partial", "pct_complete": 83.8, "human_done": 1751, "pending": 339, "human_eligible": 2090}, {"community": "chinese_simplified_china", "status": "partial", "pct_complete": 85.3, "human_done": 1497, "pending": 258, "human_eligible": 1755}, {"community": "russian_russia", "status": "partial", "pct_complete": 85.9, "human_done": 1563, "pending": 257, "human_eligible": 1820}, {"community": "portuguese_portugal", "status": "partial", "pct_complete": 86.5, "human_done": 1400, "pending": 219, "human_eligible": 1619}, {"community": "brazilian_portuguese", "status": "partial", "pct_complete": 89.3, "human_done": 1175, "pending": 141, "human_eligible": 1316}, {"community": "spanish_cuba", "status": "partial", "pct_complete": 89.6, "human_done": 1477, "pending": 171, "human_eligible": 1648}, {"community": "bengali_india", "status": "partial", "pct_complete": 90.9, "human_done": 1471, "pending": 147, "human_eligible": 1618}, {"community": "dutch_netherlands", "status": "partial", "pct_complete": 91.4, "human_done": 1322, "pending": 125, "human_eligible": 1447}, {"community": "english_canada", "status": "partial", "pct_complete": 94.0, "human_done": 1841, "pending": 118, "human_eligible": 1959}, {"community": "french_france", "status": "partial", "pct_complete": 94.9, "human_done": 1334, "pending": 72, "human_eligible": 1406}, {"community": "arabic_sudan", "status": "thin", "pct_complete": 13.4, "human_done": 289, "pending": 1874, "human_eligible": 2163}, {"community": "arabic_morocco", "status": "thin", "pct_complete": 14.6, "human_done": 280, "pending": 1637, "human_eligible": 1917}, {"community": "swahili_kenya", "status": "thin", "pct_complete": 14.6, "human_done": 301, "pending": 1767, "human_eligible": 2068}, {"community": "arabic_egypt", "status": "thin", "pct_complete": 16.0, "human_done": 290, "pending": 1523, "human_eligible": 1813}]};
101
+ const CEIL="#2f6f9f",FLOOR="#b8bfc7";
102
+ let SC="strict";
103
+
104
+ document.getElementById('sub').textContent=`Live from the human-eval flat file (updated ${D.meta.mtime}). Every score traces to the flat file — pending rows are dropped, never guessed. This is the human ceiling that complements the team's full-corpus heuristic floor. Provisional; numbers shift as coverage completes.`;
105
  const cards=[['Communities complete',`${D.meta.complete} / ${D.meta.total}`],['Models',D.meta.models],['Human-scored rows',D.meta.human_rows.toLocaleString()],['Pending',D.meta.pending.toLocaleString()]];
106
  document.getElementById('cards').innerHTML=cards.map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
107
+
108
+ const TABS=[['lb','🏆 Leaderboard'],['fail','🔍 How models fail'],['diff','🌍 Community difficulty'],['kappa','🤝 Judge vs human'],['cov','📊 Coverage']];
109
  document.getElementById('tabs').innerHTML=TABS.map((t,i)=>`<button class="tab${i==0?' on':''}" data-p="${t[0]}">${t[1]}</button>`).join('');
110
  document.querySelectorAll('.tab').forEach(b=>b.onclick=()=>{
111
  document.querySelectorAll('.tab').forEach(x=>x.classList.remove('on'));b.classList.add('on');
112
  document.querySelectorAll('.pane').forEach(p=>p.classList.remove('on'));
113
  document.getElementById(b.dataset.p).classList.add('on');window.dispatchEvent(new Event('resize'));});
114
+
115
+ const L={margin:{l:10,r:16,t:8,b:44},plot_bgcolor:'#fff',paper_bgcolor:'#fff',
116
+ font:{family:'-apple-system,Segoe UI,Roboto,sans-serif',size:12,color:'#14181f'},
117
+ xaxis:{gridcolor:'#eef0f2',zeroline:false},yaxis:{automargin:true}};
118
+
119
+ function dumbbell(el,rows,keyF,keyC,label,xlab){
120
+ const y=rows.map(label);
121
+ const segs=rows.map((r,i)=>({x:[r[keyF],r[keyC]],y:[y[i],y[i]],mode:'lines',line:{color:'#dfe3e8',width:3},showlegend:false,hoverinfo:'skip',type:'scatter'}));
122
+ const f={x:rows.map(r=>r[keyF]),y,mode:'markers',type:'scatter',name:'Heuristic (floor)',marker:{color:FLOOR,size:10,line:{color:'#9aa0a6',width:1}}};
123
+ const c={x:rows.map(r=>r[keyC]),y,mode:'markers',type:'scatter',name:'Human (ceiling)',marker:{color:CEIL,size:10}};
124
+ Plotly.newPlot(el,[...segs,f,c],{...L,height:Math.max(400,27*rows.length),xaxis:{...L.xaxis,title:xlab,range:[0,100]},legend:{orientation:'h',y:1.07}},{displayModeBar:false,responsive:true});
125
  }
126
+ function renderLB(){
127
+ const lb=D.leaderboard[SC];
128
+ dumbbell('lbchart',[...lb].sort((a,b)=>a['Human (ceiling) %']-b['Human (ceiling) %']),'Heuristic (floor) %','Human (ceiling) %',r=>r.model,`Accuracy (%), ${SC}`);
129
+ document.getElementById('lbtable').innerHTML='<table><tr><th>#</th><th>Model</th><th>Human %</th><th>Heuristic %</th><th>human-judged %</th><th>n</th></tr>'+lb.map(r=>`<tr><td>${r.rank}</td><td>${r.model}</td><td><b>${r['Human (ceiling) %']}</b></td><td>${r['Heuristic (floor) %']}</td><td>${r['human-scored %']}</td><td>${r.n}</td></tr>`).join('')+'</table>';
130
+ const d=D.difficulty[SC];
131
+ dumbbell('diffchart',d,'Heuristic %','Human %',r=>r.community,`Mean accuracy across models (%), ${SC}`);
132
+ document.getElementById('diffcap').textContent=`Mean accuracy across all ${D.meta.models} models per community. Hardest: ${d.slice(0,3).map(r=>r.community).join(', ')}. Easiest: ${d.slice(-3).map(r=>r.community).join(', ')}. Grey = heuristic floor, blue = human ceiling.`;
 
133
  }
134
+ document.querySelectorAll('.toggle button').forEach(b=>b.onclick=()=>{
135
+ document.querySelectorAll('.toggle button').forEach(x=>x.classList.remove('on'));b.classList.add('on');
136
+ SC=b.dataset.sc;renderLB();});
137
+ renderLB();
138
+
139
+ // how models fail — stacked horizontal bars, models ordered by Correct desc
140
+ (function(){
141
+ const rows=[...D.failmodes].reverse(); // plotly draws bottom-up
142
+ const y=rows.map(r=>r.model);
143
+ const traces=D.fail_order.map(cat=>({
144
+ x:rows.map(r=>r[cat]||0),y,name:cat,type:'bar',orientation:'h',
145
+ marker:{color:D.fail_colors[cat]},
146
+ hovertemplate:'%{y}<br>'+cat+': %{x:.1f}%<extra></extra>'}));
147
+ Plotly.newPlot('failchart',traces,{...L,barmode:'stack',height:Math.max(440,28*rows.length),
148
+ xaxis:{...L.xaxis,title:'Share of human-scored responses (%)',range:[0,100]},
149
+ legend:{orientation:'h',y:1.06,font:{size:11}}},{displayModeBar:false,responsive:true});
150
+ const top=D.failmodes[0],bot=D.failmodes[D.failmodes.length-1];
151
+ document.getElementById('failcap').innerHTML=`How each model's answers break down when a human judges them. <b>Hallucination (red) is the dominant failure mode and grows as capability drops</b> — from ${top.Hallucinated}% (${top.model}) to ${bot.Hallucinated}% (${bot.model}). Models almost never admit uncertainty (blue, ≤1%) — they produce a confident wrong answer instead. "Wrong entity" = right category, wrong specific answer; "too broad" = a more general answer.`;
152
+ })();
153
+
154
  // kappa
155
  const k=D.kappa;
156
  document.getElementById('kcards').innerHTML=[["Overall Cohen's κ",k.overall],['Human-correct the judge missed',k.misses.toLocaleString()],['Judge over-credits',k.overcredit.toLocaleString()]].map(c=>`<div class="card"><div class="v">${c[1]}</div><div class="l">${c[0]}</div></div>`).join('');
157
  const kp=[...k.per];
158
+ Plotly.newPlot('kchart',[{x:kp.map(r=>r.kappa),y:kp.map(r=>r.community),type:'bar',orientation:'h',marker:{color:kp.map(r=>r.kappa<0.4?'#d1552f':CEIL)},hovertemplate:'%{y}<br>κ %{x:.3f}<extra></extra>'}],{...L,height:Math.max(420,26*kp.length),xaxis:{...L.xaxis,title:"Cohen's κ (judge vs human)"},shapes:[{type:'line',x0:k.overall,x1:k.overall,y0:-0.5,y1:kp.length-0.5,line:{color:'#5b6673',dash:'dash',width:1.4}}]},{displayModeBar:false,responsive:true});
159
+ document.getElementById('kcap').innerHTML=`Two raters = the automatic judge and the human (not two humans — we have one annotator per riddle). On ${k.n.toLocaleString()} doubly-labelled rows. Red κ&lt;0.4 = string-matching unreliable (non-Latin scripts). Dashed line = overall κ ${k.overall}. The judge misses far more correct answers (${k.misses.toLocaleString()}) than it over-credits (${k.overcredit.toLocaleString()}).`;
160
+
161
  // coverage
162
  const ord={complete:0,partial:1,thin:2,not_started:3};
163
  const cv=[...D.coverage].sort((a,b)=>ord[a.status]-ord[b.status]||b.pct_complete-a.pct_complete);
164
+ document.getElementById('covtable').innerHTML='<table><tr><th>Community</th><th>Status</th><th>% complete</th><th>human</th><th>pending</th><th>eligible</th></tr>'+cv.map(r=>`<tr><td>${r.community}</td><td><span class="badge ${r.status}">${r.status.replace('_',' ')}</span></td><td>${r.pct_complete??''}</td><td>${r.human_done}</td><td>${r.pending}</td><td>${r.human_eligible}</td></tr>`).join('')+'</table>';
165
  const chase=cv.filter(r=>r.status=='not_started'||r.status=='thin').map(r=>r.community);
166
+ document.getElementById('covnote').textContent=chase.length?('Chase list (not started / thin): '+chase.join(', ')):'All started.';
167
+
168
+ // leaderboard CSV download
169
+ document.getElementById('lbdl').onclick=()=>{
170
+ const lb=D.leaderboard[SC],cols=['rank','model','Human (ceiling) %','Heuristic (floor) %','human-scored %','n'];
171
+ const csv=[cols.join(',')].concat(lb.map(r=>cols.map(c=>r[c]).join(','))).join('\n');
172
+ const a=document.createElement('a');a.href=URL.createObjectURL(new Blob([csv],{type:'text/csv'}));
173
+ a.download='human_leaderboard_'+SC+'.csv';a.click();};
174
+
175
+ document.getElementById('foot').innerHTML='Methodology: single human annotator per riddle (no inter-annotator agreement). Leaderboard and error types restricted to communities with complete human coverage. Source of truth: model_riddle_results_flat.csv (Henry Gagnier). Heuristic judge is reference-based string matching (no LLM). Cuba riddle spanish_cuba_history_016 excluded (redone in v2). Provisional until coverage completes.';
176
  </script></body></html>
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit>=1.40
2
+ pandas>=2.2
3
+ pyarrow>=16
4
+ plotly>=5.24