lnd/simulation
Olaoluwa Osuntokun 942f852092 simulation/lab: close exp-008 -- time-awareness re-evolves, loses anyway
In this commit, we record the verdict of the drift experiment, and it
answers both halves of the question cleanly while pointing them in
opposite directions. Time-awareness did re-evolve: the code_drift1
winner is the first evolved router with time-based logic, stamping
every liquidity belief, decaying its confidence on a 35 minute
half-life, expiring hard bounds outright after 20 minutes, and
interpolating between learned beliefs and the bimodal prior by that
confidence -- evidence softening with age, structurally unlike lnd's
penalty fading. Selection pressure produced exactly the mechanism the
experiment was designed to test for.

And yet it does not win. On the drift corpus itself the time-aware
winner scores 0.417 against the time-less champions' 0.455 and 0.457
-- and most damning, against gen2's 0.456, a router with the same
budget and seed style that never saw drift during evolution. lnd's
rationale for decay is validated; its necessity is not. At realistic
churn, hard evidence bounds degrade gracefully enough that a stale
bound costs one retry, which is cheaper than the information the
decay machinery throws away. Champions of record remain hb1 and
mx_c3, now validated on a fourth held-out tier.

We archive the winner's source beside the writeup and update the
notebook and CLAUDE.md accordingly.
2026-07-24 20:08:33 -07:00
..
champions simulation/champions: document each champion and the directory 2026-07-24 17:28:03 -07:00
command-center simulation: refresh dashboard for code_drift1 run 2026-07-24 20:04:51 -07:00
lab simulation/lab: close exp-008 -- time-awareness re-evolves, loses anyway 2026-07-24 20:08:33 -07:00
.gitignore simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
codex_lm.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
evaluate.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
evaluate_code.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
export_run.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
gen_scenarios.py routing: add virtual clock and background traffic to the simulator 2026-07-24 16:51:44 -07:00
preflight.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
README.md simulation: point README at durable gepa clone and uv 2026-07-24 13:04:18 -07:00
refresh_dashboard.sh simulation/command-center: add paradigm-ceiling section and drift page 2026-07-24 17:31:33 -07:00
run_gepa.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00
run_gepa_code.py routing: add virtual clock and background traffic to the simulator 2026-07-24 16:51:44 -07:00
run_gepa_omni.py simulation: add GEPA optimization harness 2026-07-24 13:01:06 -07:00

Routing Optimization Harness

This directory holds the GEPA-based optimization harness for lnd's pathfinding. The core idea: lnd's real routing code (or a candidate replacement algorithm) runs against an in-process simulated Lightning Network with hidden liquidity, an evaluator scores the outcome, and a reflective LLM optimizer (GEPA) proposes improved candidates from the failure feedback.

Components

Piece Where What
Simulator routing/sim_*.go In-memory LN with hidden balances; real pathfinding + mission control run unmodified against it
CLI cmd/routesim params JSON + scenario file in, attempt traces + aggregate JSON out
Candidate slot cmd/routesim/candidate_impl.go A complete routing algorithm behind --router=candidate; swapped per candidate via go build -overlay
Corpus gen_scenarios.py train/val/test scenario files: topology + liquidity seed + payment batch
Evaluators evaluate.py, evaluate_code.py score = success rate small saturating penalties for attempts and fee ppm
Runners run_gepa.py, run_gepa_code.py parameter mode and code mode optimization
Reflection LM codex_lm.py GEPA LM protocol via codex exec headless (default gpt-5.6-sol)
Lab notebook lab/ running log of experiments, results, ideas

Quick start

# Build the simulator binary.
go build -o /tmp/routesim ./cmd/routesim

# Generate a scenario corpus.
python3 simulation/gen_scenarios.py --out /tmp/corpus

# Score the lnd defaults on one example.
cd simulation && ROUTESIM_BIN=/tmp/routesim python3 evaluate.py /tmp/corpus/val/example_000.json

# Compare lnd stack vs the candidate router on a scenario file.
/tmp/routesim --scenarios /tmp/corpus/val/example_000.json --router=lnd    --traces=false
/tmp/routesim --scenarios /tmp/corpus/val/example_000.json --router=candidate --traces=false

# Full optimization runs. gepa must be installed from git main — a
# durable clone lives at ~/codez/gepa; prefer uv for the env:
#   uv venv /tmp/gepa-venv && uv pip install -p /tmp/gepa-venv \
#       "~/codez/gepa[full]"
# Also needs the codex CLI authenticated and OPENAI_API_KEY set.
ROUTESIM_BIN=/tmp/routesim python3 run_gepa.py --corpus /tmp/corpus --name run1 --max-evals 400
ROUTESIM_BIN=/tmp/routesim python3 run_gepa_code.py --corpus /tmp/corpus --name code1

The two optimization modes

  1. Parameter mode (run_gepa.py) — candidate = JSON of the existing heuristic's knobs (estimator choice, apriori/bimodal params, attempt cost, min probability). Validates the loop and tunes the current paradigm.
  2. Code mode (run_gepa_code.py) — candidate = the full Go source of candidate_impl.go, an entire routing algorithm implementing the routing.SimRouter interface. This is the paradigm-free path: the candidate sees only gossip, its own balances, and per-attempt feedback. Compile errors are returned to the proposer as feedback.

Anti-reward-hacking measures

  • Candidate routers receive a SimNetworkView wrapper, not the concrete graph, so hidden balances and liquidity mutation are unreachable.
  • evaluate_code.py rejects candidates using unsafe, reflect, os/exec, network packages, etc.
  • Selection happens on a val split; a sealed test split is only used for final reporting.
  • The source's own channels are rebalanced 50/50 before each batch so scores measure routing skill, not sender funding luck.

Command center

command-center/ holds a static dashboard site (serve with python3 -m http.server from that directory).