Merge remote-tracking branch 'origin/main' into feat/datacenters-norway-refresh

This commit is contained in:
Trygve Hemminghytt committed 2026-10-15 21:06:43 +02:00
commit 239ba14005
57 files changed
+1893 -162

No files matched your search

+63 -10
View File
@@ -101,6 +101,10 @@ lists at 25 rows by default. Voice offers the same queries next to its app
actions: the session lists them, and the browser runs them through the same
catalog, loaded on first use. See [tools and the MCP server](TOOLS.md).
Catalog calls check their cancellation signal immediately before executing a
tool. Already-cancelled queries do not start; cancellation after execution starts
continues to follow the existing tool and caller behavior.
## Cyber HUD — September 30, 2026
Display > HUD > Layout includes Cyber, also available through the HUD voice
@@ -252,8 +256,15 @@ Clouds only applies a soft brightness ramp to decoded pixels once, using
Cesium's sRGB-to-linear conversion (`channel ** 2.2`) and smoothstep from 0.40
to 0.70. The old 0.55 threshold is the ramp midpoint. RGB and source alpha are
preserved in Full image mode; both modes use the chosen layer opacity. This
is a display filter, not a cloud mask. Satellite share links retain the display
mode; observation history remains transient and links open latest.
is a display filter, not a cloud mask. The cloud-filter slider is a continuous
0–100% strength: 0% is Full, 100% is the existing Clouds only key, and
intermediate values blend their alpha. The value commits on slider release to
avoid restaging for every pointer event. Status refreshes retain the uncommitted
drag preview; changed model values or disabled controls supersede it.
Satellite share links carry the filter
strength; legacy `f`/`a` values keep their Clouds only / Full meanings. Soft and
Vivid remain layer-opacity presets (40%/70%); history remains transient and links
open latest.
Global infrared fetches one capped 4 MiB, 2048×1024 mosaic per frame and decodes
and processes it before staging. Globe hosts crop that canvas into 256 px tiles
to maximum level 3 on a geographic 2×1 root grid bounded to the manifest extent,
@@ -298,7 +309,8 @@ release commits immediately. Latest selects the newest frame per product, and
history labels the actual displayed frame as synced or nearest. Missing-frame
messages use each product's eligibility gap (30 minutes, or three hours for the
global mosaic). Wind shows forecast valid and issue times and does not follow
history. Satellite clouds uses Clouds only / Full image configuration labels.
history. Satellite clouds uses Clouds only / Full controls, a continuous cloud
filter slider and Soft/Vivid opacity presets in its right-rail settings.
Left weather rows retain only the toggle and one status line with a source
tooltip. Configuration and the cyclone Storms list live in the cards, as do the
@@ -1090,6 +1102,9 @@ collapse can still be undone.
## Surface keyboard lifecycle
Surface Tab cycling excludes controls with a negative tabindex, native disabled
state or inert ancestry; ordinary visible enabled controls retain their order.
`ui/surfaces` owns the capture-phase keyboard listener, Tab cycling and return
focus shared by the first-run launcher and Provider Settings. Each caller
activates it while open and deactivates it on dismissal; destruction releases
@@ -1173,7 +1188,9 @@ stalled downloads are cancelled. Development and preview use the same handler.
Overpass query validation, geometry simplification, disk caching and upstream
transport now have separate modules; military-installation search reuses that
transport. Regional briefing combines separate place, news and weather sources,
while weather effects uses only the weather source. Existing process-scoped
while weather effects uses only the weather source.
GDELT compact dates that do not name a real calendar instant keep the article
with an unknown publication time. Existing process-scoped
caches, rate limits, stale fallbacks and route ordering are preserved.
Local voice has separate HUD-summary, debug-log and Realtime-token handlers,
@@ -1202,13 +1219,21 @@ a browser key. Preview is for local build verification, not a production server.
## CCTV and radio provider modules
CCTV direction text resolves travel tokens first, then intercardinals, then
bare cardinals when enabled. Only conflicting headings within the highest
matching tier remain unknown; street quadrants and lower-tier words do not
cancel an explicit travel heading.
CCTV catalog acquisition, source normalization and frame/media delivery now live
in separate modules. Each CCTV factory owns its catalog and health state; its
`sourceRoot` option resolves relative source files against the application root.
Radio Browser station normalization, restricted outbound transport and directory
caching are separate modules. Node-only package entries expose both provider
factories. Routes, payloads, fallback behavior and existing dev/preview hook
registration are preserved; browser rendering is unchanged.
caching are separate modules. The pinned transport gives a mirror's 204, 205 or
304 reply an empty body and fails any reply outside 200–599 without throwing
outside its promise, so an unusual mirror status cannot crash the server.
Node-only package entries expose both provider factories. Routes, payloads,
fallback behavior and existing dev/preview hook registration are preserved;
browser rendering is unchanged.
## Terrain, traffic, fire and bike-share provider modules
@@ -1222,6 +1247,10 @@ The browser layers and their rendering remain in their existing modules.
## Terrain height cache bound
The terrain proxy parser rejects finite longitudes outside [-180, 180] and
latitudes outside [-90, 90] for every client before upstream resolution. One
out-of-range point rejects the whole batch; inclusive WGS84 bounds remain valid.
The client terrain-height resolver's in-memory cache is bounded at 20 000
entries (`DEFAULT_MAX_CACHE_ENTRIES`, overridable per instance through
`createTerrainHeights({ maxCacheEntries })`). Coordinate rounding makes repeated
@@ -1459,7 +1488,7 @@ accessible name remains "Don't show this again". Control behavior is unchanged.
## FIRMS source status
FIRMS ingestion and adaptation require explicit finite coordinates within WGS84 ranges; genuine zero coordinates remain valid and admitted detection indices stay sequential.
The FIRMS CSV parser rejects impossible acquisition calendar dates before the proxy filters records to the trailing 24 hours, while retaining valid UTC acquisition times.
The FIRMS proxy records source success after appending its rows. If aggregation
throws, that source reports failure without a contradictory success entry.
@@ -4111,6 +4140,10 @@ for, resolved lazily after env loading. It replaces the empty default list;
there is no built-in fallback. Local/private instances are allowed. The stable
`gods-eye-view/…` User-Agent is unchanged. URLs never appear in response headers
or upstream errors, including old cached endpoint metadata.
Disk cache entries for both routes carry a SHA-256 tag of the configured
instance set (order does not matter) and are served only while it matches, so
repointing `OVERPASS_UPSTREAMS` refetches instead of serving another instance's
answers; untagged entries stop serving once an instance is configured.
The shared transport guards `/api/overpass` and `/api/military-installations`.
With no configured upstream, each route serves existing cache data (including
@@ -4128,7 +4161,8 @@ when its own signal aborts.
Configured endpoints have per-instance cooldowns for 406/429, honoring
Retry-After; absent delays back off from 30 seconds to five minutes. Empty
`elements` is a valid answer. Existing byte, query, concurrency and cache caps
remain. Consumer capability misses never schedule automatic retries.
remain. Malformed capability-probe responses remain unknown and are retried after the existing 30-second backoff; valid configured decisions remain memoized.
Consumer capability misses never schedule automatic retries.
Operator-configured Overpass area and focus-footprint queries use body-level
`out geom` (with `center` for focus), preserving relation member outlines.
@@ -4426,7 +4460,24 @@ Providers normalize coordinates, canonical name, label, place types and optional
bounds. Camera framing, nearby landmark recovery and footprint selection remain
in their consumers, including the Capitol identity/containment safeguards.
Radio keeps localized country names in labels rather than station filters.
Reverse geocoding and nearby/text-search endpoints retain their existing behavior.
Nearby/text-search endpoints retain their existing behavior.
**Google geocoding is a server route, not a browser call** (#363). Forward and
reverse lookups go to `/api/google/geocode` and `/api/google/reverse-geocode`,
which carry `GOOGLE_MAPS_SERVER_API_KEY` (falling back to `GOOGLE_MAPS_API_KEY`)
and share the Places routes' opt-in `GEV_RATELIMIT_GOOGLE_PER_MIN` throttle.
Google's Geocoding **web service** refuses referrer-restricted keys, so the
previous browser call forced the bundled browser key — visible in devtools by
design — to be left unrestricted; it now needs only the Map Tiles API and the
Maps JavaScript API (Street View). Both routes answer in Google's own
`status`/`results` shape rather than the Places routes' `places: []` contract,
because the browser adapters normalize that shape directly. The browser key still gates the provider client-side, so a keyless
session spends no request to learn it has no Google: the route's own keyless
answer reads as an unanswered provider, which would stop the chain caching the
negative Photon or Nominatim then produces. Its query is capped at 200
characters, its reverse coordinates are validated against WGS84 bounds before
the request is paid for, and a malformed viewport bias is dropped rather than
refused, since a bias only ranks results.
Only valid answers and definitive misses enter bounded caches; malformed replies,
HTTP refusals and outages remain retryable. Searches share a 12-second total
@@ -4523,6 +4574,8 @@ are omitted rather than framing the wrong part of the globe.
### Recent Imagery (September 2026)
CMR pagination counts raw rows when checking page completion and the record budget. A catalog is truncated when upstream hits exceed the rows examined or the record cap drops valid granules from the last page; discarded malformed rows do not imply unseen imagery.
Programmatic boxes passed to the exported `setBox` and `searchHls` operations
reject missing, blank or boolean edges instead of interpreting them as zero
coordinates. Valid finite numeric edges remain accepted; the app’s drag tool,