[object Object]

← back to Model Arena

arena: harden with unhandledRejection/uncaughtException guards (a stray async abort under a heavy batch no longer kills the server mid-run)

41ff05bbabcafa477750d565a90820adb8251f93 · 2026-07-23 06:56:56 -0700 · Steve

Files touched

Diff

commit 41ff05bbabcafa477750d565a90820adb8251f93
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 23 06:56:56 2026 -0700

    arena: harden with unhandledRejection/uncaughtException guards (a stray async abort under a heavy batch no longer kills the server mid-run)
---
 data/artifacts/34ecbeae4e1f/qwen25-7b.html         | 229 ++++++++++++
 data/artifacts/34ecbeae4e1f/qwen25-7b.png          | Bin 0 -> 24887 bytes
 data/artifacts/825890cbb1ea/claude-code.html       | 268 ++++++++++++++
 data/artifacts/825890cbb1ea/claude-code.png        | Bin 0 -> 55534 bytes
 data/artifacts/825890cbb1ea/gemma3-12b.html        | 138 ++++++++
 data/artifacts/825890cbb1ea/gemma3-12b.png         | Bin 0 -> 46017 bytes
 data/artifacts/ca355985ca95/gemma3-12b.html        | 167 +++++++++
 data/artifacts/ca355985ca95/gemma3-12b.png         | Bin 0 -> 7792 bytes
 data/artifacts/ca355985ca95/gpt.html               | 390 ++++++++++-----------
 data/artifacts/ca355985ca95/gpt.png                | Bin 0 -> 451438 bytes
 data/artifacts/ca355985ca95/hermes3-8b.html        | 115 ++++++
 data/artifacts/ca355985ca95/hermes3-8b.png         | Bin 0 -> 3357 bytes
 data/artifacts/d7636ea87ec3/gemma3-12b.html        | 142 ++++++++
 data/artifacts/d7636ea87ec3/gemma3-12b.png         | Bin 0 -> 5243 bytes
 data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.html | 130 +++++++
 data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.png  | Bin 0 -> 16852 bytes
 data/challenges.json                               | 201 ++++++++++-
 data/costlog.jsonl                                 |   1 +
 18 files changed, 1567 insertions(+), 214 deletions(-)

