# Ornith-1.0-35B — live fleet bench + teamwork games (B70 Turbo)

Model: **Ornith-1.0-35B-A3B** (arch `qwen3_5_moe`, 35B/~3B active), **Q5_K_M**, llama.cpp SYCL on a
single **Intel Arc Pro B70** (30.3 GiB), `llama-server`. Ship config `-ngl 99 -fa on -ctk/-ctv q8_0
-b 8192 -ub 4096`, `GGML_SYCL_DISABLE_DNN=1`, `--jinja`. Same family/quant/serve as AgentWorld-35B, so
the throughput curve is expected to match — this run **measures** it rather than assuming.

Run date 2026-06-29 (UTC). Artifacts under `results/live_evals/ornith/`.

## 1. Live agent-fleet bench, `-np 32 -c 131072` (real concurrent requests, :8092)

Real OpenAI-API requests fired simultaneously through the live server (`concurrent_agents.py`).
Aggregate decode = sum(generated tokens) / batch wall-clock; per-agent = mean server-side decode t/s
one agent sees. Thinking ON (chat-template default); 256-token generations.

| class | prompt_n | agents | aggregate decode t/s | per-agent t/s |
|---|---:|---:|---:|---:|
| tool | 125 | 1  | 63.07  | 83.01 |
| tool | 125 | 8  | 142.19 | 19.74 |
| tool | 125 | 16 | 163.41 | 11.23 |
| **tool** | 125 | **32** | **224.92** | 7.88 |
| structured | 443 | 32 | 169.41 | 6.76 |
| novel | 775 | 32 | 135.25 | 5.66 |

**Headline:** at 32 concurrent agents Ornith sustains **135–225 t/s aggregate** decode (vs ~63 agg /
83 per-agent for a single agent) — a **2.1–3.6× total-throughput gain** from batching, per-agent
landing at 5.7–7.9 t/s (fine for autonomous/background fleets).

### Cross-check vs AgentWorld-35B (same arch/quant/serve)

| cell | Ornith agg / per-agent | AgentWorld agg / per-agent |
|---|---:|---:|
| tool×1 | 63.1 / 83.0 | 62.9 / 82.5 |
| tool×8 | 142.2 / 19.7 | 141.4 / 19.6 |
| tool×16 | 163.4 / 11.2 | 163.0 / 11.2 |
| tool×32 | 224.9 / 7.9 | 223.5 / 7.8 |
| structured×32 | 169.4 / 6.8 | 168.8 / 6.8 |
| novel×32 | 135.3 / 5.7 | 147.5 / 6.2 |

Ornith tracks AgentWorld to within run-noise across the board (identical qwen3_5_moe arch + Q5_K_M +
serve config). The only spread is `novel×32` (135 vs 148 agg), and that cell's prompt is longer for the
Ornith run (prompt_n 775 vs 651), which lowers decode share — not a model difference.

## 2. Teamwork build games (frogger + maze)

Canonical `agentic-arcade/teamwork` harness on `:8092` at **team 6 / merge-top 2 / 15-min** wall-clock,
thinking OFF, served `-np 6 -c 262144` (43,690 ctx/slot — merger-context bound, the B70 teamwork wall).
Lead seeds a complete game; each round 6 workers each return a complete improved build; a merger fuses
blackboard + top-2; a never-regress guard (jsdom runtime validation) only adopts builds that still run.

| game | rounds | winner | seed→final bytes | jsdom valid | notes |
|---|---:|---|---|:--:|---|
| **frogger** | 2 | merged (both rounds) | 19,901 → 29,268 | ✅ | 6/6 workers valid each round; merger won both |
| **maze** | 1 | worker | 18,820 → 22,724 | ✅ | reseed ×1 to a clean seed, then 6/6 workers valid; a worker build won round 1 |

> **Maze build reliability (variance at temp 0.5).** The maze took **two full runs** to land a working
> game. **Run 1** produced a non-functional maze and could not recover it: the seed failed jsdom 3× (initial
> + 2 reseeds) and **all 6 round-1 workers returned invalid HTML (0/6)**, so the never-regress guard kept the
> broken seed. Root cause (verified in the source): the model declared `let ctx` as the **Web Audio** context
> and **never called `canvas.getContext('2d')`**, yet the render code draws on `ctx` → `ReferenceError: ctx is
> not defined` (black screen). **Run 2** reseeded once to a clean seed (own `AudioSys.ctx` + correct
> `getContext('2d')`) and built the working game scored below. The failed run-1 artifact is kept at
> `games/ornith_maze_attempt1_FAILED.html`. Takeaway: Ornith's maze build is **variance-prone** — it ships a
> good game some runs and an unrecoverable one others; frogger was stable (clean seed first try, both runs).

## 3. Code-quality eval (Claude Opus 4.8 judge, /50 rubric)

