Can one knob make this book take more risk — more profit, more losses — and less risk, safely? Yes. But three things sit upstream of it, and a lever added today would be a knob wired to nothing.
One config number scaling two fields of one dataclass. It reaches every risk scope because D-098 already made them all derive from the book cap.
It cannot ship first. The seed floor — not Kelly, not the competence ladder — is what actually sizes positions today, and the drawdown brake it would rely on has no contacts.
Evidence: tests/scaffold_risk_appetite.py — the real
sizing.size_position and competence.assess, driven over SPY's own
resampled returns at the production estimator's holdout-fitted inflation.
The live 766/758 spread was bought for $1.67 against a bootstrap fair value of $2.45. Simulating it at its traded price hands the agent a 32% mispricing and every setting looks brilliant — the first version of this simulation showed a minimum-appetite book turning $100k into $734k, and I nearly believed it.
The legs are therefore repriced to zero EV under SPY's own history at
zero drift, so edge enters only through a stated drift. Verified in the scaffold header: EV
at zero drift is +$0.3/contract and P(profit) lands exactly on the break-even
probability.
At the traded price, full Kelly on the structure is 0.48. Fair-priced,
it is 0.075. Every conclusion here turns on which number is real — and
the earlier scaffold_risk_posture.py used the first one.
Full Kelly on a realistic claimed edge is 0.075. At SCALE the tier multiplier is 0.138, so
Kelly asks for 1.04% of equity — below the 2.2% seed floor.
sizing takes max(kelly, floor), so the floor wins.
| ×2 applied to, at SCALE | size | change |
|---|---|---|
| book cap, and the two caps under it | 2.01% | inert |
| Kelly multiplier | 3.02% | +50% |
| seed floor | 4.27% | +112% |
| Kelly + caps — the obvious proposal | 3.02% | +50% |
| Kelly + caps + floor | 4.27% | +112% |
A lever attached to the caps alone moves nothing. That is this project's most expensive bug class — the compactor, the cache and the shared session all shipped as code that ran and did nothing.
SEED_FRACTION is one constant for all four tiers and it binds at three of
them, so demotion changes the tier and not the size.
| at neutral appetite | EXPLORE | ESTABLISH | SCALE | MATURE |
|---|---|---|---|---|
| position size | 2.01% | 2.01% | 2.01% | 2.26% |
An 11% drawdown demotes MATURE → EXPLORE and cuts the next trade by 13%. The ladder is a circuit breaker with no contacts — and it is exactly what an aggressive setting would be relying on.
shrink_probability inverts below 50%.The docstring says “pull toward the observed base rate”. decisions.md says so
at D-013, D-047 and D-076. Calibration.base_rate is computed and displayed. The
code hardcodes 0.5, and the live base rate is 28%.
| stated | shrunk | effect |
|---|---|---|
| 20.0% | 26.9% | raised |
| 39.6% | 42.0% | raised |
| 65.0% | 61.6% | lowered |
For every claim below 50% — which is every long debit spread, the structure class this book trades — the shrink makes the agent more confident and sizes it larger. Kelly on the live structure is 0.111 / 0.075 / 0.035 depending on whether you shrink to 0.5, don't shrink, or shrink to the base rate: a 3× span set by one constant. A lever multiplies whatever Kelly produces.
500 paths × 50 trades, SPY's own returns, drawdown demotion live in the loop. Median terminal equity from a $100,000 start, as deviation from flat.
At 2.00× the lever buys +$24,413 of median upside when the thesis is right and costs −$35,206 when it is wrong. The red bar overtakes the green past 1.00× and never gives it back.
| appetite | median (right) | mean DD | median (wrong) | mean DD | P(DD>20%) |
|---|---|---|---|---|---|
| 0.25× | $103,592 | 4.2% | $95,439 | 7.1% | 0.0% |
| 1.00× | $114,364 | 16.4% | $81,407 | 26.8% | 76.6% |
| 2.00× | $124,413 | 30.9% | $64,794 | 47.1% | 99.0% |
Expected log growth under a belief mixture. The only question the operator has to answer is how sure are you the edge is real?
At a coin flip on whether the edge is real, the optimal setting is the minimum. That is the honest position for a book with 29 forecasts, zero attributed positions, and no resolved evidence its theses carry edge. The lever's first justified use is downward.
This is why the range is asymmetric — [0.25, 2.0] is two halvings down against
one doubling up. Turning it down is nearly free: at 0.25× a real edge still compounds while
the wrong-thesis loss more than halves. Turning it up needs ~70% confidence.
# config.yaml
trading:
# 1.0 = the posture the ladder alone would choose. Clamped to [0.25, 2.0].
risk_appetite: 1.0
# competence.py
def with_appetite(p: Competence, a: float) -> Competence:
a = min(2.0, max(0.25, a))
return replace(p,
kelly_multiplier=min(KELLY_CEILING, p.kelly_multiplier * a), # 0.50 = half Kelly
book_cap=min(BOOK_CEILING, p.book_cap * a)) # 0.35 absolute
book_cap. One multiplication reaches every risk scope and they cannot
desynchronise. One config key, one function, two assignments.Two things a lever could move look similar and are not.
p > 1/(1+b) have
lower expected return and higher variance. There is no curve to sit on.
It is strictly worse on both axes, and it breaks PILLAR-1.So an “aggressive” setting that loosened the gate would not buy risk. It would buy losses. Verified: maximum appetite on a structure with no claimed edge still returns 0 contracts — the gate sits upstream of every appetite multiplication.
The same move D-098 made for the other three scopes, at a share that leaves EXPLORE
untouched: seed_fraction = book_cap × 0.22.
| tier | floor now | floor derived |
|---|---|---|
| EXPLORE | 2.2% | 2.2% unchanged |
| ESTABLISH | 2.2% | 3.3% |
| SCALE | 2.2% | 4.4% |
| MATURE | 2.2% | 5.5% |
An 11% drawdown then cuts the next trade by 63% instead of 13%. But it is not a safety improvement on its own — it raises the base, so swapped in at the same appetite it loses more, brake and all. Monte Carlo, wrong thesis:
| config | median | 5th pct | mean DD | P(DD>20%) |
|---|---|---|---|---|
| constant floor, 2.00× | $64,815 | $35,344 | 47.3% | 99.0% |
| tier-derived, 2.00× not comparable | $60,963 | $33,620 | 50.9% | 100.0% |
| tier-derived, 0.85× — matched peak size | $80,983 | $63,239 | 27.9% | 86.2% |
At matched size the brake is worth a great deal: mean drawdown 47% → 28%, 5th percentile $35k → $63k. The derived floor buys responsiveness; the safety comes from responsiveness plus a recalibrated neutral appetite. It ships as a pair, not as a drop-in.
| case | behaviour | mitigation |
|---|---|---|
| Appetite cut while the book exceeds the new cap | Refused on the book cap; existing positions untouched — sizing gates new risk and never liquidates. | Correct, but the cap is a target on the way down, not an invariant. Must be reported, or an operator reads an over-cap book as a bug. |
Appetite 0, negative, or 100 |
Clamped to [0.25, 2.0]. | Log the clamp — a silently clamped input is a config the operator thinks they set. |
position ≤ underlying ≤ book at every rung × appetite |
holds | Free: all three derive from book_cap, so one multiplication moves them together. |
| More evidence never means less size | holds | Preserved because appetite is a uniform scalar across tiers. |
| Max appetite at MATURE | Kelly ×0.446 (ceiling 0.50), book 35% (ceiling), one position 17.5%. | Both clamps bind, and say so. |
| 11% drawdown at max appetite | Still demotes to EXPLORE — appetite cannot switch the ladder off. | But the demotion must actually cut size, which needs §06. |
| Max appetite, no claimed edge | 0 contracts | The EV gate is upstream of every multiplication. |
cautious/bold) instead of a
float. Aliases can be layered over the same number later; introducing them first would put
two representations of one setting on disk.seed_fraction from the tier. Without it the ladder
is decorative, the drawdown brake has no contacts, and the lever needs a third field to
bite.risk_appetite. Now one number, two fields, and it
reaches everything.Steps 1 and 2 are worth doing whether or not the lever is ever built.
SEED_SHARE = 0.22 reproduces today's EXPLORE exactly, which makes it a safe
default and an unexamined one. It has never been fitted to anything.