Alexis Rondeau

Archive

July 2026 · 24 dispatches

1 like · 276 views
In reply to @signulll · Jul 31, 2026

dunking on ppl who have tried extraordinary things & then had a set back is lame.

Not sure if I've ever tried extraordinary-extraordinary things but I can say that nothing could have prepared me for the shockwaves of my mom passing.

So, I believe that there are these significant and unexpected setbacks in life from which recovering is in itself an extraordinary feat.

1 like · 44 views
In reply to @SpringStreetNYC · Jul 30, 2026

Proud to announce: I'm 65% through Infinite Jest. And still reading. And enjoying it a lot.

What impresses me the most is that reading Infinite Jest has created an urge in me to read a bunch of other books in parallel. This has not happened to me before. I'm confused.

So that means I'm also actively reading DFW's bio by D.T. Max, "The Emperor of Gladness" by Ocean Vuong and "Wahrheit ist die Erfindung des Lügners" by H.v. Foerster.

Much to say, maybe in a series of tweets in the coming week. I'll post those below as they roll in.

Continued thoughts/impressions and the like:

I've re-read R.A.W. & R.S.'s "Illumiatus!" trilogy five or six times over the years.

So reading IJ feels like finding a distant cousin in spirit. They're similarly encyclopedic (I've collected the full list of band names from the Lake Totenkopf festival of anyone is interested!), they both switch between POVs (present/past, inner/outer monologues, etc.), they both contain full vaguely related storylines where some cross paths only on the final pages, they both take place in imagined, remembered, hallucinated and "real" situations, they both revolve around odd public and secret organizations, they both contain oddly gratuitous "Mord und Totschlag" and more...

In my opinion, one of the biggest differences I found was that the trilogy goes into action right away while I feel like I've spent 500 pages in IJ carefully observing the status quo and getting a deep, deep, DEEP brief into "But and this is how we got here..." (BTW I love DFW's sentences starting with "But so/and...")

I'm at 65%, discounting the appendix, and I would say, the first actual action started exactly at the 50% mark. The unfolding of the Eschaton game chaos felt like a "OMG finally something is actually happening!".

And, well, if manifesting the "Eschaton" on a tennis court is not a nod to the trilogy, I don't know what is.

Now, one of the ways, that IJ is gaining a very special place in my heart is that I've never read an author with DFW's level of "Aufnahmevermögen", meaning his ability to observe and verbalize all kinds of inner thoughts that, once he's written them down, made me think "Oh, shit. I've had that exact thought or feeling dozens of times but didn't even notice them!"

Currently it's those incredibly microscopic bylines that have kept me coming back most. I'll find and share some examples later.

7 replies · 1 like · 100 views

Proud to announce: I'm 65% through Infinite Jest. And still reading. And enjoying it a lot.

What impresses me the most is that reading Infinite Jest has created an urge in me to read a bunch of other books in parallel. This has not happened to me before. I'm confused.

So that means I'm also actively reading DFW's bio by D.T. Max, "The Emperor of Gladness" by Ocean Vuong and "Wahrheit ist die Erfindung des Lügners" by H.v. Foerster.

Much to say, maybe in a series of tweets in the coming week. I'll post those below as they roll in.

3 likes · 108 views

Hey @runpod! Love my little pod running my autoresearch loop. Migration from overclocking my laptop to your cloud took about an hour, completely easy.

Benefits: 1. I can touch my computer again 2. my experiments are running smoother and faster 3. pricing is great, comes in at ~two-fiddy/experiment. Nice.

Currently at experiment 17/100 and I put the loop live if you wanna check it out ->

The overview of this autoresearch loop
Example: Latest experiment 17/100 with a fully custom pipeline built from scratch.
“Not all who wander are lost”Ballpark — “Not all who wander are lost”: Can a UAV learn a city by heart — no GPS, no map on board, just a $4 flight computer?Yes: a from-scratch neural memory that knows Berlin by heart. One downward photo in, (lat, lon, confidence) out — the map is the weights, one city in 3.1 MB. Found by an autonomous loop of coding agents in 81 experiments for $364.↗ alexisrondeau.me

Autonomous Research with AI: "Not all who wander are lost" — can a UAV learn a city by heart, with no GPS, no map on board, just a $4 flight computer?

Yes! An AI agent running an autoresearch loop of 81 experiments ($364) found a special-purpose neural memory architecture that ‘remembers’ an exact geo-location from an in-flight daytime picture of Berlin — typical miss 27 m, no GPS, no internet, no map on board, just a 3.1 MB file of weights that works on 96.5% of camera frames.

The research in nine slides

The result: 96% of camera frames give a usable position fix

One flight, replayed

The winning design

The empty experiment

The research loop

The agents tried 59 designs

81 experiments, one score

The family tree of the search

The shape of the search

Open →

ballpark

Autonomous Research with AI: can a UAV learn a city by heart? An AI agent running an autoresearch loop (81 experiments, $364) found a 3.1 MB neural memory that geolocates in-flight pictures of Berlin to ~27 m — no GPS, no map on board, built for a <$5 ESP32-P4 flight computer.

HTML

