Seven tests built terrainHeightsProxy() with no cachePath, so the proxy fell
back to this checkout's .gev-cache/terrain-heights.json. A point the app had
already cached there answered a request the test expected to reach the
stubbed upstream: after running the dev server near Austin, the cross-site
test failed with 1 !== 2.
isolatedCachePath(t) gives each test a mkdtemp cache file removed in
t.after, as the over-large cache test already did; that test now uses it too.
Fixes#1242.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BNTtHAa65nobzJ7jp2Ltr4
The parity test compared getWorldPacket with voice, which now calls
getWorldPacket. Compare both against a fixed payload captured from main's
get_current_view_state before the extraction, key order included, and
cover a non-finite now.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A default parameter only covers undefined, so now: null aged every feed
against the epoch and reported stale data as just now.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- State FL511's terms the same way everywhere: individual, personal use
only, and any other use (a public deployment included) needs FDOT's
express written consent. .env.example, README, dataCredits, the source
licence string, the catalog comment and the changelog fragment said only
"individual, non-commercial use".
- Page the ArcGIS catalog on exceededTransferLimit alone and advance the
offset by the rows each page returned, so a lower server-side max
record count no longer cuts the catalog short at the first short page.
- Order pages by OBJECTID_1 (this layer's object id; a plain OBJECTID is
rejected with HTTP 400) so offset paging is stable.
- Raise the page ceiling to 40 and warn when it is hit.
- Tests: short pages with exceededTransferLimit keep paging, orderByFields
is sent, and a service that ignores resultOffset stops at the ceiling.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
aircraft_in_area stats summarized altitude over airborne aircraft but
speed over every match, so parked aircraft pulled the mean speed toward
zero. Both figures now use the same airborne subset, and the on-ground
fixture is stationary so the test can tell the difference.
Reserved AIS ship-type codes 100 to 255 now read as unknown, as type 0
does, instead of showing up in the breakdown as their own type.
Adds tests for an area where every aircraft is on the ground and for
find_vessel type and destination normalization, and notes in the
changelog fragment that every vessel answer is now normalized.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
AIS sends ship types as ITU-R M.1371 codes, so vessels_in_area grouped
"70", "74" and "79" as three types, and type: "tanker" matched nothing on
feeds that send codes. Codes now read as the family the vessel cards already
show (CARGO, TANKER, TUG), for rows, group_by and the type filter. The code
table moves to src/data/vesselTypes.js, which has no i18n import, so the
server-side tools can use it; vesselLabels re-exports it.
A destination with no letters ("0", "---") now counts as unknown.
Live, Singapore: "most by type: CARGO (3), TANKER (3), PASSENGER (1)"; "how
many tankers near Singapore" found 3.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ICAO flight-plan Item 7 caps aircraft identification at seven characters, so
the flight number after the designator is one to four characters, not five.
Philippine RP-C1234 and Cuban CU-T1240 registrations read like a designator
plus a flight number once the hyphen is dropped; they now count as unknown.
Cubana's CUB123 still counts as CUB.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- dataCredits `gbfs`: names the seven PBSC operators, with BiciMAD's
required "Powered by EMT de Madrid" linking to emtmadrid.es.
- dataCredits `jcdecaux-gbfs`: adds Valenbisi and Sevici.
- DATA_SOURCES.md: a BiciMAD row (Madrid's open-data catalogue publishes
the feed under EMT's terms, attribution required), one row for the other
six PBSC feeds (no licence published; attribution to the operator), and
the JCDecaux row widened to Valencia and Seville.
- CURRENT-STATE.md: the Bikeshare row, and the underscore and
geofenced-capacity rules in "GBFS upstream bounds".
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Adds the station-based public bike systems of seven Spanish cities on
PBSC and two on JCDecaux, 1,843 stations in all (live feeds, 2026-10-17):
- PBSC (`<city>.publicbikesystem.net`, GBFS v2 like Bicing): BiciMAD
(Madrid), Bizi Zaragoza, BIKI (Valladolid), BiciCoruña, Dbizi
(Donostia-San Sebastián), Bilbao Bizi and BicinRivas (Rivas-Vaciamadrid).
- JCDecaux (`api.cyclocity.fr/contracts/…`, like Lillestrøm): Valenbisi
(Valencia) and Sevici (Seville).
Both hosts are already allowed by the proxy. Every system uses a 40 km
load radius; the farthest station is 11.7 km from its centre (BiciMAD).
The radius also keeps out what two feeds list away from their city:
Sevici's workshop at (0,0) and lab in Madrid, and BiciCoruña's planned
stations with no position yet.
spainCitiesSystems.test.mjs checks the registry and proxy for each feed,
that the outermost live stations activate their system and sit inside
its radius, that central Madrid activates BiciMAD and BicinRivas, that
the far-away stations are not loaded through the real ingestion path,
and that JCDecaux names arrive without underscores and PBSC capacities
as docks.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PBSC adds the bikes a station accepts in the geofenced area around its
docks to `capacity`, and reports that part as `geofenced_capacity`, which
is not a GBFS field. Bilbao Bizi publishes 39 docks as capacity 839 with
geofenced_capacity 800, so its stations would read as nearly empty: red,
drawn at maximum size, and carded "39 avail · 0 docks · 839 cap".
BiciMAD (671 of 678 stations, about twice the docks) and Dbizi (11 of 70)
do the same.
The shared parser now reads `capacity − geofenced_capacity` when the
extension is present and no larger than the total, so the layer, its
colour ratio and get_bike_share all see the docks. No registered system
changes: none of the 52 publishes a geofenced capacity above 0 (live
feeds, 2026-10-17, all 13,397 capacities identical).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
JCDecaux's Spanish contracts prefix every station name with "_", and
Valenbisi joins its words with it ("_PLAZA_MUSICO_LOPEZ_CHAVARRI"), so
the card and HUD would show the raw identifier. The shared parser now
reads a run of underscores, with the spaces around it, as one word break
and trims the ends. It applies to `name`, the `short_name` fallback and
GBFS v3 localized names, so the layer and get_bike_share both read it.
No registered system changes: run over all 52 live station_information
feeds on 2026-10-17, the old and new parsers give identical names for
all 13,397 stations. Other spacing stays as the operator published it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
OpenSky, the default civil feed, reports no operator, so group_by: operator
said "no operator reported". aircraft_in_area now also takes
group_by: 'airline', read from the ICAO designator in each callsign: three
letters followed by a flight number that starts with a digit (SWA1234,
UAL12A). Registrations used as callsigns (N123AB) count as unknown. Rows are
unchanged; the designator is derived for the breakdown only.
Live, Texas: "785 aircraft ...; most by airline: AAL (89), SWA (65), UAL (52);
283 unknown."
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Providers write cache files and logs into .gev-cache and .gev-logs while the app runs. A serve-only standalone plugin adds both to server.watch.ignored, so the dev watcher no longer stats them; source changes still reload.
Route tleCatalogNumber() and noradIdFromSatnum() through one decoder that
accepts only plain digits or a valid Alpha-5 field. parseInt and Number()
read '2554A', '255 4', '-1234', '0x1F0', '1.5' and blank as numbers; they
now return null/NaN. Digit satnums of any length still decode, so OMM
satrecs numbered past 99999 keep working.
Add a layer test that several Alpha-5 satellites survive ingestion dedupe,
the changelog fragment for #767, and note in CURRENT-STATE that this is
Alpha-5 TLE compatibility and malformed fields are rejected.
World Packet #880 removes the duplicate tracking table from gevActions; the Cockpit refusal source-scan test should inspect the actual exported source of truth instead of assuming the previous file position. Fix failing Node 24 exact-head CI without duplicating runtime definitions.
Reuse one context/contacts/tracking owner in voice and World Packet. Compare voice outputs after stripping presentation fields; remove the unconsumed fingerprint API pending an actual caller. Document the exported packet boundary and reject null options safely.
Review guidance: asturksever on origin #880; Windows parity diagnosis by quanticsoul4772. Existing source ownership retained.
Reconcile #880 with current main. Delegate the view-state builder while keeping enabled-only layers, disabledLayerCount, provenance, context semantics, and existing voice behavior. Add parity and roster-read regressions; retain package export, boundaries and changelog fragment.
Preserve original GEV voice, layer and packet contributor credit.
Carry reviewed #816 onto current main without conflicts; preserve i18n updates, replace obsolete changelog edit with a fragment, and add a constructor-wiring regression alongside the owner and rail tests.
Credit: raysung-2026 (report), asturksever (review), quanticsoul4772 (Windows diagnosis).
Review follow-up on #975. The shared same-site gate refuses any forwarding header, which is right for routes that spend a key, but terrain is keyless and needed for rendering: behind the reverse proxy the README documents, every /api/terrain/heights chunk got 403 and fell back to the geoid. Terrain now uses admitSameSiteKeyless, which keeps the Sec-Fetch-Site and exact-Origin checks (comparing Origin against a single X-Forwarded-Proto scheme) but does not refuse forwarding headers. The shared admitSameSite gate is unchanged for every other route. The changelog entry moves to changelog.d/975-terrain-cross-site-gate.md.
Co-authored-by: daikaginza <[email protected]>