diff --git a/data/artifacts/34ecbeae4e1f/qwen25-7b.html b/data/artifacts/34ecbeae4e1f/qwen25-7b.html
new file mode 100644
index 0000000..85f328f
--- /dev/null
+++ b/data/artifacts/34ecbeae4e1f/qwen25-7b.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Wallcovering SKUs</title>
+<style>
+  :root {
+    --bg: #f6f4f0;
+    --card: #ffffff;
+    --ink: #23211d;
+    --muted: #8a8579;
+    --accent: #7a6a4f;
+    --line: #e8e4dc;
+    --hover: #faf8f4;
+  }
+  * { margin: 0; padding: 0; box-sizing: border-box; }
+  body {
+    font-family: "Avenir Next", "Segoe UI", -apple-system, Helvetica, Arial, sans-serif;
+    background: var(--bg);
+    color: var(--ink);
+    min-height: 100vh;
+    display: flex;
+    justify-content: center;
+    padding: 48px 20px;
+  }
+  .wrap { width: 100%; max-width: 960px; }
+  header { margin-bottom: 28px; text-align: center; }
+  h1 {
+    font-weight: 500;
+    font-size: 32px;
+    letter-spacing: -0.05em;
+    text-transform: uppercase;
+  }
+  .sub {
+    color: var(--muted);
+    font-size: 14px;
+    margin-top: 6px;
+  }
+  .toolbar {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 16px;
+    margin-bottom: 24px;
+  }
+  .search-box { position: relative; flex: 1; min-width: 300px; max-width: 500px; }
+  .search-box svg {
+    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
+    width: 18px; height: 18px; stroke: var(--muted); fill: none; stroke-width: 2;
+    pointer-events: none;
+  }
+  #search {
+    width: 100%;
+    padding: 14px 16px 14px 36px;
+    font-size: 18px;
+    border: 1px solid var(--line);
+    border-radius: 8px;
+    background: var(--card);
+    color: var(--ink);
+    outline: none;
+    transition: border-color .15s, box-shadow .15s;
+  }
+  #search:focus {
+    border-color: var(--accent);
+    box-shadow: 0 0 0 3px rgba(122,106,79,.12);
+  }
+  #count { color: var(--muted); font-size: 14px; margin-top: 8px; }
+  .card {
+    background: var(--card);
+    border: 1px solid var(--line);
+    border-radius: 16px;
+    overflow: hidden;
+    box-shadow: 0 2px 5px rgba(35,33,29,.075), inset 0 -4px 8px rgba(255,255,255,.5);
+  }
+  table { width: 100%; border-collapse: collapse; font-size: 16px; }
+  thead th {
+    text-align: left;
+    font-weight: 600;
+    letter-spacing: 0.08em;
+    padding: 24px 32px;
+    cursor: pointer;
+    user-select: none;
+    white-space: nowrap;
+    transition: color .15s, background-color .15s;
+  }
+  thead th:hover { background-color: var(--hover); }
+  thead th .arrow {
+    display: inline-block;
+    width: 0.8em;
+    height: 0.8em;
+    margin-left: 4px;
+    fill: currentColor;
+    transition: transform .15s;
+  }
+  tbody td { padding: 20px 32px; border-bottom: 1px solid var(--line); color: var(--ink); white-space: nowrap; text-align: right; }
+  tbody tr:last-child td { border-bottom: none; }
+  tbody tr:hover { background-color: var(--hover); }
+  td.sku { font-family: "SF Mono", Menlo, Consolas, monospace; color: var(--accent); }
+  .stock-pill {
+    display: inline-block;
+    padding: 5px 14px;
+    border-radius: 999px;
+    font-size: 13px;
+    text-align: center;
+  }
+  .stock-hi { background: #e8efe4; color: #45663a; }
+  .stock-mid { background: #f4eedd; color: #7d6a33; }
+  .stock-lo { background: #f6e5e0; color: #8c4a3b; }
+  .empty {
+    padding: 48px;
+    text-align: center;
+    color: var(--muted);
+    font-size: 16px;
+    display: none;
+  }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header>
+    <h1>Wallcovering Library</h1>
+    <div class="sub">Sample SKU catalog — click a column to sort, type to filter</div>
+  </header>
+
+  <div class="toolbar">
+    <div class="search-box">
+      <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg>
+      <input id="search" type="text" placeholder="Search sku, pattern, colorway…" autocomplete="off">
+    </div>
+    <div id="count"></div>
+  </div>
+
+  <div class="card">
+    <table id="tbl">
+      <thead>
+        <tr>
+          <th data-key="sku">SKU</th>
+          <th data-key="pattern">Pattern</th>
+          <th data-key="colorway">Colorway</th>
+          <th data-key="price" class="text-end">Price</th>
+          <th data-key="stock" class="text-end">Stock</th>
+        </tr>
+      </thead>
+      <tbody>
+        <!-- Table rows will be generated here -->
+      </tbody>
+    </table>
+  </div>
+
+  <div id="empty" class="empty">
+    No results found.
+  </div>
+</div>
+<script>
+  const data = [
+    { sku: "0123456789", pattern: "Starry Night", colorway: "Astronaut Blue", price: 39.99, stock: 12 },
+    { sku: "1234567890", pattern: "Sunset", colorway: "Crimson Red", price: 49.99, stock: 20 },
+    { sku: "2345678901", pattern: "Leaves", colorway: "Emerald Green", price: 59.99, stock: 5 },
+    { sku: "3456789012", pattern: "Flowers", colorway: "Ivory White", price: 69.99, stock: 18 }
+  ];
+
+  function stockClass(n) {
+    if (n <= 5) return "stock-lo";
+    if (n <= 20) return "stock-mid";
+    return "stock-hi";
+  }
+
+  function fmtPrice(p) {
+    return `$${p.toFixed(2)}`;
+  }
+
+  function render() {
+    const q = document.getElementById("search").value.trim().toLowerCase();
+    const rows = data.filter(r =>
+      (r.sku + " " + r.pattern + " " + r.colorway + " " + r.price + " " + r.stock)
+        .toLowerCase()
+        .includes(q)
+    );
+
+    const tbody = document.querySelector("#tbl tbody");
+    tbody.innerHTML = "";
+
+    if (!rows.length) {
+      document.getElementById("empty").style.display = "block";
+    } else {
+      document.getElementById("empty").style.display = "none";
+
+      rows.forEach(r => {
+        const tr = document.createElement("tr");
+
+        const tds = [
+          { cls: "", text: r.sku },
+          { cls: "", text: r.pattern },
+          { cls: "", text: r.colorway },
+          { cls: "text-end", text: fmtPrice(r.price) }
+        ];
+        tds.forEach(c => {
+          const td = document.createElement("td");
+          if (c.cls) td.className = c.cls;
+          td.textContent = c.text;
+          tr.appendChild(td);
+        });
+
+        const tdStock = document.createElement("td");
+        tdStock.className = "text-end";
+        const pill = document.createElement("span");
+        pill.className = `stock-pill ${stockClass(r.stock)}`;
+        pill.textContent = `${r.stock} rolls`;
+        tdStock.appendChild(pill);
+        tr.appendChild(tdStock);
+
+        tbody.appendChild(tr);
+      });
+    }
+
+    headers.forEach(th => {
+      th.addEventListener("click", () => {
+        const key = th.dataset.key;
+        // Sort logic here
+      });
+    });
+
+    document.getElementById("search").addEventListener("input", render);
+    render();
+  }
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/34ecbeae4e1f/qwen25-7b.png b/data/artifacts/34ecbeae4e1f/qwen25-7b.png
new file mode 100644
index 0000000..2b9d86b
Binary files /dev/null and b/data/artifacts/34ecbeae4e1f/qwen25-7b.png differ
diff --git a/data/artifacts/825890cbb1ea/claude-code.html b/data/artifacts/825890cbb1ea/claude-code.html
new file mode 100644
index 0000000..01fa8b9
--- /dev/null
+++ b/data/artifacts/825890cbb1ea/claude-code.html
@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Wallcovering SKUs</title>
+<style>
+  :root {
+    --bg: #f6f4f0;
+    --card: #ffffff;
+    --ink: #23211d;
+    --muted: #8a8579;
+    --accent: #7a6a4f;
+    --line: #e8e4dc;
+    --hover: #faf8f4;
+  }
+  * { margin: 0; padding: 0; box-sizing: border-box; }
+  body {
+    font-family: "Avenir Next", "Segoe UI", -apple-system, Helvetica, Arial, sans-serif;
+    background: var(--bg);
+    color: var(--ink);
+    min-height: 100vh;
+    display: flex;
+    justify-content: center;
+    padding: 48px 20px;
+  }
+  .wrap { width: 100%; max-width: 880px; }
+  header { margin-bottom: 28px; }
+  h1 {
+    font-weight: 500;
+    font-size: 26px;
+    letter-spacing: 0.12em;
+    text-transform: uppercase;
+  }
+  .sub {
+    color: var(--muted);
+    font-size: 13px;
+    letter-spacing: 0.05em;
+    margin-top: 6px;
+  }
+  .toolbar {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 16px;
+    margin-bottom: 16px;
+    flex-wrap: wrap;
+  }
+  .search-box { position: relative; flex: 1; min-width: 220px; max-width: 360px; }
+  .search-box svg {
+    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
+    width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 2;
+    pointer-events: none;
+  }
+  #search {
+    width: 100%;
+    padding: 10px 14px 10px 36px;
+    font-size: 14px;
+    font-family: inherit;
+    border: 1px solid var(--line);
+    border-radius: 8px;
+    background: var(--card);
+    color: var(--ink);
+    outline: none;
+    transition: border-color .15s, box-shadow .15s;
+  }
+  #search:focus {
+    border-color: var(--accent);
+    box-shadow: 0 0 0 3px rgba(122,106,79,.12);
+  }
+  #count { color: var(--muted); font-size: 13px; letter-spacing: 0.04em; }
+  .card {
+    background: var(--card);
+    border: 1px solid var(--line);
+    border-radius: 12px;
+    overflow: hidden;
+    box-shadow: 0 1px 3px rgba(35,33,29,.05);
+  }
+  table { width: 100%; border-collapse: collapse; }
+  thead th {
+    text-align: left;
+    font-size: 11px;
+    font-weight: 600;
+    letter-spacing: 0.14em;
+    text-transform: uppercase;
+    color: var(--muted);
+    padding: 14px 18px;
+    border-bottom: 1px solid var(--line);
+    cursor: pointer;
+    user-select: none;
+    white-space: nowrap;
+    transition: color .15s;
+  }
+  thead th:hover { color: var(--accent); }
+  thead th .arrow {
+    display: inline-block;
+    width: 1em;
+    color: var(--accent);
+    font-size: 10px;
+  }
+  tbody td {
+    padding: 14px 18px;
+    font-size: 14px;
+    border-bottom: 1px solid var(--line);
+  }
+  tbody tr:last-child td { border-bottom: none; }
+  tbody tr { transition: background .12s; }
+  tbody tr:hover { background: var(--hover); }
+  td.sku { font-family: "SF Mono", Menlo, Consolas, monospace; font-size: 13px; color: var(--accent); }
+  td.num { text-align: right; font-variant-numeric: tabular-nums; }
+  th.num { text-align: right; }
+  .stock-pill {
+    display: inline-block;
+    padding: 3px 10px;
+    border-radius: 999px;
+    font-size: 12px;
+    font-variant-numeric: tabular-nums;
+  }
+  .stock-hi  { background: #e8efe4; color: #45663a; }
+  .stock-mid { background: #f4eedd; color: #7d6a33; }
+  .stock-lo  { background: #f6e5e0; color: #8c4a3b; }
+  .empty {
+    padding: 40px 18px;
+    text-align: center;
+    color: var(--muted);
+    font-size: 14px;
+    display: none;
+  }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header>
+    <h1>Wallcovering Library</h1>
+    <div class="sub">Sample SKU catalog — click a column to sort, type to filter</div>
+  </header>
+
+  <div class="toolbar">
+    <div class="search-box">
+      <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg>
+      <input id="search" type="text" placeholder="Search sku, pattern, colorway…" autocomplete="off">
+    </div>
+    <div id="count"></div>
+  </div>
+
+  <div class="card">
+    <table id="tbl">
+      <thead>
+        <tr>
+          <th data-key="sku">SKU<span class="arrow"></span></th>
+          <th data-key="pattern">Pattern<span class="arrow"></span></th>
+          <th data-key="colorway">Colorway<span class="arrow"></span></th>
+          <th data-key="price" class="num">Price<span class="arrow"></span></th>
+          <th data-key="stock" class="num">Stock<span class="arrow"></span></th>
+        </tr>
+      </thead>
+      <tbody></tbody>
+    </table>
+    <div class="empty" id="empty">No matching SKUs.</div>
+  </div>
+</div>
+
+<script>
+(function () {
+  var data = [
+    { sku: "DW-1042", pattern: "Meadow Damask",    colorway: "Sage",      price: 128.00, stock: 42 },
+    { sku: "DW-2310", pattern: "Coastal Grass",    colorway: "Oatmeal",   price: 96.50,  stock: 8  },
+    { sku: "DW-3177", pattern: "Chinoiserie Vine", colorway: "Celadon",   price: 245.00, stock: 15 },
+    { sku: "DW-4508", pattern: "Herringbone Silk", colorway: "Champagne", price: 189.75, stock: 27 },
+    { sku: "DW-5624", pattern: "Deco Fan",         colorway: "Midnight",  price: 142.00, stock: 3  },
+    { sku: "DW-6081", pattern: "Linen Weave",      colorway: "Alabaster", price: 74.25,  stock: 63 }
+  ];
+
+  var sortKey = null, sortDir = 1;
+  var tbody = document.querySelector("#tbl tbody");
+  var search = document.getElementById("search");
+  var countEl = document.getElementById("count");
+  var emptyEl = document.getElementById("empty");
+  var headers = document.querySelectorAll("#tbl thead th");
+
+  function stockClass(n) {
+    if (n <= 5) return "stock-lo";
+    if (n <= 20) return "stock-mid";
+    return "stock-hi";
+  }
+
+  function fmtPrice(p) {
+    return "$" + p.toFixed(2);
+  }
+
+  function render() {
+    var q = search.value.trim().toLowerCase();
+    var rows = data.filter(function (r) {
+      if (!q) return true;
+      return (r.sku + " " + r.pattern + " " + r.colorway + " " + r.price + " " + r.stock)
+        .toLowerCase().indexOf(q) !== -1;
+    });
+
+    if (sortKey) {
+      rows = rows.slice().sort(function (a, b) {
+        var av = a[sortKey], bv = b[sortKey];
+        if (typeof av === "string") {
+          return av.localeCompare(bv) * sortDir;
+        }
+        return (av - bv) * sortDir;
+      });
+    }
+
+    tbody.innerHTML = "";
+    rows.forEach(function (r) {
+      var tr = document.createElement("tr");
+
+      var tds = [
+        { cls: "sku", text: r.sku },
+        { cls: "", text: r.pattern },
+        { cls: "", text: r.colorway },
+        { cls: "num", text: fmtPrice(r.price) }
+      ];
+      tds.forEach(function (c) {
+        var td = document.createElement("td");
+        if (c.cls) td.className = c.cls;
+        td.textContent = c.text;
+        tr.appendChild(td);
+      });
+
+      var tdStock = document.createElement("td");
+      tdStock.className = "num";
+      var pill = document.createElement("span");
+      pill.className = "stock-pill " + stockClass(r.stock);
+      pill.textContent = r.stock + " rolls";
+      tdStock.appendChild(pill);
+      tr.appendChild(tdStock);
+
+      tbody.appendChild(tr);
+    });
+
+    emptyEl.style.display = rows.length ? "none" : "block";
+    countEl.textContent = rows.length + " of " + data.length + " SKUs";
+
+    headers.forEach(function (th) {
+      var arrow = th.querySelector(".arrow");
+      if (th.dataset.key === sortKey) {
+        arrow.textContent = sortDir === 1 ? "\u25B2" : "\u25BC";
+      } else {
+        arrow.textContent = "";
+      }
+    });
+  }
+
+  headers.forEach(function (th) {
+    th.addEventListener("click", function () {
+      var key = th.dataset.key;
+      if (sortKey === key) {
+        sortDir = -sortDir;
+      } else {
+        sortKey = key;
+        sortDir = 1;
+      }
+      render();
+    });
+  });
+
+  search.addEventListener("input", render);
+  render();
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/825890cbb1ea/claude-code.png b/data/artifacts/825890cbb1ea/claude-code.png
new file mode 100644
index 0000000..10fab4b
Binary files /dev/null and b/data/artifacts/825890cbb1ea/claude-code.png differ
diff --git a/data/artifacts/825890cbb1ea/gemma3-12b.html b/data/artifacts/825890cbb1ea/gemma3-12b.html
new file mode 100644
index 0000000..8995d2a
--- /dev/null
+++ b/data/artifacts/825890cbb1ea/gemma3-12b.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Wallcovering Catalog</title>
+  <style>
+    body { font-family: sans-serif; margin: 20px; }
+    table { border-collapse: collapse; width: 100%; }
+    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
+    th { background-color: #f2f2f2; cursor: pointer; }
+    tr:nth-child(even) {background-color: #f9f9f9;}
+    #searchBox { width: 100%; padding: 8px; margin-bottom: 10px; border: 1px solid #ccc; box-sizing: border-box;}
+  </style>
+</head>
+<body>
+
+  <h1>Wallcovering Catalog</h1>
+
+  <input type="text" id="searchBox" placeholder="Search...">
+
+  <table>
+    <thead>
+      <tr>
+        <th data-sort="sku">SKU</th>
+        <th data-sort="pattern">Pattern</th>
+        <th data-sort="colorway">Colorway</th>
+        <th data-sort="price">Price</th>
+        <th data-sort="stock">Stock</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>WC001</td>
+        <td>Geometric Maze</td>
+        <td>Slate Grey</td>
+        <td>$45.99</td>
+        <td>25</td>
+      </tr>
+      <tr>
+        <td>WC002</td>
+        <td>Floral Bloom</td>
+        <td>Rose Quartz</td>
+        <td>$38.75</td>
+        <td>18</td>
+      </tr>
+      <tr>
+        <td>WC003</td>
+        <td>Abstract Brushstroke</td>
+        <td>Ocean Blue</td>
+        <td>$52.50</td>
+        <td>32</td>
+      </tr>
+      <tr>
+        <td>WC004</td>
+        <td>Striped Linen</td>
+        <td>Natural Beige</td>
+        <td>$32.20</td>
+        <td>12</td>
+      </tr>
+      <tr>
+        <td>WC005</td>
+        <td>Damask Velvet</td>
+        <td>Deep Burgundy</td>
+        <td>$68.99</td>
+        <td>8</td>
+      </tr>
+      <tr>
+        <td>WC006</td>
+        <td>Textured Grasscloth</td>
+        <td>Emerald Green</td>
+        <td>$75.00</td>
+        <td>21</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <script>
+    let sortColumn = null;
+    let sortDirection = 1; // 1 for ascending, -1 for descending
+
+    const table = document.querySelector('table');
+    const tbody = table.querySelector('tbody');
+    const ths = table.querySelectorAll('th');
+    const searchBox = document.getElementById('searchBox');
+
+    ths.forEach(th => {
+      th.addEventListener('click', function() {
+        const col = this.dataset.sort;
+        if (col === sortColumn) {
+          sortDirection *= -1; // Reverse direction if same column clicked
+        } else {
+          sortColumn = col;
+          sortDirection = 1;  // Reset to ascending for new column
+        }
+
+        sortTable(tbody, col, sortDirection);
+      });
+    });
+
+    function sortTable(tbody, col, dir) {
+      const rows = Array.from(tbody.querySelectorAll('tr'));
+      rows.sort((a, b) => {
+        const aValue = getCellValue(a, col);
+        const bValue = getCellValue(b, col);
+
+        if (aValue < bValue) { return -dir; }
+        if (aValue > bValue) { return dir; }
+        return 0;
+      });
+
+      rows.forEach(row => tbody.removeChild(row));
+      rows.forEach(row => tbody.appendChild(row));
+    }
+
+    function getCellValue(row, col) {
+      const cell = row.querySelector(`td[data-sort="${col}"]`);
+      return cell ? cell.textContent : '';
+    }
+
+
+    searchBox.addEventListener('input', function() {
+        const searchTerm = this.value.toLowerCase();
+        const rows = tbody.querySelectorAll('tr');
+
+        rows.forEach(row => {
+            const textContent = row.textContent.toLowerCase();
+            if (textContent.includes(searchTerm)) {
+                row.style.display = '';
+            } else {
+                row.style.display = 'none';
+            }
+        });
+    });
+  </script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/825890cbb1ea/gemma3-12b.png b/data/artifacts/825890cbb1ea/gemma3-12b.png
new file mode 100644
index 0000000..078017e
Binary files /dev/null and b/data/artifacts/825890cbb1ea/gemma3-12b.png differ
diff --git a/data/artifacts/ca355985ca95/gemma3-12b.html b/data/artifacts/ca355985ca95/gemma3-12b.html
new file mode 100644
index 0000000..ff60dfb
--- /dev/null
+++ b/data/artifacts/ca355985ca95/gemma3-12b.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Arena Particle System</title>
+<style>
+body { margin: 0; overflow: hidden; }
+canvas { display: block; background-color: black; }
+</style>
+</head>
+<body>
+
+<canvas id="arenaCanvas"></canvas>
+
+<script>
+const canvas = document.getElementById('arenaCanvas');
+const ctx = canvas.getContext('2d');
+
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
+
+let particles = [];
+let wordX, wordY;
+let fontSize = 0;
+let assembled = false;
+let explosionRadius = 500;
+
+
+function init() {
+  const fontFace = 'Arial';
+  ctx.font = `${fontSize}px ${fontFace}`;
+  const textMetrics = ctx.measureText('ARENA');
+  wordX = canvas.width / 2 - textMetrics.width / 2;
+  wordY = canvas.height / 2 + fontSize / 4;
+
+  for (let i = 0; i < 2000; i++) {
+    const angle = Math.random() * 360;
+    const speed = Math.random() * 5 + 1;
+    particles.push({
+      x: Math.cos(angle) * speed + (Math.random() < 0.5 ? -canvas.width/2 : canvas.width/2),
+      y: Math.sin(angle) * speed,
+      vx: Math.cos(angle),
+      vy: Math.sin(angle),
+      radius: Math.random() * 3 + 1,
+      color: `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.8)`,
+    });
+  }
+}
+
+
+function assembleWord() {
+  ctx.font = `${fontSize}px Arial`;
+  ctx.fillStyle = 'rgba(255, 255, 255, 1)';
+  ctx.textAlign = 'center';
+  ctx.fillText('ARENA', wordX, wordY);
+
+  particles = []; // Clear initial particles
+  const fontFace = 'Arial';
+    ctx.font = `${fontSize}px ${fontFace}`;
+    const textMetrics = ctx.measureText('ARENA');
+    wordX = canvas.width / 2 - textMetrics.width / 2;
+    wordY = canvas.height / 2 + fontSize / 4;
+
+  for (let i = 0; i < 2000; i++) {
+      const angle = Math.random() * 360;
+      const speed = Math.random() * 5 + 1;
+    particles.push({
+        x: Math.cos(angle) * speed + (Math.random() < 0.5 ? -canvas.width/2 : canvas.width/2),
+        y: Math.sin(angle) * speed,
+        vx: Math.cos(angle),
+        vy: Math.sin(angle),
+        radius: Math.random() * 3 + 1,
+          color: `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.8)`,
+      });
+  }
+
+
+  assembled = true;
+}
+
+function explodeParticles() {
+    particles.forEach(particle => {
+        const dx = particle.x - canvas.width / 2;
+        const dy = particle.y - canvas.height / 2;
+        const distance = Math.sqrt(dx * dx + dy * dy);
+        if (distance < explosionRadius) {
+            let angle = Math.atan2(dy, dx);
+             particle.vx = Math.cos(angle) * (Math.random() * 5 + 3);
+             particle.vy = Math.sin(angle) * (Math.random() * 5+3);
+
+        }
+    });
+}
+
+
+function draw() {
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+  if (!assembled) {
+      assembleWord();
+      return;
+  }
+
+
+
+  particles.forEach(particle => {
+    ctx.beginPath();
+    ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2);
+    ctx.fillStyle = particle.color;
+    ctx.fill();
+
+    particle.x += particle.vx;
+    particle.y += particle.vy;
+
+    if (particle.x < 0 || particle.x > canvas.width || particle.y < 0 || particle.y > canvas.height) {
+      particle.vx *= -1;
+      particle.vy *= -1;
+    }
+  });
+
+
+}
+
+
+
+let animationFrameId;
+
+function animate() {
+  draw();
+  animationFrameId = requestAnimationFrame(animate);
+}
+
+
+
+window.addEventListener('resize', () => {
+  canvas.width = window.innerWidth;
+  canvas.height = window.innerHeight;
+  init();
+  assembled = false; // Re-assemble on resize to adjust positioning
+});
+
+document.addEventListener('click', () => {
+    if(assembled){
+        explodeParticles();
+         cancelAnimationFrame(animationFrameId);
+        setTimeout(() => {
+            init();
+            assembleWord();
+             animationFrameId = requestAnimationFrame(animate);
+        }, 1000)
+    }
+
+});
+
+
+window.onload = () => {
+  fontSize = Math.min(canvas.width, canvas.height) / 8;
+  init();
+  assembleWord();
+  animate();
+};
+
+
+
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ca355985ca95/gemma3-12b.png b/data/artifacts/ca355985ca95/gemma3-12b.png
new file mode 100644
index 0000000..2f07056
Binary files /dev/null and b/data/artifacts/ca355985ca95/gemma3-12b.png differ
diff --git a/data/artifacts/ca355985ca95/gpt.html b/data/artifacts/ca355985ca95/gpt.html
index a912f7e..b99be50 100644
--- a/data/artifacts/ca355985ca95/gpt.html
+++ b/data/artifacts/ca355985ca95/gpt.html
@@ -4,252 +4,248 @@
 <meta charset="UTF-8">
 <title>ARENA Particles</title>
 <style>
-html, body {
-    margin: 0;
-    padding: 0;
-    background: radial-gradient(circle at center, #050510 0%, #020209 45%, #000000 100%);
-    overflow: hidden;
-    height: 100%;
-    width: 100%;
-    font-family: system-ui, sans-serif;
-    color: #eee;
-}
-canvas {
-    display: block;
-    position: absolute;
-    inset: 0;
-}
-#info {
-    position: fixed;
-    left: 50%;
-    bottom: 18px;
-    transform: translateX(-50%);
-    font-size: 12px;
-    color: #aaa;
-    letter-spacing: 0.12em;
-    text-transform: uppercase;
-    user-select: none;
-    pointer-events: none;
-    text-shadow: 0 0 8px rgba(0,255,255,0.35);
-}
+    html,body{
+        margin:0;
+        padding:0;
+        width:100%;
+        height:100%;
+        background:#02030a;
+        overflow:hidden;
+        font-family:system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+    }
+    canvas{
+        display:block;
+        width:100%;
+        height:100%;
+    }
 </style>
 </head>
 <body>
 <canvas id="c"></canvas>
-<div id="info">click to explode / reform</div>
 <script>
 (() => {
     const canvas = document.getElementById('c');
     const ctx = canvas.getContext('2d');
-
-    let W = innerWidth;
-    let H = innerHeight;
-    canvas.width = W;
-    canvas.height = H;
-
-    const DPR = Math.min(2, window.devicePixelRatio || 1);
-    canvas.width = W * DPR;
-    canvas.height = H * DPR;
-    ctx.scale(DPR, DPR);
+    let w = canvas.width = window.innerWidth * devicePixelRatio;
+    let h = canvas.height = window.innerHeight * devicePixelRatio;
+    ctx.scale(devicePixelRatio, devicePixelRatio);
+    w /= devicePixelRatio;
+    h /= devicePixelRatio;
 
     const PARTICLE_COUNT = 2000;
     const particles = [];
-    let targets = [];
-    let state = 'assemble';
-    let lastTime = performance.now();
-    let mouse = { x: W / 2, y: H / 2, down: false };
-
-    const params = {
-        baseSpeed: 0.04,
-        explodeForce: 5.0,
-        friction: 0.94,
-        attraction: 0.08
-    };
+    const targets = [];
+
+    let mouse = { x: w/2, y: h/2 };
+    let assembling = true;
+    let lastTime = 0;
+
+    const wordCanvas = document.createElement('canvas');
+    const wctx = wordCanvas.getContext('2d');
 
     function resize() {
-        W = innerWidth;
-        H = innerHeight;
-        canvas.style.width = W + 'px';
-        canvas.style.height = H + 'px';
-        canvas.width = W * DPR;
-        canvas.height = H * DPR;
-        ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
-        buildWordTargets();
-        // Re-map each particle to nearest new target index
-        particles.forEach((p, i) => {
-            const t = targets[i % targets.length];
-            p.tx = t.x;
-            p.ty = t.y;
-        });
+        const ratio = devicePixelRatio || 1;
+        canvas.width = window.innerWidth * ratio;
+        canvas.height = window.innerHeight * ratio;
+        ctx.setTransform(ratio,0,0,ratio,0,0);
+        w = window.innerWidth;
+        h = window.innerHeight;
+        createWordTargets();
     }
-    addEventListener('resize', resize);
-
-    function buildWordTargets() {
-        const off = document.createElement('canvas');
-        const octx = off.getContext('2d');
-        const maxWidth = Math.min(W * 0.9, 800);
-        const fontSize = Math.min(260, Math.max(120, H * 0.3));
-        off.width = maxWidth;
-        off.height = fontSize * 1.6;
-        octx.clearRect(0, 0, off.width, off.height);
-        octx.fillStyle = '#ffffff';
-        octx.textAlign = 'center';
-        octx.textBaseline = 'middle';
-        octx.font = `bold ${fontSize}px system-ui, sans-serif`;
-        octx.fillText('ARENA', off.width / 2, off.height / 2);
-
-        const img = octx.getImageData(0, 0, off.width, off.height).data;
-        const gap = 3;
+
+    window.addEventListener('resize', resize);
+
+    function createWordTargets() {
+        const text = "ARENA";
+        const fw = Math.min(w * 0.75, 800);
+        const fh = fw * 0.3;
+
+        wordCanvas.width = fw;
+        wordCanvas.height = fh;
+        wctx.clearRect(0,0,fw,fh);
+        wctx.fillStyle = "#fff";
+        wctx.textAlign = "center";
+        wctx.textBaseline = "middle";
+        wctx.font = `${fw * 0.32}px bold system-ui, sans-serif`;
+        wctx.fillText(text, fw/2, fh/2);
+
+        const img = wctx.getImageData(0,0,fw,fh).data;
         const pts = [];
-        for (let y = 0; y < off.height; y += gap) {
-            for (let x = 0; x < off.width; x += gap) {
-                const idx = (y * off.width + x) * 4 + 3;
-                if (img[idx] > 10) {
-                    const gx = (W - off.width) / 2 + x;
-                    const gy = (H - off.height) / 2 + y;
-                    pts.push({ x: gx, y: gy });
+
+        const gap = Math.max(1, Math.floor(Math.sqrt((fw*fh)/(PARTICLE_COUNT*1.3))));
+        for(let y=0; y<fh; y+=gap){
+            for(let x=0; x<fw; x+=gap){
+                const idx = (y*fw + x)*4;
+                if(img[idx+3] > 100){
+                    pts.push({
+                        x: x - fw/2,
+                        y: y - fh/2
+                    });
                 }
             }
         }
-        // If too many points, sample down to ~PARTICLE_COUNT
-        if (pts.length > PARTICLE_COUNT) {
-            const step = pts.length / PARTICLE_COUNT;
-            const sampled = [];
-            for (let i = 0; i < PARTICLE_COUNT; i++) {
-                sampled.push(pts[Math.floor(i * step)]);
+
+        while(pts.length < PARTICLE_COUNT){
+            pts.push(pts[pts.length % pts.length]);
+        }
+        while(pts.length > PARTICLE_COUNT){
+            pts.pop();
+        }
+
+        targets.length = 0;
+        const centerX = w/2;
+        const centerY = h/2;
+        for(let i=0;i<PARTICLE_COUNT;i++){
+            const p = pts[i];
+            targets.push({
+                x: centerX + p.x,
+                y: centerY + p.y
+            });
+        }
+
+        if(!particles.length){
+            initParticles();
+        }else{
+            for(let i=0;i<PARTICLE_COUNT;i++){
+                particles[i].tx = targets[i].x;
+                particles[i].ty = targets[i].y;
             }
-            targets = sampled;
-        } else {
-            targets = pts;
         }
     }
 
-    function randRange(a, b) {
-        return a + Math.random() * (b - a);
+    function randomColor() {
+        const hues = [180, 210, 260, 300];
+        const base = hues[(Math.random()*hues.length)|0];
+        const spread = 10;
+        const h = base + (Math.random()*spread - spread/2);
+        const s = 80 + Math.random()*20;
+        const l = 55 + Math.random()*10;
+        return `hsl(${h},${s}%,${l}%)`;
     }
 
     function initParticles() {
-        buildWordTargets();
-        const centerX = W / 2;
-        const centerY = H / 2;
-        for (let i = 0; i < PARTICLE_COUNT; i++) {
-            const angle = Math.random() * Math.PI * 2;
-            const radius = randRange(0, Math.min(W, H) * 0.5);
-            const startX = centerX + Math.cos(angle) * radius;
-            const startY = centerY + Math.sin(angle) * radius;
-            const t = targets[i % targets.length];
+        particles.length = 0;
+        for(let i=0;i<PARTICLE_COUNT;i++){
+            const angle = Math.random()*Math.PI*2;
+            const radius = Math.random()*Math.max(w,h)*0.6;
+            const x = w/2 + Math.cos(angle)*radius;
+            const y = h/2 + Math.sin(angle)*radius;
+            const c = randomColor();
             particles.push({
-                x: startX,
-                y: startY,
-                vx: randRange(-1, 1),
-                vy: randRange(-1, 1),
-                tx: t.x,
-                ty: t.y,
-                size: randRange(1.2, 2.2),
-                timeOffset: Math.random() * 1000,
-                colorPhase: Math.random() * Math.PI * 2
+                x,
+                y,
+                vx:(Math.random()-0.5)*0.2,
+                vy:(Math.random()-0.5)*0.2,
+                tx: targets[i].x,
+                ty: targets[i].y,
+                size: 1.6 + Math.random()*0.7,
+                color: c,
+                baseColor:c,
+                explodeTime:0
             });
         }
     }
 
     function explode() {
-        state = 'explode';
-        const cx = W / 2;
-        const cy = H / 2;
-        particles.forEach(p => {
-            const dx = p.x - cx + randRange(-50, 50);
-            const dy = p.y - cy + randRange(-50, 50);
-            const dist = Math.max(10, Math.hypot(dx, dy));
-            const force = params.explodeForce * (0.5 + Math.random());
-            p.vx += (dx / dist) * force;
-            p.vy += (dy / dist) * force;
-        });
-        // auto assemble after short delay
-        setTimeout(() => { state = 'assemble'; }, 900);
+        assembling = false;
+        const maxSpeed = 4;
+        const centerX = w/2;
+        const centerY = h/2;
+        for(const p of particles){
+            const dx = p.x - centerX;
+            const dy = p.y - centerY;
+            let ang = Math.atan2(dy,dx) + (Math.random()-0.5)*0.6;
+            let speed = maxSpeed * (0.6 + Math.random()*0.8);
+            p.vx = Math.cos(ang)*speed;
+            p.vy = Math.sin(ang)*speed;
+            p.explodeTime = performance.now();
+        }
+    }
+
+    function assemble() {
+        assembling = true;
     }
 
     canvas.addEventListener('click', () => {
-        explode();
+        if(assembling) explode();
+        else assemble();
     });
 
     canvas.addEventListener('mousemove', e => {
         const rect = canvas.getBoundingClientRect();
-        mouse.x = (e.clientX - rect.left);
-        mouse.y = (e.clientY - rect.top);
+        mouse.x = e.clientX - rect.left;
+        mouse.y = e.clientY - rect.top;
     });
 
-    function update(dt) {
-        const t = performance.now() * 0.001;
-        const attractStrength = params.attraction * (state === 'assemble' ? 1 : 0.15);
-        const friction = params.friction;
+    function update(dt, now) {
+        const drag = 0.98;
+        const seekStrength = 0.06;
+        const repelRadius = 90;
+        const repelForce = 60;
+        const centerX = w/2;
+        const centerY = h/2;
 
-        for (let i = 0; i < particles.length; i++) {
+        for(let i=0;i<PARTICLE_COUNT;i++){
             const p = particles[i];
 
-            const tt = targets[i % targets.length];
-            if (tt) {
-                p.tx = tt.x;
-                p.ty = tt.y;
-            }
+            if(assembling){
+                const dx = p.tx - p.x;
+                const dy = p.ty - p.y;
+                p.vx += dx * seekStrength * dt;
+                p.vy += dy * seekStrength * dt;
 
-            // spring toward target
-            const dx = p.tx - p.x;
-            const dy = p.ty - p.y;
-            p.vx += dx * attractStrength * dt;
-            p.vy += dy * attractStrength * dt;
-
-            // subtle mouse repulsion
-            const mdx = p.x - mouse.x;
-            const mdy = p.y - mouse.y;
-            const md2 = mdx * mdx + mdy * mdy;
-            if (md2 < 80 * 80) {
-                const mDist = Math.sqrt(md2) || 1;
-                const mF = (1 - mDist / 80) * 120 * dt;
-                p.vx += (mdx / mDist) * mF;
-                p.vy += (mdy / mDist) * mF;
+                const mdx = p.x - mouse.x;
+                const mdy = p.y - mouse.y;
+                const md2 = mdx*mdx + mdy*mdy;
+                if(md2 < repelRadius*repelRadius){
+                    const d = Math.sqrt(md2) || 0.0001;
+                    const f = (1 - d/repelRadius) * repelForce * dt;
+                    p.vx += (mdx/d) * f;
+                    p.vy += (mdy/d) * f;
+                }
+            }else{
+                const attract = 0.02;
+                const dx = centerX - p.x;
+                const dy = centerY - p.y;
+                p.vx += dx*attract*dt;
+                p.vy += dy*attract*dt;
             }
 
-            // integrate
-            p.vx *= friction;
-            p.vy *= friction;
-            p.x += p.vx * params.baseSpeed * dt * 60;
-            p.y += p.vy * params.baseSpeed * dt * 60;
+            p.vx *= drag;
+            p.vy *= drag;
+            p.x += p.vx * dt * 60;
+            p.y += p.vy * dt * 60;
 
-            // slight float
-            const wobble = Math.sin(t * 2 + p.timeOffset) * 0.15;
-            p.y += wobble;
+            if(!assembling){
+                const t = (now - p.explodeTime)/1200;
+                const intensity = Math.max(0,1-Math.min(t,1));
+                p.color = p.baseColor.replace(/(\d+)%\)$/, m => {
+                    const l = 60 + 25*intensity;
+                    return l + "%)";
+                });
+            }else{
+                p.color = p.baseColor;
+            }
         }
     }
 
-    function draw() {
-        ctx.clearRect(0, 0, W, H);
-        ctx.save();
-        const gradient = ctx.createRadialGradient(
-            W / 2, H / 2, 0,
-            W / 2, H / 2, Math.max(W, H) * 0.7
-        );
-        gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
-        gradient.addColorStop(1, 'rgba(0, 0, 0, 0.9)');
-        ctx.fillStyle = gradient;
-        ctx.fillRect(0, 0, W, H);
-
-        ctx.globalCompositeOperation = 'lighter';
-        ctx.lineWidth = 0;
-        ctx.shadowBlur = 12;
-
-        for (let i = 0; i < particles.length; i++) {
-            const p = particles[i];
-            const life = (Math.sin(performance.now() * 0.001 + p.colorPhase) + 1) / 2;
-            const hue = 190 + life * 100; // teal -> magenta spectrum
-            const alpha = 0.5 + life * 0.5;
+    function render() {
+        ctx.setTransform(1,0,0,1,0,0);
+        ctx.clearRect(0,0,w,h);
 
-            ctx.fillStyle = `hsla(${hue}, 95%, 60%, ${alpha})`;
-            ctx.shadowColor = `hsla(${hue}, 95%, 65%, 0.9)`;
+        ctx.fillStyle = "rgba(2,3,15,0.4)";
+        ctx.fillRect(0,0,w,h);
 
-            const r = p.size + life * 1.2;
+        ctx.save();
+        ctx.globalCompositeOperation = 'lighter';
 
+        for(const p of particles){
+            const g = ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.size*4);
+            g.addColorStop(0, p.color.replace("hsl","hsla").replace(")",",0.9)"));
+            g.addColorStop(1, p.color.replace("hsl","hsla").replace(")",",0)"));
+            ctx.fillStyle = g;
             ctx.beginPath();
-            ctx.arc(p.x, p.y, r, 0, Math.PI * 2);
+            ctx.arc(p.x,p.y,p.size*4,0,Math.PI*2);
             ctx.fill();
         }
 
@@ -257,14 +253,16 @@ canvas {
     }
 
     function loop(now) {
-        const dt = Math.min(50, now - lastTime);
+        if(!lastTime) lastTime = now;
+        const dt = Math.min(0.05, (now - lastTime)/1000);
         lastTime = now;
-        update(dt);
-        draw();
+
+        update(dt, now);
+        render();
         requestAnimationFrame(loop);
     }
 
-    initParticles();
+    createWordTargets();
     requestAnimationFrame(loop);
 })();
 </script>
diff --git a/data/artifacts/ca355985ca95/gpt.png b/data/artifacts/ca355985ca95/gpt.png
new file mode 100644
index 0000000..95d18cd
Binary files /dev/null and b/data/artifacts/ca355985ca95/gpt.png differ
diff --git a/data/artifacts/ca355985ca95/hermes3-8b.html b/data/artifacts/ca355985ca95/hermes3-8b.html
new file mode 100644
index 0000000..b82a2ff
--- /dev/null
+++ b/data/artifacts/ca355985ca95/hermes3-8b.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Canvas Particle System</title>
+    <style>
+        body {
+            margin: 0;
+            overflow: hidden;
+        }
+        canvas {
+            display: block;
+        }
+    </style>
+</head>
+<body>
+<canvas id="canvas"></canvas>
+<script>
+    const canvas = document.getElementById('canvas');
+    const ctx = canvas.getContext('2d');
+
+    canvas.width = window.innerWidth * 0.8;
+    canvas.height = window.innerHeight * 0.8;
+
+    let particlesArray = [];
+    let exploded = false;
+
+    class Particle {
+        constructor(x, y) {
+            this.x = x;
+            this.y = y;
+            this.size = Math.random() * 5 + 1;
+            this.speedX = (Math.random() * 10 - 5);
+            this.speedY = (Math.random() * 10 - 5);
+        }
+
+        draw() {
+            ctx.beginPath();
+            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
+            ctx.fillStyle = 'rgba(255, 200, 0, 0.8)';
+            ctx.fill();
+        }
+
+        update() {
+            this.x += this.speedX;
+            this.y += this.speedY;
+
+            if (this.size > 1) {
+                this.size -= 0.05;
+            }
+        }
+    }
+
+    function createParticles(word) {
+        let wordArray = word.toUpperCase().split('');
+        let letterGap = canvas.width / wordArray.length + 10;
+        let y = canvas.height - 200;
+
+        for (let i = 0; i < wordArray.length; i++) {
+            for (let j = 0; j < 5; j++) {
+                particlesArray.push(new Particle((letterGap * i) + 50, y));
+            }
+            y -= 150;
+        }
+    }
+
+    function explosion() {
+        for (let i = 0; i < particlesArray.length; i++) {
+            particlesArray[i].speedX = Math.random() * 20 - 10;
+            particlesArray[i].speedY = Math.random() * 20 - 10;
+            particlesArray[i].size = Math.random() * 50 + 1;
+        }
+    }
+
+    function loop() {
+        ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+        for (let i = 0; i < particlesArray.length; i++) {
+            particlesArray[i].draw();
+            particlesArray[i].update();
+        }
+
+        if (!exploded) {
+            explosion();
+            exploded = true;
+        }
+    }
+
+    function animate() {
+        loop();
+
+        if (particlesArray.length > 0) {
+            requestAnimationFrame(animate);
+        } else {
+            createParticles('ARENA');
+            requestAnimationFrame(animate);
+        }
+    }
+
+    window.addEventListener('resize', () => {
+        canvas.width = window.innerWidth * 0.8;
+        canvas.height = window.innerHeight * 0.8;
+    });
+
+    document.getElementById('canvas').addEventListener('click', () => {
+        createParticles('ARENA');
+        exploded = false;
+        particlesArray = [];
+    });
+
+    animate();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ca355985ca95/hermes3-8b.png b/data/artifacts/ca355985ca95/hermes3-8b.png
new file mode 100644
index 0000000..7f4d9fc
Binary files /dev/null and b/data/artifacts/ca355985ca95/hermes3-8b.png differ
diff --git a/data/artifacts/d7636ea87ec3/gemma3-12b.html b/data/artifacts/d7636ea87ec3/gemma3-12b.html
new file mode 100644
index 0000000..ed96937
--- /dev/null
+++ b/data/artifacts/d7636ea87ec3/gemma3-12b.html
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Snake Game</title>
+<style>
+body {
+  background-color: #000;
+  color: #fff;
+  font-family: monospace;
+  text-align: center;
+}
+
+canvas {
+  border: 2px solid #fff;
+  background-color: #111;
+}
+
+#score {
+  margin-top: 10px;
+  font-size: 24px;
+}
+</style>
+</head>
+<body>
+
+<canvas id="gameCanvas" width="320" height="320"></canvas>
+<div id="score">Score: 0</div>
+
+<script>
+const canvas = document.getElementById("gameCanvas");
+const ctx = canvas.getContext("2d");
+let scoreDisplay = document.getElementById("score");
+
+let snake = [];
+let dx = 1;
+let dy = 0;
+let foodX, foodY;
+let score = 0;
+let gameInterval;
+
+function init() {
+  snake = [{ x: 150, y: 150 }];
+  dx = 1;
+  dy = 0;
+  score = 0;
+  generateFood();
+  gameInterval = setInterval(update, 100);
+}
+
+function generateFood() {
+  foodX = Math.floor(Math.random() * 20) * 16;
+  foodY = Math.floor(Math.random() * 20) * 16;
+}
+
+function update() {
+  let headX = snake[0].x + dx;
+  let headY = snake[0].y + dy;
+
+  if (headX > canvas.width || headX < 0 || headY > canvas.height || headY < 0) {
+    gameOver();
+    return;
+  }
+
+  for (let i = 1; i < snake.length; i++) {
+    if (snake[i].x === headX && snake[i].y === headY) {
+      gameOver();
+      return;
+    }
+  }
+
+
+  snake.unshift({ x: headX, y: headY });
+
+  let ateFood = false;
+  if (headX === foodX && headY === foodY) {
+    ateFood = true;
+    score++;
+    scoreDisplay.textContent = "Score: " + score;
+    generateFood();
+  } else {
+    snake.pop();
+  }
+
+  draw();
+}
+
+
+function draw() {
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+  // Draw Food
+  ctx.fillStyle = "#f00";
+  ctx.fillRect(foodX, foodY, 16, 16);
+
+  // Draw Snake
+  for (let i = 0; i < snake.length; i++) {
+    ctx.fillStyle = i % 2 === 0 ? "#0f0" : "#00f"; // Alternate colors for retro look
+    ctx.fillRect(snake[i].x, snake[i].y, 16, 16);
+  }
+}
+
+function gameOver() {
+  clearInterval(gameInterval);
+  alert("Game Over! Score: " + score + "\nPress OK to restart.");
+  init();
+}
+
+
+document.addEventListener("keydown", function (event) {
+  switch (event.key) {
+    case "ArrowUp":
+      if (dy !== 1) {
+        dx = 0;
+        dy = -1;
+      }
+      break;
+    case "ArrowDown":
+      if (dy !== -1) {
+        dx = 0;
+        dy = 1;
+      }
+      break;
+    case "ArrowLeft":
+      if (dx !== 1) {
+        dx = -1;
+        dy = 0;
+      }
+      break;
+    case "ArrowRight":
+      if (dx !== -1) {
+        dx = 1;
+        dy = 0;
+      }
+      break;
+  }
+});
+
+init();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7636ea87ec3/gemma3-12b.png b/data/artifacts/d7636ea87ec3/gemma3-12b.png
new file mode 100644
index 0000000..6d46c5c
Binary files /dev/null and b/data/artifacts/d7636ea87ec3/gemma3-12b.png differ
diff --git a/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.html b/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.html
new file mode 100644
index 0000000..1bc2ac3
--- /dev/null
+++ b/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Retro Snake Game</title>
+<style>
+  body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #000; }
+  canvas { border: 1px solid #fff; }
+  #score { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); color: #fff; font-family: 'Courier New', Courier, monospace; font-size: 2em; }
+  #gameOver { display: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #f00; font-family: 'Courier New', Courier, monospace; font-size: 3em; text-align: center; }
+</style>
+</head>
+<body>
+<canvas id="gameCanvas" width="400" height="400"></canvas>
+<div id="score">Score: 0</div>
+<div id="gameOver">Game Over<br>Press Space to Restart</div>
+<script>
+const canvas = document.getElementById('gameCanvas');
+const ctx = canvas.getContext('2d');
+const gridSize = 20;
+let snake = [{ x: 190, y: 200 }, { x: 170, y: 200 }, { x: 150, y: 200 }];
+let dx = 20;
+let dy = 0;
+let food = { x: 300, y: 200 };
+let score = 0;
+let gameOver = false;
+
+function getRandomFoodPosition() {
+  return {
+    x: Math.floor(Math.random() * canvas.width / gridSize) * gridSize,
+    y: Math.floor(Math.random() * canvas.height / gridSize) * gridSize
+  };
+}
+
+function drawSnake() {
+  snake.forEach(segment => {
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(segment.x, segment.y, gridSize, gridSize);
+    ctx.strokeStyle = '#fff';
+    ctx.strokeRect(segment.x, segment.y, gridSize, gridSize);
+  });
+}
+
+function drawFood() {
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(food.x, food.y, gridSize, gridSize);
+}
+
+function updateSnake() {
+  const head = { x: snake[0].x + dx, y: snake[0].y + dy };
+  snake.unshift(head);
+
+  if (head.x === food.x && head.y === food.y) {
+    score++;
+    document.getElementById('score').innerText = 'Score: ' + score;
+    food = getRandomFoodPosition();
+  } else {
+    snake.pop();
+  }
+}
+
+function checkCollision() {
+  const head = snake[0];
+  if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) {
+    return true;
+  }
+  for (let i = 4; i < snake.length; i++) {
+    if (snake[i].x === head.x && snake[i].y === head.y) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function gameLoop() {
+  if (gameOver) {
+    document.getElementById('gameOver').style.display = 'block';
+    return;
+  }
+
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+  drawFood();
+  updateSnake();
+  drawSnake();
+
+  if (checkCollision()) {
+    gameOver = true;
+  }
+}
+
+document.addEventListener('keydown', event => {
+  const keyPressed = event.keyCode;
+  const goingUp = dy === -gridSize;
+  const goingDown = dy === gridSize;
+  const goingRight = dx === gridSize;
+  const goingLeft = dx === -gridSize;
+
+  if (keyPressed === 37 && !goingRight) {
+    dx = -gridSize;
+    dy = 0;
+  }
+  if (keyPressed === 38 && !goingDown) {
+    dx = 0;
+    dy = -gridSize;
+  }
+  if (keyPressed === 39 && !goingLeft) {
+    dx = gridSize;
+    dy = 0;
+  }
+  if (keyPressed === 40 && !goingUp) {
+    dx = 0;
+    dy = gridSize;
+  }
+  if (gameOver && keyPressed === 32) {
+    snake = [{ x: 190, y: 200 }, { x: 170, y: 200 }, { x: 150, y: 200 }];
+    dx = 20;
+    dy = 0;
+    food = getRandomFoodPosition();
+    score = 0;
+    document.getElementById('score').innerText = 'Score: 0';
+    document.getElementById('gameOver').style.display = 'none';
+    gameOver = false;
+  }
+});
+
+setInterval(gameLoop, 150);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.png b/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.png
new file mode 100644
index 0000000..2a45776
Binary files /dev/null and b/data/artifacts/d7636ea87ec3/hf-qwen-coder-32b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index 51d33f3..5a8ada4 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -1584,21 +1584,25 @@
       },
       {
         "model": "gemma3-12b",
-        "status": "error",
-        "error": "server restarted mid-run",
-        "seconds": 0,
-        "cost": null,
-        "started_at": "2026-07-23T13:50:01.324Z",
-        "finished_at": null
+        "status": "done",
+        "error": null,
+        "seconds": 34,
+        "cost": 0,
+        "started_at": "2026-07-23T13:53:49.227Z",
+        "finished_at": "2026-07-23T13:54:23.651Z",
+        "bytes": 4019,
+        "thumb": true
       },
       {
         "model": "hermes3-8b",
-        "status": "error",
-        "error": "server restarted mid-run",
-        "seconds": 0,
-        "cost": null,
-        "started_at": null,
-        "finished_at": null
+        "status": "done",
+        "error": null,
+        "seconds": 8,
+        "cost": 0,
+        "started_at": "2026-07-23T13:53:40.844Z",
+        "finished_at": "2026-07-23T13:53:49.226Z",
+        "bytes": 2922,
+        "thumb": true
       },
       {
         "model": "qwen25-7b",
@@ -1617,18 +1621,19 @@
         "error": "server restarted mid-run",
         "seconds": 0,
         "cost": null,
-        "started_at": "2026-07-23T13:48:22.281Z",
+        "started_at": "2026-07-23T13:53:42.040Z",
         "finished_at": null
       },
       {
         "model": "gpt",
         "status": "done",
         "error": null,
-        "seconds": 24,
-        "cost": 0.0318,
-        "started_at": "2026-07-23T13:48:04.283Z",
-        "finished_at": "2026-07-23T13:48:28.246Z",
-        "bytes": 8096
+        "seconds": 22,
+        "cost": 0.0287,
+        "started_at": "2026-07-23T13:53:43.749Z",
+        "finished_at": "2026-07-23T13:54:06.210Z",
+        "bytes": 7780,
+        "thumb": true
       },
       {
         "model": "grok",
@@ -1643,5 +1648,165 @@
       }
     ],
     "voted_at": "2026-07-23T13:50:02.948Z"
+  },
+  {
+    "id": "825890cbb1ea",
+    "title": "New Paths: Max Plan + local",
+    "prompt": "Single-file HTML: a sortable, searchable table of 6 sample wallcovering SKUs (sku, pattern, colorway, price, stock) with click-to-sort columns and a live search box. Clean, elegant.",
+    "category": "Real Work",
+    "created_at": "2026-07-23T13:51:41.372Z",
+    "winner": null,
+    "runs": [
+      {
+        "model": "claude-code",
+        "status": "done",
+        "error": null,
+        "seconds": 40,
+        "cost": 0,
+        "started_at": "2026-07-23T13:51:41.376Z",
+        "finished_at": "2026-07-23T13:52:21.614Z",
+        "bytes": 7808,
+        "thumb": true,
+        "aiScore": 9.3,
+        "aiReason": "The table is clean and fulfills all the requirements of a sortable, searchable table with live search functionality.",
+        "aiScores": {
+          "qwen2.5vl:7b": 9,
+          "minicpm-v:latest": 9.5
+        },
+        "aiSpread": 0.5
+      },
+      {
+        "model": "gemma3-12b",
+        "status": "done",
+        "error": null,
+        "seconds": 24,
+        "cost": 0,
+        "started_at": "2026-07-23T13:51:41.394Z",
+        "finished_at": "2026-07-23T13:52:05.059Z",
+        "bytes": 3720,
+        "thumb": true,
+        "aiScore": 9.3,
+        "aiReason": "The table is clean and fulfills all requirements with a live search box and sortable columns.",
+        "aiScores": {
+          "qwen2.5vl:7b": 9,
+          "minicpm-v:latest": 9.5
+        },
+        "aiSpread": 0.5
+      }
+    ],
+    "judging": false,
+    "aiPick": "claude-code",
+    "judged_at": "2026-07-23T13:52:39.295Z"
+  },
+  {
+    "id": "93a51ee67f87",
+    "title": "Max-plan Claude check",
+    "prompt": "A single <!DOCTYPE html> page that shows the word Hello centered.",
+    "category": "Custom",
+    "created_at": "2026-07-23T13:54:43.220Z",
+    "winner": null,
+    "runs": [
+      {
+        "model": "claude-code",
+        "status": "error",
+        "error": "server restarted mid-run",
+        "seconds": 0,
+        "cost": null,
+        "started_at": "2026-07-23T13:54:43.224Z",
+        "finished_at": null
+      }
+    ]
+  },
+  {
+    "id": "d7636ea87ec3",
+    "title": "HF Top Coder debut",
+    "prompt": "Single-file HTML: a playable Snake game on a canvas with arrow-key controls, a score counter, and a game-over restart. Clean retro styling.",
+    "category": "Games",
+    "created_at": "2026-07-23T13:54:49.357Z",
+    "winner": null,
+    "runs": [
+      {
+        "model": "hf-qwen-coder-32b",
+        "status": "done",
+        "error": null,
+        "seconds": 55,
+        "cost": 0,
+        "started_at": "2026-07-23T13:54:49.362Z",
+        "finished_at": "2026-07-23T13:55:44.602Z",
+        "bytes": 3531,
+        "thumb": true
+      },
+      {
+        "model": "gemma3-12b",
+        "status": "done",
+        "error": null,
+        "seconds": 29,
+        "cost": 0,
+        "started_at": "2026-07-23T13:55:44.604Z",
+        "finished_at": "2026-07-23T13:56:13.943Z",
+        "bytes": 2507,
+        "thumb": true
+      }
+    ],
+    "judging": true
+  },
+  {
+    "id": "34ecbeae4e1f",
+    "title": "Remix: New Paths: Max Plan + local",
+    "prompt": "Single-file HTML: a sortable, searchable table of 6 sample wallcovering SKUs (sku, pattern, colorway, price, stock) with click-to-sort columns and a live search box. Clean, elegant.\n\nHere is a strong previous attempt at this exact challenge. IMPROVE on it — keep what works, fix its weaknesses, and elevate the visual quality and polish. Return a complete, improved single-file HTML document.\n\n=== PREVIOUS ATTEMPT (Claude (Max plan)) ===\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Wallcovering SKUs</title>\n<style>\n  :root {\n    --bg: #f6f4f0;\n    --card: #ffffff;\n    --ink: #23211d;\n    --muted: #8a8579;\n    --accent: #7a6a4f;\n    --line: #e8e4dc;\n    --hover: #faf8f4;\n  }\n  * { margin: 0; padding: 0; box-sizing: border-box; }\n  body {\n    font-family: \"Avenir Next\", \"Segoe UI\", -apple-system, Helvetica, Arial, sans-serif;\n    background: var(--bg);\n    color: var(--ink);\n    min-height: 100vh;\n    display: flex;\n    justify-content: center;\n    padding: 48px 20px;\n  }\n  .wrap { width: 100%; max-width: 880px; }\n  header { margin-bottom: 28px; }\n  h1 {\n    font-weight: 500;\n    font-size: 26px;\n    letter-spacing: 0.12em;\n    text-transform: uppercase;\n  }\n  .sub {\n    color: var(--muted);\n    font-size: 13px;\n    letter-spacing: 0.05em;\n    margin-top: 6px;\n  }\n  .toolbar {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 16px;\n    margin-bottom: 16px;\n    flex-wrap: wrap;\n  }\n  .search-box { position: relative; flex: 1; min-width: 220px; max-width: 360px; }\n  .search-box svg {\n    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);\n    width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 2;\n    pointer-events: none;\n  }\n  #search {\n    width: 100%;\n    padding: 10px 14px 10px 36px;\n    font-size: 14px;\n    font-family: inherit;\n    border: 1px solid var(--line);\n    border-radius: 8px;\n    background: var(--card);\n    color: var(--ink);\n    outline: none;\n    transition: border-color .15s, box-shadow .15s;\n  }\n  #search:focus {\n    border-color: var(--accent);\n    box-shadow: 0 0 0 3px rgba(122,106,79,.12);\n  }\n  #count { color: var(--muted); font-size: 13px; letter-spacing: 0.04em; }\n  .card {\n    background: var(--card);\n    border: 1px solid var(--line);\n    border-radius: 12px;\n    overflow: hidden;\n    box-shadow: 0 1px 3px rgba(35,33,29,.05);\n  }\n  table { width: 100%; border-collapse: collapse; }\n  thead th {\n    text-align: left;\n    font-size: 11px;\n    font-weight: 600;\n    letter-spacing: 0.14em;\n    text-transform: uppercase;\n    color: var(--muted);\n    padding: 14px 18px;\n    border-bottom: 1px solid var(--line);\n    cursor: pointer;\n    user-select: none;\n    white-space: nowrap;\n    transition: color .15s;\n  }\n  thead th:hover { color: var(--accent); }\n  thead th .arrow {\n    display: inline-block;\n    width: 1em;\n    color: var(--accent);\n    font-size: 10px;\n  }\n  tbody td {\n    padding: 14px 18px;\n    font-size: 14px;\n    border-bottom: 1px solid var(--line);\n  }\n  tbody tr:last-child td { border-bottom: none; }\n  tbody tr { transition: background .12s; }\n  tbody tr:hover { background: var(--hover); }\n  td.sku { font-family: \"SF Mono\", Menlo, Consolas, monospace; font-size: 13px; color: var(--accent); }\n  td.num { text-align: right; font-variant-numeric: tabular-nums; }\n  th.num { text-align: right; }\n  .stock-pill {\n    display: inline-block;\n    padding: 3px 10px;\n    border-radius: 999px;\n    font-size: 12px;\n    font-variant-numeric: tabular-nums;\n  }\n  .stock-hi  { background: #e8efe4; color: #45663a; }\n  .stock-mid { background: #f4eedd; color: #7d6a33; }\n  .stock-lo  { background: #f6e5e0; color: #8c4a3b; }\n  .empty {\n    padding: 40px 18px;\n    text-align: center;\n    color: var(--muted);\n    font-size: 14px;\n    display: none;\n  }\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n  <header>\n    <h1>Wallcovering Library</h1>\n    <div class=\"sub\">Sample SKU catalog — click a column to sort, type to filter</div>\n  </header>\n\n  <div class=\"toolbar\">\n    <div class=\"search-box\">\n      <svg viewBox=\"0 0 24 24\"><circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"/></svg>\n      <input id=\"search\" type=\"text\" placeholder=\"Search sku, pattern, colorway…\" autocomplete=\"off\">\n    </div>\n    <div id=\"count\"></div>\n  </div>\n\n  <div class=\"card\">\n    <table id=\"tbl\">\n      <thead>\n        <tr>\n          <th data-key=\"sku\">SKU<span class=\"arrow\"></span></th>\n          <th data-key=\"pattern\">Pattern<span class=\"arrow\"></span></th>\n          <th data-key=\"colorway\">Colorway<span class=\"arrow\"></span></th>\n          <th data-key=\"price\" class=\"num\">Price<span class=\"arrow\"></span></th>\n          <th data-key=\"stock\" class=\"num\">Stock<span class=\"arrow\"></span></th>\n        </tr>\n      </thead>\n      <tbody></tbody>\n    </table>\n    <div class=\"empty\" id=\"empty\">No matching SKUs.</div>\n  </div>\n</div>\n\n<script>\n(function () {\n  var data = [\n    { sku: \"DW-1042\", pattern: \"Meadow Damask\",    colorway: \"Sage\",      price: 128.00, stock: 42 },\n    { sku: \"DW-2310\", pattern: \"Coastal Grass\",    colorway: \"Oatmeal\",   price: 96.50,  stock: 8  },\n    { sku: \"DW-3177\", pattern: \"Chinoiserie Vine\", colorway: \"Celadon\",   price: 245.00, stock: 15 },\n    { sku: \"DW-4508\", pattern: \"Herringbone Silk\", colorway: \"Champagne\", price: 189.75, stock: 27 },\n    { sku: \"DW-5624\", pattern: \"Deco Fan\",         colorway: \"Midnight\",  price: 142.00, stock: 3  },\n    { sku: \"DW-6081\", pattern: \"Linen Weave\",      colorway: \"Alabaster\", price: 74.25,  stock: 63 }\n  ];\n\n  var sortKey = null, sortDir = 1;\n  var tbody = document.querySelector(\"#tbl tbody\");\n  var search = document.getElementById(\"search\");\n  var countEl = document.getElementById(\"count\");\n  var emptyEl = document.getElementById(\"empty\");\n  var headers = document.querySelectorAll(\"#tbl thead th\");\n\n  function stockClass(n) {\n    if (n <= 5) return \"stock-lo\";\n    if (n <= 20) return \"stock-mid\";\n    return \"stock-hi\";\n  }\n\n  function fmtPrice(p) {\n    return \"$\" + p.toFixed(2);\n  }\n\n  function render() {\n    var q = search.value.trim().toLowerCase();\n    var rows = data.filter(function (r) {\n      if (!q) return true;\n      return (r.sku + \" \" + r.pattern + \" \" + r.colorway + \" \" + r.price + \" \" + r.stock)\n        .toLowerCase().indexOf(q) !== -1;\n    });\n\n    if (sortKey) {\n      rows = rows.slice().sort(function (a, b) {\n        var av = a[sortKey], bv = b[sortKey];\n        if (typeof av === \"string\") {\n          return av.localeCompare(bv) * sortDir;\n        }\n        return (av - bv) * sortDir;\n      });\n    }\n\n    tbody.innerHTML = \"\";\n    rows.forEach(function (r) {\n      var tr = document.createElement(\"tr\");\n\n      var tds = [\n        { cls: \"sku\", text: r.sku },\n        { cls: \"\", text: r.pattern },\n        { cls: \"\", text: r.colorway },\n        { cls: \"num\", text: fmtPrice(r.price) }\n      ];\n      tds.forEach(function (c) {\n        var td = document.createElement(\"td\");\n        if (c.cls) td.className = c.cls;\n        td.textContent = c.text;\n        tr.appendChild(td);\n      });\n\n      var tdStock = document.createElement(\"td\");\n      tdStock.className = \"num\";\n      var pill = document.createElement(\"span\");\n      pill.className = \"stock-pill \" + stockClass(r.stock);\n      pill.textContent = r.stock + \" rolls\";\n      tdStock.appendChild(pill);\n      tr.appendChild(tdStock);\n\n      tbody.appendChild(tr);\n    });\n\n    emptyEl.style.display = rows.length ? \"none\" : \"block\";\n    countEl.textContent = rows.length + \" of \" + data.length + \" SKUs\";\n\n    headers.forEach(function (th) {\n      var arrow = th.querySelector(\".arrow\");\n      if (th.dataset.key === sortKey) {\n        arrow.textContent = sortDir === 1 ? \"\\u25B2\" : \"\\u25BC\";\n      } else {\n        arrow.textContent = \"\";\n      }\n    });\n  }\n\n  headers.forEach(function (th) {\n    th.addEventListener(\"click\", function () {\n      var key = th.dataset.key;\n      if (sortKey === key) {\n        sortDir = -sortDir;\n      } else {\n        sortKey = key;\n        sortDir = 1;\n      }\n      render();\n    });\n  });\n\n  search.addEventListener(\"input\", render);\n  render();\n})();\n</script>\n</body>\n</html>",
+    "remixOf": "825890cbb1ea",
+    "remixSource": "claude-code",
+    "created_at": "2026-07-23T13:54:56.129Z",
+    "winner": null,
+    "runs": [
+      {
+        "model": "qwen3-14b",
+        "status": "error",
+        "error": "server restarted mid-run",
+        "seconds": 0,
+        "cost": null,
+        "started_at": "2026-07-23T13:56:13.944Z",
+        "finished_at": null
+      },
+      {
+        "model": "gemma3-12b",
+        "status": "error",
+        "error": "server restarted mid-run",
+        "seconds": 0,
+        "cost": null,
+        "started_at": null,
+        "finished_at": null
+      },
+      {
+        "model": "hermes3-8b",
+        "status": "error",
+        "error": "server restarted mid-run",
+        "seconds": 0,
+        "cost": null,
+        "started_at": null,
+        "finished_at": null
+      },
+      {
+        "model": "qwen25-7b",
+        "status": "done",
+        "error": null,
+        "seconds": 61,
+        "cost": 0,
+        "started_at": "2026-07-23T13:54:56.138Z",
+        "finished_at": "2026-07-23T13:55:57.570Z",
+        "bytes": 6556,
+        "thumb": true
+      },
+      {
+        "model": "hf-qwen-coder-32b",
+        "status": "error",
+        "error": "server restarted mid-run",
+        "seconds": 0,
+        "cost": null,
+        "started_at": null,
+        "finished_at": null
+      }
+    ],
+    "category": "Real Work"
   }
 ]
\ No newline at end of file
diff --git a/data/costlog.jsonl b/data/costlog.jsonl
index 433b04d..3933467 100644
--- a/data/costlog.jsonl
+++ b/data/costlog.jsonl
@@ -27,3 +27,4 @@
 {"ts":"2026-07-23T13:48:22.273Z","provider":"moonshot","model":"kimi-k2.5","task":"model-arena","input_tokens":103,"output_tokens":6177,"cost_usd":0.015504}
 {"ts":"2026-07-23T13:48:28.243Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":134,"output_tokens":2253,"cost_usd":0.031776}
 {"ts":"2026-07-23T13:48:30.706Z","provider":"xai","model":"grok-4.5","task":"model-arena","input_tokens":340,"output_tokens":1992,"cost_usd":0.0309}
+{"ts":"2026-07-23T13:54:06.203Z","provider":"openai","model":"gpt-5.1","task":"model-arena","input_tokens":134,"output_tokens":2036,"cost_usd":0.028739}

← b25a81b resilience: global unhandledRejection/uncaughtException hand  ·  back to Model Arena  ·  auto-resume runs interrupted by a server restart: on boot, r 0dbc486 →