Essay · Mar 2026 · 9 min

The specification is the artefact the agent and I both edit

Asking a coding agent to build a detector produces code you then have to argue with. Asking it to write a rigorous specification first, then implement that specification, changes what you review and what you fix. The interesting part is not that this produces better code — it is that the specification becomes the only place a disagreement can be resolved.

Give a competent coding agent a pattern name and a paragraph of description, and it will write you a detector. It will run. It will produce output. The output will be wrong in ways you cannot localise, because the thresholds are inline constants, the rules are implicit in control flow, and the reasoning that produced them is gone.

You are now in the worst position in software: reviewing a plausible implementation of an unstated specification. Every disagreement — this fires too often, that anchor is misplaced — has to be litigated against code, and the fix is a patch to a magic number whose provenance nobody knows. Do that a few times and you have a detector nobody can explain, tuned to whatever examples happened to be in front of you.

The fix that worked for me is structural, and it is mostly about what artefact the human reviews.

Separate the contracts

Instead of one prompt producing one program, I split the work into stages, each governed by a written contract that says what that stage delivers and what it is forbidden to touch.

A specification-writing contract. Its output is a document, not code: overview, a table of every configurable parameter with defaults and types, minimum data requirements, how extrema are identified, the geometric rules of the formation each with a numbered ID and a formula, the breakout condition, target and stop derivation, invalidation rules, and the output schema. Two rules in that contract do nearly all the work. First: every threshold must be a named configurable parameter, never a magic number buried in prose. Second: do not invent novel heuristics — stick to what a standard reference would describe, translated into algorithmic rules.

A detector contract. Pure analysis. Takes a chunk of price data, returns structured metadata about instances found. Explicitly forbidden from file I/O, sliding-window iteration, deduplication, plotting, or parallelism — and the contract says outright that if you find yourself importing a plotting library, you have crossed the boundary.

A renderer contract. Everything the detector is banned from: iteration over the data, deduplication across overlapping windows, drawing, file naming.

An evaluation contract. Scores rendered output against the specification, which I will come back to because it is the piece that makes the loop close.

The stages run in order and none may begin before the previous finishes. That constraint sounds bureaucratic and turns out to be the point.

What changes when the spec is the deliverable

The immediate benefit is legibility, and it is not a small one. A numbered rule with a formula and a named parameter can be read by a domain expert who does not program. They can tell you rule 2.3 is too strict without reading a single line of Python — and they can tell you before the implementation exists, which is when it is cheap.

But the effect I did not anticipate is what happens to disagreement.

When output is wrong and the artefact of record is code, the argument is "the detector is firing too much," and the fix is somebody changing a constant. When the artefact of record is a specification, the same complaint has to be localised: which rule admitted this? And that question has an answer, because every threshold has a name and every rule has an ID. The fix is a change to a named parameter with a stated default, and the implementation is regenerated to match.

The specification becomes the single place a disagreement can be resolved, and that is worth more than any improvement in the code it generates. This is the same claim I have made about informal chart-pattern descriptions generally — that the specification is the deliverable and the detector is a by-product — but the agentic setting makes it operationally forced rather than merely advisable. When code is cheap to regenerate, the code stops being the asset. The reviewed, argued-over document is the asset, and the code is a build product.

That has an uncomfortable corollary for how this work gets estimated. The time is not in implementation, which is now fast. It is in specification and evaluation, which are not, and which look like "writing documents" to anyone measuring progress in commits.

The loop only closes if something grades the output

A specification and an implementation are still two artefacts that can silently disagree. Code review does not catch this well, because the code can be a perfectly faithful implementation of a rule that turns out to be wrong about the world.

What closes the loop is evaluation against rendered output — the same charts a human would look at — scored on a rubric that references the specification's own rule IDs.

