D-258 rulings 5 and 6: the pre-seed biome input is class ids only, on two
maps, because compute_biome was already computing them apart and throwing
one away. It gave every land pixel its Whittaker (climate) class, then painted
terrain over it (ocean bands, ice, altitude snow, mountain rock, lava and ash,
the dry, lunar and ferric ground).
planet_simulation:
- compute_biome_layers returns (biome, terrain). Each rule declares the layer
it writes, by RULE not by class: ice from the cold climate box is biome,
altitude snow is terrain with the lowland biome kept beneath. Rules that
place life (thermophiles, mats, crust, the oasis rings) write the biome and
clear the terrain under them.
- 255 means "nothing on this layer", not 0, because class 0 is ocean_deep,
itself terrain. Ids stay literal.
- compute_biome is now compose_layers() of the pair, so the renderers are
untouched. Proven byte-identical, dtype included, on 65 real bodies: every
8th standard-atmosphere body plus every thin, thick, reducing and trace one,
captured before the edit and compared after it.
- simulate() carries both maps as biome_layer / terrain_layer.
reach atlas planet bake-biome [--body --limit --dry-run --check]:
- Writes biomemap.png + terrainmap.png (8-bit, 1024x512, tEXt: layer, none,
classes, decision) beside each heightmap. Scope is the heightmap bake set
with an atmosphere (257 bodies; airless are deferred, per D-258).
- Pre-seed by construction: simulate() is keyed on the body frontmatter's
seed, and no world seed is accepted anywhere.
- --check re-simulates and compares DECODED PIXELS, never bytes, since PNG
encoding drifts across Pillow/zlib versions (T-1291) and a check that trips
on that gets muted. Mutation-proven: one flipped pixel exits 1 and names
the file; the restored file exits 0.
- import_heightmaps' body lookup is extracted as body_def_for and shared,
not copied.
Tests (make test-tooling): rock keeps its biome beneath, thin-atmosphere
ground is terrain with only scattered life, water is terrain only, no pixel is
empty on both maps, and stacking equals the rendered grid. Routing rock
through the biome map fails two of them by name. The router drift test covers
the new verb.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 30-file tree moves under atlas as its third rung (D-243), ten verbs
fronting it. Each verb restates its module's options so `--help` describes
something; tooling/test_planet_router.py hands every declared option to the
module's own argparse and fails on drift, and now runs in make test-tooling.
The 2026-09-02 half of this move had converted the top-level imports and the
repo roots. Finishing it found what the half-move left:
- Lazy in-function imports, and all of sol_data/, still named siblings bare.
They resolved only through sys.path.insert hacks, so under reach the first
globe render in generate, batch or sol-import would have raised
ModuleNotFoundError. Qualified; the hacks are gone.
- 247 print() calls and a stdout progress writer that fired once per 8 KB
block. Report verbs (audit, quality) write through console.out, progress
through console.event, and download progress is throttled to 10% steps
so a job log is not tens of thousands of lines.
- Every error exit raises ReachError with a fix.
Two checks that could not fail:
- batch --verify-determinism printed a warning and exited 0 on a mismatch.
- import-provinces exited 0 with errors > 0.
Both now raise. The 271-body bake is only safe to re-run because the first
one holds.
sol-import --body is action="append" in the module but the router took one
value, so --body GJ0d --body GJ0e kept one. Now repeatable, and _flags repeats
list options.
test_conformance walked one level, so a nested group was reported as a verb
missing @command and its ten verbs were never checked. It recurses now;
proven by stripping @command from `planet quality` and watching it fail.
Stray PNGs from the 2026-09-03 runaway router-test run are parked in
.cache/t1288-stray-pngs/, not committed. Their reliefmaps differ from HEAD
while the heightmap regenerated byte-identical — filed as T-1291.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>