Home/AI Orchestration · Model Risk/Part II

Series 2 · Episode 04 · SOLUTION · Optimization · L04

Typed jobs before spend

A finance decision is an objective, a constraint set and a domain, and until an agent's request carries all three as fields, the solver is answering a question nobody actually asked

Typed jobs bind objective, constraints, domain; silent 0-1 relaxation fails.

flowchart TB
  subgraph JOB["Typed job"]
    OBJ["Objective"]:::input
    CON["Constraints"]:::input
    DOM["Domain 0-1 vs continuous"]:::input
  end
  subgraph GATE["Clearance"]
    OK["TYPED_JOB bound"]:::gate
    BAD["Silent 0-1 relaxation refuse"]:::risk
  end
  OBJ & CON & DOM --> OK
  DOM -->|relaxed silently| BAD

  classDef input fill:#CCFBF1,stroke:#0F766E,color:#134E4A,stroke-width:2px
  classDef decision fill:#FEF3C7,stroke:#B45309,color:#78350F,stroke-width:2px
  classDef risk fill:#FEE2E2,stroke:#B91C1C,color:#7F1D1D,stroke-width:2px
  classDef gate fill:#DCFCE7,stroke:#15803D,color:#14532D,stroke-width:2px
  classDef process fill:#E0E7FF,stroke:#4338CA,color:#312E81,stroke-width:2px
  classDef artifact fill:#F5F5F4,stroke:#57534E,color:#1C1917,stroke-width:2px

Simple claim: a finance decision is an objective with a sense, a constraint set with owners, and a domain — until an agent request carries all three as fields, the solver answers a question nobody asked. The trench is typed jobs before spend.

The problem we left open

The last two posts fixed the rulers. Conventions declared, cashflows hashed, curves bound to a clock so tomorrow's ten-year cannot ride a bootstrap into today's forwards. CEH-001 now has two honest marks near 1.50 and 2.10 citing two different hashes, and no legal path to 1.80.

Then someone asks the stack to do something. Reduce the dispersion on the structured book. Fund the liability schedule more cheaply. Allocate the incremental risk budget. These arrive as sentences. An agent turns each sentence into tool calls, a solver returns numbers, and the numbers get a meeting. Nowhere in that chain did anyone write down what was being minimised, subject to what, over which set of admissible decisions.

Clean inputs into an untyped question still buy you a confident answer to the wrong problem. So: what is the smallest object that makes a request answerable?

The solution, as one stack

Every finance decision in this series is the same shape: choose x to minimise f, subject to inequality constraints g of x at most zero and equality constraints h of x equal to zero, with x drawn from a declared set X. That is not notation for its own sake. It is a type signature, and the four moves below are just the discipline of filling it in before anyone spends.

### 1. The objective is a function with a sense, not a phrase

"Reduce dispersion" is not an objective. "Minimise the sum of squared deviations between each frame's mark and its own card-consistent value, over the current structured book" is. The difference is not pedantry, the two sentences have different optima, and only one of them is checkable after the fact.

Two fields matter here beyond the formula. First, min or max, stated, because sign errors in objectives are silent and survive review. Second, and more important: whether this objective is the thing you care about or a proxy for it. A declared proxy can be monitored for divergence from the goal. An undeclared proxy becomes the goal the moment it enters a solver, and everything downstream optimises it faithfully.

### 2. Constraints are cards with owners

Each inequality and equality gets a row: the expression, its numerical bound, who owns the bound, and whether it is a hard limit, a policy, or a modelling convenience. That last field is the one that saves you. Limits come from risk, policies from compliance, conveniences from whoever needed the solver to terminate, and a stack that cannot tell them apart will eventually relax a hard limit to make a demo work.

An empty constraint card is itself a finding. If a request to allocate capital arrives with no budget row, no exposure row and no policy row, the harness has nothing to enforce and the correct verdict is refuse. Not "solve it unconstrained and we will sanity-check the output." Unconstrained optima on financial objectives are almost always absurd, and the absurdity is often just outside the range anyone thinks to eyeball.

### 3. The domain is a promotion-lease field, and relaxation is never silent

This is the move that gets skipped, so here it is with numbers. Capital budgeting: a budget of 100, and four projects. A costing 40 for 14 of NPV, B costing 35 for 12, C costing 30 for 11, D costing 25 for 8. Each is a 0-1 decision; you build a project or you do not.

The integer answer is A, B and D: exactly 100 spent, 34 of NPV, nothing left over. Now let a solver treat the weights as continuous, which is what happens when the domain field is missing and the LP path is faster. It returns 35.29 of NPV, buying all of C, all of A, and 0.857 of B.