The rubric I used scores each detection on five dimensions, zero to three: are the anchor points where a skilled analyst would put them; does the shape actually resemble the named pattern; is the breakout genuine; are the target and stop consistent with the spec's formulas; and, standing back, is this a valid instance at all. Composite below eight gets flagged as a likely false positive. Two details matter more than the dimensions: the rubric demands explicit calibration — a top score should be rare, most legitimate patterns should land in the middle — and it requires cited rule IDs, with an instruction not to invent one when unsure. A grader that cannot point at a violated rule must say so in free text rather than fabricate a citation.

This makes the evaluation a measurement of spec-implementation agreement rather than a vibe check. When the score is low, the follow-up question is whether the specification was wrong or the implementation diverged from it, and those are different repairs.

What the evaluation pass finds, and why it is the useful half

The characteristic first-pass outcome, for a formation with several free parameters, is far too many detections — a set large enough that nobody will inspect it, containing genuine instances buried in noise. That much is predictable. What is not predictable is why, and this is where scoring rendered output earns its place.

The evaluation names specific causes and — crucially — tags each as a spec-level or an implementation-level problem. In my experience the spec-level ones dominate, and they have a family resemblance worth naming:

A structural precondition left optional. Many patterns are only meaningful in a particular context — a reversal formation means nothing in a flat range. If the spec makes the prior-trend requirement a parameter defaulting to off, the detector will dutifully find the shape everywhere, and every one of those is a false positive that no amount of geometric tightening removes.

A minimum size small enough to admit noise. Any shape defined by a handful of turning points will occur constantly at small scales. The bound that separates structure from noise is a real modelling decision and it usually is not in the textbook description.

An anchor permitted at a degenerate position. Let a defining point sit at the very edge of the formation and the shape collapses into a different pattern that still satisfies every stated inequality. Degenerate configurations are the most common way a rule set admits things it never meant to.

A threshold set where the test does nothing. A volume filter with a ratio of exactly 1.0 is not a lenient filter, it is an absent one. These are easy to miss in review because the parameter exists, is named, and appears to be doing work.

None of those are bugs. Every one is the code faithfully implementing a rule that was wrong about the world — precisely the failure that code review cannot catch, because the code is correct, and that rendered-output evaluation does catch, because the chart is visibly not the pattern.

Correcting defaults of that kind moves a detector from far-too-many to far-too-few, and both extremes are informative. The second regime is the more dangerous one to stop at, because a small set of clean detections looks like success. The same evaluation that flagged the false positives will tell you recall has collapsed, and the disciplined next move is to recover it by loosening exactly one lever at a time — starting with a quality threshold rather than reopening the geometry rules, so that each change has an attributable effect.

I am describing the shape of the process rather than reporting numbers from it, deliberately. The specific detection counts and rubric scores from a client engagement are not mine to publish, and they would not transfer anyway. What transfers is the categories: these four spec defects recur across quite different formations, and knowing to look for them is most of the value.

One thing worth being clear about regardless. These scores measure agreement between a specification and its implementation, as judged against rendered charts. They say nothing whatever about whether the pattern predicts anything. Detection quality and predictive value are separate questions, and this loop only measures the first.

Where I would not push this

The failure mode of this whole approach is that a model grading model-generated output can share the generator's blind spots. If both stages misunderstand the pattern in the same direction, the loop will happily converge on a confident, well-documented, wrong detector. Nothing internal to the loop catches that. Human review of the specification — by someone who knows the domain and never sees the code — is the only defence I found, and it is the step most likely to get skipped because everything else is automated.

The second limit is that rubric scores are estimates from small samples. Scoring a few dozen rendered charts is not a large evaluation set, and small differences in the fraction judged acceptable sit well inside what sampling noise produces. Treat a change of regime — far too many detections becoming far too few — as real, and treat a few points of composite score as noise until a larger sample says otherwise.

What I would carry anywhere: make the artefact you review the artefact you can argue with. Agents made implementation cheap enough that the specification is no longer the preliminary. It is the product, and everything downstream of it — including the code — should be regenerable from it.