Judge reads each game's actual source against the fixed rubric (each dimension /10): **Completeness**
(required features really implemented) · **Correctness** (runs *and plays* correctly) · **Structure**
(organization/readability) · **Robustness** (edge cases, resets) · **Polish** (audio/anim/visual/UX).

| game | chars | **/50** | Comp | Corr | Struct | Robust | Polish |
|---|---:|---:|:--:|:--:|:--:|:--:|:--:|
| **Frogger** | 29,268 | **33** | 9 | 5 | 8 | 5 | 6 |
| **Maze** | 22,724 | **34** | 9 | 4 | 8 | 5 | 8 |

### Frogger — 33/50

Clean, well-structured single-file build: `getContext('2d')` set up correctly, classes for
`Particle / Frog / Obstacle`, frame-rate-independent grid movement (lerp + 100 ms move gate), two level
layouts, cars + logs/turtles, lives/score/level HUD, menu/game-over/victory/level-transition states,
AABB collision, raft-carry, even a mobile virtual D-pad. Validates clean in jsdom (no JS errors → not a
black screen).

**But two real gameplay bugs the static gate can't see:**

1. **Unwinnable.** `levelComplete()` is defined (line 557) but **never called** — there is no goal-row
   (`gridY === 0`) handler in `checkCollisions()` or the loop. You can move, dodge, ride rafts, and die,
   but reaching the goal does nothing, so a level can never advance and the game can't be won. (Same
   class of bug as the earlier CrewAI "unwinnable frogger.")
2. **Particles render invisibly.** The loop draws particles (lines 766–767) **before** `drawBackground()`
   (line 770), so the background paints over every particle. The death/splash/goal-confetti system —
   the headline polish feature — never shows.

Movement feel, sprites, raft physics, HUD, and state flow are genuinely good (hence Comp 9 / Struct 8),
but the dead win-path caps Correctness/Robustness at 5 and the invisible particles cap Polish at 6.

### Maze — 34/50 (run-2 build)

The strongest-*polished* of the two: `getContext('2d')` correct, a real recursive-backtracker maze
generator, a `AudioSys` object with **six working Web Audio SFX** (shoot/hit/enemyDie/playerDie/dash/win,
on its own audio context — the exact thing run 1 got wrong), **visible** particle FX, a SHIFT **dash**
mechanic with a cooldown bar and dash-kill, two enemy AI types (chaser/patrol), animated neon exit, and a
proper exit→`wave++` progression (it's **winnable**). Validates clean (7/7 assertions, no JS errors).

**But the core shooter loop is dead, and the static gate misses it:**

- **Enemies have no `radius`.** Enemy objects are created without a `radius` field (line 341), yet bullet→
  enemy collision (`dist < e.radius + 4`, line 480) and enemy→player collision (`dist < player.radius +
  e.radius`, line 524) both reference `e.radius` → `undefined + n = NaN` → the comparison is **always
  false**. So **bullets pass through robots (you can't shoot them) and robots pass through you (no damage,
  no dash-kill).** For a "Robot-Filled Maze *Shooter*" the central verb does nothing. NaN comparison is
  valid JS (no error), so jsdom and the assertion gate both pass it.
- **Shift capitalizes WASD.** `keys` tracks lowercase `w/a/s/d`, but holding SHIFT makes `e.key` arrive as
  `"W"` etc., which isn't in the set → dash-while-using-WASD is flaky (arrows are unaffected). Minor.

Excellent presentation and structure (Comp 9 / Struct 8 / Polish 8 — audio + particles + dash all really
work), but the undefined-radius NaN guts the shoot/avoid loop → Correctness 4.

### Pattern across both games

Both Ornith builds **pass the runtime validator and the playability assertions yet ship a dead core
mechanic** that only source inspection catches — frogger can't be won (`levelComplete()` never called),
maze can't shoot (enemy `radius` undefined → NaN collisions). The teamwork loop (whole-game workers +
merge + never-regress) keeps the games *coherent and runnable* but does not catch **semantic** logic gaps,
because the validator checks "does it load without JS errors," not "does the win/shoot path fire." Net:
solid scaffolding and polish, brittle game logic — **33–34/50**, well below AgentWorld-35B's teamwork
games (41–42/50) on the same harness, despite the identical arch.

## Reproduce
```bash
SKIP_BENCH=0 bash /home/frosty40/qworld_turbo/bench/run_live_evals.sh \
  /home/frosty40/ornith/ornith-1.0-35b-Q5_K_M.gguf ornith-1.0-35b-turbo ornith 8092
# validator: NODE_PATH=/home/frosty40/.cache/teamwork-validator/node_modules node \
#   /home/frosty40/agentic-arcade/teamwork/validate_game.js <game.html>
```
