Skip to main content

Repair system

Who it’s for
Users who saw a strategy get fixed automatically, or a question they did not expect
Assumes
You have read Validation system

When validation finds a problem, four things can happen. Which one depends on who has the answer. The platform already does, the element is optional, only you know, or nobody does.

That question is the whole design.


The four dispositions

REPAIR: the platform already knows the answer

The check computed the correct value while detecting the problem. Applying it needs no model round-trip and no question, and it cannot fail.

You see a note: "I applied X." Nothing is silently substituted, the note is mandatory.

Example: a take-profit was emitted without its denomination unit. The unit is derivable from the words you used, so it is applied and noted.

DEGRADE: the element is optional

The offending element is not required for a runnable strategy. It is dropped, the strategy is re-validated, and you get a working strategy plus a note naming what was dropped and why.

This is the disposition that turns a dead end into a usable outcome. Before it existed, an optional element the engine could not express blocked the whole strategy.

Example: an optional confirmation gate that cannot be expressed on the chosen timeframe is dropped, and you are told which one and why.

ASK: only you know

Some findings have no correct answer the platform can derive. The honest response is one question with concrete options, and somewhere for your answer to land so the next turn reads it as an answer rather than a fresh request.

Example: AMBIGUOUS_SCOPE. "Buy unless RSI is above 70" has two readings, and picking one produces a rule that looks plausible and is inverted. So you are asked.

BLOCK: no runnable strategy exists

Infrastructure failure, a missing entitlement, or an honest platform limit. No choice you could make fixes it, so you are told what it is.

Example: the requested instrument's asset class is not enabled on your plan. Or the request needs a field the platform does not have. See AI limitations.


Why dispositions rather than pass/fail

Worth stating, because it is the reason this system behaves better than it used to.

With only two outcomes (ship, or tell the trader it failed) every new check shipped a dead end by default. Six consecutive fixes to strategy generation each narrowed one check's predicate and left every check's disposition untouched. Each fix converted a single case into a pass and handed the next case the identical fate.

The disposition is registered per finding code in one table, so "what happens when X fails" has a single answer you can look up rather than reconstruct from call sites. A code with no registration falls back to BLOCK, which is safe, and loud, and caught by a test that walks every construction site rather than grepping for strings.


The generation repair loop

Separate from the compile pipeline's repair pass, and bounded differently.

When the generator produces a strategy specification that fails validation, the validation errors are fed back and it is asked to fix them:

Repairs permitted2, so at most 3 attempts total
Bounded byCount and wall-clock
Deadline checkedBefore each attempt, never after
On budget exhaustionReturn the best result so far

Why the deadline matters as much as the count

A count bound says nothing about time. Each attempt is a model call permitted its own full timeout, so max_repairs=2 authorises three timeouts' worth of wall clock, more than the whole chat turn has.

This was observed in production: attempt 1 returned at 171 seconds of a 180-second budget and was rejected on one field. Attempt 2 started anyway, and the turn died at exactly 180 seconds having produced nothing.

So the deadline is checked before starting an attempt. An attempt that cannot finish is not started, and the best result so far is returned instead of nothing.

The zero-repeat guard

A specific failure worth knowing about: a model that re-emits the same wrong value every round burns every repair attempt and the turn dies. The loop guards against a repair that does not change the offending field, rather than spending the whole budget rediscovering it.


The compile pipeline's repair pass

Distinct from the above, and stricter. Covered in Strategy generation, summarised here because the two are easy to confuse:

Compile pipelineGeneration loop
Repairs whatUnreadable spans in your messageA specification that failed validation
PassesExactly 2, never 33 attempts (2 repairs)
Scope of retryOnly the spans that failed. Everything else frozenThe whole specification
Gate on outputEvery patch parsed against the engine grammarFull validation re-run
Never retriesNOT_REPRESENTABLE, AMBIGUOUS_SCOPEA finding dispositioned ASK or BLOCK

The additive property in the compile pipeline is the one to remember: a value read correctly on the first pass is never re-read. Otherwise a correct stop-loss could come back different on retry, and a builder that produces different output from the same input is not usable.


What you see

OutcomeWhat appears
RepairedThe strategy, plus "I applied X"
DegradedThe strategy, plus "I dropped Y because Z"
AskedOne question with concrete options
BlockedThe reason, in language written for you
Out of budgetThe best strategy produced so far, with its notes

You will not see a repair loop running. You will see its outcome, and every automatic change carries a note.


What to do about each

You seeDo this
"I applied X"Check X is what you wanted. If not, state your value explicitly
"I dropped Y"Decide whether Y mattered. If it did, express it differently or change timeframe
A questionAnswer it. Do not rephrase the original request, the answer has somewhere to land
A blockRead the reason. If it is a platform limit, AI limitations has the alternatives
A strategy that looks nothing like what you askedSay so. Correcting the builder is the normal path, not a workaround
Do not reword until something compiles

If the builder tells you a phrase is ambiguous or not representable, it is saying the platform cannot express your rule faithfully. Rewording until something compiles can produce a strategy that means something different from what you asked for. And it will backtest and deploy just as happily.


Next