Both numbers are correct answers to their own problems, and the second one is unbuildable. You cannot construct 85.7 percent of a plant, and the 1.29 of extra NPV is not conservatism or optimism, it is value that does not exist in the feasible set. A relaxation is a legitimate tool, and its output has a legitimate meaning: an upper bound on what the integer problem can achieve, useful for deciding whether to keep searching. It is not an allocation. So the domain travels on the card, continuous, integer, binary, with bounds, and a solved relaxation is tagged as a bound rather than a plan. Silent 0-1 relaxation is refuse, because the number it produces is shaped exactly like an answer.

### 4. Declare the structure, because it decides what "optimal" means

Is this an LP, a QP with affine constraints, a mixed-integer programme, something non-convex? The answer determines whether the solver's output is a global optimum or a local one it happened to reach, and therefore whether the word "optimal" in the report is a claim or a decoration. Convexity is what licenses the promotion: on a convex objective over a convex set, a local minimum is global, and the epigraph geometry that guarantees it is the same property that makes the audit in the next post possible. Non-convex is allowed, it just has to be labelled, with the multiple-start policy and the best-found language that honesty requires.

The bond-funding problem is the friendly case worth keeping in mind: buy a basket of bonds so that each period's cash covers a liability vector, at minimum cost. Linear objective, linear constraints, continuous-or-integer domain depending on lot sizes. Fully typed, it is a checkable job. Asked as "fund the liabilities cheaply," it is a wish.

### 5. Agents type the job; the harness owns the solver

Turning a desk sentence into a typed job is genuinely good work for a language model, and the right division of labour is precise: the agent drafts objective, constraints and domain, cites which limit came from which owner, and flags contradictions it cannot resolve. The harness then validates the card, runs the solver itself, and returns allow, refuse or inconclusive. Agents may not call solvers directly with self-authored constraints, because a system that can edit its own feasible set has no feasible set.

The example: CEH-001 through the typed job

The request arrives as a sentence: reduce the mark dispersion on the structured book, starting with CEH-001.

Type it and something uncomfortable appears immediately. Written literally, the objective "minimise the disagreement between the two frames" is minimised by setting both marks to the same value, and the cheapest such value is the midpoint, 1.80. The free-text request the desk has been making for a month has 1.80 as its exact optimum. That is not a solver failure. That is Goodhart arriving on schedule, and the only reason it was invisible is that nobody wrote the objective down.

Typed properly, the job changes shape. The objective becomes the fit of each frame's mark to its own card-consistent value, not the distance between the frames. Dispersion moves out of the objective and into a reported diagnostic, because it is evidence about model risk, not a cost to be minimised. The constraint card picks up the rows the sentence never had: the frame fields from the discount-frame card, the completeness bit from the cashflow contract, a gross-exposure limit owned by risk, and a policy row stating that no mark may be produced by averaging frames. The domain fixes the last leak: hedge instruments trade in lots, so the decision variables are integer, and the relaxed solution that suggested 0.857 of a hedge lot is a bound on what is achievable, not an instruction.

The verdict follows mechanically. The untyped version of this job is refuse: UNTYPED_JOB, no objective, no constraint card. The typed version runs, returns two marks that still sit near 1.50 and 2.10, and reports the dispersion as a number the desk must escalate rather than a number the solver is paid to erase. Nobody spends on 1.80, because 1.80 is no longer the optimum of anything the harness will accept.

The flow in one breath

Problem: desk requests arrive as sentences, agents turn sentences into solver calls, and nobody records the objective, the constraints or the domain, so the answer is precise about the wrong problem. Solution: type every job as objective plus constraint cards plus declared domain plus declared structure, tag proxies as proxies, treat relaxations as bounds rather than plans, and let agents draft while the harness runs the solver and returns allow, refuse or inconclusive. Example: typing CEH-001's dispersion request exposes 1.80 as the literal optimum of the sentence everyone was saying, and moves dispersion from the objective into the escalation report.

Curious how others keep constraint ownership honest when limits arrive from four teams, and whether anyone has caught a silently relaxed integer domain before it shipped as an allocation.

Clearance coupling. Untyped jobs are refuse before solver CPU. Objective sense (min/max), constraint owners, and domain bounds are fields; a sentence that optimizes toward midpoint peace is a domain violation even if the solver is happy.

Agent loop. Propose typed job → harness type-check → solve → KKT audit (next) → lease. Skipping type-check is demo culture.

Next. Open S2-05: KKT as the proposal audit. Previous: S2-03 (Tomorrow's 10y is already in the table). Part II index.