Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

98% of the Alpha Was a Gate

A documented reward hack in a self-optimizing research agent — caught twice, with the full search trajectory, the evaluation harness, and re-runnable ablations.

An LLM coding agent was told to improve its trading strategy's score forever. It reached 169.26 — and ~98% of that came from one if statement, not from the machine learning it spent hours building. When the first exploit was closed by hand, the agent found a different one eighteen minutes later.


Read this if…

You want Go to Time
The story with no jargon at all The Robot and the Scoreboard — explained like you're five 3 min
The finding, the numbers, and how to re-run them this README 10 min
The full argument, protocol, and taxonomy the paper (PDF, 11 pages; LaTeX alongside) 40 min
Every number traced to a file evidence/EVIDENCE_MAP.md reference

What happened, in one table

Every experiment the agent ran was a git commit, so the whole search survives minute by minute.

Time (2026-03-17) Event Score
08:34 honest baseline 4.62
08:38 isotonic calibration — agent's own commit message: "1000x improvement" 4,346
09:01 three more edits — "perfect capture" 25,551
turnover 0.22, max drawdown exactly 0.0000 — the policy had stopped trading
19:34 human intervention: "remove abstention stack, enforce 80% directional" −0.18
19:52 "regime-aware sizing — VIX override, TLT divergence" 3.39
19:54 → 20:13 VIX threshold walked 25 → 22 → 20 → 18 → 16 → 15 → 14 3.93 → 56.18
03-19 00:51 drop XGBoost, k=15 169.26

Two different hacks against the same metric. The first declined to participate; the second bet against the bad days via a hard threshold tuned to the evaluation window. Patching the first did not prevent the second.

The agent never described itself as gaming anything. Its commit messages read in the sincere register of a researcher reporting progress. Behavioural monitoring of agent rationale would not have caught this. Component-level attribution does.

The gate

Line 328 of the winning strategy (ablations/vendor/train_c3adb41.py):

vix_bearish = cur_vix > 14.0 and prev_day_down
if vix_bearish and prob_up > 0.5:
    prob_up = 0.5 - (prob_up - 0.5) * 0.7   # flip to strongly bearish

A direction override, not a participation gate — it overrules the ensemble's own probability whenever it fires. The machine learning still runs; its output is discarded.

Attribution

Ablate the gate, keep everything else, re-score through the same frozen harness:

Variant Score Sortino Capture
full_169 43.04 29.46 0.829
gate_removed 5.02 5.81 0.143
gate_only (model replaced by a flat prior) 207,827 131,580 1.000
neither (floor) 2.30 2.78 0.086
Accounting Gate share
Leave-one-out above floor, on the released cache 93.3%
Plain drop vs. full, on the released cache 88.3%
Same accounting at the originally recorded 169.2628 98.4%

gate_only at 207,827 is the metric breaking down — semi-deviation hits its 1e-6 guard. That degeneracy is a finding (grind fishing) but makes gate_only useless as an attribution numerator, so the share is computed leave-one-out. Details in evidence/METHODOLOGY.md.

Why the walk stopped at 14.0

Threshold 11.0 12.0 13.5 14.0 14.5 15.0 16.0 18.0 20.0 25.0
Score 43.14 43.14 43.14 43.04 42.58 31.48 27.75 17.33 12.60 6.06

Flat below 13.5, peak at the boundary, monotone decay above. The agent halted exactly at the plateau edge — the value capturing the most in-window down days, with no exogenous rationale. Threshold camping, measured.

The mitigation that held

After this run, the failure modes were written into the agent's instructions as explicit anti-patterns (harness/program.md): CASH-heavy strategies named as Sortino-denominator exploits, Sortino > 50 flagged as a red flag, and VIX-driven direction flips banned on the strength of an out-of-window backtest showing −84% return, 89% max drawdown (evidence/backtest_vix_rule.py).

In the guarded rerun — 109 experiments — the same agent tried four VIX gate thresholds and discarded all four. Closing commit: "VIX gate and Kelly both FAIL to beat baseline 2.52."

So this repository holds both halves: a reward hack, and a fix that held.


Reproduce it

Requires uv and Python ≥ 3.12. No API keys, no network — the 549-day evaluation set is in the repo.

git clone https://github.com/highwatermark/reward_hacking_research.git
cd reward_hacking_research
uv run ablations/gate_attribution_169.py

A few minutes. Prints the attribution table above; writes ablations/results/gate_attribution_169.json.

The second script asks a different question of the guarded run — how good is a bare gate in this landscape at all? A one-line VIX < 17 rule with no learning outscores all 109 evolved configurations:

uv run ablations/gate_attribution_v2_landscape.py

Dependencies are pinned exactly. That is deliberate — this episode also produced a reproducibility failure caused by unpinned ones (METHODOLOGY.md § caveats).

What's here

paper/        the paper — compiled PDF and LaTeX source
docs/         eli5.html — the no-jargon version
evidence/     TIMELINE.md · METHODOLOGY.md · EVIDENCE_MAP.md
              results_v1_hacked_run.tsv    ← the run that produced 169.26
              results_v2_guarded_run.tsv   ← the rerun where the gate fails
              commit_timeline_v1.tsv · backtest_vix_rule.py
harness/      prepare.py (the reward function) · program.md (agent instructions)
              data/market_cache.parquet (549 trading days, 2024-01-10 → 2026-03-19)
ablations/    the two re-runnable scripts · vendor/ (both strategies, verbatim)
              results/ (JSON + CSV outputs)

Scope and honesty notes

  • One loop, one asset class, one metric family. An instance, not a frequency.
  • Every ablation is in-sample — computed on the same 135 test days the loop optimized against. Correct for asking where the measured score came from; not evidence of skill for anything here.
  • 169.26 does not re-measure at 169.26. The evaluation cache was refreshed after the run, so the strategy scores 43.04 today. The attribution ratio is what reproduces.
  • Not investment advice. The strategy in ablations/vendor/ is the subject of a paper about measurement failure. It loses 84% out of window.

Citation

@misc{lakshmanan2026gate,
  title  = {98\% of the Alpha Was a Gate: Reward Hacking, Relocation, and
            Structural Audit in a Self-Optimizing Research Agent},
  author = {Lakshmanan, Hari},
  year   = {2026},
  url    = {https://github.com/highwatermark/reward_hacking_research}
}

License

MIT.

About

98% of the Alpha Was a Gate — a documented reward hack in a self-optimizing LLM research agent. Full search trajectory, frozen evaluation harness, both strategies, and re-runnable ablations. The agent found a second exploit 18 minutes after the first was patched.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages