alinacao2000's picture
sync: update pipeline visualization
ff083ad verified
Raw
History Blame Contribute Delete
145 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>DebugBelief Β· Pipeline</title>
<style>
:root {
--blue: #0066cc;
--blue-focus: #0071e3;
--blue-dark: #2997ff;
--blue-tint: #e8f0fb;
--amber: #f5a623;
--green: #34c759;
--gold: #b8860b;
--gold-tint: rgba(184,134,11,.06);
--gold-line: #d4a017;
--silver-line:#9e9e9e;
--silver-tint:rgba(158,158,158,.06);
--canvas: #ffffff;
--parchment: #f5f5f7;
--pearl: #fafafc;
--ink: #1d1d1f;
--ink-80: #333333;
--ink-48: #6e6e73;
--hairline: #e0e0e0;
--divider: #f0f0f0;
--black: #000000;
--r-sm: 8px; --r-md: 11px; --r-lg: 18px; --r-pill: 9999px;
--font: "SF Pro Text",system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
--font-d: "SF Pro Display",system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
--font-mo:"SF Mono","Fira Code",Menlo,Consolas,monospace;
--panel-w: 380px;
}
*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
font-family: var(--font);
background: var(--parchment);
color: var(--ink);
-webkit-font-smoothing: antialiased;
overflow: hidden;
}
/* ── Nav ── */
.global-nav {
background: var(--black);
height: 44px;
display: flex;
align-items: center;
padding: 0 32px;
position: fixed;
top: 0; left: 0; right: 0;
z-index: 300;
gap: 10px;
}
.nav-brand { font-family: var(--font-d); font-size: 15px; font-weight: 600; letter-spacing: -.2px; color: #fff; }
.nav-brand em { font-style: normal; color: var(--blue-dark); }
.nav-sep { width: 1px; height: 14px; background: rgba(255,255,255,.18); }
.nav-sub { font-size: 12px; letter-spacing: -.12px; color: rgba(255,255,255,.52); }
.nav-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.nav-badge {
font-size: 11px; padding: 2px 9px;
border-radius: var(--r-pill);
background: rgba(255,255,255,.1);
color: rgba(255,255,255,.7);
border: 1px solid rgba(255,255,255,.15);
cursor: pointer;
transition: background .15s;
}
.nav-badge.live { background: rgba(52,199,89,.15); border-color: rgba(52,199,89,.3); color: #34c759; }
/* ── Layout ── */
.page-layout {
position: fixed;
top: 44px; left: 0; right: 0; bottom: 0;
display: flex;
transition: right .32s cubic-bezier(.32,.8,.32,1);
}
.page-layout.panel-open { right: var(--panel-w); }
/* ── Canvas scroll area ── */
.canvas-scroll {
flex: 1;
overflow: auto;
padding: 36px 60px 80px;
background: var(--parchment);
}
/* ── Pipeline canvas ── */
.pipeline-canvas {
position: relative;
width: 3300px;
min-width: 3300px;
height: 1130px;
margin: 0 auto;
}
/* ── SVG arrows ── */
.arrows-svg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: visible;
}
/* ── Node cards ── */
.node {
position: absolute;
width: 180px;
background: var(--canvas);
border: 1px solid var(--hairline);
border-radius: var(--r-lg);
padding: 12px 14px 10px;
cursor: pointer;
transition: border-color .15s;
display: flex;
flex-direction: column;
gap: 4px;
user-select: none;
}
.node:hover { border-color: #b0cae8; }
.node.active { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,102,204,.14); }
.node:active { transform: scale(.985); }
/* Mini nodes for gold/silver within a lane */
.node.mini {
width: 80px;
padding: 10px 10px 8px;
gap: 3px;
}
.node.mini .node-title { font-size: 11px; }
.node.mini .node-count { font-size: 16px; }
/* Gold / Silver mini node backgrounds */
.node.gold-n { background: var(--gold-tint); border-color: var(--gold-line); }
.node.silver-n { background: var(--silver-tint); border-color: var(--silver-line); }
.node.gold-n:hover { border-color: var(--gold); }
.node.silver-n:hover { border-color: #757575; }
/* Merge / Final nodes */
.node.final {
width: 260px;
padding: 14px 16px 12px;
border-width: 1.5px;
}
/* Group background bands */
.group-band {
position: absolute;
border-radius: 18px;
pointer-events: none;
}
.group-band.swe { background: rgba(0,102,204,.025); border: 1px dashed rgba(0,102,204,.14); }
.group-band.gh { background: rgba(245,166,35,.020); border: 1px dashed rgba(245,166,35,.18); }
.group-band.exp { background: rgba(245,166,35,.030); border: 1px dashed rgba(245,166,35,.24); }
/* Group / Lane headers */
.group-hd {
position: absolute;
font-size: 11px;
font-weight: 600;
letter-spacing: .35px;
text-transform: uppercase;
pointer-events: none;
}
.group-hd.swe { color: var(--blue); }
.group-hd.gh { color: var(--amber); }
.group-hd.exp { color: #c4780a; }
.node-hd {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
margin-bottom: 1px;
}
.type-dot {
width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.type-dot.src { background: var(--blue); }
.type-dot.proc { background: var(--amber); }
.type-dot.out { background: var(--green); }
.type-dot.gold { background: #e6b800; }
.type-dot.sil { background: #9e9e9e; }
.node-count {
font-family: var(--font-d);
font-size: 17px;
font-weight: 600;
letter-spacing: -.3px;
color: var(--ink);
line-height: 1.1;
}
.node-count.dim { color: var(--ink-48); font-family: var(--font); font-size: 12px; font-weight: 400; }
.node-count.warn { color: var(--amber); }
.node-count.ok { color: var(--green); }
.node-title {
font-size: 12px;
font-weight: 600;
letter-spacing: -.12px;
color: var(--ink);
line-height: 1.25;
}
.node-file {
font-size: 10px;
font-family: var(--font-mo);
color: var(--ink-48);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.node-prog {
height: 3px;
border-radius: 2px;
background: var(--divider);
overflow: hidden;
margin-top: 2px;
}
.node-prog-fill {
height: 100%;
border-radius: 2px;
background: var(--blue);
width: 0%;
transition: width .6s ease;
}
.node-prog-fill.amber { background: var(--amber); }
.node-prog-fill.gold { background: var(--gold); }
.node-prog-fill.green { background: var(--green); }
/* ── Legend ── */
.legend {
display: flex;
gap: 18px;
align-items: center;
margin: 24px auto 0;
width: 2550px;
min-width: 2550px;
padding: 10px 18px;
background: var(--canvas);
border: 1px solid var(--hairline);
border-radius: var(--r-md);
}
.leg-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-48); }
.leg-dot { width: 7px; height: 7px; border-radius: 50%; }
/* ── Detail panel ── */
.detail-panel {
position: fixed;
top: 44px; right: 0;
width: var(--panel-w);
height: calc(100vh - 44px);
background: var(--canvas);
border-left: 1px solid var(--hairline);
overflow-y: auto;
transform: translateX(100%);
transition: transform .32s cubic-bezier(.32,.8,.32,1);
z-index: 200;
display: flex;
flex-direction: column;
}
.detail-panel.open { transform: translateX(0); }
.panel-close-btn {
position: absolute; top: 14px; right: 14px;
width: 26px; height: 26px; border-radius: 50%;
background: var(--parchment); border: 1px solid var(--hairline);
color: var(--ink-48); font-size: 13px; cursor: pointer;
display: flex; align-items: center; justify-content: center;
transition: background .12s; flex-shrink: 0;
}
.panel-close-btn:hover { background: var(--divider); color: var(--ink); }
.panel-hero {
padding: 26px 22px 18px; border-bottom: 1px solid var(--divider); flex-shrink: 0;
}
.panel-type-row { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; }
.panel-type-lbl { font-size: 10px; font-weight: 600; letter-spacing: .45px; text-transform: uppercase; color: var(--ink-48); }
.panel-title { font-family: var(--font-d); font-size: 22px; font-weight: 600; letter-spacing: -.374px; color: var(--ink); line-height: 1.2; margin-bottom: 5px; }
.panel-file { font-family: var(--font-mo); font-size: 11px; color: var(--ink-48); word-break: break-all; margin-bottom: 10px; }
.panel-desc { font-size: 13px; color: var(--ink-48); line-height: 1.52; letter-spacing: -.1px; }
.panel-stats { padding: 16px 22px; border-bottom: 1px solid var(--divider); display: flex; flex-direction: column; gap: 10px; flex-shrink: 0; }
.pstat { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.pstat-k { font-size: 13px; color: var(--ink-48); letter-spacing: -.1px; }
.pstat-v { font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: -.15px; font-family: var(--font-mo); text-align: right; }
.pstat-v.blue { color: var(--blue); }
.pstat-v.green { color: var(--green); }
.pstat-v.amber { color: var(--amber); }
.pstat-v.dim { color: var(--ink-48); font-weight: 400; }
.pstat.sep { border-top: 1px solid var(--divider); padding-top: 6px; margin-top: 2px; }
.pstat.sep .pstat-k { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
.pstat.sep .pstat-v { display: none; }
.panel-bar-wrap { padding: 14px 22px 4px; border-bottom: 1px solid var(--divider); flex-shrink: 0; }
.panel-bar-labels { display: flex; justify-content: space-between; font-size: 11px; color: var(--ink-48); margin-bottom: 6px; }
.panel-bar-track { height: 6px; border-radius: 3px; background: var(--divider); overflow: hidden; }
.panel-bar-fill { height: 100%; border-radius: 3px; background: var(--blue); transition: width .6s ease; }
.panel-bar-fill.amber { background: var(--amber); }
.panel-sec-hd { padding: 14px 22px 6px; font-size: 10px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--ink-48); flex-shrink: 0; }
.entry-list { padding: 0 10px; flex-shrink: 0; }
.entry-row { display: flex; align-items: baseline; gap: 7px; padding: 7px 10px; border-radius: var(--r-sm); cursor: pointer; transition: background .1s; }
.entry-row:hover { background: var(--parchment); }
.entry-repo { font-size: 11px; font-weight: 600; color: var(--blue); flex-shrink: 0; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-title { font-size: 12px; color: var(--ink-48); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.entry-score { font-size: 11px; font-family: var(--font-mo); color: var(--ink-48); flex-shrink: 0; }
.panel-browse-btn {
margin: 12px 22px 20px; background: var(--blue); color: #fff; border: none;
border-radius: var(--r-pill); padding: 9px 20px;
font-family: var(--font); font-size: 14px; cursor: pointer;
transition: opacity .15s; display: block; width: calc(100% - 44px); text-align: center;
}
.panel-browse-btn:hover { opacity: .85; }
.panel-loading { padding: 20px 22px; font-size: 13px; color: var(--ink-48); text-align: center; }
.panel-empty {
flex: 1; display: flex; align-items: center; justify-content: center;
font-size: 13px; color: var(--ink-48); padding: 40px; text-align: center; line-height: 1.6;
}
</style>
<script>
/* BAKED BY bake_space.py β€” do not edit this block manually */
(function() {
var _BAKED = {"timestamp": "2026-07-11T01:21:36.534623+00:00", "plan": {"swe_bench_total": 2294, "mean_score": 0.2198, "tier_split": 0.31}, "tier1": {"queued": 533, "collected": 533, "extracted": 533, "built": 449, "gold": 52, "score_min": 0.31, "score_max": 0.73, "score_mean": 0.3973}, "tier2": {"queued": 511, "collected": 511, "extracted": 511, "built": 71, "gold": 0, "score_min": 0.22, "score_max": 0.305, "score_mean": 0.2576}, "github": {"queued": 3107, "tier1_queued": 1568, "tier2_queued": 1539, "tier1_collected": 1568, "tier1_extracted": 1440, "tier1_built": 947, "tier2_collected": 1539, "tier2_extracted": 1290, "tier2_built": 749, "collected": 11677, "extracted": 9387, "built": 459, "denom": 3107, "score_min": 0.22, "score_max": 0.72, "score_mean": 0.3368, "pool_median": 0.22}, "raw_cache": {"total": 12721, "by_repo": {"django/django": 846, "scikit-learn/scikit-learn": 713, "pandas-dev/pandas": 501, "sympy/sympy": 453, "pola-rs/polars": 434, "apache/airflow": 403, "microsoft/onnxruntime": 400, "huggingface/transformers": 400, "pytorch/pytorch": 400, "vllm-project/vllm": 400, "sqlalchemy/sqlalchemy": 397, "llvm/llvm-project": 341, "astropy/astropy": 325, "denoland/deno": 303, "microsoft/TypeScript": 300, "golang/go": 300, "rust-lang/rust": 300, "moby/moby": 300, "vercel/next.js": 300, "nodejs/node": 300, "kubernetes/kubernetes": 300, "hashicorp/terraform": 300, "numba/numba": 278, "elastic/elasticsearch": 254, "spring-projects/spring-framework": 250, "JuliaLang/julia": 250, "rails/rails": 250, "vitejs/vite": 250, "apache/tvm": 201, "pydata/xarray": 193, "sphinx-doc/sphinx": 186, "matplotlib/matplotlib": 184, "microsoft/DeepSpeed": 183, "facebook/react": 173, "tokio-rs/tokio": 131, "triton-lang/triton": 122, "pytest-dev/pytest": 117, "rubygems/rubygems": 111, "aio-libs/aiohttp": 110, "clap-rs/clap": 105, "astral-sh/ruff": 96, "cupy/cupy": 96, "scrapy/scrapy": 89, "google/jax": 73, "tiangolo/sqlmodel": 60, "psf/requests": 59, "pylint-dev/pylint": 57, "gem5/gem5": 36, "openxla/xla": 32, "mwaskom/seaborn": 31, "fastapi/fastapi": 15, "pallets/flask": 13}}, "llm_cache": {"total": 10431, "by_repo": {"scikit-learn/scikit-learn": 686, "django/django": 531, "pandas-dev/pandas": 483, "sympy/sympy": 406, "huggingface/transformers": 395, "pola-rs/polars": 394, "apache/airflow": 373, "pytorch/pytorch": 348, "vllm-project/vllm": 347, "astropy/astropy": 309, "microsoft/TypeScript": 300, "denoland/deno": 299, "hashicorp/terraform": 287, "moby/moby": 253, "spring-projects/spring-framework": 250, "elastic/elasticsearch": 242, "numba/numba": 238, "sqlalchemy/sqlalchemy": 233, "JuliaLang/julia": 233, "vitejs/vite": 231, "llvm/llvm-project": 223, "rails/rails": 218, "rust-lang/rust": 217, "apache/tvm": 201, "nodejs/node": 199, "microsoft/onnxruntime": 188, "pydata/xarray": 181, "golang/go": 179, "facebook/react": 171, "matplotlib/matplotlib": 161, "microsoft/DeepSpeed": 135, "tokio-rs/tokio": 130, "triton-lang/triton": 122, "vercel/next.js": 119, "rubygems/rubygems": 106, "aio-libs/aiohttp": 106, "clap-rs/clap": 105, "sphinx-doc/sphinx": 103, "pytest-dev/pytest": 100, "cupy/cupy": 96, "astral-sh/ruff": 90, "scrapy/scrapy": 89, "tiangolo/sqlmodel": 60, "google/jax": 56, "psf/requests": 55, "pylint-dev/pylint": 51, "kubernetes/kubernetes": 46, "openxla/xla": 25, "mwaskom/seaborn": 19, "gem5/gem5": 18, "fastapi/fastapi": 15, "pallets/flask": 9}}, "trajectories": {"total": 979, "stage1_total": 575, "stage2_total": 459, "swe_total": 520, "github_total": 459, "chain_complete": 361, "avg_turns": 10.8, "avg_corrections": 0.77, "avg_quality": 0.493, "by_repo": {"pandas-dev/pandas": 167, "astropy/astropy": 144, "django/django": 144, "sympy/sympy": 119, "scikit-learn/scikit-learn": 114, "matplotlib/matplotlib": 68, "pydata/xarray": 65, "psf/requests": 28, "pytest-dev/pytest": 24, "sphinx-doc/sphinx": 22, "pylint-dev/pylint": 18, "pallets/flask": 3, "mwaskom/seaborn": 2}}, "gold": {"total": 528, "target": 1000, "swe_bench": 0, "swe_tier1": 52, "swe_tier2": 71, "gh_tier1": 332, "gh_tier2": 76, "gold_final": 528, "gold_extended": 2430, "gold_v2": 2958, "gold_v2_per_group": {"ex_tier_a_nopython": 456, "ex_tier_a_nopython_ts": 6, "ex_tier_a_nopython_typescript": 1, "ex_tier_a_python": 263, "ex_tier_b_python": 172, "ex_tier_b_mix": 29, "ex_tier_b_jvm_tier_c": 677, "ex_tier_b_rust_go": 466, "ex_tier_gpu_compilers": 95, "ex_tier_gpu_inference": 125, "ex_tier_gpu_libs": 140}, "avg_quality": 0.644, "avg_turns": 14.7, "by_repo": {"scikit-learn/scikit-learn": 231, "pandas-dev/pandas": 73, "sympy/sympy": 68, "pydata/xarray": 30, "django/django": 29, "pola-rs/polars": 29, "astropy/astropy": 13, "psf/requests": 12, "sqlalchemy/sqlalchemy": 12, "matplotlib/matplotlib": 10, "astral-sh/ruff": 10, "pytest-dev/pytest": 6, "pylint-dev/pylint": 3, "sphinx-doc/sphinx": 2}}, "silver": {"swe_tier1": 156, "swe_tier2": 0, "gh_tier1": 615, "gh_tier2": 673, "total": 1271}, "expansion": {"total": 2601, "tier_a_nopython": 463, "tier_a_python": 263, "tier_b_mix": {"queued": 683, "gold": 171, "silver": 216, "built": 387}, "tier_b_jvm": {"queued": 2179, "gold": 677, "silver": 812, "built": 1489}, "tier_b_python": 172, "tier_b_rust_go": 495, "target": 3000, "avg_turns": 21.2, "avg_corrections": 1.45, "by_repo": {"apache/airflow": 246, "moby/moby": 151, "microsoft/TypeScript": 139, "huggingface/transformers": 135, "pytorch/pytorch": 128, "hashicorp/terraform": 127, "nodejs/node": 114, "rust-lang/rust": 111, "rails/rails": 110, "JuliaLang/julia": 108, "golang/go": 105, "denoland/deno": 102, "vitejs/vite": 101, "tokio-rs/tokio": 88, "spring-projects/spring-framework": 84, "vercel/next.js": 77, "llvm/llvm-project": 73, "scrapy/scrapy": 60, "clap-rs/clap": 56, "elastic/elasticsearch": 46, "rubygems/rubygems": 25, "kubernetes/kubernetes": 24, "facebook/react": 16, "tiangolo/sqlmodel": 8}, "tier_a_py": {"queued": 800, "gold": 263, "silver": 340, "built": 603}, "tier_a_nopy": {"queued": 1494, "gold": 463, "silver": 304, "built": 767}, "tier_b_py": {"queued": 552, "gold": 172, "silver": 212, "built": 384}, "tier_b_rustgo": {"queued": 1139, "gold": 495, "silver": 455, "built": 950}, "tier_gpu_libs": {"queued": 625, "gold": 140, "silver": 240, "built": 380}, "tier_gpu_inf": {"queued": 800, "gold": 125, "silver": 172, "built": 297}, "tier_gpu_comp": {"queued": 396, "gold": 95, "silver": 152, "built": 247}}, "splits": {"dev": 176, "test": 176, "few_shot": 176}, "batch_progress": [{"batch": 0, "count": 1, "exists": true}, {"batch": 1, "count": 0, "exists": true}, {"batch": 2, "count": 4, "exists": true}, {"batch": 3, "count": 9, "exists": true}, {"batch": 4, "count": 3, "exists": true}, {"batch": 5, "count": 0, "exists": true}, {"batch": 6, "count": 15, "exists": true}, {"batch": 7, "count": 20, "exists": true}, {"batch": 8, "count": 0, "exists": true}, {"batch": 9, "count": 17, "exists": true}], "quality_histogram": [{"bin": "0.0–0.1", "count": 63}, {"bin": "0.1–0.2", "count": 59}, {"bin": "0.2–0.3", "count": 60}, {"bin": "0.3–0.4", "count": 86}, {"bin": "0.4–0.5", "count": 149}, {"bin": "0.5–0.6", "count": 153}, {"bin": "0.6–0.7", "count": 173}, {"bin": "0.7–0.8", "count": 143}, {"bin": "0.8–0.9", "count": 29}, {"bin": "0.9–1.0", "count": 3}], "filter_stats": {"counts": {}, "batches_done": 10}, "log_files": ["stage1_batch_0.log", "stage1_batch_1.log", "stage1_batch_2.log", "stage1_batch_3.log", "stage1_batch_4.log", "stage1_batch_5.log", "stage1_batch_6.log", "stage1_batch_7.log", "stage1_batch_8.log", "stage1_batch_9.log"]};
var _origFetch = window.fetch;
window.fetch = function(url, opts) {
if (typeof url === 'string' && url.includes('/api/stats')) {
return Promise.resolve({
ok: true,
json: function() { return Promise.resolve(_BAKED); }
});
};
if (_origFetch) return _origFetch.apply(this, arguments);
return Promise.reject(new Error('fetch not available'));
};
})();
</script>
</head>
<body>
<nav class="global-nav">
<span class="nav-brand">Debug<em>Belief</em></span>
<span class="nav-sep"></span>
<span class="nav-sub">Pipeline</span>
<div class="nav-right">
<span class="nav-badge" id="liveBadge">● loading</span>
</div>
</nav>
<div class="page-layout" id="pageLayout">
<div class="canvas-scroll" id="canvasScroll">
<div class="pipeline-canvas" id="pipelineCanvas">
<!-- SVG arrow layer -->
<svg class="arrows-svg" id="arrowsSvg">
<defs>
<marker id="mArrow" markerWidth="7" markerHeight="5" refX="6" refY="2.5" orient="auto">
<polygon points="0 0, 7 2.5, 0 5" style="fill:#d0d0d5"/>
</marker>
<marker id="mArrowHi" markerWidth="7" markerHeight="5" refX="6" refY="2.5" orient="auto">
<polygon points="0 0, 7 2.5, 0 5" style="fill:rgba(0,102,204,.45)"/>
</marker>
<marker id="mArrowGold" markerWidth="7" markerHeight="5" refX="6" refY="2.5" orient="auto">
<polygon points="0 0, 7 2.5, 0 5" style="fill:rgba(184,134,11,.5)"/>
</marker>
<marker id="mArrowSil" markerWidth="7" markerHeight="5" refX="6" refY="2.5" orient="auto">
<polygon points="0 0, 7 2.5, 0 5" style="fill:rgba(158,158,158,.5)"/>
</marker>
</defs>
</svg>
<!-- ── Group background bands ── -->
<div class="group-band swe" style="left:26px;top:28px;width:453px;height:714px"></div>
<div class="group-band gh" style="left:563px;top:28px;width:461px;height:714px"></div>
<div class="group-band exp" style="left:1074px;top:28px;width:2220px;height:714px"></div>
<!-- ── Group headers ── -->
<div class="group-hd swe" style="left:170px;top:14px">SWE-bench</div>
<div class="group-hd gh" style="left:720px;top:14px">GitHub Search</div>
<div class="group-hd exp" style="left:1438px;top:14px">GitHub Expansion</div>
<div class="group-hd exp" style="left:2900px;top:14px">GPU / HLM</div>
<!-- ════════════════════════════════════════════════════════
LANE 1 β€” SWE Tier 1 (cx=130, node-left=40)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-swe_t1_queue" data-nid="swe_t1_queue" style="left:40px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-swe_t1_queue">β€”</span></div>
<div class="node-title">SWE Tier 1 Queue</div>
<div class="node-file">score β‰₯ 0.310</div>
</div>
<div class="node" id="n-swe_t1_collect" data-nid="swe_t1_collect" style="left:40px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t1_collect">β€”</span></div>
<div class="node-title">GitHub Collector</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t1_collect"></div></div>
</div>
<div class="node" id="n-swe_t1_extract" data-nid="swe_t1_extract" style="left:40px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t1_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t1_extract"></div></div>
</div>
<div class="node" id="n-swe_t1_build" data-nid="swe_t1_build" style="left:40px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t1_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t1_build"></div></div>
</div>
<div class="node" id="n-swe_t1_filter" data-nid="swe_t1_filter" style="left:40px;top:550px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t1_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">llmβ‰₯0.35 Β· corrections</div>
</div>
<div class="node mini gold-n" id="n-swe_t1_gold" data-nid="swe_t1_gold" style="left:44px;top:672px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-swe_t1_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-swe_t1_silver" data-nid="swe_t1_silver" style="left:136px;top:672px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-swe_t1_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 2 β€” SWE Tier 2 (cx=375, node-left=285)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-swe_t2_queue" data-nid="swe_t2_queue" style="left:285px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-swe_t2_queue">β€”</span></div>
<div class="node-title">SWE Tier 2 Queue</div>
<div class="node-file">score 0.220–0.305</div>
</div>
<div class="node" id="n-swe_t2_collect" data-nid="swe_t2_collect" style="left:285px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t2_collect">β€”</span></div>
<div class="node-title">GitHub Collector</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t2_collect"></div></div>
</div>
<div class="node" id="n-swe_t2_extract" data-nid="swe_t2_extract" style="left:285px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t2_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t2_extract"></div></div>
</div>
<div class="node" id="n-swe_t2_build" data-nid="swe_t2_build" style="left:285px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t2_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-swe_t2_build"></div></div>
</div>
<div class="node" id="n-swe_t2_filter" data-nid="swe_t2_filter" style="left:285px;top:550px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-swe_t2_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">llmβ‰₯0.35 Β· corrections</div>
</div>
<div class="node mini gold-n" id="n-swe_t2_gold" data-nid="swe_t2_gold" style="left:289px;top:672px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-swe_t2_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-swe_t2_silver" data-nid="swe_t2_silver" style="left:381px;top:672px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-swe_t2_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 3 β€” GitHub Tier 1 (cx=670, node-left=580)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-gh_t1_queue" data-nid="gh_t1_queue" style="left:580px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-gh_t1_queue">β€”</span></div>
<div class="node-title">GitHub Tier 1 Queue</div>
<div class="node-file">score β‰₯ pool median</div>
</div>
<div class="node" id="n-gh_t1_collect" data-nid="gh_t1_collect" style="left:580px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t1_collect">β€”</span></div>
<div class="node-title">GitHub Collector</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t1_collect"></div></div>
</div>
<div class="node" id="n-gh_t1_extract" data-nid="gh_t1_extract" style="left:580px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t1_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t1_extract"></div></div>
</div>
<div class="node" id="n-gh_t1_build" data-nid="gh_t1_build" style="left:580px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t1_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t1_build"></div></div>
</div>
<div class="node" id="n-gh_t1_filter" data-nid="gh_t1_filter" style="left:580px;top:550px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t1_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-gh_t1_gold" data-nid="gh_t1_gold" style="left:584px;top:672px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-gh_t1_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-gh_t1_silver" data-nid="gh_t1_silver" style="left:676px;top:672px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-gh_t1_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 4 β€” GitHub Tier 2 (cx=915, node-left=825)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-gh_t2_queue" data-nid="gh_t2_queue" style="left:825px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-gh_t2_queue">β€”</span></div>
<div class="node-title">GitHub Tier 2 Queue</div>
<div class="node-file">score &lt; pool median</div>
</div>
<div class="node" id="n-gh_t2_collect" data-nid="gh_t2_collect" style="left:825px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t2_collect">β€”</span></div>
<div class="node-title">GitHub Collector</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t2_collect"></div></div>
</div>
<div class="node" id="n-gh_t2_extract" data-nid="gh_t2_extract" style="left:825px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t2_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t2_extract"></div></div>
</div>
<div class="node" id="n-gh_t2_build" data-nid="gh_t2_build" style="left:825px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t2_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-gh_t2_build"></div></div>
</div>
<div class="node" id="n-gh_t2_filter" data-nid="gh_t2_filter" style="left:825px;top:550px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-gh_t2_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-gh_t2_gold" data-nid="gh_t2_gold" style="left:829px;top:672px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-gh_t2_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-gh_t2_silver" data-nid="gh_t2_silver" style="left:921px;top:672px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-gh_t2_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 5 β€” Exp Tier A Python (node-left=1088)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_a_py_queue" data-nid="ex_a_py_queue" style="left:1088px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-ex_a_py_queue">β€”</span></div>
<div class="node-title">Exp A – Python</div>
<div class="node-file">score β‰₯ mean Β· python repos</div>
</div>
<div class="node" id="n-ex_a_py_extract" data-nid="ex_a_py_extract" style="left:1088px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_py_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_a_py_extract"></div></div>
</div>
<div class="node" id="n-ex_a_py_build" data-nid="ex_a_py_build" style="left:1088px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_py_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_a_py_build"></div></div>
</div>
<div class="node" id="n-ex_a_py_filter" data-nid="ex_a_py_filter" style="left:1088px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_py_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">llmβ‰₯0.35 Β· corrections</div>
</div>
<div class="node mini gold-n" id="n-ex_a_py_gold" data-nid="ex_a_py_gold" style="left:1092px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_a_py_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_a_py_silver" data-nid="ex_a_py_silver" style="left:1184px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_a_py_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 6 β€” Exp Tier A No-Python (node-left=1333)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_a_nopy_queue" data-nid="ex_a_nopy_queue" style="left:1333px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count" id="c-ex_a_nopy_queue">β€”</span></div>
<div class="node-title">Exp A – No-Python</div>
<div class="node-file">TS Β· Go Β· Rust Β· k8s Β· Next.js</div>
</div>
<div class="node" id="n-ex_a_nopy_extract" data-nid="ex_a_nopy_extract" style="left:1333px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_nopy_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_a_nopy_extract"></div></div>
</div>
<div class="node" id="n-ex_a_nopy_build" data-nid="ex_a_nopy_build" style="left:1333px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_nopy_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_a_nopy_build"></div></div>
</div>
<div class="node" id="n-ex_a_nopy_filter" data-nid="ex_a_nopy_filter" style="left:1333px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_a_nopy_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">7 language sub-batches</div>
</div>
<div class="node mini gold-n" id="n-ex_a_nopy_gold" data-nid="ex_a_nopy_gold" style="left:1337px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_a_nopy_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_a_nopy_silver" data-nid="ex_a_nopy_silver" style="left:1429px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_a_nopy_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 7 β€” Exp Tier B JVM + Tier C (node-left=1578)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_b_jvm_queue" data-nid="ex_b_jvm_queue" style="left:1578px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_b_jvm_queue">β€”</span></div>
<div class="node-title">Exp B – JVM + Tier C</div>
<div class="node-file">spring Β· kafka Β· rails Β· node</div>
</div>
<div class="node" id="n-ex_b_jvm_extract" data-nid="ex_b_jvm_extract" style="left:1578px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_jvm_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_jvm_extract"></div></div>
</div>
<div class="node" id="n-ex_b_jvm_build" data-nid="ex_b_jvm_build" style="left:1578px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_jvm_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_jvm_build"></div></div>
</div>
<div class="node" id="n-ex_b_jvm_filter" data-nid="ex_b_jvm_filter" style="left:1578px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_jvm_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_b_jvm_gold" data-nid="ex_b_jvm_gold" style="left:1582px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_b_jvm_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_b_jvm_silver" data-nid="ex_b_jvm_silver" style="left:1674px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_b_jvm_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 8 β€” Exp Tier B Mix (node-left=1823)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_b_mix_queue" data-nid="ex_b_mix_queue" style="left:1823px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_b_mix_queue">β€”</span></div>
<div class="node-title">Exp B – Mix</div>
<div class="node-file">diverse repo search</div>
</div>
<div class="node" id="n-ex_b_mix_extract" data-nid="ex_b_mix_extract" style="left:1823px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_mix_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_mix_extract"></div></div>
</div>
<div class="node" id="n-ex_b_mix_build" data-nid="ex_b_mix_build" style="left:1823px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_mix_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_mix_build"></div></div>
</div>
<div class="node" id="n-ex_b_mix_filter" data-nid="ex_b_mix_filter" style="left:1823px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_mix_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_b_mix_gold" data-nid="ex_b_mix_gold" style="left:1827px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_b_mix_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_b_mix_silver" data-nid="ex_b_mix_silver" style="left:1919px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_b_mix_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 9 β€” Exp Tier B Python (node-left=2068)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_b_py_queue" data-nid="ex_b_py_queue" style="left:2068px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_b_py_queue">β€”</span></div>
<div class="node-title">Exp B – Python</div>
<div class="node-file">python repos Β· running</div>
</div>
<div class="node" id="n-ex_b_py_extract" data-nid="ex_b_py_extract" style="left:2068px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_py_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_py_extract"></div></div>
</div>
<div class="node" id="n-ex_b_py_build" data-nid="ex_b_py_build" style="left:2068px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_py_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_py_build"></div></div>
</div>
<div class="node" id="n-ex_b_py_filter" data-nid="ex_b_py_filter" style="left:2068px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_py_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_b_py_gold" data-nid="ex_b_py_gold" style="left:2072px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_b_py_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_b_py_silver" data-nid="ex_b_py_silver" style="left:2164px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_b_py_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 10 β€” Exp Tier B Rust+Go (node-left=2313)
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_b_rustgo_queue" data-nid="ex_b_rustgo_queue" style="left:2313px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_b_rustgo_queue">β€”</span></div>
<div class="node-title">Exp B – Rust+Go</div>
<div class="node-file">rust Β· golang repos Β· running</div>
</div>
<div class="node" id="n-ex_b_rustgo_extract" data-nid="ex_b_rustgo_extract" style="left:2313px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_rustgo_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_rustgo_extract"></div></div>
</div>
<div class="node" id="n-ex_b_rustgo_build" data-nid="ex_b_rustgo_build" style="left:2313px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_rustgo_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_b_rustgo_build"></div></div>
</div>
<div class="node" id="n-ex_b_rustgo_filter" data-nid="ex_b_rustgo_filter" style="left:2313px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_b_rustgo_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_b_rustgo_gold" data-nid="ex_b_rustgo_gold" style="left:2317px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_b_rustgo_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_b_rustgo_silver" data-nid="ex_b_rustgo_silver" style="left:2409px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_b_rustgo_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 11 β€” GPU Libs (node-left=2558)
cupy Β· numba Β· xla Β· DeepSpeed Β· gem5
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_gpu_libs_queue" data-nid="ex_gpu_libs_queue" style="left:2558px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_gpu_libs_queue">β€”</span></div>
<div class="node-title">GPU Libs Search</div>
<div class="node-file">cupy Β· numba Β· xla Β· DeepSpeed</div>
</div>
<div class="node" id="n-ex_gpu_libs_extract" data-nid="ex_gpu_libs_extract" style="left:2558px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_libs_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_libs_extract"></div></div>
</div>
<div class="node" id="n-ex_gpu_libs_build" data-nid="ex_gpu_libs_build" style="left:2558px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_libs_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_libs_build"></div></div>
</div>
<div class="node" id="n-ex_gpu_libs_filter" data-nid="ex_gpu_libs_filter" style="left:2558px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_libs_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_gpu_libs_gold" data-nid="ex_gpu_libs_gold" style="left:2562px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_gpu_libs_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_gpu_libs_silver" data-nid="ex_gpu_libs_silver" style="left:2654px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_gpu_libs_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 12 β€” GPU Inference (node-left=2803)
vllm Β· onnxruntime
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_gpu_inf_queue" data-nid="ex_gpu_inf_queue" style="left:2803px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_gpu_inf_queue">β€”</span></div>
<div class="node-title">GPU Inference Search</div>
<div class="node-file">vllm Β· onnxruntime</div>
</div>
<div class="node" id="n-ex_gpu_inf_extract" data-nid="ex_gpu_inf_extract" style="left:2803px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_inf_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_inf_extract"></div></div>
</div>
<div class="node" id="n-ex_gpu_inf_build" data-nid="ex_gpu_inf_build" style="left:2803px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_inf_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_inf_build"></div></div>
</div>
<div class="node" id="n-ex_gpu_inf_filter" data-nid="ex_gpu_inf_filter" style="left:2803px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_inf_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_gpu_inf_gold" data-nid="ex_gpu_inf_gold" style="left:2807px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_gpu_inf_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_gpu_inf_silver" data-nid="ex_gpu_inf_silver" style="left:2899px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_gpu_inf_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
LANE 13 β€” GPU Compilers (node-left=3048)
triton Β· tvm Β· jax
════════════════════════════════════════════════════════ -->
<div class="node" id="n-ex_gpu_comp_queue" data-nid="ex_gpu_comp_queue" style="left:3048px;top:80px">
<div class="node-hd"><span class="type-dot src"></span><span class="node-count dim" id="c-ex_gpu_comp_queue">β€”</span></div>
<div class="node-title">GPU Compilers Search</div>
<div class="node-file">triton Β· tvm Β· jax</div>
</div>
<div class="node" id="n-ex_gpu_comp_extract" data-nid="ex_gpu_comp_extract" style="left:3048px;top:196px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_comp_extract">β€”</span></div>
<div class="node-title">LLM Extractor</div>
<div class="node-file">collect_expansion.py</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_comp_extract"></div></div>
</div>
<div class="node" id="n-ex_gpu_comp_build" data-nid="ex_gpu_comp_build" style="left:3048px;top:314px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_comp_build">β€”</span></div>
<div class="node-title">Traj Builder</div>
<div class="node-prog"><div class="node-prog-fill" id="p-ex_gpu_comp_build"></div></div>
</div>
<div class="node" id="n-ex_gpu_comp_filter" data-nid="ex_gpu_comp_filter" style="left:3048px;top:432px">
<div class="node-hd"><span class="type-dot proc"></span><span class="node-count dim" id="c-ex_gpu_comp_filter">5 gates</span></div>
<div class="node-title">Quality Filter</div>
<div class="node-file">pre-filtered during batch</div>
</div>
<div class="node mini gold-n" id="n-ex_gpu_comp_gold" data-nid="ex_gpu_comp_gold" style="left:3052px;top:550px">
<div class="node-hd"><span class="type-dot gold"></span></div>
<div class="node-count dim" id="c-ex_gpu_comp_gold">β€”</div>
<div class="node-title">Gold</div>
</div>
<div class="node mini silver-n" id="n-ex_gpu_comp_silver" data-nid="ex_gpu_comp_silver" style="left:3144px;top:550px">
<div class="node-hd"><span class="type-dot sil"></span></div>
<div class="node-count dim" id="c-ex_gpu_comp_silver">β€”</div>
<div class="node-title">Silver</div>
</div>
<!-- ════════════════════════════════════════════════════════
MERGE β€” Gold Final + Silver Final
════════════════════════════════════════════════════════ -->
<div class="node final gold-n" id="n-gold_final" data-nid="gold_final" style="left:175px;top:786px">
<div class="node-hd">
<span class="type-dot gold"></span>
<span class="node-count dim" id="c-gold_final">β€”</span>
</div>
<div class="node-title">Gold Final</div>
<div class="node-file">gold/gold_final.jsonl</div>
<div class="node-prog"><div class="node-prog-fill gold" id="p-gold_final"></div></div>
</div>
<div class="node final silver-n" id="n-silver_final" data-nid="silver_final" style="left:615px;top:786px">
<div class="node-hd">
<span class="type-dot sil"></span>
<span class="node-count dim" id="c-silver_final">β€”</span>
</div>
<div class="node-title">Silver Final</div>
<div class="node-file">processed/silver_final.jsonl</div>
</div>
<!-- ════════════════════════════════════════════════════════
MERGE β€” Gold Extended (all expansion gold aggregated)
════════════════════════════════════════════════════════ -->
<div class="node final gold-n" id="n-gold_extended" data-nid="gold_extended" style="left:1940px;top:786px">
<div class="node-hd">
<span class="type-dot gold"></span>
<span class="node-count dim" id="c-gold_extended">β€”</span>
</div>
<div class="node-title">Gold Extended</div>
<div class="node-file">gold/gold_extended.jsonl</div>
<div class="node-prog"><div class="node-prog-fill gold" id="p-gold_extended"></div></div>
</div>
<!-- ════════════════════════════════════════════════════════
MERGE β€” Gold v2 (gold_final + gold_extended merged)
════════════════════════════════════════════════════════ -->
<div class="node final gold-n" id="n-gold_v2" data-nid="gold_v2" style="left:1057px;top:870px">
<div class="node-hd">
<span class="type-dot gold"></span>
<span class="node-count dim" id="c-gold_v2">β€”</span>
</div>
<div class="node-title">Gold v2</div>
<div class="node-file">gold/gold_v2.jsonl</div>
<div class="node-prog"><div class="node-prog-fill gold" id="p-gold_v2"></div></div>
</div>
<!-- ════════════════════════════════════════════════════════
SPLITS
════════════════════════════════════════════════════════ -->
<div class="node" id="n-dev" data-nid="dev" style="left:90px;top:1040px;width:180px">
<div class="node-hd"><span class="type-dot out"></span><span class="node-count" id="c-dev">β€”</span></div>
<div class="node-title">Dev Split</div>
<div class="node-file">splits/dev.jsonl</div>
</div>
<div class="node" id="n-test" data-nid="test" style="left:435px;top:1040px;width:180px">
<div class="node-hd"><span class="type-dot out"></span><span class="node-count" id="c-test">β€”</span></div>
<div class="node-title">Test Split</div>
<div class="node-file">splits/test.jsonl</div>
</div>
<div class="node" id="n-few_shot" data-nid="few_shot" style="left:780px;top:1040px;width:180px">
<div class="node-hd"><span class="type-dot out"></span><span class="node-count" id="c-few_shot">β€”</span></div>
<div class="node-title">Few-shot Pool</div>
<div class="node-file">splits/few_shot_pool.jsonl</div>
</div>
</div><!-- /pipeline-canvas -->
<div class="legend" id="legend">
<div class="leg-item"><div class="leg-dot" style="background:#0066cc"></div>Input Queue</div>
<div class="leg-item"><div class="leg-dot" style="background:#f5a623"></div>Processing</div>
<div class="leg-item"><div class="leg-dot" style="background:#e6b800"></div>Gold</div>
<div class="leg-item"><div class="leg-dot" style="background:#9e9e9e"></div>Silver</div>
<div class="leg-item"><div class="leg-dot" style="background:#34c759"></div>Output Split</div>
<span style="margin-left:auto;font-size:11px;color:var(--ink-48)">Click any node for details</span>
</div>
</div><!-- /canvas-scroll -->
</div><!-- /page-layout -->
<!-- ── Detail Panel ── -->
<div class="detail-panel" id="detailPanel">
<button class="panel-close-btn" id="panelCloseBtn" title="Close">βœ•</button>
<div id="panelBody">
<div class="panel-empty">Select a node to view<br>statistics and entries.</div>
</div>
</div>
<script>
// ─────────────────────────────────────────────────────────────
// Node metadata
// ─────────────────────────────────────────────────────────────
const NODE_META = {
swe_t1_queue: { title:'SWE Tier 1 Queue', type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/swe_tier1.jsonl', browseable:false, desc:'533 SWE-bench issues scoring 0.310–0.730 (above pool median). Highest-quality SWE source; priority extraction target.' },
swe_t1_collect: { title:'GitHub Collector', type:'Processing', typeColor:'#f5a623', file:'debugbench/collection/github_collector.py', browseable:false, desc:'Fetches issue thread + linked PR from GitHub REST API for each Tier 1 SWE-bench entry. Results cached in data/raw/.' },
swe_t1_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/llm_extractor.py', browseable:false, desc:'Annotates conversation turns via LLM (gpt-oss-120b). Produces LLMExtractionResult with labeled turns, hypotheses, corrections, evidence.' },
swe_t1_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory from LLM extraction. Sets source=github_via_swe_bench. Propagates llm_quality_score β†’ tier1_trajectories.jsonl.' },
swe_t1_filter: { title:'Quality Filter (SWE T1)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold gate: corrections non-empty Β· llm_quality_score β‰₯ 0.35 Β· turns β‰₯ 2 Β· ambiguity < 0.90 Β· final_root_cause non-empty. Silver: relaxed (turns β‰₯ 2, ambiguity < 0.90, root_cause or fix_summary, llm > 0).' },
swe_t1_gold: { title:'SWE T1 Gold', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_swe_tier1.jsonl', browseable:true, desc:'Gold entries from SWE-bench Tier 1 (github_via_swe_bench). All 5 quality gates passed. Sorted by gold_score descending.' },
swe_t1_silver: { title:'SWE T1 Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/silver_swe_tier1.jsonl', browseable:false, desc:'Silver entries from SWE-bench Tier 1. Passes basic validity (turns β‰₯ 2, ambiguity < 0.90) but fails gold gates (no corrections or llm < 0.35).' },
swe_t2_queue: { title:'SWE Tier 2 Queue', type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/swe_tier2.jsonl', browseable:false, desc:'511 SWE-bench issues scoring 0.220–0.305 (below pool median but above dataset mean). Secondary extraction target.' },
swe_t2_collect: { title:'GitHub Collector', type:'Processing', typeColor:'#f5a623', file:'debugbench/collection/github_collector.py', browseable:false, desc:'Fetches issue thread + linked PR from GitHub REST API for each Tier 2 SWE-bench entry. Results cached in data/raw/.' },
swe_t2_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/llm_extractor.py', browseable:false, desc:'Annotates conversation turns via LLM. Produces LLMExtractionResult with labeled turns, corrections, evidence.' },
swe_t2_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory from LLM extraction. Sets source=github_via_swe_bench. Propagates llm_quality_score β†’ tier2_trajectories.jsonl.' },
swe_t2_filter: { title:'Quality Filter (SWE T2)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'Same 5-gate filter as SWE T1. Gold: corrections non-empty Β· llm β‰₯ 0.35 Β· turns β‰₯ 2 Β· ambiguity < 0.90 Β· final_root_cause. Silver: relaxed.' },
swe_t2_gold: { title:'SWE T2 Gold', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_swe_tier2.jsonl', browseable:true, desc:'Gold entries from SWE-bench Tier 2 (github_via_swe_bench). All quality gates passed. Run build_per_source_gold_silver.py to regenerate.' },
swe_t2_silver: { title:'SWE T2 Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/silver_swe_tier2.jsonl', browseable:false, desc:'Silver entries from SWE-bench Tier 2. Passes basic validity but fails gold gates.' },
gh_t1_queue: { title:'GitHub Tier 1 Queue',type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/github_tier1.jsonl', browseable:false, desc:'Higher-scoring GitHub Search issues (score β‰₯ pool median). Sourced from same repos as SWE-bench but not in SWE-bench dataset. Source tag: github_raw.' },
gh_t1_collect: { title:'GitHub Collector', type:'Processing', typeColor:'#f5a623', file:'debugbench/collection/github_collector.py', browseable:false, desc:'Fetches full issue thread + linked PR from GitHub REST API. Progress tracked against Tier 1 queue size.' },
gh_t1_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/llm_extractor.py', browseable:false, desc:'Annotates conversation turns via LLM. Caches per-issue extraction JSON in data/raw/.' },
gh_t1_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Sets source=github_raw. Gold+silver count approximates total trajectories built.' },
gh_t1_filter: { title:'Quality Filter (GH T1)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'Same 5-gate filter. GitHub Tier 1 entries were pre-filtered to gold standards during batch collection; gold_gh_tier1.jsonl is the quality-selected subset.' },
gh_t1_gold: { title:'GH T1 Gold', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_gh_tier1.jsonl', browseable:true, desc:'Gold entries from GitHub search Tier 1 (github_raw). Pre-filtered during batch collection. Sorted by gold_score.' },
gh_t1_silver: { title:'GH T1 Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/silver_gh_tier1.jsonl', browseable:false, desc:'Silver entries from GitHub search Tier 1. Passes basic validity but fails gold gates (no corrections or llm < 0.35).' },
gh_t2_queue: { title:'GitHub Tier 2 Queue',type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/github_tier2.jsonl', browseable:false, desc:'Lower-scoring GitHub Search issues (score < pool median). Secondary source; already collected in batch as expansion tier.' },
gh_t2_collect: { title:'GitHub Collector', type:'Processing', typeColor:'#f5a623', file:'debugbench/collection/github_collector.py', browseable:false, desc:'Fetches full issue thread + linked PR from GitHub REST API for each Tier 2 GitHub entry.' },
gh_t2_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/llm_extractor.py', browseable:false, desc:'Annotates conversation turns via LLM. Caches per-issue extraction JSON in data/raw/.' },
gh_t2_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Sets source=github_raw. Gold+silver count approximates total trajectories built for Tier 2.' },
gh_t2_filter: { title:'Quality Filter (GH T2)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'Same 5-gate filter. GitHub Tier 2 entries were pre-filtered during batch collection; gold_gh_tier2.jsonl holds the quality-selected subset.' },
gh_t2_gold: { title:'GH T2 Gold', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_gh_tier2.jsonl', browseable:true, desc:'Gold entries from GitHub search Tier 2 (github_raw). Pre-filtered during batch collection. Sorted by gold_score.' },
gh_t2_silver: { title:'GH T2 Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/silver_gh_tier2.jsonl', browseable:false, desc:'Silver entries from GitHub search Tier 2. Passes basic validity but fails gold gates.' },
// ── Expansion Tier A Python ──
ex_a_py_queue: { title:'Exp A – Python Queue', type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/expansion_tier_a_python.jsonl', browseable:false, desc:'800 GitHub issues from Python repos (pytorch, sqlalchemy, FastAPI, etc.) scoring above heuristic mean. Source tag: github_raw.' },
ex_a_py_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction in a single batch pass. Built count = fully extracted trajectories. Caches per-issue JSON in data/raw/.' },
ex_a_py_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built count = gold + silver.' },
ex_a_py_filter: { title:'Quality Filter (Exp A Py)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold gate: corrections Β· llmβ‰₯0.35 Β· turnsβ‰₯2 Β· ambiguity<0.90 Β· final_root_cause. Silver: relaxed.' },
ex_a_py_gold: { title:'Exp A Py Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_a_python.jsonl', browseable:false, desc:'Gold entries from Expansion Tier A Python (github_raw). Passes all 5 quality gates.' },
ex_a_py_silver: { title:'Exp A Py Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_a_python_silver.jsonl', browseable:false, desc:'Silver entries from Expansion Tier A Python. Passes basic validity but fails gold gates.' },
// ── Expansion Tier A No-Python ──
ex_a_nopy_queue: { title:'Exp A – No-Python Queue', type:'Input', typeColor:'#0066cc', file:'data/extraction_queue/expansion_tier_a_nopython.jsonl', browseable:false, desc:'1,494 GitHub issues from non-Python repos: TypeScript, Go, Rust, Next.js, Kubernetes, and others scoring above mean.' },
ex_a_nopy_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction across 7 language sub-batches (golang, k8s, nextjs, rust, ts, typescript) in one batch pass.' },
ex_a_nopy_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Aggregates 7 language sub-batch outputs.' },
ex_a_nopy_filter: { title:'Quality Filter (Exp A NoPy)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter across all language sub-batches. TypeScript is the heaviest contributor.' },
ex_a_nopy_gold: { title:'Exp A No-Py Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_a_nopython*.jsonl', browseable:false, desc:'Gold entries aggregated from all 7 Tier A No-Python sub-batches (TS, Go, Rust, k8s, Next.js). Deduplicated by instance_id.' },
ex_a_nopy_silver: { title:'Exp A No-Py Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_a_nopython*_silver.jsonl', browseable:false, desc:'Silver entries across all Tier A No-Python sub-batches. Passes basic validity but fails gold gates.' },
// ── Expansion Tier B JVM + Tier C ──
ex_b_jvm_queue: { title:'Exp B JVM+C Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across JVM repos (spring-framework, kafka, elasticsearch) and Tier C (node.js, rails, julia, llvm). ~1,980 candidates identified.' },
ex_b_jvm_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for JVM and Tier C language issues in one batch pass.' },
ex_b_jvm_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_b_jvm_filter: { title:'Quality Filter (Exp B JVM)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. JVM + Tier C entries were pre-filtered during batch collection.' },
ex_b_jvm_gold: { title:'Exp B JVM+C Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_b_jvm_tier_c.jsonl', browseable:false, desc:'Gold entries from Expansion Tier B JVM + Tier C (github_raw). All quality gates passed.' },
ex_b_jvm_silver: { title:'Exp B JVM+C Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_b_jvm_tier_c_silver.jsonl', browseable:false, desc:'Silver entries from Expansion Tier B JVM + Tier C.' },
// ── Expansion Tier B Mix ──
ex_b_mix_queue: { title:'Exp B Mix Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across diverse mixed repos for broad language and domain coverage.' },
ex_b_mix_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for mixed-language GitHub issues in one batch pass.' },
ex_b_mix_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_b_mix_filter: { title:'Quality Filter (Exp B Mix)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. Expansion Tier B Mix entries were pre-filtered during batch collection.' },
ex_b_mix_gold: { title:'Exp B Mix Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_b_mix.jsonl', browseable:false, desc:'Gold entries from Expansion Tier B Mix (github_raw).' },
ex_b_mix_silver: { title:'Exp B Mix Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_b_mix_silver.jsonl', browseable:false, desc:'Silver entries from Expansion Tier B Mix.' },
// ── Expansion Tier B Python ──
ex_b_py_queue: { title:'Exp B Py Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across Python repos for Tier B expansion. Running β€” output in data/processed/expansion_tier_b_python.jsonl.' },
ex_b_py_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for Python GitHub issues in one batch pass.' },
ex_b_py_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_b_py_filter: { title:'Quality Filter (Exp B Py)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. Tier B Python entries were pre-filtered during batch collection.' },
ex_b_py_gold: { title:'Exp B Py Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_b_python.jsonl', browseable:false, desc:'Gold entries from Expansion Tier B Python (github_raw). All quality gates passed.' },
ex_b_py_silver: { title:'Exp B Py Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_b_python_silver.jsonl', browseable:false, desc:'Silver entries from Expansion Tier B Python.' },
// ── Expansion Tier B Rust+Go ──
ex_b_rustgo_queue: { title:'Exp B Rust+Go Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across Rust and Go repos for Tier B expansion. Running β€” output in data/processed/expansion_tier_b_rust_go.jsonl.' },
ex_b_rustgo_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for Rust and Go GitHub issues in one batch pass.' },
ex_b_rustgo_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_b_rustgo_filter: { title:'Quality Filter (Exp B Rust+Go)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. Tier B Rust+Go entries were pre-filtered during batch collection.' },
ex_b_rustgo_gold: { title:'Exp B Rust+Go Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_b_rust_go.jsonl', browseable:false, desc:'Gold entries from Expansion Tier B Rust+Go (github_raw). All quality gates passed.' },
ex_b_rustgo_silver: { title:'Exp B Rust+Go Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_b_rust_go_silver.jsonl', browseable:false, desc:'Silver entries from Expansion Tier B Rust+Go.' },
// ── GPU Libs (cupy Β· numba Β· xla Β· DeepSpeed Β· gem5) ──
ex_gpu_libs_queue: { title:'GPU Libs Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across GPU library repos: cupy, numba, openxla/xla, DeepSpeed, gem5. Phase-3 GPU/HLM expansion. 140 entries extracted.' },
ex_gpu_libs_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for GPU library repos in one batch pass.' },
ex_gpu_libs_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_gpu_libs_filter: { title:'Quality Filter (GPU Libs)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. GPU Libs entries were pre-filtered during batch collection.' },
ex_gpu_libs_gold: { title:'GPU Libs Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_gpu_libs.jsonl', browseable:false, desc:'140 gold entries from GPU library repos (cupy/numba/xla/DeepSpeed/gem5). All 5 quality gates passed.' },
ex_gpu_libs_silver: { title:'GPU Libs Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_gpu_libs_silver.jsonl', browseable:false, desc:'Silver entries from GPU Libs expansion. Passes basic validity but fails gold gates.' },
// ── GPU Inference (vllm Β· onnxruntime) ──
ex_gpu_inf_queue: { title:'GPU Inference Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across GPU inference repos: vllm-project/vllm, microsoft/onnxruntime. Phase-3 GPU/HLM expansion. 125 entries extracted.' },
ex_gpu_inf_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for GPU inference repos in one batch pass.' },
ex_gpu_inf_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_gpu_inf_filter: { title:'Quality Filter (GPU Inf)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. GPU Inference entries were pre-filtered during batch collection.' },
ex_gpu_inf_gold: { title:'GPU Inference Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_gpu_inference.jsonl', browseable:false, desc:'125 gold entries from GPU inference repos (vllm/onnxruntime). All 5 quality gates passed.' },
ex_gpu_inf_silver: { title:'GPU Inference Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_gpu_inference_silver.jsonl', browseable:false, desc:'Silver entries from GPU Inference expansion. Passes basic validity but fails gold gates.' },
// ── GPU Compilers (triton Β· tvm Β· jax) ──
ex_gpu_comp_queue: { title:'GPU Compilers Search', type:'Input', typeColor:'#0066cc', file:'dynamic', browseable:false, desc:'Dynamic GitHub search across GPU compiler repos: triton-lang/triton, apache/tvm, google/jax. Phase-3 GPU/HLM expansion. 95 entries extracted.' },
ex_gpu_comp_extract: { title:'LLM Extractor', type:'Processing', typeColor:'#f5a623', file:'debugbench/cli/collect_expansion.py', browseable:false, desc:'collect_expansion.py runs GitHub collection + LLM extraction for GPU compiler repos in one batch pass.' },
ex_gpu_comp_build: { title:'Traj Builder', type:'Processing', typeColor:'#f5a623', file:'debugbench/extraction/trajectory_builder.py', browseable:false, desc:'Assembles DebugTrajectory. Source=github_raw. Built = gold + silver.' },
ex_gpu_comp_filter: { title:'Quality Filter (GPU Comp)', type:'Processing', typeColor:'#f5a623', file:'debugbench/quality/filter.py', browseable:false, desc:'5-gate gold filter. GPU Compilers entries were pre-filtered during batch collection.' },
ex_gpu_comp_gold: { title:'GPU Compilers Gold', type:'Gold', typeColor:'#b8860b', file:'data/processed/expansion_tier_gpu_compilers.jsonl', browseable:false, desc:'95 gold entries from GPU compiler repos (triton/tvm/jax). All 5 quality gates passed.' },
ex_gpu_comp_silver: { title:'GPU Compilers Silver', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/expansion_tier_gpu_compilers_silver.jsonl', browseable:false, desc:'Silver entries from GPU Compilers expansion. Passes basic validity but fails gold gates.' },
gold_final: { title:'Gold Final', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_final.jsonl', browseable:true, desc:'Authoritative gold set: all 4 source gold files merged and deduped. Target 1,000 entries, all passing 5 quality gates. Evaluation splits (dev/test/few_shot) are built from this file.' },
silver_final: { title:'Silver Final', type:'Silver', typeColor:'#9e9e9e', file:'data/processed/silver_final.jsonl', browseable:false, desc:'Merged silver set from all 4 sources. Passes basic validity (turns β‰₯ 2, ambiguity < 0.90, root_cause/fix_summary non-empty, llm > 0) but fails gold gates. suitable_for_benchmark=False. Suitable for auxiliary or pretraining use.' },
gold_extended: { title:'Gold Extended', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_extended.jsonl', browseable:true, desc:'Aggregated and deduplicated gold entries from all 9 expansion lanes (Tier A Python, Tier A No-Python, Tier B Python/Mix/JVM/Rust+Go, GPU Libs/Inference/Compilers). Labeled with collection_group, collection_label, collection_tier for provenance tracking. 2,430 unique entries.' },
gold_v2: { title:'Gold v2', type:'Gold', typeColor:'#b8860b', file:'data/gold/gold_v2.jsonl', browseable:true, desc:'Full merged gold set: gold_final (528 SWE-bench legacy, labeled swe_bench_legacy) + gold_extended (2,430 expansion, labeled by source). All entries carry collection_group/collection_label/collection_tier provenance fields. 2,958 total entries. Evaluation splits are sampled from this file.' },
dev: { title:'Dev Split', type:'Output', typeColor:'#34c759', file:'data/splits/dev.jsonl', browseable:true, desc:'Sampled at seed=42 from gold_v2. Used for prompt tuning and ablation studies.' },
test: { title:'Test Split', type:'Output', typeColor:'#34c759', file:'data/splits/test.jsonl', browseable:true, desc:'Sampled at seed=42 from gold_v2. Used for final reported benchmark numbers.' },
few_shot: { title:'Few-shot Pool', type:'Output', typeColor:'#34c759', file:'data/splits/few_shot_pool.jsonl', browseable:true, desc:'Sampled at seed=42 from gold_v2. Used as in-context examples during agent simulation.' },
};
// ─────────────────────────────────────────────────────────────
// Arrow definitions β€” [from_nid, to_nid, style?]
// style: 'gold' | 'silver' | undefined (default gray)
// ─────────────────────────────────────────────────────────────
const ARROWS = [
// SWE T1 lane
['swe_t1_queue','swe_t1_collect'],
['swe_t1_collect','swe_t1_extract'],
['swe_t1_extract','swe_t1_build'],
['swe_t1_build','swe_t1_filter'],
['swe_t1_filter','swe_t1_gold', 'gold'],
['swe_t1_filter','swe_t1_silver', 'silver'],
// SWE T2 lane
['swe_t2_queue','swe_t2_collect'],
['swe_t2_collect','swe_t2_extract'],
['swe_t2_extract','swe_t2_build'],
['swe_t2_build','swe_t2_filter'],
['swe_t2_filter','swe_t2_gold', 'gold'],
['swe_t2_filter','swe_t2_silver', 'silver'],
// GH T1 lane
['gh_t1_queue','gh_t1_collect'],
['gh_t1_collect','gh_t1_extract'],
['gh_t1_extract','gh_t1_build'],
['gh_t1_build','gh_t1_filter'],
['gh_t1_filter','gh_t1_gold', 'gold'],
['gh_t1_filter','gh_t1_silver', 'silver'],
// GH T2 lane
['gh_t2_queue','gh_t2_collect'],
['gh_t2_collect','gh_t2_extract'],
['gh_t2_extract','gh_t2_build'],
['gh_t2_build','gh_t2_filter'],
['gh_t2_filter','gh_t2_gold', 'gold'],
['gh_t2_filter','gh_t2_silver', 'silver'],
// Gold merge (all 4 gold β†’ Gold Final)
['swe_t1_gold','gold_final', 'gold'],
['swe_t2_gold','gold_final', 'gold'],
['gh_t1_gold','gold_final', 'gold'],
['gh_t2_gold','gold_final', 'gold'],
// Silver merge (all 4 silver β†’ Silver Final)
['swe_t1_silver','silver_final', 'silver'],
['swe_t2_silver','silver_final', 'silver'],
['gh_t1_silver','silver_final', 'silver'],
['gh_t2_silver','silver_final', 'silver'],
// Expansion gold β†’ Gold Extended (all 9 expansion gold lanes)
['ex_a_py_gold', 'gold_extended', 'gold'],
['ex_a_nopy_gold', 'gold_extended', 'gold'],
['ex_b_jvm_gold', 'gold_extended', 'gold'],
['ex_b_mix_gold', 'gold_extended', 'gold'],
['ex_b_py_gold', 'gold_extended', 'gold'],
['ex_b_rustgo_gold','gold_extended', 'gold'],
['ex_gpu_libs_gold','gold_extended', 'gold'],
['ex_gpu_inf_gold', 'gold_extended', 'gold'],
['ex_gpu_comp_gold','gold_extended', 'gold'],
// Gold Final + Gold Extended β†’ Gold v2
['gold_final', 'gold_v2', 'gold'],
['gold_extended', 'gold_v2', 'gold'],
// Evaluation splits from Gold v2
['gold_v2','dev'],
['gold_v2','test'],
['gold_v2','few_shot'],
// Expansion Tier A Python lane (collect+extract bundled in collect_expansion.py)
['ex_a_py_queue','ex_a_py_extract', undefined, 'github_collector.py'],
['ex_a_py_extract','ex_a_py_build'],
['ex_a_py_build','ex_a_py_filter'],
['ex_a_py_filter','ex_a_py_gold', 'gold'],
['ex_a_py_filter','ex_a_py_silver', 'silver'],
// Expansion Tier A No-Python lane
['ex_a_nopy_queue','ex_a_nopy_extract', undefined, 'github_collector.py'],
['ex_a_nopy_extract','ex_a_nopy_build'],
['ex_a_nopy_build','ex_a_nopy_filter'],
['ex_a_nopy_filter','ex_a_nopy_gold', 'gold'],
['ex_a_nopy_filter','ex_a_nopy_silver', 'silver'],
// Expansion Tier B JVM+C lane
['ex_b_jvm_queue','ex_b_jvm_extract', undefined, 'github_collector.py'],
['ex_b_jvm_extract','ex_b_jvm_build'],
['ex_b_jvm_build','ex_b_jvm_filter'],
['ex_b_jvm_filter','ex_b_jvm_gold', 'gold'],
['ex_b_jvm_filter','ex_b_jvm_silver', 'silver'],
// Expansion Tier B Mix lane
['ex_b_mix_queue','ex_b_mix_extract', undefined, 'github_collector.py'],
['ex_b_mix_extract','ex_b_mix_build'],
['ex_b_mix_build','ex_b_mix_filter'],
['ex_b_mix_filter','ex_b_mix_gold', 'gold'],
['ex_b_mix_filter','ex_b_mix_silver', 'silver'],
// Expansion Tier B Python lane
['ex_b_py_queue','ex_b_py_extract', undefined, 'github_collector.py'],
['ex_b_py_extract','ex_b_py_build'],
['ex_b_py_build','ex_b_py_filter'],
['ex_b_py_filter','ex_b_py_gold', 'gold'],
['ex_b_py_filter','ex_b_py_silver', 'silver'],
// Expansion Tier B Rust+Go lane
['ex_b_rustgo_queue','ex_b_rustgo_extract', undefined, 'github_collector.py'],
['ex_b_rustgo_extract','ex_b_rustgo_build'],
['ex_b_rustgo_build','ex_b_rustgo_filter'],
['ex_b_rustgo_filter','ex_b_rustgo_gold', 'gold'],
['ex_b_rustgo_filter','ex_b_rustgo_silver', 'silver'],
// GPU Libs lane
['ex_gpu_libs_queue','ex_gpu_libs_extract'],
['ex_gpu_libs_extract','ex_gpu_libs_build'],
['ex_gpu_libs_build','ex_gpu_libs_filter'],
['ex_gpu_libs_filter','ex_gpu_libs_gold', 'gold'],
['ex_gpu_libs_filter','ex_gpu_libs_silver', 'silver'],
// GPU Inference lane
['ex_gpu_inf_queue','ex_gpu_inf_extract'],
['ex_gpu_inf_extract','ex_gpu_inf_build'],
['ex_gpu_inf_build','ex_gpu_inf_filter'],
['ex_gpu_inf_filter','ex_gpu_inf_gold', 'gold'],
['ex_gpu_inf_filter','ex_gpu_inf_silver', 'silver'],
// GPU Compilers lane
['ex_gpu_comp_queue','ex_gpu_comp_extract'],
['ex_gpu_comp_extract','ex_gpu_comp_build'],
['ex_gpu_comp_build','ex_gpu_comp_filter'],
['ex_gpu_comp_filter','ex_gpu_comp_gold', 'gold'],
['ex_gpu_comp_filter','ex_gpu_comp_silver', 'silver'],
];
// ─────────────────────────────────────────────────────────────
// Arrow drawing
// ─────────────────────────────────────────────────────────────
function nodeRect(id) {
const el = document.getElementById('n-' + id);
if (!el) return null;
return { l: el.offsetLeft, t: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight };
}
function edgePt(r, edge) {
if (edge === 'bot') return [r.l + r.w/2, r.t + r.h];
if (edge === 'top') return [r.l + r.w/2, r.t];
if (edge === 'right') return [r.l + r.w, r.t + r.h/2];
if (edge === 'left') return [r.l, r.t + r.h/2];
}
function drawArrows(activeId) {
const svg = document.getElementById('arrowsSvg');
Array.from(svg.children).forEach(c => { if (c.tagName !== 'defs') c.remove(); });
ARROWS.forEach(([from, to, style, label]) => {
const rF = nodeRect(from), rT = nodeRect(to);
if (!rF || !rT) return;
const isActive = activeId && (from === activeId || to === activeId);
const [x1, y1] = edgePt(rF, 'bot');
const [x2, y2] = edgePt(rT, 'top');
const dy = Math.abs(y2 - y1) * 0.55;
const dx = x2 - x1;
const cx1 = x1 + (Math.abs(dx) > 40 ? dx * 0.12 : 0);
const cx2 = x2 - (Math.abs(dx) > 40 ? dx * 0.12 : 0);
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d',
`M ${x1.toFixed(1)} ${y1.toFixed(1)} C ${cx1.toFixed(1)} ${(y1+dy).toFixed(1)}, ${cx2.toFixed(1)} ${(y2-dy).toFixed(1)}, ${x2.toFixed(1)} ${y2.toFixed(1)}`
);
path.setAttribute('fill', 'none');
if (isActive) {
path.setAttribute('stroke', 'rgba(0,102,204,.42)');
path.setAttribute('stroke-width', '1.8');
path.setAttribute('stroke-dasharray', 'none');
path.setAttribute('marker-end', 'url(#mArrowHi)');
} else if (style === 'gold') {
path.setAttribute('stroke', 'rgba(184,134,11,.32)');
path.setAttribute('stroke-width', '1.2');
path.setAttribute('stroke-dasharray', '4 3');
path.setAttribute('marker-end', 'url(#mArrowGold)');
} else if (style === 'silver') {
path.setAttribute('stroke', 'rgba(158,158,158,.32)');
path.setAttribute('stroke-width', '1.2');
path.setAttribute('stroke-dasharray', '4 3');
path.setAttribute('marker-end', 'url(#mArrowSil)');
} else {
path.setAttribute('stroke', '#d0d0d5');
path.setAttribute('stroke-width', '1.5');
path.setAttribute('stroke-dasharray', '5 3');
path.setAttribute('marker-end', 'url(#mArrow)');
}
svg.appendChild(path);
if (label) {
const mx = (x1 + x2) / 2;
const my = (y1 + y2) / 2;
const tw = label.length * 5.2 + 14;
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('x', (mx - tw / 2).toFixed(1));
rect.setAttribute('y', (my - 7).toFixed(1));
rect.setAttribute('width', tw.toFixed(1));
rect.setAttribute('height', '13');
rect.setAttribute('rx', '3');
rect.setAttribute('fill', 'rgba(255,255,255,0.94)');
rect.setAttribute('stroke', 'rgba(180,180,185,0.6)');
rect.setAttribute('stroke-width', '0.5');
svg.appendChild(rect);
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('x', mx.toFixed(1));
text.setAttribute('y', (my + 3.5).toFixed(1));
text.setAttribute('text-anchor', 'middle');
text.setAttribute('font-size', '8');
text.setAttribute('font-family', '"SF Mono","Fira Code",Menlo,monospace');
text.setAttribute('fill', '#6e6e73');
text.textContent = label;
svg.appendChild(text);
}
});
}
// ─────────────────────────────────────────────────────────────
// Stats rendering
// ─────────────────────────────────────────────────────────────
let _stats = null;
let _activeNid = null;
function fmt(n) { return n != null ? Number(n).toLocaleString() : 'β€”'; }
function pct(a, b) { return b ? Math.round(a / b * 100) + '%' : '0%'; }
function setW(id, ratio) {
const el = document.getElementById(id);
if (el) el.style.width = Math.min(100, Math.max(0, Math.round((ratio || 0) * 100))) + '%';
}
function set(id, v) { const el = document.getElementById(id); if (el) el.textContent = v; }
function addClass(id, cls) { const el = document.getElementById(id); if (el) el.classList.add(cls); }
function removeClass(id, cls) { const el = document.getElementById(id); if (el) el.classList.remove(cls); }
function applyStats(s) {
_stats = s;
const t1 = s.tier1 || {}, t2 = s.tier2 || {}, gh = s.github || {};
const go = s.gold || {}, sv = s.silver || {};
// ── SWE T1 lane ──
set('c-swe_t1_queue', fmt(t1.queued));
set('c-swe_t1_collect', fmt(t1.collected) + '/' + fmt(t1.queued));
set('c-swe_t1_extract', fmt(t1.extracted) + '/' + fmt(t1.queued));
set('c-swe_t1_build', fmt(t1.built) + '/' + fmt(t1.queued));
set('c-swe_t1_filter', t1.built ? pct(go.swe_tier1||0, t1.built) + ' gold' : '5 gates');
set('c-swe_t1_gold', fmt(go.swe_tier1 || 0));
set('c-swe_t1_silver', fmt(sv.swe_tier1 || 0));
setW('p-swe_t1_collect', t1.collected / (t1.queued || 1));
setW('p-swe_t1_extract', t1.extracted / (t1.queued || 1));
setW('p-swe_t1_build', t1.built / (t1.queued || 1));
if (go.swe_tier1) removeClass('c-swe_t1_gold', 'dim');
if (sv.swe_tier1) removeClass('c-swe_t1_silver', 'dim');
// ── SWE T2 lane ──
set('c-swe_t2_queue', fmt(t2.queued));
set('c-swe_t2_collect', fmt(t2.collected) + '/' + fmt(t2.queued));
set('c-swe_t2_extract', fmt(t2.extracted) + '/' + fmt(t2.queued));
set('c-swe_t2_build', fmt(t2.built) + '/' + fmt(t2.queued));
set('c-swe_t2_filter', t2.built ? pct(go.swe_tier2||0, t2.built) + ' gold' : '5 gates');
set('c-swe_t2_gold', fmt(go.swe_tier2 || 0));
set('c-swe_t2_silver', fmt(sv.swe_tier2 || 0));
setW('p-swe_t2_collect', t2.collected / (t2.queued || 1));
setW('p-swe_t2_extract', t2.extracted / (t2.queued || 1));
setW('p-swe_t2_build', t2.built / (t2.queued || 1));
if (go.swe_tier2) removeClass('c-swe_t2_gold', 'dim');
if (sv.swe_tier2) removeClass('c-swe_t2_silver', 'dim');
// ── GH T1 lane ──
const gh1q = gh.tier1_queued || 0, gh1c = gh.tier1_collected || 0;
const gh1e = gh.tier1_extracted || 0, gh1b = gh.tier1_built || 0;
set('c-gh_t1_queue', fmt(gh1q));
set('c-gh_t1_collect', gh1q ? fmt(gh1c) + '/' + fmt(gh1q) : fmt(gh1c));
set('c-gh_t1_extract', gh1q ? fmt(gh1e) + '/' + fmt(gh1q) : fmt(gh1e));
set('c-gh_t1_build', gh1q ? fmt(gh1b) + '/' + fmt(gh1q) : fmt(gh1b));
set('c-gh_t1_filter', (go.gh_tier1||0) ? pct(go.gh_tier1, gh1b||go.gh_tier1) + ' gold' : '5 gates');
set('c-gh_t1_gold', fmt(go.gh_tier1 || 0));
set('c-gh_t1_silver', fmt(sv.gh_tier1 || 0));
if (gh1q) { setW('p-gh_t1_collect', gh1c/gh1q); setW('p-gh_t1_extract', gh1e/gh1q); setW('p-gh_t1_build', gh1b/gh1q); }
if (go.gh_tier1) removeClass('c-gh_t1_gold', 'dim');
if (sv.gh_tier1) removeClass('c-gh_t1_silver', 'dim');
// ── GH T2 lane ──
const gh2q = gh.tier2_queued || 0, gh2c = gh.tier2_collected || 0;
const gh2e = gh.tier2_extracted || 0, gh2b = gh.tier2_built || 0;
set('c-gh_t2_queue', fmt(gh2q));
set('c-gh_t2_collect', gh2q ? fmt(gh2c) + '/' + fmt(gh2q) : fmt(gh2c));
set('c-gh_t2_extract', gh2q ? fmt(gh2e) + '/' + fmt(gh2q) : fmt(gh2e));
set('c-gh_t2_build', gh2q ? fmt(gh2b) + '/' + fmt(gh2q) : fmt(gh2b));
set('c-gh_t2_filter', (go.gh_tier2||0) ? pct(go.gh_tier2, gh2b||go.gh_tier2) + ' gold' : '5 gates');
set('c-gh_t2_gold', fmt(go.gh_tier2 || 0));
set('c-gh_t2_silver', fmt(sv.gh_tier2 || 0));
if (gh2q) { setW('p-gh_t2_collect', gh2c/gh2q); setW('p-gh_t2_extract', gh2e/gh2q); setW('p-gh_t2_build', gh2b/gh2q); }
if (go.gh_tier2) removeClass('c-gh_t2_gold', 'dim');
if (sv.gh_tier2) removeClass('c-gh_t2_silver', 'dim');
// ── Merge ──
const goldTotal = go.total || 0;
set('c-gold_final', fmt(goldTotal) + '/' + fmt(go.target || 1000));
setW('p-gold_final', goldTotal / (go.target || 1000));
removeClass('c-gold_final', 'dim');
if (goldTotal < (go.target || 1000)) addClass('c-gold_final', 'warn');
else addClass('c-gold_final', 'ok');
const svTotal = sv.total || 0;
set('c-silver_final', fmt(svTotal));
if (svTotal) removeClass('c-silver_final', 'dim');
// ── Splits ──
const sp = s.splits || {};
if (sp.dev != null) { set('c-dev', fmt(sp.dev)); removeClass('c-dev','dim'); }
if (sp.test != null) { set('c-test', fmt(sp.test)); removeClass('c-test','dim'); }
if (sp.few_shot!= null) { set('c-few_shot', fmt(sp.few_shot)); removeClass('c-few_shot','dim'); }
// ── Expansion ──
const ex = s.expansion || {};
const exApy = ex.tier_a_py || {};
const exAnopy = ex.tier_a_nopy || {};
const exBjvm = ex.tier_b_jvm || {};
const exBmix = ex.tier_b_mix || {};
const exBpy = ex.tier_b_py || {};
const exBrustgo = ex.tier_b_rustgo || {};
const exGpuLibs = ex.tier_gpu_libs || {};
const exGpuInf = ex.tier_gpu_inf || {};
const exGpuComp = ex.tier_gpu_comp || {};
// Tier A Python
set('c-ex_a_py_queue', exApy.queued ? fmt(exApy.queued) : 'β€”');
set('c-ex_a_py_extract', exApy.built ? fmt(exApy.built) + '/' + fmt(exApy.queued||0) : 'β€”');
set('c-ex_a_py_build', exApy.built ? fmt(exApy.built) + '/' + fmt(exApy.queued||0) : 'β€”');
set('c-ex_a_py_filter', exApy.built ? pct(exApy.gold||0, exApy.built) + ' gold' : '5 gates');
set('c-ex_a_py_gold', fmt(exApy.gold || 0));
set('c-ex_a_py_silver', fmt(exApy.silver || 0));
if (exApy.queued) { setW('p-ex_a_py_extract', (exApy.built||0) / exApy.queued); setW('p-ex_a_py_build', (exApy.built||0) / exApy.queued); }
if (exApy.gold) removeClass('c-ex_a_py_gold', 'dim');
if (exApy.silver) removeClass('c-ex_a_py_silver', 'dim');
// Tier A No-Python
set('c-ex_a_nopy_queue', exAnopy.queued ? fmt(exAnopy.queued) : 'β€”');
set('c-ex_a_nopy_extract', exAnopy.built ? fmt(exAnopy.built) + '/' + fmt(exAnopy.queued||0) : 'β€”');
set('c-ex_a_nopy_build', exAnopy.built ? fmt(exAnopy.built) + '/' + fmt(exAnopy.queued||0) : 'β€”');
set('c-ex_a_nopy_filter', exAnopy.built ? pct(exAnopy.gold||0, exAnopy.built) + ' gold' : '5 gates');
set('c-ex_a_nopy_gold', fmt(exAnopy.gold || 0));
set('c-ex_a_nopy_silver', fmt(exAnopy.silver || 0));
if (exAnopy.queued) { setW('p-ex_a_nopy_extract', (exAnopy.built||0) / exAnopy.queued); setW('p-ex_a_nopy_build', (exAnopy.built||0) / exAnopy.queued); }
if (exAnopy.gold) removeClass('c-ex_a_nopy_gold', 'dim');
if (exAnopy.silver) removeClass('c-ex_a_nopy_silver', 'dim');
// Tier B JVM+C
set('c-ex_b_jvm_queue', exBjvm.queued ? fmt(exBjvm.queued) : 'β€”');
set('c-ex_b_jvm_extract', exBjvm.built ? fmt(exBjvm.built) + '/' + fmt(exBjvm.queued||0) : 'β€”');
set('c-ex_b_jvm_build', exBjvm.built ? fmt(exBjvm.built) + '/' + fmt(exBjvm.queued||0) : 'β€”');
set('c-ex_b_jvm_filter', exBjvm.built ? pct(exBjvm.gold||0, exBjvm.built) + ' gold' : '5 gates');
set('c-ex_b_jvm_gold', fmt(exBjvm.gold || 0));
set('c-ex_b_jvm_silver', fmt(exBjvm.silver || 0));
if (exBjvm.queued) { setW('p-ex_b_jvm_extract', (exBjvm.built||0) / exBjvm.queued); setW('p-ex_b_jvm_build', (exBjvm.built||0) / exBjvm.queued); }
if (exBjvm.queued) removeClass('c-ex_b_jvm_queue', 'dim');
if (exBjvm.gold) removeClass('c-ex_b_jvm_gold', 'dim');
if (exBjvm.silver) removeClass('c-ex_b_jvm_silver', 'dim');
// Tier B Mix
set('c-ex_b_mix_queue', exBmix.queued ? fmt(exBmix.queued) : 'β€”');
set('c-ex_b_mix_extract', exBmix.built ? fmt(exBmix.built) + '/' + fmt(exBmix.queued||0) : 'β€”');
set('c-ex_b_mix_build', exBmix.built ? fmt(exBmix.built) + '/' + fmt(exBmix.queued||0) : 'β€”');
set('c-ex_b_mix_filter', exBmix.built ? pct(exBmix.gold||0, exBmix.built) + ' gold' : '5 gates');
set('c-ex_b_mix_gold', fmt(exBmix.gold || 0));
set('c-ex_b_mix_silver', fmt(exBmix.silver || 0));
if (exBmix.queued) { setW('p-ex_b_mix_extract', (exBmix.built||0) / exBmix.queued); setW('p-ex_b_mix_build', (exBmix.built||0) / exBmix.queued); }
if (exBmix.queued) removeClass('c-ex_b_mix_queue', 'dim');
if (exBmix.gold) removeClass('c-ex_b_mix_gold', 'dim');
if (exBmix.silver) removeClass('c-ex_b_mix_silver', 'dim');
// Tier B Python
set('c-ex_b_py_queue', exBpy.queued ? fmt(exBpy.queued) : 'β€”');
set('c-ex_b_py_extract', exBpy.built ? fmt(exBpy.built) + '/' + fmt(exBpy.queued||0) : 'β€”');
set('c-ex_b_py_build', exBpy.built ? fmt(exBpy.built) + '/' + fmt(exBpy.queued||0) : 'β€”');
set('c-ex_b_py_filter', exBpy.built ? pct(exBpy.gold||0, exBpy.built) + ' gold' : '5 gates');
set('c-ex_b_py_gold', fmt(exBpy.gold || 0));
set('c-ex_b_py_silver', fmt(exBpy.silver || 0));
if (exBpy.queued) { setW('p-ex_b_py_extract', (exBpy.built||0) / exBpy.queued); setW('p-ex_b_py_build', (exBpy.built||0) / exBpy.queued); }
if (exBpy.queued) removeClass('c-ex_b_py_queue', 'dim');
if (exBpy.gold) removeClass('c-ex_b_py_gold', 'dim');
if (exBpy.silver) removeClass('c-ex_b_py_silver', 'dim');
// Tier B Rust+Go
set('c-ex_b_rustgo_queue', exBrustgo.queued ? fmt(exBrustgo.queued) : 'β€”');
set('c-ex_b_rustgo_extract', exBrustgo.built ? fmt(exBrustgo.built) + '/' + fmt(exBrustgo.queued||0) : 'β€”');
set('c-ex_b_rustgo_build', exBrustgo.built ? fmt(exBrustgo.built) + '/' + fmt(exBrustgo.queued||0) : 'β€”');
set('c-ex_b_rustgo_filter', exBrustgo.built ? pct(exBrustgo.gold||0, exBrustgo.built) + ' gold' : '5 gates');
set('c-ex_b_rustgo_gold', fmt(exBrustgo.gold || 0));
set('c-ex_b_rustgo_silver', fmt(exBrustgo.silver || 0));
if (exBrustgo.queued) { setW('p-ex_b_rustgo_extract', (exBrustgo.built||0) / exBrustgo.queued); setW('p-ex_b_rustgo_build', (exBrustgo.built||0) / exBrustgo.queued); }
if (exBrustgo.queued) removeClass('c-ex_b_rustgo_queue', 'dim');
if (exBrustgo.gold) removeClass('c-ex_b_rustgo_gold', 'dim');
if (exBrustgo.silver) removeClass('c-ex_b_rustgo_silver', 'dim');
// GPU Libs
set('c-ex_gpu_libs_queue', exGpuLibs.queued ? fmt(exGpuLibs.queued) : 'β€”');
set('c-ex_gpu_libs_extract', exGpuLibs.built ? fmt(exGpuLibs.built) + '/' + fmt(exGpuLibs.queued||0) : 'β€”');
set('c-ex_gpu_libs_build', exGpuLibs.built ? fmt(exGpuLibs.built) + '/' + fmt(exGpuLibs.queued||0) : 'β€”');
set('c-ex_gpu_libs_filter', exGpuLibs.built ? pct(exGpuLibs.gold||0, exGpuLibs.built) + ' gold' : '5 gates');
set('c-ex_gpu_libs_gold', fmt(exGpuLibs.gold || 0));
set('c-ex_gpu_libs_silver', fmt(exGpuLibs.silver || 0));
if (exGpuLibs.queued) { setW('p-ex_gpu_libs_extract', (exGpuLibs.built||0) / exGpuLibs.queued); setW('p-ex_gpu_libs_build', (exGpuLibs.built||0) / exGpuLibs.queued); }
if (exGpuLibs.queued) removeClass('c-ex_gpu_libs_queue', 'dim');
if (exGpuLibs.gold) removeClass('c-ex_gpu_libs_gold', 'dim');
if (exGpuLibs.silver) removeClass('c-ex_gpu_libs_silver', 'dim');
// GPU Inference
set('c-ex_gpu_inf_queue', exGpuInf.queued ? fmt(exGpuInf.queued) : 'β€”');
set('c-ex_gpu_inf_extract', exGpuInf.built ? fmt(exGpuInf.built) + '/' + fmt(exGpuInf.queued||0) : 'β€”');
set('c-ex_gpu_inf_build', exGpuInf.built ? fmt(exGpuInf.built) + '/' + fmt(exGpuInf.queued||0) : 'β€”');
set('c-ex_gpu_inf_filter', exGpuInf.built ? pct(exGpuInf.gold||0, exGpuInf.built) + ' gold' : '5 gates');
set('c-ex_gpu_inf_gold', fmt(exGpuInf.gold || 0));
set('c-ex_gpu_inf_silver', fmt(exGpuInf.silver || 0));
if (exGpuInf.queued) { setW('p-ex_gpu_inf_extract', (exGpuInf.built||0) / exGpuInf.queued); setW('p-ex_gpu_inf_build', (exGpuInf.built||0) / exGpuInf.queued); }
if (exGpuInf.queued) removeClass('c-ex_gpu_inf_queue', 'dim');
if (exGpuInf.gold) removeClass('c-ex_gpu_inf_gold', 'dim');
if (exGpuInf.silver) removeClass('c-ex_gpu_inf_silver', 'dim');
// GPU Compilers
set('c-ex_gpu_comp_queue', exGpuComp.queued ? fmt(exGpuComp.queued) : 'β€”');
set('c-ex_gpu_comp_extract', exGpuComp.built ? fmt(exGpuComp.built) + '/' + fmt(exGpuComp.queued||0) : 'β€”');
set('c-ex_gpu_comp_build', exGpuComp.built ? fmt(exGpuComp.built) + '/' + fmt(exGpuComp.queued||0) : 'β€”');
set('c-ex_gpu_comp_filter', exGpuComp.built ? pct(exGpuComp.gold||0, exGpuComp.built) + ' gold' : '5 gates');
set('c-ex_gpu_comp_gold', fmt(exGpuComp.gold || 0));
set('c-ex_gpu_comp_silver', fmt(exGpuComp.silver || 0));
if (exGpuComp.queued) { setW('p-ex_gpu_comp_extract', (exGpuComp.built||0) / exGpuComp.queued); setW('p-ex_gpu_comp_build', (exGpuComp.built||0) / exGpuComp.queued); }
if (exGpuComp.queued) removeClass('c-ex_gpu_comp_queue', 'dim');
if (exGpuComp.gold) removeClass('c-ex_gpu_comp_gold', 'dim');
if (exGpuComp.silver) removeClass('c-ex_gpu_comp_silver', 'dim');
// ── Gold Extended ──
const gext = (go.gold_extended || 0);
const gv2 = (go.gold_v2 || 0);
set('c-gold_extended', fmt(gext));
setW('p-gold_extended', gext / (ex.total || 1));
if (gext) removeClass('c-gold_extended', 'dim');
// ── Gold v2 (merged final) ──
// TODO: fetch from /api/stats β€” gold.gold_v2_target is not yet returned by
// serve_progress_panel.py. When added to compute_stats(), replace the
// literal below with: const v2Target = go.gold_v2_target || 3500;
const v2Target = go.gold_v2_target || 3500;
set('c-gold_v2', fmt(gv2) + '/' + fmt(v2Target));
setW('p-gold_v2', gv2 / v2Target);
if (gv2) { removeClass('c-gold_v2', 'dim'); }
if (gv2 < v2Target) addClass('c-gold_v2', 'warn');
else addClass('c-gold_v2', 'ok');
// Live badge
const b = document.getElementById('liveBadge');
b.textContent = '● LIVE';
b.classList.add('live');
}
// ─────────────────────────────────────────────────────────────
// Detail panel
// ─────────────────────────────────────────────────────────────
function openPanel(nid) {
if (_activeNid) {
const prev = document.getElementById('n-' + _activeNid);
if (prev) prev.classList.remove('active');
}
_activeNid = nid;
const el = document.getElementById('n-' + nid);
if (el) el.classList.add('active');
drawArrows(nid);
const meta = NODE_META[nid];
if (!meta) return;
const body = document.getElementById('panelBody');
body.innerHTML = buildHero(nid, meta) + buildStats(nid) +
(meta.browseable ? '<div class="panel-loading" id="entryLoad">Loading entries…</div>' : '');
document.getElementById('detailPanel').classList.add('open');
document.getElementById('pageLayout').classList.add('panel-open');
if (meta.browseable) fetchEntries(nid);
}
function closePanel() {
if (_activeNid) {
const el = document.getElementById('n-' + _activeNid);
if (el) el.classList.remove('active');
_activeNid = null;
}
document.getElementById('detailPanel').classList.remove('open');
document.getElementById('pageLayout').classList.remove('panel-open');
drawArrows(null);
}
function buildHero(nid, meta) {
return `<div class="panel-hero">
<div class="panel-type-row">
<div class="leg-dot" style="background:${meta.typeColor}"></div>
<span class="panel-type-lbl">${meta.type}</span>
</div>
<div class="panel-title">${meta.title}</div>
<div class="panel-file">${meta.file}</div>
<p class="panel-desc">${meta.desc}</p>
</div>`;
}
function buildStats(nid) {
if (!_stats) return '';
const rows = getStatRows(nid, _stats);
const bar = getBarDef(nid, _stats);
if (!rows.length && !bar) return '';
let html = '<div class="panel-stats">';
rows.forEach(([k, v, cls]) => {
const isSep = cls === 'sep';
html += `<div class="pstat${isSep ? ' sep' : ''}"><span class="pstat-k">${k}</span><span class="pstat-v ${isSep ? '' : (cls||'')}">${v}</span></div>`;
});
html += '</div>';
if (bar) {
html += `<div class="panel-bar-wrap">
<div class="panel-bar-labels"><span>${bar.label}</span><span>${bar.pct}%</span></div>
<div class="panel-bar-track"><div class="panel-bar-fill ${bar.cls||''}" style="width:${bar.pct}%"></div></div>
</div>`;
}
return html;
}
function getStatRows(nid, s) {
const t1=s.tier1||{}, t2=s.tier2||{}, gh=s.github||{};
const go=s.gold||{}, sv=s.silver||{}, sp=s.splits||{};
const ex=s.expansion||{};
const exApy=ex.tier_a_py||{}, exAnopy=ex.tier_a_nopy||{};
const exBjvm=ex.tier_b_jvm||{}, exBmix=ex.tier_b_mix||{};
const exBpy=ex.tier_b_py||{}, exBrustgo=ex.tier_b_rustgo||{};
const exGpuLibs=ex.tier_gpu_libs||{}, exGpuInf=ex.tier_gpu_inf||{}, exGpuComp=ex.tier_gpu_comp||{};
switch (nid) {
// SWE T1
case 'swe_t1_queue': return [['Queued',fmt(t1.queued),'blue'],['Score range',`${(t1.score_min||0).toFixed(3)}–${(t1.score_max||0).toFixed(3)}`,''],['Score mean',(t1.score_mean||0).toFixed(3),''],['Source','github_via_swe_bench','']];
case 'swe_t1_collect': return [['Collected',fmt(t1.collected),''],['Queue',fmt(t1.queued),''],['Completion',pct(t1.collected,t1.queued),'blue'],['Cache','data/raw/<slug>/<num>.json','']];
case 'swe_t1_extract': return [['Extracted',fmt(t1.extracted),''],['Queued',fmt(t1.queued),''],['Completion',pct(t1.extracted,t1.queued),'blue'],['Model','gpt-oss-120b','']];
case 'swe_t1_build': return [['Built',fmt(t1.built),'blue'],['Queued',fmt(t1.queued),''],['Output','tier1_trajectories.jsonl',''],['Source tag','github_via_swe_bench','']];
case 'swe_t1_filter': return [['Input (built)',fmt(t1.built),''],['β†’ Gold',fmt(go.swe_tier1||0),'amber'],['β†’ Silver',fmt(sv.swe_tier1||0),''],['Gold pass rate',pct(go.swe_tier1||0,t1.built),'blue'],['Gold gates','corrections Β· llmβ‰₯0.35 Β· turnsβ‰₯2','']];
case 'swe_t1_gold': return [['Count',fmt(go.swe_tier1||0),'amber'],['Source','github_via_swe_bench',''],['Script','build_per_source_gold_silver.py',''],['File','gold/gold_swe_tier1.jsonl','']];
case 'swe_t1_silver': return [['Count',fmt(sv.swe_tier1||0),''],['Source','github_via_swe_bench',''],['Gate','turnsβ‰₯2 Β· ambiguity<0.90 Β· root_cause or llm>0',''],['suitable_for_benchmark','False','']];
// SWE T2
case 'swe_t2_queue': return [['Queued',fmt(t2.queued),'blue'],['Score range',`${(t2.score_min||0).toFixed(3)}–${(t2.score_max||0).toFixed(3)}`,''],['Score mean',(t2.score_mean||0).toFixed(3),''],['Source','github_via_swe_bench','']];
case 'swe_t2_collect': return [['Collected',fmt(t2.collected),''],['Queue',fmt(t2.queued),''],['Completion',pct(t2.collected,t2.queued),'blue'],['Cache','data/raw/<slug>/<num>.json','']];
case 'swe_t2_extract': return [['Extracted',fmt(t2.extracted),''],['Queued',fmt(t2.queued),''],['Completion',pct(t2.extracted,t2.queued),'blue'],['Model','gpt-oss-120b','']];
case 'swe_t2_build': return [['Built',fmt(t2.built),'blue'],['Queued',fmt(t2.queued),''],['Output','tier2_trajectories.jsonl',''],['Source tag','github_via_swe_bench','']];
case 'swe_t2_filter': return [['Input (built)',fmt(t2.built),''],['β†’ Gold',fmt(go.swe_tier2||0),'amber'],['β†’ Silver',fmt(sv.swe_tier2||0),''],['Gold pass rate',pct(go.swe_tier2||0,t2.built),'blue'],['Gold gates','corrections Β· llmβ‰₯0.35 Β· turnsβ‰₯2','']];
case 'swe_t2_gold': return [['Count',fmt(go.swe_tier2||0),'amber'],['Source','github_via_swe_bench',''],['Script','build_per_source_gold_silver.py',''],['File','gold/gold_swe_tier2.jsonl','']];
case 'swe_t2_silver': return [['Count',fmt(sv.swe_tier2||0),''],['Source','github_via_swe_bench',''],['Gate','turnsβ‰₯2 Β· ambiguity<0.90',''],['suitable_for_benchmark','False','']];
// GH T1
case 'gh_t1_queue': return [['Queued',fmt(gh.tier1_queued),'blue'],['Source','github_raw',''],['Score','β‰₯ pool median',''],['Pool median',(gh.pool_median||0).toFixed(4),'']];
case 'gh_t1_collect': return [['Collected',fmt(gh.tier1_collected),''],['Queue',fmt(gh.tier1_queued),''],['Completion',pct(gh.tier1_collected,gh.tier1_queued),'blue']];
case 'gh_t1_extract': return [['Extracted',fmt(gh.tier1_extracted),''],['Queue',fmt(gh.tier1_queued),''],['Completion',pct(gh.tier1_extracted,gh.tier1_queued),'blue']];
case 'gh_t1_build': return [['Built (gold+silver)',fmt(gh.tier1_built),'blue'],['Source tag','github_raw',''],['Note','Pre-filtered during batch collection','']];
case 'gh_t1_filter': return [['β†’ Gold',fmt(go.gh_tier1||0),'amber'],['β†’ Silver',fmt(sv.gh_tier1||0),''],['Total processed',fmt(gh.tier1_built),''],['Note','Pre-filtered during batch collection','']];
case 'gh_t1_gold': return [['Count',fmt(go.gh_tier1||0),'amber'],['Source tag','github_raw',''],['Script','build_per_source_gold_silver.py',''],['File','gold/gold_gh_tier1.jsonl','']];
case 'gh_t1_silver': return [['Count',fmt(sv.gh_tier1||0),''],['Source','github_raw',''],['suitable_for_benchmark','False','']];
// GH T2
case 'gh_t2_queue': return [['Queued',fmt(gh.tier2_queued),'blue'],['Source','github_raw',''],['Score','< pool median',''],['Pool median',(gh.pool_median||0).toFixed(4),'']];
case 'gh_t2_collect': return [['Collected',fmt(gh.tier2_collected),''],['Queue',fmt(gh.tier2_queued),''],['Completion',pct(gh.tier2_collected,gh.tier2_queued),'blue']];
case 'gh_t2_extract': return [['Extracted',fmt(gh.tier2_extracted),''],['Queue',fmt(gh.tier2_queued),''],['Completion',pct(gh.tier2_extracted,gh.tier2_queued),'blue']];
case 'gh_t2_build': return [['Built (gold+silver)',fmt(gh.tier2_built),'blue'],['Source tag','github_raw',''],['Note','Pre-filtered during batch collection','']];
case 'gh_t2_filter': return [['β†’ Gold',fmt(go.gh_tier2||0),'amber'],['β†’ Silver',fmt(sv.gh_tier2||0),''],['Total processed',fmt(gh.tier2_built),''],['Note','Pre-filtered during batch collection','']];
case 'gh_t2_gold': return [['Count',fmt(go.gh_tier2||0),'amber'],['Source tag','github_raw',''],['Script','build_per_source_gold_silver.py',''],['File','gold/gold_gh_tier2.jsonl','']];
case 'gh_t2_silver': return [['Count',fmt(sv.gh_tier2||0),''],['Source','github_raw',''],['suitable_for_benchmark','False','']];
// Merge
case 'gold_final': {
const rows = [
['Total (deduped)',fmt(go.total),'amber'],
['Target',fmt(go.target||1000),''],
['Shortfall',fmt(Math.max(0,(go.target||1000)-go.total)),go.total>=(go.target||1000)?'ok':'amber'],
['','','sep'],
['SWE Tier 1',fmt(go.swe_tier1||0),''],
['SWE Tier 2',fmt(go.swe_tier2||0),''],
['GitHub Tier 1',fmt(go.gh_tier1||0),''],
['GitHub Tier 2',fmt(go.gh_tier2||0),''],
['','','sep'],
['Avg quality',(go.avg_quality||0).toFixed(3),''],
['Avg turns',(go.avg_turns||0).toFixed(1),''],
];
if (go.by_repo) {
rows.push(['','','sep']);
rows.push(['Top repos','','sep']);
Object.entries(go.by_repo).slice(0,5).forEach(([r,n]) => {
rows.push([(r.includes('/')?r.split('/')[1]:r), fmt(n), '']);
});
}
return rows;
}
case 'silver_final': return [
['Total (deduped)',fmt(sv.total||0),'blue'],
['','','sep'],
['SWE Tier 1',fmt(sv.swe_tier1||0),''],
['SWE Tier 2',fmt(sv.swe_tier2||0),''],
['GitHub Tier 1',fmt(sv.gh_tier1||0),''],
['GitHub Tier 2',fmt(sv.gh_tier2||0),''],
['','','sep'],
['suitable_for_benchmark','False',''],
['Use case','Auxiliary / pretraining',''],
];
case 'gold_extended': {
const pg = go.gold_v2_per_group || {};
const nopy = (pg['ex_tier_a_nopython']||0) + (pg['ex_tier_a_nopython_ts']||0) + (pg['ex_tier_a_nopython_typescript']||0);
const rows = [
['Total (deduped)', fmt(go.gold_extended||0), 'amber'],
['Collection tag', 'github_raw', ''],
['', '', 'sep'],
['Exp A – No-Python', fmt(nopy), ''],
['Exp A – Python', fmt(pg['ex_tier_a_python']||0), ''],
['Exp B – Python', fmt(pg['ex_tier_b_python']||0), ''],
['Exp B – Mix', fmt(pg['ex_tier_b_mix']||0), ''],
['Exp B – JVM + C', fmt(pg['ex_tier_b_jvm_tier_c']||0), ''],
['Exp B – Rust+Go', fmt(pg['ex_tier_b_rust_go']||0), ''],
['GPU Libraries', fmt(pg['ex_tier_gpu_libs']||0), ''],
['GPU Inference', fmt(pg['ex_tier_gpu_inference']||0), ''],
['GPU Compilers', fmt(pg['ex_tier_gpu_compilers']||0), ''],
['', '', 'sep'],
['Dedup key', 'issue_url', ''],
['Script', 'debugbench/cli/merge_gold.py', ''],
];
return rows;
}
case 'gold_v2': {
const pg = go.gold_v2_per_group || {};
const legacy = go.gold_final || 0;
const extended = go.gold_extended || 0;
const nopy = (pg['ex_tier_a_nopython']||0) + (pg['ex_tier_a_nopython_ts']||0) + (pg['ex_tier_a_nopython_typescript']||0);
const rows = [
['Total (merged)', fmt(go.gold_v2||0), 'amber'],
['', '', 'sep'],
['SWE-bench legacy', fmt(legacy), ''],
['Expansion (new)', fmt(extended), ''],
['', '', 'sep'],
['Exp A – No-Python', fmt(nopy), ''],
['Exp A – Python', fmt(pg['ex_tier_a_python']||0), ''],
['Exp B – Python', fmt(pg['ex_tier_b_python']||0), ''],
['Exp B – Mix', fmt(pg['ex_tier_b_mix']||0), ''],
['Exp B – JVM + C', fmt(pg['ex_tier_b_jvm_tier_c']||0), ''],
['Exp B – Rust+Go', fmt(pg['ex_tier_b_rust_go']||0), ''],
['GPU Libraries', fmt(pg['ex_tier_gpu_libs']||0), ''],
['GPU Inference', fmt(pg['ex_tier_gpu_inference']||0), ''],
['GPU Compilers', fmt(pg['ex_tier_gpu_compilers']||0), ''],
['', '', 'sep'],
['Provenance fields', 'collection_group Β· collection_label Β· collection_tier', ''],
['Script', 'debugbench/cli/merge_gold.py', ''],
];
return rows;
}
case 'dev': return [['Count',fmt(sp.dev),'blue'],['Seed','42',''],['Purpose','Prompt tuning / ablations','']];
case 'test': return [['Count',fmt(sp.test),'blue'],['Seed','42',''],['Purpose','Final reported numbers','']];
case 'few_shot': return [['Count',fmt(sp.few_shot),'blue'],['Seed','42',''],['Purpose','In-context examples','']];
// ── Expansion Tier A Python ──
case 'ex_a_py_queue': return [['Queued',fmt(exApy.queued||0),'blue'],['Language','Python',''],['Source','github_raw',''],['Repos','pytorch Β· sqlalchemy Β· FastAPI Β· …','']];
case 'ex_a_py_extract': return [['Built',fmt(exApy.built||0),'blue'],['Queue',fmt(exApy.queued||0),''],['Completion',pct(exApy.built||0,exApy.queued||1),'blue'],['Model','gemma-4-31B-it',''],['Note','collect_expansion.py bundles collect + extract','']];
case 'ex_a_py_build': return [['Built',fmt(exApy.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_a_py_filter': return [['β†’ Gold',fmt(exApy.gold||0),'amber'],['β†’ Silver',fmt(exApy.silver||0),''],['Gold rate',pct(exApy.gold||0,exApy.built||1),'blue'],['Gold gates','corrections Β· llmβ‰₯0.35 Β· turnsβ‰₯2','']];
case 'ex_a_py_gold': return [['Count',fmt(exApy.gold||0),'amber'],['Source','github_raw',''],['File','processed/expansion_tier_a_python.jsonl','']];
case 'ex_a_py_silver': return [['Count',fmt(exApy.silver||0),''],['suitable_for_benchmark','False','']];
// ── Expansion Tier A No-Python ──
case 'ex_a_nopy_queue': return [['Queued',fmt(exAnopy.queued||0),'blue'],['Languages','TypeScript Β· Go Β· Rust Β· Next.js Β· k8s',''],['Source','github_raw','']];
case 'ex_a_nopy_extract': return [['Built',fmt(exAnopy.built||0),'blue'],['Queue',fmt(exAnopy.queued||0),''],['Completion',pct(exAnopy.built||0,exAnopy.queued||1),'blue'],['Sub-batches','golang Β· k8s Β· nextjs Β· rust Β· ts Β· typescript',''],['Note','collect_expansion.py bundles collect + extract','']];
case 'ex_a_nopy_build': return [['Built',fmt(exAnopy.built||0),'blue'],['Source tag','github_raw',''],['Note','Aggregated from 7 sub-batch runs','']];
case 'ex_a_nopy_filter': return [['β†’ Gold',fmt(exAnopy.gold||0),'amber'],['β†’ Silver',fmt(exAnopy.silver||0),''],['Gold rate',pct(exAnopy.gold||0,exAnopy.built||1),'blue'],['Dedup','by instance_id across sub-batches','']];
case 'ex_a_nopy_gold': return [['Count',fmt(exAnopy.gold||0),'amber'],['Note','Deduplicated across 7 sub-batch files',''],['Largest sub-batch','TypeScript','']];
case 'ex_a_nopy_silver': return [['Count',fmt(exAnopy.silver||0),''],['suitable_for_benchmark','False','']];
// ── Expansion Tier B JVM+C ──
case 'ex_b_jvm_queue': return [['Search','Dynamic GitHub search','blue'],['Repos','spring Β· kafka Β· elasticsearch Β· node Β· rails Β· julia Β· llvm',''],['Candidates','~1,980','']];
case 'ex_b_jvm_extract': return [['Built',fmt(exBjvm.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','Complete','']];
case 'ex_b_jvm_build': return [['Built',fmt(exBjvm.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_b_jvm_filter': return [['β†’ Gold',fmt(exBjvm.gold||0),'amber'],['β†’ Silver',fmt(exBjvm.silver||0),''],['Gold rate',pct(exBjvm.gold||0,exBjvm.built||1),'blue']];
case 'ex_b_jvm_gold': return [['Count',fmt(exBjvm.gold||0),'amber'],['File','processed/expansion_tier_b_jvm_tier_c.jsonl','']];
case 'ex_b_jvm_silver': return [['Count',fmt(exBjvm.silver||0),''],['suitable_for_benchmark','False','']];
// ── Expansion Tier B Mix ──
case 'ex_b_mix_queue': return [['Search','Dynamic GitHub search','blue'],['Coverage','Diverse mixed repos','']];
case 'ex_b_mix_extract': return [['Built',fmt(exBmix.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','Complete','']];
case 'ex_b_mix_build': return [['Built',fmt(exBmix.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_b_mix_filter': return [['β†’ Gold',fmt(exBmix.gold||0),'amber'],['β†’ Silver',fmt(exBmix.silver||0),''],['Gold rate',pct(exBmix.gold||0,exBmix.built||1),'blue']];
case 'ex_b_mix_gold': return [['Count',fmt(exBmix.gold||0),'amber'],['File','processed/expansion_tier_b_mix.jsonl','']];
case 'ex_b_mix_silver': return [['Count',fmt(exBmix.silver||0),''],['suitable_for_benchmark','False','']];
// ── Expansion Tier B Python ──
case 'ex_b_py_queue': return [['Search','Dynamic GitHub search','blue'],['Language','Python',''],['Status','Running','amber']];
case 'ex_b_py_extract': return [['Built',fmt(exBpy.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','In progress','amber']];
case 'ex_b_py_build': return [['Built',fmt(exBpy.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_b_py_filter': return [['β†’ Gold',fmt(exBpy.gold||0),'amber'],['β†’ Silver',fmt(exBpy.silver||0),''],['Gold rate',pct(exBpy.gold||0,exBpy.built||1),'blue']];
case 'ex_b_py_gold': return [['Count',fmt(exBpy.gold||0),'amber'],['File','processed/expansion_tier_b_python.jsonl','']];
case 'ex_b_py_silver': return [['Count',fmt(exBpy.silver||0),''],['suitable_for_benchmark','False','']];
// ── Expansion Tier B Rust+Go ──
case 'ex_b_rustgo_queue': return [['Search','Dynamic GitHub search','blue'],['Languages','Rust Β· Go',''],['Status','Running','amber']];
case 'ex_b_rustgo_extract': return [['Built',fmt(exBrustgo.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','In progress','amber']];
case 'ex_b_rustgo_build': return [['Built',fmt(exBrustgo.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_b_rustgo_filter': return [['β†’ Gold',fmt(exBrustgo.gold||0),'amber'],['β†’ Silver',fmt(exBrustgo.silver||0),''],['Gold rate',pct(exBrustgo.gold||0,exBrustgo.built||1),'blue']];
case 'ex_b_rustgo_gold': return [['Count',fmt(exBrustgo.gold||0),'amber'],['File','processed/expansion_tier_b_rust_go.jsonl','']];
case 'ex_b_rustgo_silver': return [['Count',fmt(exBrustgo.silver||0),''],['suitable_for_benchmark','False','']];
// ── GPU Libs ──
case 'ex_gpu_libs_queue': return [['Search','Dynamic GitHub search','blue'],['Repos','cupy Β· numba Β· xla Β· DeepSpeed Β· gem5',''],['Status','Complete','']];
case 'ex_gpu_libs_extract': return [['Built',fmt(exGpuLibs.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','Complete','']];
case 'ex_gpu_libs_build': return [['Built',fmt(exGpuLibs.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_gpu_libs_filter': return [['β†’ Gold',fmt(exGpuLibs.gold||0),'amber'],['β†’ Silver',fmt(exGpuLibs.silver||0),''],['Gold rate',pct(exGpuLibs.gold||0,exGpuLibs.built||1),'blue']];
case 'ex_gpu_libs_gold': return [['Count',fmt(exGpuLibs.gold||0),'amber'],['File','processed/expansion_tier_gpu_libs.jsonl',''],['Avg turns','12.6',''],['Avg corrections','1.3','']];
case 'ex_gpu_libs_silver': return [['Count',fmt(exGpuLibs.silver||0),''],['suitable_for_benchmark','False','']];
// ── GPU Inference ──
case 'ex_gpu_inf_queue': return [['Search','Dynamic GitHub search','blue'],['Repos','vllm Β· onnxruntime',''],['Status','Complete','']];
case 'ex_gpu_inf_extract': return [['Built',fmt(exGpuInf.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','Complete','']];
case 'ex_gpu_inf_build': return [['Built',fmt(exGpuInf.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_gpu_inf_filter': return [['β†’ Gold',fmt(exGpuInf.gold||0),'amber'],['β†’ Silver',fmt(exGpuInf.silver||0),''],['Gold rate',pct(exGpuInf.gold||0,exGpuInf.built||1),'blue']];
case 'ex_gpu_inf_gold': return [['Count',fmt(exGpuInf.gold||0),'amber'],['File','processed/expansion_tier_gpu_inference.jsonl',''],['Avg turns','13.9',''],['Avg corrections','1.3','']];
case 'ex_gpu_inf_silver': return [['Count',fmt(exGpuInf.silver||0),''],['suitable_for_benchmark','False','']];
// ── GPU Compilers ──
case 'ex_gpu_comp_queue': return [['Search','Dynamic GitHub search','blue'],['Repos','triton Β· tvm Β· jax',''],['Status','Complete','']];
case 'ex_gpu_comp_extract': return [['Built',fmt(exGpuComp.built||0),'blue'],['Note','collect_expansion.py bundles collect + extract',''],['Run status','Complete','']];
case 'ex_gpu_comp_build': return [['Built',fmt(exGpuComp.built||0),'blue'],['Source tag','github_raw','']];
case 'ex_gpu_comp_filter': return [['β†’ Gold',fmt(exGpuComp.gold||0),'amber'],['β†’ Silver',fmt(exGpuComp.silver||0),''],['Gold rate',pct(exGpuComp.gold||0,exGpuComp.built||1),'blue']];
case 'ex_gpu_comp_gold': return [['Count',fmt(exGpuComp.gold||0),'amber'],['File','processed/expansion_tier_gpu_compilers.jsonl',''],['Avg turns','10.8',''],['Avg corrections','1.3','']];
case 'ex_gpu_comp_silver': return [['Count',fmt(exGpuComp.silver||0),''],['suitable_for_benchmark','False','']];
default: return [];
}
}
function getBarDef(nid, s) {
const t1=s.tier1||{}, t2=s.tier2||{}, gh=s.github||{}, go=s.gold||{};
const ex=s.expansion||{};
const exApy=ex.tier_a_py||{}, exAnopy=ex.tier_a_nopy||{};
const exBjvm=ex.tier_b_jvm||{}, exBmix=ex.tier_b_mix||{};
const exBpy=ex.tier_b_py||{}, exBrustgo=ex.tier_b_rustgo||{};
const exGpuLibs=ex.tier_gpu_libs||{}, exGpuInf=ex.tier_gpu_inf||{}, exGpuComp=ex.tier_gpu_comp||{};
switch (nid) {
case 'swe_t1_queue': return { label:`Collected (${t1.collected}/${t1.queued})`, pct:Math.round((t1.collected||0)/(t1.queued||1)*100), cls:'' };
case 'swe_t2_queue': return { label:`Collected (${t2.collected}/${t2.queued})`, pct:Math.round((t2.collected||0)/(t2.queued||1)*100), cls:'' };
case 'gh_t1_queue': return gh.tier1_queued ? { label:`Collected (${gh.tier1_collected||0}/${gh.tier1_queued})`, pct:Math.min(100,Math.round((gh.tier1_collected||0)/(gh.tier1_queued)*100)), cls:'' } : null;
case 'gh_t2_queue': return gh.tier2_queued ? { label:`Collected (${gh.tier2_collected||0}/${gh.tier2_queued})`, pct:Math.min(100,Math.round((gh.tier2_collected||0)/(gh.tier2_queued)*100)), cls:'' } : null;
case 'swe_t1_build': return { label:`Built (${t1.built}/${t1.queued})`, pct:Math.round((t1.built||0)/(t1.queued||1)*100), cls:'' };
case 'swe_t2_build': return { label:`Built (${t2.built}/${t2.queued})`, pct:Math.round((t2.built||0)/(t2.queued||1)*100), cls:'' };
case 'swe_t1_gold': return { label:`Gold pass rate (${go.swe_tier1||0}/${t1.built||0})`, pct:Math.round((go.swe_tier1||0)/(t1.built||1)*100), cls:'amber' };
case 'swe_t2_gold': return { label:`Gold pass rate (${go.swe_tier2||0}/${t2.built||0})`, pct:Math.round((go.swe_tier2||0)/(t2.built||1)*100), cls:'amber' };
case 'gold_final': return { label:`Progress (${go.total||0}/${go.target||1000})`, pct:Math.round((go.total||0)/(go.target||1000)*100), cls:'amber' };
case 'gold_extended': return (go.gold_extended) ? { label:`Coverage (${go.gold_extended}/${ex.total||1})`, pct:Math.min(100,Math.round((go.gold_extended||0)/(ex.total||1)*100)), cls:'amber' } : null;
case 'gold_v2': return (go.gold_v2) ? { label:`Merged (${go.gold_v2}/${go.gold_v2_target||3500})`, pct:Math.min(100,Math.round((go.gold_v2||0)/(go.gold_v2_target||3500)*100)), cls:'amber' } : null; // TODO: fetch gold_v2_target from /api/stats
case 'ex_a_py_gold': return (exApy.built) ? { label:`Gold pass rate (${exApy.gold||0}/${exApy.built})`, pct:Math.round((exApy.gold||0)/(exApy.built)*100), cls:'amber' } : null;
case 'ex_a_py_extract': return exApy.queued ? { label:`Built (${exApy.built||0}/${exApy.queued})`, pct:Math.round((exApy.built||0)/(exApy.queued)*100), cls:'' } : null;
case 'ex_a_nopy_gold': return (exAnopy.built) ? { label:`Gold pass rate (${exAnopy.gold||0}/${exAnopy.built})`, pct:Math.round((exAnopy.gold||0)/(exAnopy.built)*100), cls:'amber' } : null;
case 'ex_a_nopy_extract': return exAnopy.queued ? { label:`Built (${exAnopy.built||0}/${exAnopy.queued})`, pct:Math.round((exAnopy.built||0)/(exAnopy.queued)*100), cls:'' } : null;
case 'ex_b_jvm_gold': return (exBjvm.built) ? { label:`Gold pass rate (${exBjvm.gold||0}/${exBjvm.built})`, pct:Math.round((exBjvm.gold||0)/(exBjvm.built)*100), cls:'amber' } : null;
case 'ex_b_mix_gold': return (exBmix.built) ? { label:`Gold pass rate (${exBmix.gold||0}/${exBmix.built})`, pct:Math.round((exBmix.gold||0)/(exBmix.built)*100), cls:'amber' } : null;
case 'ex_b_py_gold': return (exBpy.built) ? { label:`Gold pass rate (${exBpy.gold||0}/${exBpy.built})`, pct:Math.round((exBpy.gold||0)/(exBpy.built)*100), cls:'amber' } : null;
case 'ex_b_rustgo_gold': return (exBrustgo.built) ? { label:`Gold pass rate (${exBrustgo.gold||0}/${exBrustgo.built})`, pct:Math.round((exBrustgo.gold||0)/(exBrustgo.built)*100), cls:'amber' } : null;
case 'ex_gpu_libs_gold': return (exGpuLibs.built) ? { label:`Gold pass rate (${exGpuLibs.gold||0}/${exGpuLibs.built})`, pct:Math.round((exGpuLibs.gold||0)/(exGpuLibs.built)*100), cls:'amber' } : null;
case 'ex_gpu_inf_gold': return (exGpuInf.built) ? { label:`Gold pass rate (${exGpuInf.gold||0}/${exGpuInf.built})`, pct:Math.round((exGpuInf.gold||0)/(exGpuInf.built)*100), cls:'amber' } : null;
case 'ex_gpu_comp_gold': return (exGpuComp.built) ? { label:`Gold pass rate (${exGpuComp.gold||0}/${exGpuComp.built})`, pct:Math.round((exGpuComp.gold||0)/(exGpuComp.built)*100), cls:'amber' } : null;
default: return null;
}
}
// ─────────────────────────────────────────────────────────────
// Entry list (fetched from serve_dashboard.py)
// ─────────────────────────────────────────────────────────────
async function fetchEntries(nid) {
const loadDiv = document.getElementById('entryLoad');
try {
const res = await fetch(`/api/pipeline/entries?node=${encodeURIComponent(nid)}&limit=15`);
if (!res.ok) throw new Error('HTTP ' + res.status);
const data = await res.json();
if (!document.getElementById('entryLoad')) return;
let html = `<div class="panel-sec-hd">Sample Entries (${fmt(data.total)} total)</div>`;
html += '<div class="entry-list">';
(data.entries || []).forEach(e => {
const repo = (e.repo || '').split('/').pop() || (e.instance_id||'').split('__')[0] || 'β€”';
const title = (e.title || e.instance_id || '').slice(0, 52);
const score = e.llm_quality_score != null ? e.llm_quality_score.toFixed(2) : '';
const iid = (e.instance_id || '').replace(/'/g, "\\'");
html += `<div class="entry-row" onclick="openEntry('${iid}')">
<span class="entry-repo">${repo}</span>
<span class="entry-title">${title}</span>
${score ? `<span class="entry-score">${score}</span>` : ''}
</div>`;
});
html += '</div>';
if (data.total > 15) {
html += `<button class="panel-browse-btn" onclick="window.open('/browser','_blank')">Browse all ${fmt(data.total)} entries</button>`;
}
const el = document.getElementById('entryLoad');
if (el) el.outerHTML = html;
} catch (err) {
const el = document.getElementById('entryLoad');
if (el) el.textContent = 'Could not load entries: ' + err.message;
}
}
function openEntry(iid) {
window.open('/browser#' + encodeURIComponent(iid), '_blank');
}
// ─────────────────────────────────────────────────────────────
// API + init
// ─────────────────────────────────────────────────────────────
async function loadStats() {
try {
const res = await fetch('/api/stats');
if (!res.ok) throw new Error('HTTP ' + res.status);
applyStats(await res.json());
setTimeout(() => drawArrows(_activeNid), 60);
} catch (e) {
const b = document.getElementById('liveBadge');
b.textContent = '● OFFLINE';
b.classList.remove('live');
}
}
document.querySelectorAll('.node').forEach(node => {
node.addEventListener('click', () => openPanel(node.dataset.nid));
});
document.getElementById('panelCloseBtn').addEventListener('click', closePanel);
window.addEventListener('load', () => { loadStats(); setTimeout(() => drawArrows(null), 80); });
window.addEventListener('resize', () => drawArrows(_activeNid));
</script>
</body>
</html>