Twenty Thousand Leagues Under the Sea gives the Nautilus a hull of 5 cm plating on a 4 m radius. Thin-cylinder hoop stress puts the crush depth at 342 metres. Verne narrates a dive to 16,000.
At 16,000 m the external pressure is about 1,608 atmospheres and the hoop stress is 12.9 GPa, roughly 47 times the plating's yield. Surviving it would need approximately 2.34 metres of steel, which weighs more than the entire boat.
That number came out of a simulator, not a spreadsheet, and the simulator is the point. This is the second of four projects testing what current AI can do with legacy systems, and the variable being changed is the quality of the source. The last one had a formal spec, real preserved code, and an independent implementation to check against. This one has a novel.
Extracting a spec from fiction
The project's thesis is one sentence: legacy documentation lies by omission, not by error. Verne itemises the art in the Nautilus's salon. He never gives the air budget.
So the first phase produced no code at all. Two independent claim-extraction passes ran chapter-by-chapter over the French original, each tagging every physical assertion with its quote, chapter, category, and a precision marker — stated, hedged, implied, or demonstrated. The two passes were then diffed and reconciled into 731 claims, with a human reviewing the reconciliation. Contradictions were recorded and deliberately not resolved, because which resolution you pick changes the answer and that choice needs to be visible rather than buried.
Then the harder half. A simulator needs numbers the novel never supplies, and inventing them quietly is how you get a result that means nothing. Every such parameter became a gap entry with a plausible range and a sourced rationale, and the gate rule was absolute: every parameter in the spec traces to either a claim with a chapter citation or a gap with a range. Nothing enters as a bare constant.
Ranges are anchored where possible to Plongeur, the French Navy submarine launched in April 1863 — the actual state of the art Verne could have known about. Plongeur was 43 m and about 420 tonnes, with 23 compressed-air tanks at 12.5 bar occupying 153 m³ of its hull to drive an 80 hp engine to 4 knots and a range of 5 nautical miles.
Two things follow from that immediately. Stored gas and ballast machinery eat an enormous fraction of a submarine's internal volume, so the Nautilus's breathable space is far smaller than its 1,500 m³ envelope. And 60 kW moved a 420-tonne boat at 4 knots, which sets expectations for what Verne's stated 1.47 MW should do to 1,500 tonnes.
The core is a pure function
The simulator is Ada, built as a pure function of (spec, seed, command stream). No wall clock, no filesystem access, no network, no environment reads inside the core. Everything crosses a single seam — JSON Lines on stdin and stdout — and the UI, the genetic algorithm, the fuzzer, the test harness and the save files all speak the same protocol. There are no side channels.
Three consequences fall out of that shape, and all three matter for supervising an AI:
- Any result reproduces from files in the repo plus a binary hash. The spec is canonicalised and SHA-256'd by the core itself; the wrapper cross-checks and aborts on mismatch. Every recording is pinned to a spec hash.
- The protocol was frozen before the physics existed. Determinism, replay and malformed-input fuzzing were green in the one check harness before a single equation landed.
-
The invariants are append-only and human-signed. Twelve of them live in
invariants/, covering physical bounds, monotonicity, and event ordering — depth is never negative, stored energy never rises, CO₂ only increases while sealed and may drop only to fresh air via a surface renewal, no state tick may follow a crush event.
That last one is the load-bearing supervision decision. When the fuzzer finds a violation, the repair workflow says the AI patches the core, never the invariant. Weakening an invariant to make an exploit pass is prevented by a checksum in invariants/manifest.sha256 that only a human re-signs. The model is free to fix the physics and structurally unable to move the goalposts.
Five findings
Running the committed spec under real physics and comparing to the narrative:
| axis | the legend | the physics | robust to gaps? | |
|---|---|---|---|---|
| F1 | buoyancy | dives at will | under-ballasted — the mass budget only closes in fresh water | yes, it's arithmetic |
| F2 | speed | 50 knots | ~15 kn; 50 kn needs ~24× the stated power | yes, 15–22 kn across the drag range |
| F3 | range | 20,000 leagues | ~1,400 nmi per charge → 30–4,000 recharges of a battery whose capacity is never stated | capacity unknown to 100× |
| F4 | depth | 16,000 m | crushes at ~340 m | yes, 249–435 m |
| F5 | endurance | weeks submerged | 6–211 h; no CO₂ scrubbing means a 1–2 day surface tether | endurance unknown to 35× |
F1 is the most elegant. Verne's mass budget is internally consistent — in fresh water, where one cubic metre conveniently weighs a tonne. In seawater at 1,025 kg/m³ the same 1,500 m³ hull displaces 1,537,705 kg, and the boat with main ballast full reaches only 1,507,200 kg. It is about 30 tonnes positively buoyant and cannot submerge on main ballast alone. The arithmetic is fine. The ocean is the wrong one.
F5 is the subtlest, and it cuts both ways. Verne explicitly states the Nautilus has no CO₂ scrubbing — absorbing it would need caustic-potash canisters he says aren't carried — so air is refreshed only by surfacing. Where he lets that constraint bite, he is right: the roughly 48-hour crisis under the Antarctic ice sits squarely inside the plausible band. The failure is everywhere else, where the narrative implies indefinite submersion that the stated design forbids.
And the single most operationally important number in the book — how long the boat can stay under — ranges across 6 to 211 hours depending on parameters Verne never gives. That 35× spread is the finding.
The genetic algorithm cheats, correctly
With the physics quiescent, the question becomes: can a physically honest Nautilus be designed to reach Verne's? A GA got 29 design genes and a push-to-limit mission that dives until hull stress hits its safe limit and cruises until the battery is flat.
The best evolved champion reaches 562 metres. Verne claims 16,000. The gap is about 28×, after pushing every parameter to its most favourable plausible value — the strongest steel, the thickest plating, the biggest battery, the sleekest hull.
The interesting part is what the optimiser did first. Its opening move to extend endurance was to add CO₂ scrubbing at 6.5 L/s — the exact system Verne states the Nautilus lacks, and the omission behind F5's surface tether. With no knowledge of the novel and no term in its objective mentioning air, the GA independently identified and fixed the book's single most consequential design gap. Range roughly doubled once the CO₂ clock came off.
What the fuzzer found
Nothing, which took some doing to trust.
A 24-hour random-command soak ran 42 lives and 879,643 ticks, killing the boat 29 times by crushing it, and produced zero invariant violations. Five consecutive fuzz campaigns, sixty more lives, also zero. A harness that finds nothing is indistinguishable from a harness that is broken, so it was validated against a deliberately poisoned invariant — which it caught, delta-debugged from seven commands down to two, and packaged as a reproducible exploit.
The only finding in the whole loop is filed under exploits/001-objective-pinning, and it is a flaw in the experiment, not the physics: the GA had been optimising survival rather than performance, because the original controller pinned depth and distance to fixed targets. No core patch. A design-of-experiment fix, and the Pareto front went from a collapsed cluster to a real trade-off surface.
Then the frozen Ada core was re-implemented in TypeScript and both were replayed against a golden corpus, with any divergence defined in advance as a TypeScript bug. Event sequences matched exactly. The worst numeric delta was about 5×10⁻⁷ — and all of it traces to the Ada core rounding its output to six decimals at the wire. The two integrators actually agree to about 10⁻⁷, tighter than the reference bothers to report. The only genuine computational difference is the actuator-disk cube root, where Ada's X ** (1.0/3.0) and JavaScript's Math.pow disagree in the last bits and surface as 10⁻¹⁰ watts.
No oracle means you build one
HAL/S could check itself against an independent interpreter written by someone else. There is no independent implementation of Jules Verne. The oracle here had to be constructed, which means the credibility of every number above rests entirely on the scaffolding — the two-pass claim extraction, the traceability gate, the frozen protocol, the human-signed invariants, the determinism enforced before any physics existed, the harness validated against a poisoned check.
An AI will produce a confident simulation of a submarine with far less than that. It will also produce confident numbers that mean nothing, and from the outside the two look identical.
Next: no spec and no oracle again, but this time the thing being rebuilt is a product people remember using, the substrate underneath it has been replaced, and every defect that mattered turned out to be invisible to the tests.
Code: https://github.com/singular-state/nautilus-sim. Every figure regenerates from the committed repo via scripts/check.sh; each finding re-derives from the hash-pinned canonical spec, and each GA champion replays from its (genome, spec_hash, seed, scenario) triple. Pinned GNAT, fixed timestep, seeded PCG — byte-identical replay.
Top comments (0)