260915 – Dev update

229 commits, 1,696 files, ~167k insertions (~19k deletions). Two programmes dominate this window: the mobile memory remediation chain (14 items, F1245–F1267) and the hangar/profile/settings UX sweep (5 items, run as owner-on-device audits). 31 features newly Implemented, plus 18 bug fixes to already-shipped ones, and 28 new items defined and queued.

🧠 Memory β€” the OOM chain, from metering to measured wins

Terrain elevation grids were deep-copied into the worklet runtimes on every crossing, and MemoryController could not see a single byte of it. The five SharedValue conduits are now metered and visible in Diagnostics (F1245)

The copy itself is gone: a runtime that already holds the identical bytes no longer receives them again (F1254). The two land-cover mask and mid-zoom fill conduits that were still crossing unmeasured are now on the same seam (F1249)

Stream instead of buffer: native file-to-file gunzip, the base64 rope surface removed, gzip fails closed (F1257), and the true-samples .hgt read stopped buffering the whole cell, which is what finally claimed F1257’s 328:1 mid-zoom prize (F1265)

Four terrain grid references outlived their use and the cache that evicted them had no way to say so; full resolution was being allocated on the branch the policy had already denied (F1256)

The 0.5 Hz airspace alert tick was re-gunzipping cells it had just evicted and retrying absent ones forever β€” on a LEVEL C proximity-alert path (F1264)

Five dead or wasteful mobile paths, including an error log that rewrote 1 MB per report (F1262). The offline intent queue grew unbounded, and its TTL purge only ran once it was no longer needed (F1267)

Rostering a compute worker silently cost memory, because the roster was simultaneously the placement policy and the ceiling on how many Hermes runtimes exist; those are now two things (F1251, F916)

If worklet-crossing waste came back, nothing would have told us. Now it would (F1255)

3D map defaults restored, behind a memory-pressure gate (F1238)

πŸ›©οΈ The Hangar, Profile & Settings β€” four owner-on-device audits

Adding and editing an aircraft were two different products: a guided wizard versus a four-tab form with 17 inputs. Now one section at a time, tabs gone, dates you pick instead of spell, and a glider is never asked for fuel (F1188)

The aircraft screen now fits eight capability tiles and its delete control on one phone screen, and the summary card says what the aeroplane actually is (F1284)

Checklists for this aircraft, reachable from the aircraft, owned by the club when the club owns the aircraft β€” mobile and web, through one permission resolver (F1285)

Settings tightened: a doubled safe-area inset that clipped content top and bottom, icons on plates, menus in an order that explains itself, developer tools became a page that says who they are for, one section heading instead of four, and an alias you can actually change (F1241)

Profile became one pattern: cards became rows, Account split by what the thing is, the upgrade banner gone and the plan moved to Me & Preferences, Support became just support, deletion moved to the pilot, and the preferred fuel finally does something (F1244)

πŸ—ΊοΈ The web map drew its basemap for the first time

The web basemap had never drawn. Two causes, both real: the open tier was never authenticated, and MapLibre 6’s worker was never emitted at all β€” a template-literal URL no bundler sees, in dev and in build (F1277, F935)

Every viewport-driven web layer fetched exactly the visible rectangle, so panning revealed empty space and data popped in behind the pilot. The fetch box is padded, and a 404 no longer degrades the basemap (F1252)

The web map always opened at a hardcoded point in the English Midlands, wherever the pilot was (F1253)

πŸ“ Charts & cartography

An ICAO 1:500 000 chart style now sits alongside CAA and Vela, selectable on mobile (F1236)

The topographic base became part of the chart style: world and regional basemap tiers lifted onto the mounter, web reading its basemap off the shared spec, and the chart switch repaints without reloading (F1237)

Map level-of-detail programme defined β€” 7 items (F1301–F1307): one LOD config file and one fade primitive, viewport data gates that currently empty a source before any fade can run, the ~150 layers with no fade at all, where each layer should first appear, airspace larger than the viewport ceasing to fill it, and the relief DEM band hard-swap at camera z4 and z8. Plus the shipped fix that started it: minzoom is the start of a fade ramp, not its end (F1137)

✈️ Airspace & routing

Airspace that cannot affect you stops covering the map β€” and the 3D extrusion filter that had been inert on iOS since F908 works again (F1290)

Over-water routing is a reach test, not a water-class veto: a reservoir is a non-event, the North Sea is not. Golden vectors first, then wired into both products (F1289)

A route had one altitude, so the map gated every leg at the same height; each leg is now gated at its own planned altitude (F1299)

Airspace avoidance is enabled by default (F1293). FLTA no longer assumes a glide ratio of 9, and the terrain strip uses the aircraft’s own speed before reaching for a 100 kt stand-in (F24, F883)

Airspace ingest widened to 43 verified countries.

πŸ”Š Audio

One central audio queue that every producer registers with, and an annunciation policy behind it (F997).

πŸ” Privacy & data integrity

Analytics toggle now lives in the Profile and is account-wide (F1298)

Seven WatermelonDB tables had no registered model class: three map layers and two offline-first caches had never worked, and sign-out reported four failures. Registered, and the three hazard/reference syncs got their first caller (F1240)

A mid-cycle republish silently poisoned device airspace caches for 30 days; cells are now published at content-addressed paths and the downloaded body is verified against its hash (F1242)

βš™οΈ Lifecycle & CI

Web CVEs cleared, including a critical in maplibre-gl, and the stale security overrides that hid them (F935).