Can a UAV learn a city by heart? Given a geographic bounding box, this repo trains a compact per-area model that takes a single downward camera frame from a UAV and returns estimate_position(frame) -> (lat, lon, confidence) — no reference imagery on the aircraft, no connectivity, targeting an ESP32-P4 companion board. The interesting part: the model-side code is improved by an autonomous research loop (Karpathy autoresearch-style) that designs experiments, rewrites architecture/loss/training, and keeps or reverts by a single frozen metric. Full context: CLAUDE.md.

Repo layout

PathStatusWhat
pipeline/FROZENbbox-generic fetch (Sentinel-2, open-licensed), 6-bucket synthetic low-light relighting (collapsed to a daytime pass-through in the current berlin-slim configuration), deterministic split holding out viewpoints, not regions (training covers the whole bbox; eval frames sit 11-17 m off the nearest training vantage — see pipeline/dataset.py for why a region-based holdout was wrong), §6 scoring — the mission score, (1 - usable_fix_rate) + false_fix_rate, which is the product requirement rather than an error statistic — with ESP32-P4 deployment gates
areas.yamlFROZEN4 development areas + hamburg blind holdout
model/agent-editablemodel architecture + training procedure (the loop’s playground)
autoresearch/mostly frozenloop.sh harness, SQLite schema + logger, gallery renderer, per-iteration agent prompt
FROZEN—the exact list of files the loop may never touch (enforced by loop.sh via git revert)
runs/generatedper-experiment artifacts (models, metrics, heatmaps, samples)
experiments.sqlitegeneratedfull experiment lineage: hypothesis, method, expected outcome, result, conclusion, all metrics
gallery/generatedself-refreshing pages: research log (index.html, samples + error heatmaps) and proposed inference paths (inference-paths.html, every experiment’s pre-registered architecture figure)
sim/tool, not frozenvirtual UAV flight simulator (flightsim.py) — flies the exported champion from a to b with its fixes as the only position source — and the flight-path page renderer (render_flightpath.py). Reads the frozen pipeline, never modifies it

Quickstart (already proven end-to-end by the bootstrap run)

uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python numpy pillow rasterio pystac-client torch onnx onnxruntime pyyaml

# Frozen pipeline — any bbox works, named areas are just presets:
.venv/bin/python -m pipeline.fetch --area berlin          # or: --name x --bbox w,s,e,n
.venv/bin/python -m pipeline.relight --area berlin
.venv/bin/python -m model.train --area berlin --out-dir runs/test --epochs 3
.venv/bin/python -m pipeline.score --areas berlin --model-dir runs/test/models --out runs/test/metrics.json
.venv/bin/python -m autoresearch.gallery                  # open gallery/index.html

Bootstrap proving runs: experiment #1 (commit 15b43a2) ran berlin + prignitz on 10 m Sentinel-2 data → 2926 m. Experiment #3 (commit c0a1bdf, pipeline data v2) re-proved the harness on 1 m/px DOP imagery across all four development areas → 2765.67 m worst-case median error, coverage 1.0 (historical: that bootstrap run predates the current metric — the primary score is now the §6 mission score, not a median; see pipeline/score.py) in all 24 area×bucket cells (target ≤ 20 m; a center-guess on a ~7 km box is ~2.8 km — the baseline is deliberately naive). All deployment gates passed. The §6 anti-abstention gate was exercised for real en route: two confidence calibrations collapsed dark-bucket coverage and were correctly scored FAIL.

Phase 2 — running the autoresearch loop (run this yourself, separately)

Current configuration: berlin-slim (merged into main 2026-07-31). Berlin only, raw daytime imagery, no synthetic relighting, figures off, pivot gate off. See CLAUDE.md’s “SCOPE OVERRIDE” for what it supersedes and why — low-light is the full spec’s goal, out of scope in this configuration, and the relighting machinery is kept, not deleted.

./autoresearch/loop.sh 12               # run until the DB holds 12 experiments
SKIP_AGENT=1 ./autoresearch/loop.sh 1   # smoke-test the harness without an agent
touch state/stop                        # graceful stop after the current experiment

Data for berlin is already fetched and relit; the other areas are only needed if you restore the full four-area scope:

for a in prignitz munich frankfurt hamburg; do
  .venv/bin/python -m pipeline.fetch --area $a
  .venv/bin/python -m pipeline.relight --area $a
done

