With GEV_NEWS_ORIGIN unset, Core answers the News layer's routes itself.
Conflicts need no key: the last 24 h of GDELT 2.0 event exports, physical
violence only (CAMEO 18-20), one report per story (copies of one agency
story merged), placed where GDELT put it, a town the article's own words
name winning over a bare country, and titled by the article's page title
from the GKG export of the same quarter hour (the newest 3 h), else by its
address words. GDELT's actor coding is never shown. Exports are read up to
the newest GDELT lists; one that cannot be read is given up on without
holding the rest back, and an outage of two hours answers 502 rather than
an empty feed. With LIVEUAMAP_API_KEY, Liveuamap's mapped items join them.
Local reads World News API by the source country at the view centre
(WORLDNEWSAPI_KEY, at most WORLDNEWSAPI_DAILY_READS a day), with the
Conflicts reports placed inside the area. Disputed areas (11 from Natural
Earth, bundled) and territories without a country code are named as
themselves and read from no country's outlets; a country's outline leaves
them out.
Categories, relevance and severity come from shared rules; keyed answers
are cached and served while they refresh, and no key or address is logged.
`./server/providers/news` (node) with its own package boundary, so a host composing its own local providers can serve /api/news from GEV_NEWS_ORIGIN as Core's standalone server does.
Events ▸ News draws the last 24 hours of reports from curated hotspots
(Ukraine–Russia, Israel–Gaza–Lebanon, Iran–Hormuz, Yemen–Red Sea, Sudan,
Sahel) and developing situations elsewhere, from any server that answers the
`/api/news` read routes.
- Globe: one marker per merged event, clamped to the ground and culled at the
horizon; one beacon per hotspot when zoomed out and a pulsing beacon for a
developing situation; hotspot outlines with disputed areas dotted and
labelled by who administers and who claims them; picture cards for at most
ten major or fast-growing events with two or more sources, never
overlapping, switchable off.
- Panel: hotspot chips, a severity filter (significant and above by default),
categories, minor news off by default, and a scrolling list of event cards
with picture, headline, place, sources, age and the sides that reported it.
"In view" lists what is near the map below 3,000 km once the camera
settles. A card flies the globe to its event and opens it with a link to
the publisher. Reduced motion stops the pulse and the flights.
- Core serves no news itself: the local server proxies GEV_NEWS_ORIGIN when it
is set, and answers 503 unavailable otherwise, so the layer reads "not
configured" once instead of retrying.
- Share token 9 (enabled-only); voice stays off for this layer.
The pure half of a news layer: validated records for a news server's
`/api/news/hotspots|feed|outline` contract, a presentation model and canvas
markers and picture cards, and a fetch client.
- Colour carries severity only (0 no physical event, 1 minor, 2 significant,
3 major), never a side; the category is the icon, the rim is attestation
(confirmed, a claim, one side's own press), size grows with sources and
markers fade with age.
- Cards say "Reported by {side} sources" and mark official channels; a
machine-read English headline is labelled as such.
- `createNewsSource` reads same-origin routes with a 15 s timeout, a 4 MiB cap
and record-by-record validation; `NEWS_API_PATHS` and `newsQueryAllowed`
let a host proxy exactly what the client sends. A 503 marked unavailable
means "not configured": no retries.
- Exported as `./layers/news/source`, with its own package boundary.
Regional News showed "REGIONAL NEWS UNAVAILABLE" above populated rows and a
static "RECENT" footer over months-old articles. The status banner kept
`display: grid` when hidden, every non-empty answer carried the unavailable
text, and nothing limited or sorted articles by age.
- One window (regionalNewsWindow.js, 24 h): the local proxy asks Google News
with `when:1d` and GDELT for 24 h, drops undated, older or future-dated
articles, sorts newest first, and reports newsWindowHours/newsFetchedAt.
- The Cockpit labels four states: fresh (banner hidden, "LAST 24 H"),
kept after a failed refresh ("CACHED · REFRESH FAILED"), no news in the
window, and unavailable. The footer lives in the news state, so it
survives page and tab changes, and the client drops out-of-window rows.
- `.cockpit-brief-status[hidden]` now hides the banner.
Recent community wildlife observations, as a new Wildlife group in the
layer panel.
- Server: keyless iNaturalist proxy (v2 observations with only the
projected fields; undocumented v1 UTFGrid density tiles, decoded on the
server) sharing one paced queue (burst 4, ~1/s, 60/min, 8,000/day budget,
up to four in flight), in-memory caches and upstream-only cooldowns;
Acartia Salish Sea marine-mammal feed rounded to 0.01 degrees with
comments dropped.
- Layer: grid counts drawn as a soft view-ranked density glow; real sampled
sightings as taxon badges at their true positions with ambient photo
thumbnails and labels; obscured records stay privacy cells; a clicked
sighting stays pinned through camera moves and refreshes.
- Anchored photo card per selection with the single iNaturalist link;
attribution in the layer row and the Data attribution popover.
- Filters (CONFIRMED, taxa presets) round-trip in share links with token 9.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Navara 0.2.1 never frees pick batch ids, and the mover banks rebuilt
their instanced meshes on each attach, leaking about 260 KiB of
WebAssembly memory per switch. A per-view pool hands released ids back
out; the long soak now asserts native growth of at most 32 KiB per switch.
- Navara 0.2.1 sometimes drops the first show:false update on a new
vector layer, so a zone turned off right after a switch back stayed
drawn. Polygon displays hide by deleting their layers and rebuild them
when shown.
- Camera verbs drive both engines through the globe contract; the Cesium
viewer rig and the tests of states it can no longer reach are gone.
- Flights and military tracking share src/layers/aircraft/tracking.js.
- The geo import scenario reads movers only where the engine has them.
- Add the Navara section to docs/CURRENT-STATE.md and a changelog fragment.
- src/geo drops the ported debug argument checks and the tests that
bitExact already covers; package boundaries accept a directory entry,
so src/geo/ is listed once per group.
- Cesium no longer carries movers and lines nobody draws with: they are
optional engine capabilities. The fake engine and the Cesium camera use
the shared cameraMath; unused contract tables, clock.ticked, the
'finest' surface detail and Navara click statistics are gone.
- ALPR keeps one overlay core and one presentation model for both
engines, bikeshare one station bookkeeping, the Navara ground effects
one definition helper; image atlases, view centres, mover banks and
colours are shared.
- The legacy switch route, the clock offset and rate controls and other
unused exports are removed.
- The acceptance runs the Navara draw, geo import and scope checks;
scenarios use the harness switch and page helpers; the main chunk
check keeps the size budget only and runs once in CI.
The launches layer swallowed every fetch error in its update, so the
manager treated a 429 or timeout on /api/launches as a successful start.
Context then committed the isolating mode with no missions: the other
layers stayed off, unrelated enables were refused, the camera stayed at
the full-globe view and the roster kept reading "loading".
Until the first index loads, the update now reports the failure. The
manager fails the enable closed and both entry routes roll back to the
pre-entry layers. The camera pose captured at entry is restored when the
mode is left before any index loaded, and the roster shows a failed
state instead of loading. A valid empty index still enters, and a
refresh failure after a loaded index keeps its records.
- Replace the four era chips with the start and end year pickers the
air-accidents layer uses (the same RowRange control, ported as is);
the era colours stay as a legend under the row.
- Rasterize the boat marker at 144 px so large markers stay sharp.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A new Events layer maps shipwrecks with a card per wreck:
- EMODnet Human Activities heritage shipwrecks (about 6,500 in European
waters, CC BY 4.0), skipping rows taken from wrecksite.eu.
- Wikidata shipwrecks with a Wikipedia article plus sinking events
(CC0); an event folds into its ship for the date and death toll.
- A same-origin /api/shipwrecks proxy refreshes once a day and serves
the last snapshot as stale for up to a week.
Markers are a boat icon coloured by era and sized by deaths; four era
chips filter the layer. The card follows the air-accidents layout
(deaths first). Text that names people is dropped; victims appear as
a count only.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
At the ~20 px the fleet renders at, the bus, tram, metro and unknown
glyphs were near-symmetric boxes: rotated along the course, nothing showed
which end was the front. Each now has a front built into its outline (an
arrow-like nose for the bus, a pointed cab for the tram, a chamfered cab
for the metro), so it survives the tint, the halo and the sensor profiles,
which keep only the outline.
A vehicle with no known course sits at rotation 0, where a pointed glyph
would claim it is heading north. Those vehicles, fleet and selected alike,
now get a symmetric outline (rail and ferry included) and switch to the
pointed one once a course arrives. The raster cache doubles to a fixed 72
variants.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Cockpit entry no longer needs Contacts or both flight feeds: a civilian
aircraft needs Live Flights, a military one Military Flights. Contacts and
every other layer can be turned on or off before or during a session, and
turning off the ridden layer ends it. A Context mode change in flight still
blocks entry.
When the other air feed is off, Live Signals and the Contact card say
FLIGHTS FEED OFF or MILITARY FEED OFF · PARTIAL PICTURE instead of
presenting a partial picture as complete. Voice refuses entry with
subject-layer-off rather than contacts-inactive, and its tool description
says Contacts is not required.
Double-clicking the followed aircraft enters Cockpit through the same gate.
The Cockpit takes the scene's double-click before Cesium's stock handler,
which would otherwise untrack a followed aircraft whose model is a
primitive. The entry also shows under the Intel HUD readout, sharing the
Contacts button's face. A test keeps the classes the Cockpit adds to the
body from matching another element's rule.
Brings the Active Fires intensity work: the FRP filter, the confidence
switch, the ember-to-white-hot ramp and the far-zoom heatmap.
The filter, switch and ramp work on both engines. The heatmap drapes on
Cesium through the layer's Cesium renderer, which also fades the markers
across the hand-off; it goes with that renderer on an engine switch and is
built again on the next Cesium globe. Navara keeps heat cells for the far
bands, now coloured on the FRP ramp.
Main's new layers (drone airspace, OSM places, sea marks, ski pistes) are
Cesium-only for now: they join the layer directory and the Cesium catalog,
are built afresh for each Cesium catalog, and show as unavailable on Navara.
The zoom-out guard is a scene part that attaches to Cesium globes only. The
awareness range pulses and their echoes draw on Cesium through the awareness
display's viewer; Navara keeps the plain range ring. Camera-input wakes go
through the display, and the analyst keeps the session-owned memory with
main's area presentation. A disposed voice runner aborts work in flight, and
an engine switch still keeps the last answer.
Modules main added that read Cesium while they load (zoomOutGuard,
awarenessEcho, the ground-sampling scratch in localGeojsonCore) now build
those values on first use or use src/geo, so a Navara page still starts
without the SDK. The OSM view box reads the engine's view rectangle.
Main grew its own main chunk by 93,873 bytes gzip-9 since the merge base, so
the baseline is raised to the merged size.
The long soak's heap slope counted the per-aircraft dead-reckoning history (POSITION_HISTORY_LIMIT fixes for 10 000 aircraft, about 14 MiB over the first 2.5 min of polls) as switch growth: a run with the same workload and no switches grows as much and then levels off. With --assert the soak now waits until the flights feed has been read more times than the history keeps before it switches; over 500 switches the heap then grows 1.07 KiB per switch.
qa-strict-context-loss records, only when no non-blank frame came, how many frames the running and the watched engine drew in 3 s and how much of the last one differs from its first pixel.
index.html no longer loads /cesium/Cesium.js and widgets.css: the Cesium scene loads both before it builds its viewer. A cold Navara start requests nothing of the Cesium library again, and qa-strict-cold-chunks asserts that without the known-gap allowance. The strict harness puts an accessor in place of the Cesium global on every page and fails a scenario that reads it before Cesium.js has run; GEV_QA_CESIUM_TRAP=record lists every such read site instead.
Every Cesium read that a Navara page made was surveyed with the strict acceptance (GEV_QA_CESIUM_TRAP=record). Math on those paths now uses src/geo: screen annotations, weather and wind center readings, cyclone picks, scene data pack polygons and images (new navaraGeometry.js), the awareness subject, the orbit offset of camera verbs, voice frame_overhead, the agent world packet and Directions colours and ground picks. The celestial ring's Sun and Moon come from a bit-identical port of Cesium's Simon1994 model, JulianDate and TEME rotation (src/geo/simon1994.js, julianDate.js, transforms.js); a Cesium globe still applies its ICRF rotation once loaded.
Traffic, Street Level, the Nepal event and locator and geo import build on Cesium's math or entity model on either globe; their enable (or the import) now loads the SDK first through src/app/loadCesium.js, synchronously when it is already there. A production page guards the global so a missed read is reported and starts the load. No module reads Cesium while it loads (scripts/check-cesium-load-time.mjs, run by npm test). Cesium.js is still loaded by index.html here.
The changelog fragment named share-link token 6 (sea marks); the layer
reserves 8. CURRENT-STATE said voice could toggle and query the layer and
listed it among the analyst record sources, but it is in VOICE_OFF_LAYERS.
Say voice is off for now, and that the layer covers FAA prohibited and
restricted special-use airspace only, not the UAS Facility Map / LAANC grids
or TFRs. A test pins these claims to the token ledger and the voice manifest.
The look's sun follows the page clock, so the frame these checks compare was as bright as the hour they ran at: in the acceptance run the half-strength bloom changed the frame by 0.29 against 3.5 earlier, and at dusk the full bloom changes nothing (luma 13).
Measured over the second half the heap still grew about 20 KiB per switch in the acceptance run (117.8 to 123.8 MiB from switch 250 to 500), so the narrower window did not separate warm-up from growth; the original check stays.
Under the soak workload V8's compiled code and the layers' caches grow for about 250 switches and then the heap is flat (121.4, 121.7, 120.4, 119.1 MiB after 250 to 400 switches), so a line fitted from switch 20 measured the warm-up. Over the second half the threshold stays 10 KiB per switch; the run before the layer effect fix measures 19 KiB there.