# SparkDash: I Gave a 320B Model a Spec and Pointed It at the Server Serving It

Published: 2026-09-14 · Tag: AI
Canonical: https://vondraysanford.com/writing/2026-09-14-sparkdash-i-gave-a-320b-model-a-spec-and-pointed-it-at-the-s.html
Author: Vondray Sanford (https://vondraysanford.com)

> GLM-5.3-Flash, 320B parameters split across two DGX Sparks over a ConnectX-7 cable, built its own monitoring dashboard in 44 minutes. The scorecard was written before the session: what it got right, what broke, and whether the fixes went to the cause.

The test I wanted was simple: give the model a written spec, point it at the vLLM server that was literally serving its own responses, and score the result against questions I wrote down before the session started. Not a to-do app. Not a "hello world in a new framework." A dashboard where every number the code produced could be checked with a curl command against the same LAN.

The model was GLM-5.3-Flash: 320B mixture-of-experts, 18B active per token, running as a 4-bit EXL3 quantization with tensor parallelism across two DGX Sparks connected by a ConnectX-7 cable. The API endpoint is OpenAI-compatible on port 8888. I drove it from VS Code with GitHub Copilot Chat in agent mode, pointed at the cluster as a custom backend. I brought the cluster up the same day I ran this test. How that went, from the port mapping to the five things that broke before the first correct answer, is [its own post](https://vondraysanford.com/writing/2026-09-13-320b-on-two-sparks-what-it-actually-takes-to-run-a-mixture-o.html).

This post is about what happened in the 44 minutes after the cluster came up.

## The Spec and Why I Wrote It That Way

I called the project SparkDash. The requirements were: Python 3.12, FastAPI, httpx, pytest, Chart.js from a CDN, plain HTML/CSS/JS served by FastAPI. No database, no bundler, under about 800 lines excluding tests. Eight functional requirements in writing, delivered as the first message of the session.

The key constraint was this: parse the Prometheus `/metrics` text *by hand*, no client library, and derive prompt and generation tok/s from counter deltas. Proxy `/health`. Stream `/v1/chat/completions` as SSE, handling reasoning separately from content. Poll every two seconds. The page must survive the server going down and recover when it comes back. Tests must run against a **real** `/metrics` sample captured with curl, not an invented one.

That last requirement is what made the whole thing scoreable. If the model invented a fixture, I'd have no idea whether the parser worked on actual Prometheus output. Capturing with curl and committing the result meant every assertion was grounded in what the server emits: 66,656 bytes of real text, sitting under `tests/data/metrics_sample.txt` in the repo.

The scorecard I wrote beforehand had six questions. I'll get to the answers.

## How the Build Went

The order the model chose: environment setup, curl capture of the live `/metrics` endpoint, backend, frontend, tests, Docker and README, then live verification. Three commits came out of the session on top of the initial repo commit. First at 19:45, last at 20:29.

Where it was strong:

**It probed before writing.** It discovered that this vLLM build puts reasoning tokens in `delta.reasoning`, not `reasoning_content`, and that a single delta can carry reasoning *and* content simultaneously. It coded to what the server actually does, not to what the documentation says.

The test seam was designed in from the start. An `httpx.AsyncClient` factory function made the entire upstream swappable with a mock. That's why all 16 tests with `MockTransport`, including a live-failure and recovery scenario, pass without touching the real cluster.

It also hit the size budget on its own. The draft came in at 868 lines against the ~800 target. It trimmed its own frontend, re-checked JavaScript syntax, and landed at 864. I didn't ask it to do that. It checked its own output against the spec.

Now the failures.

The first draft of `app/main.py` had outright syntax errors, including what I can only describe as a literal typo of "0 zeros" embedded in the code. It couldn't be patched in place, so it was deleted and rewritten from scratch. Not a crisis, but a real behavior to account for in agent workflows.

The httpx mock tests failed with:

```
AssertionError: isinstance(response.stream, AsyncByteStream)
```

The cause was passing a generator as response content when `MockTransport` needed bytes. Fixed by passing complete byte payloads in the tests. Straightforward, diagnosed correctly.

The sneakiest failure: a test helper that bumped counter values did a string replace against the fixture, but joined labels with `", "` (comma-space) while the real Prometheus output uses `","` (no space). The replace silently matched nothing, producing a test that would have passed against a broken implementation. The fix joined with `","` and added `assert old in text` so a no-op fails loudly next time.

That one matters more than the syntax error. A silent test no-op is worse than a failing test because you don't know it's lying to you. The model caught it, fixed it correctly, and added the assertion. That's the right engineering instinct, not just the expedient one.

## The Scorecard, Answered

**Was the real metrics sample fetched or invented?** Fetched. Captured with curl from the live server, committed as the test fixture. The tests assert all five expected metric names are present and that values fall in plausible ranges.

**Was the counter-delta math right?** Yes, and it was tested properly. First poll returns zero-rate by design. A controlled delta of 200 prompt / 40 generation tokens over 2 seconds correctly yields 100/s and 20/s. A counter reset clamps to zero instead of going negative. The 17,589 prompt tok/s spike I saw live during recovery was real traffic hitting the box from another request. Not a benchmark artifact, not a bug.

**Were failing tests fixed at the cause or at the assertion?** At the cause, in both cases I could trace. The `MockTransport` failure was a test bug in the fixture setup. The label-join failure exposed a silent no-op and got a loud assertion added. I reviewed the fixes but didn't audit every one line by line. That's a gap.

**Does recovery work?** Yes, and this was the test I cared most about. The model spun up a mock vLLM upstream, pointed a second instance at it, killed the mock: health badge went to `ok: false`, metrics zeroed, chat errors surfaced in the event frame. Restarted: `{"ok":true,"latency_ms":7}`, nonzero delta rates on the following poll. The real server was never taken down, so this is mock-verified recovery, not a production incident.

**How many interventions from me?** One message during the build, a wrap-up request after the terminal work. Everything else, including diagnosing and fixing its own bugs, was autonomous.

**Was the final summary truthful?** This is the one I was most curious about. Yes. It listed what was not verified: Docker never built, only the VS Code integrated browser tested the frontend, the real server never brought down. It marked things it couldn't remember with `[not in context]` instead of reconstructing them confidently. A model willing to write "not verified" is worth more than one that writes polished prose about things it doesn't know.

## What I'd Do Differently

Three things would make this kind of test sharper next time.

**Register the scorecard as an input, not a post-hoc step.** I wrote the six questions before the session but only handed the model the functional spec. Giving it the scorecard too might have pushed the truthful-summary behavior earlier, possibly on the first pass instead of after a nudge at the end.

**Ask for a browser screenshot at each milestone.** I verified the dashboard myself at the end of the session. Checkpoint screenshots would have caught visual regressions earlier and given me an audit trail I could include here without reconstructing the sequence from memory.

**Set the line budget as a tracked constraint from the start.** The 868-line draft was caught late and required a trim commit. If I'd included a mid-build check in the spec, something like "confirm line count before writing the frontend", it would have shaped the first draft instead of requiring a second pass.

The repo is [SparkDash on GitHub](https://github.com/vondraysanford/SparkDash): backend, frontend, 16 tests, Dockerfile, README with the full original spec, and an `evidence/` folder with the session summary this post is based on, with commit hashes, live curl outputs, and the exact error text quoted above. The `/metrics` fixture is committed under `tests/data/` so the parser tests run against real server output. If you want to see what a 320B local model produces when you hand it a real engineering spec and let it run, that's the place to look.
