# The Specification Boundary

> A wake-word bug that turned into a hotkey revealed a bigger pattern: some problems eventually collapse into specifications, and others keep needing judgment no matter how well you understand them. That split is the specification boundary.

Source: Sumit | Date: 2026-07-24 | Reading time: 6 min | Canonical: https://againstentropy.dev/essays/the-specification-boundary/

---

I was building [Kavi](https://github.com/caprion/voice-assistant), a local voice assistant, on a ten-year-old laptop. Most of it worked surprisingly well. The language model [Parakeet](https://huggingface.co/collections/nvidia/parakeet-asr) was fast enough to chat with, transcription was usable, and Linux seemed determined to prove that old hardware still had a few good years left.
One thing kept refusing to cooperate though, the wake word. Sometimes it triggered when I was not talking and other times it ignored me completely. I tried everything I could: assumed the matcher was not good enough, simplified the wake word to two syllables, tweaked fuzzy matching thresholds. I even played with transcription timing and added more heuristics. Every change fixed one failure mode but created another.

After a few rounds, I totally gave up. And replaced the wake word with a keyboard shortcut. Press the key. Start listening. Press again. Stop and transcribe.
I also added a small icon to show whether the assistant was listening or transcribing. The experience became dramatically better. Not because the model became smarter.
Because I had stopped asking it to solve the wrong problem.

## Something did not add up
At first I assumed this was a hardware problem. A faster laptop should have helped, of course. Then I thought it was a model problem, maybe a larger model would be a better speech recognizer. Then maybe it was just cost. Or latency. Or reliability.

Each explanation sounded reasonable. But they all failed the same thought experiment I kept repeating in my head.
Imagine next year's model is perfect. It understands speech flawlessly. It responds instantly. It is completely open and costs nothing.

Would I remove the hotkey? No.

That whole idea surprised me. The hotkey was not a compromise anymore. It was simply the better solution. Which meant the real question had nothing to do with how capable the model was.
Something else had changed.

## What actually changed?
The more I thought about it, the stranger it seemed that the hotkey was the right experience. Nothing about the hardware or model had changed. 

The only thing that changed was the *shape of the decision*. Originally, every sound from the microphone had to answer a fuzzy question:
*"Is the user trying to wake me up?"* There is no perfect rule for that in a home setup: someone coughing, talking in the corridor, or even the noisy fan of the old laptop can all look convincing enough.

The hotkey removed that trigger entirely and the assistant did not have to infer intent. It only had to answer a much simpler question.
*"Is the key currently pressed?"* That is not just a better approximation but a different approach altogether. 

I realized the problem I was trying to solve was entirely different. It wasn't **"How good is the model?"**, but **"Does this problem still need inference?"**

## The specification boundary
Some decisions never stop needing interpretation. Writing a sentence, understanding what someone meant. Every new situation like this asks you to reason again. 
Then there are ideas where once we understand them better, we do not need inference altogether. We write the answer down once, and software can repeat it forever. I was thinking about that boundary and how I kept running into it. Problems whose answers can eventually become specifications, and problems that continue to require judgment.

I started thinking of it as **the specification boundary**. The boundary is not fixed. As our understanding improves, today's inference sometimes becomes tomorrow's software. 

Once I had the word for it, I could not stop noticing it. The wake word became better understood. While the voice activity detection moved in the opposite direction for me. I started with heuristics: thresholds, silence timers, background noise filters. They worked until they did not. And replacing those with a small neural model fixed the problem immediately. 

That was when I realized I wasn't deciding between AI and non-AI, but where the inference really belonged. 

## Software has always worked this way
And then I started seeing this everywhere. 
A compiler does not reinterpret your program every time it runs. TCP does not negotiate how [retransmission](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Retransmission) should work for every packet.

Pac-Man's ghosts don't think, though it feels like they do. Each follows a small set of rules that someone eventually understood well enough to write down once, [rules simple enough that a single dossier can lay out every ghost's exact targeting logic, tile by tile](https://www.gamedeveloper.com/design/the-pac-man-dossier).
That's how software has always grown by discovering which decisions no longer require intelligence. **Every mature system we see today is really a collection of judgments that stopped being judgments.**

And now the same thing is happening in modern AI applications.

The early vision of agents was simple: hand everything to a language model and let it figure things out. Reality has gone in almost the opposite direction.
Every successful agent framework seems to spend enormous effort removing unnecessary inference. We write AGENTS.md files, create tool schemas, define structured outputs, write evaluation suites, maintain memories, and increasingly package the whole thing as a [formal skill specification](https://agentskills.io/specification).
At first glance, these look like prompts but they are specifications. 

Each one says the same thing:
"We have already figured this part out. The model does not need to rediscover it every time." And so the language model is no longer the whole system. It is becoming the inference layer that fills the gaps specifications cannot yet cover.

## Better models can shrink themselves
When people imagine more capable models, they often imagine software becoming more intelligent. But that is not what I have observed. As models improve, we become better at discovering which parts never needed the models in the first place. Yesterday's prompt becomes today's skill. As reasoning becomes specifications, judgment becomes tomorrow's software.
The frontier keeps moving and not just because inference expands, but also because our understanding does.

## How I think about building now
Whenever I build something, I ask one question. **Is this inference, or is this an undiscovered specification?**
If I think the answer can eventually be written down, I treat the model as temporary. And its job becomes to help me discover the specification for the problem. 
If I think the problem fundamentally requires interpretation, I stop trying to eliminate the model. Most systems contain both.
The hard part is not choosing AI over software. It's discovering where one should become the other.

## Closing
The hotkey is still there, and I wrote most of this essay through it. But it is not because speech models aren't good enough.
Because I no longer think waking the assistant is an inference problem. That small bug made me reflect on something much larger.

Software is not the opposite of intelligence. It is what remains after we have understood something well enough that intelligence is no longer required. 
Maybe that's what engineering has always been. The slow, relentless conversion of inference into specification.