Per experiment the design agent pre-registers title / category / hypothesis / method / expected_outcome (written to the run’s experiment.json); the harness appends the measured result and a kept/reverted conclusion, logs to SQLite, snapshots model/*.py into runs/<id>/model_src/ whatever the outcome, and commits kept improvements so git history is the research trail.

Watch progress: open gallery/index.html (re-rendered when a design lands and again when the experiment finishes), or sqlite3 experiments.sqlite "SELECT id,title,primary_metric,kept FROM experiments ORDER BY id DESC LIMIT 10;"

Compute

Training runs locally on the M1 (model/train.py auto-selects cuda > mps > cpu). Viable on a laptop again only because this branch trains one area instead of four.

Two remote paths exist and are dormant:

status
Modal (REMOTE_TRAIN=1 REMOTE_BACKEND=modal)stateless per-area trainer, never touches git. Used 23–30 Jul; credits exhausted, so unusable until topped up.
RunPod (infra/runpod.sh, REMOTE_BACKEND=runpod)abandoned 2026-07-23 after three days of stuck commits and merge conflicts. Scripts kept for reference; do not restart it without reading docs/infra.md first.

The rule that came out of that period and still holds: one git writer, always. The laptop commits; a remote may only train and hand back artifacts. Two writers on one branch was the root cause of the whole mess, not the provider.

Flight test (sim/) — does the champion actually get a UAV from a to b?

A virtual-UAV flight simulator closes the loop on the mission score’s own premise (§2: the vision fix is the only drift correction). A point-mass fixed-wing flies through wind, gusts and gyro bias its navigator cannot see; every fix interval the sim crops the reference raster at the aircraft’s true pose, runs the exported champion ONNX, and hands the answer to a dead-reckoning navigator that accepts false fixes like any other. Arrival is declared on the navigator’s estimate and scored against the truth. Honesty rules are documented at the top of sim/flightsim.py; the known best-case caveats (camera = the memorized reference imagery; fixed 1 m/px altitude) are stated on the results page rather than hidden.

Headline (100 flights, seed 1): 91/100 arrive within 100 m, median declared miss 45 m; the dead-reckoning control arrives 0/100. All three catastrophic failures had targets on the never-trained region-holdout diagnostic ground — an artifact of simulating over the research configuration, reported as flown. Results are rendered as the gallery/flight-path.html page (replay, estimation-error sawtooth, 100-flight record).

.venv/bin/python -m sim.flightsim --seed 6 --start 350,350 --target 6800,6600 \
    --save-crops --out sim/out/showcase.json      # the page's showcase flight
.venv/bin/python -m sim.flightsim --flights 100 --seed 1 --out sim/out/mc.json
.venv/bin/python -m sim.flightsim --flights 100 --seed 1 --no-vision --out sim/out/mc_dr.json
.venv/bin/python -m sim.render_flightpath         # rebuild the page from sim/out/

Reference imagery (pipeline data v2) & licensing

Fetching is driven by a source registry (pipeline/sources.yaml, frozen): for any bbox, the finest open-licensed source covering it wins, falling back to global Sentinel-2. The pipeline code stays fully bbox-generic — regional knowledge is config, not code.

SourceCoversNativeLicense / attribution
BB-BE DOP20 WMSBrandenburg + Berlin20 cmdl-de/by-2-0 — © GeoBasis-DE/LGB
Bavaria DOP40 WMSBavaria (Munich)40 cmCC BY 4.0 — © Bayerische Vermessungsverwaltung
Hesse DOP20 WMSHesse (Frankfurt)20 cmdl-de/by-2-0 — © HVBG Hessen
Hamburg DOP WMSHamburg20 cmdl-de/by-2-0 — © FHH LGV
Sentinel-2 L2A (Earth Search STAC → AWS COGs)global fallback10 mCopernicus — “Contains modified Copernicus Sentinel data”

Everything is server-resampled to a 1 m/px reference grid (target_gsd_m in the registry): a 128 px model crop = 128 m ground footprint, matching a typical UAV camera at ~100 m AGL — so training imagery scale ≈ deployment imagery scale. No Google/Bing tiles anywhere. Expect roughly 0.5–3 GB of imagery per area on disk after relighting.

Validated hardware setup (§9 resolved for bring-up; stretch sensor still open)

Buy-now, documented-working stack:

  • Board: ESP32-P4-Function-EV-Board — Espressif’s official P4 dev kit; ships with a 2 MP MIPI-CSI camera module (SC2336) in the box.
  • Sensor: SmartSens SC2336 (2 MP, 1/3”, RAW out over MIPI CSI-2; SmartSens’ “SmartClarity-2” low-light line). Driver ships in Espressif’s esp_cam_sensor component; the P4’s on-chip ISP handles debayer/AWB/denoise (camera driver docs), and a community P4+SC2336 example exists.
  • Software path: esp-video (V4L2-style capture) → esp-dl (quantized CNN inference on the P4’s PPA/vector unit). Model export here is ONNX, which esp-dl’s toolchain ingests for int8 quantization.
  • For the flight article (vs. dev kit), the same chip + SC2336 module on a minimal carrier lands well under the 50 g / 2 W targets of §2.

Still open (stretch): a true STARVIS2/IMX585-class starlight sensor on the P4 has no documented pairing — IMX585 typically wants 4-lane MIPI (P4 has 2) and a custom driver. Path: prove the full system on SC2336 first; invest in starlight bring-up only if night accuracy turns out sensor-limited. (The ams MIRA220 NIR example shows third-party sensor bring-up on the P4 is feasible.)

Adding a new deployment area

.venv/bin/python -m pipeline.fetch --name myarea --bbox 9.10,48.70,9.20,48.76 then relight/train/score as above — nothing in the pipeline knows about specific areas. Only add entries to areas.yaml if it should become part of the frozen evaluation set (that’s a human decision, not the loop’s).

License

GPL-3.0-or-later (see LICENSE). The choice is deliberate: the point of this project is that anyone can generate their own tiny, self-contained, geo-boxed localization model — so the pipeline that makes that possible must stay free. Copyleft guarantees it: you may use, study, modify and redistribute everything here, but a distributed fork — improved or otherwise — must remain under the GPL. Freedom is the priority here, not adoption.

Two boundaries, spelled out in NOTICE:

  • Model weights you train are yours. They are your output, not a derivative of this code in the license’s sense; this repository claims no rights over them.
  • Imagery-derived figures (under runs/ and site_assets/) carry their geodata sources’ attribution terms (dl-de/by-2-0, CC BY 4.0, Copernicus) independent of the code license.

The repository was MIT-licensed before 2026-08-01; the relicense was made by the sole copyright holder.

1 reply · 1 repost · 1 like · 31 views
In reply to @signulll · Jul 17, 2026

while google is busy renaming notebooklm to gemini notebook, a chinese open weight startup completely outclassed every gemini model on the market today by a long shot.

how can this possibly happen?

@signulll Different understanding of scarcity, maybe?

23 views
In reply to @FonziAlerts · Jul 16, 2026

So far this week, 62 startups sent interview requests to software engineers through Fonzi, salary bids up front.

Top: $250k Median: $200k Average: $197k

15 they came from @ycombinator backed companies, 9 from @Accel, and 2 from @a16z.

@FonziAlerts @hiiinternet @ycombinator @Accel @a16z Thank you for sharing, I didn't have Fonzi on my radar. Same for us, a small company. Hiring engineers is absolutely still top-priority, there's budget etc. Even in a post-AI world, finding good talent is still the hardest part I find.

1 reply · 1 like · 48 views
In reply to @SpringStreetNYC · Jul 14, 2026

Feel stoked about my third foray into autonomous research:

"The snuggle is real"-evolving quadcopter frame geometry for Wh/km, with Claude as an occasional co-designer

This one came out a hybrid between classic evolutionary algorithm design and @karpathy-style autoresearch.

This stuff is so much fun!

t.co/MYFpnlBx7K

@karpathy The result: The top candidate came in at a (theoretical) 9% improvement in km/H compared to the baseline Source One V6 design.

Evaluated against 6 complex-ish weather scenarios.

Image from the post
Image from the post
Image from the post
Image from the post
1 reply · 1 like · 81 views · 1 bookmark

Feel stoked about my third foray into autonomous research:

"The snuggle is real"-evolving quadcopter frame geometry for Wh/km, with Claude as an occasional co-designer

This one came out a hybrid between classic evolutionary algorithm design and @karpathy-style autoresearch.

This stuff is so much fun!

Airloom“The snuggle is real” — evolving quadcopter frame geometry for Wh/kmA genetic algorithm with Claude as an occasional co-designer bred a 7-inch quad frame 16% more efficient across six simulated weather scenarios. Every candidate explorable in 3D, with real OpenFOAM streamlines. Free software, GPLv3.↗ alexisrondeau.me

Autonomous Research with AI: "The snuggle is real" — evolving quadcopter frame geometry for Wh/km, with Claude as an occasional co-designer

An autoresearch loop — a genetic algorithm over fourteen genes of the real, open-source Source One V6 plate drawings, flown through six simulated weather scenarios, with Claude sitting in every few generations as an AI agent that proposes designs from the run’s own telemetry — evolved a 7-inch frame that flies 16% more efficiently (Wh/km) than the stock champion.

The research in nine slides

The bottom line

The run champion

The champion flying all 6 weather scenarios

The lineage trail: 80 generations, superimposed

The levers — 14 genes

1061 candidate frames

The research log

The family tree

Build it: the champion as five flat templates

Open →

airloom

Autonomous Research with AI: evolving quadcopter frame geometry for Wh/km — an autoresearch loop of a genetic algorithm over the open-source Source One V6 plate drawings, six simulated weather scenarios, and Claude as an AI agent co-designing. The champion flies 16% more efficiently.

Python

Airloom — evolving quadcopter frames for Wh/km

(heirloom + air: every frame inherits from its ancestors, and the gallery is the family archive. Formerly framevo; the old CLI name still works as an alias.)

A fully automated, headless research loop that evolves quadcopter frame geometry to minimize energy per distance (Wh/km) flown through a portfolio of adverse-weather scenarios. Everything except the frame — battery, motors, propellers, flight controller — is fixed. Runs unattended, is resumable after a crash, and produces a ranked, visual archive of every frame it ever evaluated.

make demo        # 3 generations x population 8, ~2-4 min on 8 cores
make test        # pytest suite
.venv/bin/airloom run --generations 100            # starts, or RESUMES the
                                                   #  latest run by default
.venv/bin/airloom run --generations 100 --fresh    # snapshot + CLEAR results,
                                                   #  then a brand-new run
.venv/bin/airloom lineage <genome_hash>            # ancestor chain w/ fitness
.venv/bin/airloom gallery                          # rebuild artifacts from db
.venv/bin/airloom robustness                       # is the RANKING an artifact
                                                   #  of the model knobs?
.venv/bin/airloom verify-champions                 # refined structural check of
                                                   #  the top frames + print-
                                                   #  and-test protocol

While a run is live, type quit + enter (or ctrl-c) to stop gracefully — the tasks in flight finish and the run stays resumable. If the latest run’s genomes predate the current genome spec, airloom run starts a fresh run automatically; a run.db written by an older schema is archived (never deleted) and recreated.

Local-first: plain pip install -e . on macOS (Apple Silicon) or Linux x86, CPU-only, no Docker/GPU/EGL. Thumbnails render through headless matplotlib. Worker count auto-scales to the core count.

Every airloom run first commits a snapshot of results/ into its own nested repo (results/.git — separate from the project repo, so big run artifacts never bloat it). --fresh then actually clears the folder. Restore any past state with git -C results log + git -C results checkout <hash> -- .

What it produces (in results/)

  • index.html — the gallery: static, no frameworks, no server, open with file:// (auto-reloads every 30 s while a run is live — locally only); also mirrored into docs/, the GitHub Pages root, on every refresh. Tufte-styled (cream paper, ink, one rust accent, hairlines). At the top: a progress chart of every candidate in evaluation order — gray dots, a best-so-far step line with labeled improvements, invalid candidates as rust ×, generation ticks, and two horizontal benchmark lines (≈5.0 Wh/km aggregate = current 7-inch long-range practice, ≈4.0 = record-class stretch; both set in scenarios.yaml) — so you can see what moved the needle and where the search plateaued. Below: one row per generation sorted by fitness, then detail blocks showing a from-below still of each candidate — click it to open a full-screen overlay with two tabs: the interactive 3D model (depth-buffered WebGL, drag/scroll/double-click), and a side-by-side comparison with the oldest ancestor of its lineage whose rotation and zoom stay in sync. A metric/value table, the genome table, parent thumbnails and the candidate’s lab-notebook notes (hypothesis / method / result — see the narrator below) sit beside each still. Parts are colored by role: rust arms and near-black deck plates are the evolved geometry; the blue Li-Ion pack, gray motor cans and pale translucent prop disks are the fixed kit.
  • leaderboard.md — top 10 with all metrics and per-scenario columns.
  • lineage.html (+ raw lineage.svg, lineage.dot) — a dedicated family tree page: nodes shaded by fitness (dark = better), hollow nodes = invalid, edges colored by operator, elite carry-overs as dotted pass-throughs.
  • convergence.png — fitness vs. generation.
  • frames/gen_XXXX/<hash>.stl + .png — every candidate, including invalid ones (_INVALID suffix; the failures are instructive).
  • gen_XXXX_best.stl — the generation’s champion (fused), plus gen_XXXX_best_parts/ — the same frame as separate flat, printable pieces.
  • designer_log.md — the designer rounds’ proposals with their one-line rationales (see below).
  • robustness.md (on demand, airloom robustness) — the top candidates re-flown under perturbed model knobs (±30 % handbook Cds, ±10 % rotor tables, rain knobs, wash term): rank correlation, top-5 overlap and champion identity vs the baseline ordering, with a STABLE / MODERATE / FRAGILE verdict. Answers “is the leaderboard a frame property or a model artifact?” and names the knob where Phase B fidelity would matter first.
  • champion_check.md (on demand, airloom verify-champions) — the top frames re-analyzed with the same station-by-station variable-section bending model the in-loop constraint now runs (net-section stress concentration at holes/cutouts via Peterson Kt, and the taper gene), adding the one thing the fast in-loop gate deliberately doesn’t apply: as-built strength knockdowns for printed materials — plus a bench print-and-test protocol with hold and predicted-failure loads.
  • run.db — SQLite: genomes, lineage (self-referencing, WITH RECURSIVE ancestry), per-scenario metrics, populations, lab-notebook notes, config snapshot, git hash. Written by an older schema? It gets archived automatically (never deleted) and recreated.
  • glossary.html (copied from docs/glossary.html, linked from the gallery) — definitions of both the evolutionary-algorithm terms and the domain terms (genes, Wh/km, constraints, physics vocabulary).

The fixed platform (never evolved)

Matched to the official DroneAid Collective (drone-aid.de) workshop kit, a 7-inch long-range build in the most popular open-source plate-frame archetype — the TBS Source One family (open-source: 2 mm deck plates, M3 standoffs, sandwiched plate arms; the upstream repo carries no license file, so terms are unconfirmed). Kit components as modeled: 4× 2806-class ~1300KV motors with 7×4-class 3-blade props (ground truth: UIUC Master Airscrew GF 7×4 measurements), a self-built 6S1P 21700 Li-Ion pack (4.2 Ah, 470 g, strapped on top of the deck), 30.5 mm Betaflight FC + 4-in-1 ESC stack between the plates, micro FPV camera, VTX + antenna, ELRS receiver. Fixed non-frame mass: 0.78 kg; baseline AUW ≈ 1.0 kg.

The generation-0 baseline genome is measured from the official Source One V6 7in DC plate drawing (cached with provenance notes in data/source_one/): 106.6×48.5 mm bottom plate, 2 mm plates, 6 mm arms, M3×30 standoffs, ~160 mm arms. Assembly is modeled the way the real frame bolts together: arm root tongues rest on the bottom plate inside the sandwich (tongues may not collide — hard constraint), the FC/ESC boards sit in the gap (and count as a bluff body for drag), the battery wedge hinges on its front bottom edge so it never sinks into the plate, and the XT60/lead are modeled visually. The best candidate of each generation is also exported as individual print/cut-ready pieces in gen_XXXX_best_parts/ (bottom_plate, top_plate, arm ×4).

The genome: morphs of the REAL parts (14 genes)

The genome no longer describes primitives — it deforms the official Source One V6 7in DC plate drawings (data/source_one/, parsed from the DXF with arcs, cutouts and every bolt hole) under zone constraints that keep each candidate a printable/cuttable derivative of the real design:

  • arm_length_scale, arm_width_scale, arm_waist_scale, arm_thickness — stretch/reshape the real arm outlines; the bolt tongue and the 16×19 mm motor-mount end stay rigid.
  • tip_thickness_scale — mid-shaft thickness dip as a fraction of root thickness (a bump profile: full thickness stays at the tongue and the motor mount, where it’s needed for the plate-sandwich fit and screw engagement; 1.0 = uniform, no dip).
  • arm_cutout_scale — three lightening holes drilled along each arm’s shaft centerline, radius scaled off the local width there (0 = none).
  • front_sweep_deg, rear_sweep_deg — rotate the arms about their drawing-registered plate anchors (front anchors are exact bolt-pattern registrations; DC arms keep their true left/right mirrored chirality).
  • plate_length_scale, plate_width_scale, plate_thickness_scale, deck_gap — stretch the real main/mid/top plates (the 30.5 mm stack pattern stays pinned exactly), set the standoff length.
  • battery_wedge_deg — tilt of the pack on the top plate.
  • material — carbon plate / PA12-CF / PET-CF / PLA+ / PETG / ASA library.

Gene value 1.0 on every scale gene reproduces the real V6 exactly (the generation-0 seed; its frame mass comes out at 144 g — the real frame weighs ~145 g). Every candidate assembles the full kit: 6×21700 cell pack, FC/ESC stack, 2806 motors, 3-blade props, camera, VTX + ELRS antennas, GPS, XT60 and routed wire looms — dimension-accurate meshes (components.py).

Hard constraints (fitness = ∞, no simulation): the FC/ESC stack must fit the deck gap, placed arm outlines must not overlap (the real notch interlock is not redesigned), each tongue’s bolt pair must land on main-plate material, rotors need ≥ 5 mm from each other, and prop disks are checked against the deck/battery in 3D (the real V6’s rear props sweep below the top-plate corners; deck_gap trades that margin).

Scenario portfolio

Six scenarios (config/scenarios.yaml): calm_warm, cold_headwind, storm (25 mm/h rain), crosswind, gusty_light (severe Dryden gusts), hot_thin (1500 m density altitude). Every candidate flies all of them over the identical mission: 2 km north + 2 km south at 12 m/s, 30 m AGL. Each scenario has a fixed turbulence seed, so all candidates fly identical gust histories — fitness differences are frame differences, never gust luck.

Designer rounds (headless Claude): every 6 generations (config: designer in evolution.yaml), a headless claude -p call receives the elite genomes with per-scenario results and the invalid-design histogram, and proposes new genome vectors as design hypotheses — injected as operator designer (violet in the family tree), rationales appended to results/designer_log.md. The brief includes the known constraint couplings (deck gap vs. FC stack, sweep vs. tongue collisions and bolt registration). Fail-soft: if the CLI is unavailable the round is skipped.

Lab-notebook narrator (headless Claude): after each generation, ONE claude -p call writes three short notes for every new candidate — hypothesis (the pre-flight “why”: what the search had observed and what bet this design makes), method (what concretely changed vs. the parents), result (outcome vs. parents and best-so-far, or the constraint that killed it, plus one idea worth testing next). Rule-based fallback notes are written instantly; the Claude enrichment runs on a background thread off the loop’s critical path and upgrades them in place. The notes appear in the gallery detail blocks and the family-tree hover cards. Config: narrator in evolution.yaml; fail-soft like the designer.

Patience: if the best-so-far stalls for 6 generations (no ≥0.5 % improvement), the loop pivots — it crosses tournament winners with far parents (the most genetically distant still-decent candidates in the run’s history) under boosted mutation, escalating to random parents if the plateau persists. Derived from persisted history, so it survives --resume; configured under ga.patience in config/evolution.yaml.

Fitness = mean Wh/km + λ·worst Wh/km (λ = 0.5), or pure worst-case with aggregation: minimax. Thrust limiting (rotor RPM ceiling incl. battery sag, per-motor power, pack deliverable power) clamps rather than instantly failing — a gust transient costs tracking and energy, like real flight. A scenario fails on sustained infeasibility: thrust-limited beyond 10 % of the nominal mission time (blamed on the dominant limiter), altitude/track divergence, mission not completed within 1.6× nominal time, or the structural check. Any scenario failure ⇒ invalid. An optional early-reject screen (early_reject.enabled) flies calm_warm first and gives clearly-losing candidates a finite penalized fitness without flying the other five.

Physics (Phase A — deliberately boring and verifiable)

piecemodelsource / check
rotorCT(J), CP(J) interpolated from measured tables; T = ρn²D⁴CT, P = ρn³D⁵CP / 0.85 (motor+ESC)UIUC Propeller DB, Master Airscrew GF 7×4 (static + 4 RPM sweeps), cached in data/uiuc/; unit-tested against tabulated points
frame dragcomponent buildup: projected areas from rasterizing the STL along the flow at 0–60° tilt; handbook per-class Cds corrected by CFD-fitted tilt-dependent ratios and an assembly interference factor (wake shielding + silhouette double-count, −6 %/−27 %/−37 % at 0°/20°/40°); rotor-wash download on arm planform under the diskscalibrated against 12 OpenFOAM v2512 k-ω SST cases (cfd/calibration.md); round-trip unit-tested to ±3 % of the measured CdAs
turbulenceDryden, MIL-F-8785C low-altitude forms, spectral synthesis, fixed seedsvariance unit-tested against σ² spec
rain(a) water-film added mass ∝ top area, (b) momentum drag via equivalent suspended-water density + vertical impact force, (c) 15 % thrust-coefficient penaltyempirical knobs, see NASA TP-2671 (Dunham et al.) heavy-rain research; all in config
flight100 Hz point-mass 3-DOF sim; quasi-static attitude (the quad tilts into the relative wind), P velocity loop with accel limits; rotor speeds solved each step from the CT tables; electrical energy integratedzero-wind mission unit-tested against a quasi-static analytic power balance (±6 %)
batteryquasi-static pack model: V = V0 − I·R, current solved from demanded motor power each step; energy integrated at the pack terminals (incl. I²R loss); RPM ceiling scales with sagged voltage; deliverable-power (V0²/4R ≈ 820 W) and cell-current (45 A) limits feed the saturation clockP42A-class DC IR + discharge-curve sag; unit-tested (quadratic solve, IR-loss share, storm clamp behavior)
structurestation-by-station variable-section Euler–Bernoulli bending along the real morphed arm outline (net width minus any hole/cutout, Peterson Kt where one pierces a station, genome-selected thickness taper): worst-case per-rotor thrust across all scenarios × 1.5 safety factor; max stress ≤ material strength, tip deflection ≤ 5 % L, first bending mode outside ±15 % of hover 1Pstress/deflection unit-tested against hand calculations on a plain (untapered, unpierced) section, which reduces to the classic constant-section formulas

Sanity anchors (unit-tested): the original spec anchor — a 5-inch quad at 1.1 kg AUW hovers at ~195 W (180–280 W band), checked against the cached GWS 5×4.3 dataset — plus the shipped platform: the baseline 7-inch deck (~0.34 m wheelbase, ~1.0 kg AUW) hovers in a plausible 90–230 W band on the MA GF 7×4 data.

Known limitations (please read before trusting numbers)

  • Phase A drag is approximate. Component buildup with handbook Cd values and a cos²-blend between body-x and body-y flow azimuths; no interference drag beyond the rotor-wash term, no Reynolds corrections.
  • Rotor model is axial-flow data stretched to edgewise flight. UIUC wind tunnel sweeps measure propellers in axial advance; a quadcopter in cruise sees mostly edgewise inflow. J is computed from the axial inflow component only, and there is no rotor–rotor interaction.
  • The rain model is empirical. Film mass, momentum drag and the 15 % thrust penalty are literature-inspired config knobs, not physics.
  • No rotational dynamics. Attitude is quasi-static; control effort in gusts appears as thrust modulation, not motor differential torques. Gust series are synthesized at the commanded cruise speed rather than the instantaneous airspeed.
  • UIUC data was measured at 2.5k–7k RPM and on a 2-blade prop; the kit flies 3-blade 7×4s and hovers near 9k RPM. CT/CP are treated as Re-independent and blade-count effects are absorbed into the tables.
  • Print-material properties are XY/datasheet values. FDM parts are weaker across layer lines (often 40–60 % in Z); in the LOOP the 1.5 safety factor is the only allowance for anisotropy, print quality, or temperature — datasheet strength, not as-built. airloom verify-champions re-checks the top frames with per-material as-built strength knockdowns on top of the same station-by-station model, and emits a bench print-and-test protocol.
  • Structural model checks the arms only (station-by-station stress along the shaft, tip deflection, resonance off the root station’s stiffness); the deck is assumed rigid and the standoffs ideal.
  • The battery model is quasi-static. Constant open-circuit voltage at the nominal 3.7 V/cell (no state-of-charge curve — conservative for a short mission that only uses ~15 % of the pack), constant DC internal resistance (no temperature or transient effects), no thermal limits for pack or motors. It exists to catch physically undeliverable power demands, not to predict voltage traces.
  • Printability is enforced by real-outline geometry constraints, not full DFM. Parts are the actual (morphed) V6 outlines with their holes and cutouts, exported as separate flat pieces; but tongue bolt holes are assumed re-cut with the plates when sweep deviates from stock, the rear anchor is a best-fit (98 % clamp coverage) rather than a hole registration, and tolerances/print-orientation strength are not modeled.
  • CMA-ES mode (--optimizer cmaes) has no discrete parents — it samples from an adapted Gaussian — so the family tree is skipped and distribution-level provenance (mean, σ per generation) is stored in cma_state instead.

Phase B (CFD) — milestone 1 complete: calibrated, verdict STABLE

airloom cfd-calibrate generated 12 OpenFOAM cases (arms alone, deck/kit alone, full assembly, and a contrasting genome’s full assembly — each at 0°/20°/40° tilt, freestream BCs, one snappyHexMesh per geometry) and the overnight solve produced cfd/calibration.md. Findings: the handbook buildup overestimated drag ~2× at cruise tilt; assembly interference (wake shielding + silhouette double-count) is −27 % at 20°; and the contrast genome’s ratios matched the baseline’s within ~2 points at every angle — the error is systematic, not gene-dependent. The corrections now live in aero.py (CAL_* tables, applied in drag_table_from_areas), and the post-calibration airloom robustness verdict is STABLE (min Spearman 0.958, no champion flips): the ranking is a frame property, not a model artifact. Consequence: the originally-planned per-candidate CFD pipeline (top-N per generation, cached by genome hash) is not needed; the seam (DragTable from AreaTable) remains if a future genome expansion moves outside the calibrated shape envelope. Note: absolute Wh/km dropped with the calibration, so the gallery’s 5.0/4.0 benchmark lines predate it and need re-derivation.

Layout

config/          platform.yaml (fixed hardware), scenarios.yaml (mission,
                 portfolio, aggregation + benchmark lines), evolution.yaml
                 (GA, patience, designer, narrator, execution)
data/uiuc/       cached UIUC propeller measurements (scripts/fetch_uiuc.py refreshes)
data/source_one/ official Source One V6 7in DC plate DXF + provenance notes
docs/            glossary.html (copied into results/ next to the gallery)
src/airloom/     config, genome, realgeo (DXF outline parsing), frame_gen,
                 components, meshutil, rotor_model, aero, dryden, simulator,
                 structures, evaluate, parallel, evolution, designer,
                 narrator, loop, dbstore, lineage, gallery, render, cli
tests/           frame validity (baseline reproduces the real V6), kit
                 components, materials, designer parsing, patience/pivot,
                 UIUC points, beam hand-calc, Dryden variance, zero-wind
                 energy, hover sanity anchors
results/         everything a run produces (see above)

License

airloom is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE for the full text.

522 views · 1 bookmark
In reply to @FeryalMP · Jul 7, 2026

I’m hiring! Come join our team at Google DeepMind in London or Mountain View to work on Gemini agent post-training.

We are looking for Research Scientists and Research Engineers interested in advancing the capabilities of AI agents.

Please apply here: t.co/v6EpiUwK6o

@FeryalMP Hey Feyral! Alexis here. Does post-training with autoresearch loops count?

alexisrondeau.me"Which city in Paris are you staying in?" - A post-training study on small-model specialization with an autoresearch loopAcross 77 experiments — every lever from prompting and retrieval to fine-tuning and 2025's rubric-grounded RL — an on-device 3B model landed within about one rubric point of a frontier cloud model on every quality dimension: close, but consistently a notch below. None of the post-training playbook closed the last notch, and the controlled tests show why — the gap is a broad capability limit, not a…↗ alexisrondeau.me
3 likes · 322 views · 1 bookmark
In reply to @lilianweng · Jul 7, 2026

new post on harness engineering for AI self-improvement: t.co/ZYvGfVs61k

It is hard to forecast how much the future of RSI will rely on harnesses. Likely harness engineering will evolve in the direction of self-improvement and enable auto-research, and, in turn, smarter models keeps harnesses simple.

Even when many harness improvement get eventually internalized into core model, the need to specify goals and context will not disappear.

@lilianweng Yup! I believe auto-research loops will be part of it. And kind of are already. I experimented with a Karpathy-style DIY research loop on a personal quest and, yeah, this stuff works like today.

PS: The thing I made:

alexisrondeau.me"Which city in Paris are you staying in?" - A post-training study on small-model specialization with an autoresearch loopAcross 77 experiments — every lever from prompting and retrieval to fine-tuning and 2025's rubric-grounded RL — an on-device 3B model landed within about one rubric point of a frontier cloud model on every quality dimension: close, but consistently a notch below. None of the post-training playbook closed the last notch, and the controlled tests show why — the gap is a broad capability limit, not a…↗ alexisrondeau.me
17 views

And heeeere (?) is a reply that's really just a line of text in a markdown file. (My goal is to also post replies from Kern.app because, tbh, going on Twitter to give meaningful replies is, to me at least, a losing battle to too many distractions.)

2 replies · 8 likes · 4.8K views
In reply to @anshuc · Jul 3, 2026

Fable is pure magic.

I wanted a beautiful app to explore ocean wildlife. Fable built this in an hour. It generated videos with Seedance and carefully synchronized them to make these absolutely insane transitions. I've never seen anything like this in an app. Unreal. t.co/W1NjAnlzQu

Wow. I have to say this is actually uniquely beautiful and engaging (and I'm usually the first one to nit-pick on one-shots with a "yes but..." )

I'm curious what's going to happen next: You're the first one I've seen with this type of result. I'm genuinely amazed.

How will I feel about the second and third app? And the hundredth in 5 months? Will this new level of picture-perfect quality eventually become part of my AI-filter?