The Cheapest Test Is the One You Run Before You Build
Suneet Malhotra
Sep 04, 2026
The most expensive engineering mistakes in my systems were not hard bugs. They were reasonable implementations of questions nobody had defined.
That distinction matters because the usual response to a bad result is to improve the implementation. Add retries. Increase context. Tune the threshold. Capture another metric. Sometimes that is the right move. Often it is a way to avoid asking whether the system was ever measuring the thing that mattered.
The cheapest test is the one you run before you build.
Start with the state transition
When I describe a feature, I now try to finish this sentence first: "After this succeeds, the observable state that changes is..."
For a trading workflow, the answer might be an order intent persisted with a unique identifier, followed by a broker-confirmed terminal state. For an agent workflow, it might be an allowlisted file changed and a postcondition checked against the resulting file. For a content pipeline, it might be a specific post committed to a specific repository.
If I cannot name the state transition, I do not yet have a feature. I have a desired feeling.
This test catches a surprising number of attractive designs. A dashboard that displays signals may be useful, but it has not demonstrated that a decision was made. A retry that returns HTTP 200 may have improved transport reliability, but it has not shown that the action is idempotent. A generated draft may be well written, but it has not been published.
The interface is not the output. The output is the verified change in state.
Separate the question from the mechanism
The next cheap test is to write down the question in a form that could be falsified.
"Make the agent smarter" is not a question. "Reduce refusals caused by missing context" is closer, but still needs an observable measure. "On a fixed evaluation set, preserve the same policy boundary while reducing tool-selection errors from the current baseline" is testable.
This sounds like process overhead until the first implementation fails. Then the wording becomes an escape hatch. If the original goal was vague, every partial improvement can be reported as progress. The system can be faster, more verbose, or more sophisticated without being more correct.
I have made this mistake in quantitative work too. A backtest can answer whether a set of recorded trades had a particular return. It cannot answer whether signals that never became trades were better opportunities. A report can be numerically precise and still be about the wrong population.
The practical fix is to define the population before looking at the result. Which events count? Which refusals count? What does a missing row mean? These are design decisions, not cleanup details.
Put the boundary in the test
A good test does not only check the happy path. It checks who or what is allowed to cause the change.
An agent may propose edits across a repository, but the routine may permit only one file to be staged. A market process may receive a valid signal, but the risk layer may refuse the order because exposure is already at its limit. A scheduled job may run, but a closed market window is a valid refusal rather than an error to retry.
The boundary should be explicit in both code and records. Otherwise a successful result proves only that the mechanism worked, not that it was permitted to run.
This is also where logs become more useful than screenshots. A screenshot shows what the system looked like after the fact. A durable decision record can show the input, the rule, the authority, the refusal or action, and the postcondition. That record makes the next test possible.
The uncomfortable career lesson
Engineers are rewarded for shipping visible things. A new route, a larger model, a faster query, and a polished dashboard are easy to point at. Defining the missing state transition is less visible, especially when it prevents a week of implementation from starting.
But the ability to stop early is not a lack of ambition. It is a form of technical judgment.
My current checklist is short:
- What exact question is this system answering?
- What state changes when it succeeds?
- What state proves that it succeeded?
- Which inputs can legitimately cause that change?
- What is the valid refusal, and where is it recorded?
If those answers fit in a paragraph, implementation is usually straightforward. If they do not, adding code tends to make the ambiguity more expensive.
The best engineering improvement I made this week was not a new tool. It was moving the test to the front of the work. A ten-minute definition prevented an elegant solution to a problem I had not actually specified.
Share this post
You Might Also Like
The Record Cannot Authorize the Fix
A failure log can preserve the facts and still leave the system unchanged. The missing field is not more context. It is authority.
Career & Best PracticesThe Runbook Is Not the System
A documented fix is not a shipped fix. The difference is a control boundary: who can execute it, when, and what proves it happened.
Quantitative TradingA Signal Is Not a Decision
A signal says that conditions are interesting. It does not say that the portfolio should trade. The missing layer is the decision record between detection and execution.
Agentic AIThe Plan Is Not the Permission
An AI agent can produce a correct plan and still be unsafe to run. The plan describes an action; it does not authorize the write boundary that makes the action real.
Latest Blog Posts
A Signal Is Not a Decision
A signal says that conditions are interesting. It does not say that the portfolio should trade. The missing layer is the decision record between detection and execution.
The Plan Is Not the Permission
An AI agent can produce a correct plan and still be unsafe to run. The plan describes an action; it does not authorize the write boundary that makes the action real.
The Quote Is Not the Fill
A backtest can use the right price and still model the wrong trade. The missing variable is often not slippage. It is the time between seeing a quote and joining the book.
Related Tools & Demos
The QA Field Manual to Language Models
A free 24-chapter book. Start at βwhat is AI, really?β and finish with a small language model you built yourself β one that reads a failing Playwright test and proposes a fix you can run. Read it in your browser, or download the PDF or the Mac app.
View Source Code βMulti-Model LLM Harness
One interface to call any AI model β capability routing, fallback chains, budgets, circuit breakers, and a quality feedback loop. A practical architecture pattern write-up.
Automated Trading System
Multi-engine trading platform with real-time risk management, regime-based strategy selection, and automated order execution.
View Source Code β
Stay in the Loop
Get weekly insights on AI-driven QA, engineering leadership, and automation strategies.
No spam, ever. Unsubscribe anytime.