---
title: "A model is not a product: the harness I built on the fly"
url: "https://toddpaulbrownjr.com/writing/a-model-is-not-a-product/"
author: "Todd Paul Brown Jr."
description: "The speech model was the easy part. Chunking, retries, sync, caching and a UI I trust are what made Cadence a product I use every day."
kind: "article"
updated: "2026-09-26T02:50:22+00:00"
---

# A model is not a product: the harness I built on the fly

I asked Claude Code to get an open-source speech model running. I expected it to work out of the box — download, configure, run — and I'd have a working proofreading tool by the end of the day. Instead I spent three days designing the product I thought was going to ship with the model, before I understood what I was actually working with.

The model was the easy part. Chunking, retries, sync, caching, and a UI I could trust are what made [Cadence](/builds/cadence/) a product.

## The prompt that forbade code

The opening prompt was 1,105 lines. Line nine stated plainly: "Do not implement the application in this task." I didn't ask for code. I asked for a repo audit, a product spec, architecture decision records, a phased roadmap, design requirements, and a handoff prompt for a separate design agent. All six deliverables exist.

That design went through a 19-entry reconciliation ledger. Every proposed feature got graded: Essential, Beneficial, or Decorative. About half were rejected before any implementation started.

The result: 368 backend tests passing, and 6.94 hours of narration rendered from a 63,000-word manuscript in 98.2 minutes of GPU time across 1,869 segments. Zero failures.

## What the harness actually does

Cadence is a fully local, proofread-by-ear desktop app. It turns a folder of Markdown files into narration that highlights each paragraph as it's read. I'm dyslexic — the eye skips, autocorrects, and fills in what it expects to see — so I proofread by ear instead of by eye. It runs entirely on my laptop: no account, no subscription, no cloud upload.

The core is Electron with a Python/FastAPI sidecar. Documents parse into content-addressed blocks so highlighting, notes, change detection, and audio caching all line up on the same units. When a manuscript is revised, only changed paragraphs re-render. Notes follow the text that moved, flagged for review rather than silently reattached when a match is uncertain.

That diff-and-reconcile engine was the riskiest component, so I attacked it first. Three confirmed bugs, each fixed with a regression test, before I declared it safe to build on.

## The failures that mattered

A Windows quirk failed silently for weeks. A hidden file attribute on an entire project folder made every chapter show as stale and refuse to regenerate. The JSON writes kept succeeding, so the app looked fine while the audio never updated. The worker couldn't log the failure either. Both are fixed now.

The speech model itself is not the constraint. I've rendered 2,995 segments across two real projects — 1,869 from that manuscript, 1,126 from 51 company knowledge-base documents (2.51 hours of audio) — with zero failures. The model does what it does. The harness is what makes it reliable.

## The rule that came out of it

When a model "should just work" and doesn't, the missing piece usually isn't more model. It's the harness: a spec, decision records, and a design your own review can push back on. An agent will happily build that harness once you ask for it by name.

I ended up with a tool I use every day, built across three consecutive days in July with two later single days adding project management and a notes export. The roadmap existed before the first line of code. The tests existed before I trusted the diff engine. The audio pipeline is boring and reliable because I designed the failure modes first.

The full story is in [Cadence: the proofreading tool I built because my brain is worst at proofreading](/writing/inside-cadence/). The receipts — test counts, render times, segment counts — are on the [Cadence build page](/builds/cadence/).

## Learn it on a toy

I learned how coding agents actually fail on a project with no business case behind it: a creature-battler game in Godot that started in October 2024 and is still in development. The battle math was designed and balanced in a spreadsheet first. The engine was verified against that same spreadsheet before any animation or UI existed.

In March of this year, the loop reversed. LEGION's own session-prompt and timer apparatus was ported back into the game, and an unattended planning-execution-refinement chain took the project's test count from 651 to 1,725 in a single day.

The game is parked for one specific reason: no automated 2D-art pipeline good enough yet. The engine itself is fully functional and tested. I know that because I learned on a toy where the only thing at stake was my own time.

Give yourself a project with no business case. It's the only place you can afford to find out how agents actually fail, before that failure costs you anything real.

The full breakdown of that day's test-expansion sprint, along with the receipts from the October–November work, is in [An on-device interactive fiction engine: 38 decisions, 1,010 tests, and why it's parked](/writing/inside-the-interactive-fiction-engine/).

## Pilot it, then delete it

I briefly ran a job-search pipeline on a third-party orchestration platform: a Node.js server with an embedded Postgres database, an org chart, and issue-based task routing. It successfully piloted one job through the pipeline end-to-end.

Then I removed it completely over three sprints in favor of two Python packages and plain JSON/YAML files on disk. The docs were rewritten so a later session would never encounter it as a concept. The removal was of the orchestration layer only — the underlying pipeline kept working, and applications continued to go out through it.

A successful pilot proves a tool works. It doesn't prove you need the infrastructure it requires.

## Eight months of not building it

I first tried to build LEGION in April 2025. I kept trying, by different means, without success. It came together only after I learned to work with coding agents and new models were released in December 2025. The first working files on disk are dated 2026-03-13.

When a build keeps failing, separate "my approach is wrong" from "the tools cannot do this yet" from "I cannot do this yet." Two of those fix themselves only if you keep building something else in the meantime.

LEGION is live now. It runs Adroit's production systems — Content Ops, Sadyr, the website — and it's built on what I learned failing at personal projects first. The full story is in [The layer finally arrived in my native language](/writing/the-layer-arrived-in-my-native-language/).
