Skip to content

v0.6.0

Choose a tag to compare

@ttezer ttezer released this 17 Jul 11:56

Scores are not comparable to 0.5.0. False positives were removed from five rules and two rules were regrouped, so a feed's numbers move even though the feed is unchanged. Re-baseline any Golden snapshots after upgrading.

This release comes out of running 250 feeds sampled across 71 countries from the MobilityData catalogue and comparing every finding against MobilityData's own report for the same snapshot.

Our test corpus had been three feeds — BART, Tokyo Toei, TriMet. Every bug below is one that corpus could not surface: they need non-ASCII text, minute-rounded times, a repeated stop name, a ", " separator, or a multi-agency feed.

Fixed

Valid feeds were rejected outright when a header read split a UTF-8 character. K1 reads only the first 8 KB of trips.txt, stop_times.txt and calendar_dates.txt; when that cut landed inside a multi-byte character the truncated tail was read as invalid encoding, and on a required file that became a fatal error — the feed produced no analysis at all. Japanese, Lithuanian and Thai feeds were rejected while MobilityData reported two of them with zero errors.

FLG_002 reported false criticals for valid Fares v2 networks. A network_id may be declared in networks.txt, routes.txt, or route_networks.txt; only the first was recognised. On TriMet this removed all 7 criticals and raised the Publication Score from 89.3 to 100.

STM_012 called a stop pair impossible on a fixed 1 km distance. When two stops share a whole-minute timestamp the real travel time is unknown — rounding hides 0–59 seconds — yet a bus covering 1.1 km within that minute only needs 66 km/h. The distance must now be unreachable even if a full minute had elapsed (max_speed_kmh(route_type) / 60). One feed: 42 findings → the single 29.4 km jump MobilityData also reports.

TRP_020 flagged headsigns that correctly name the last stop. The rule excluded the terminal by stop_id but matched by name, so a trip was flagged whenever an earlier stop shared the terminal's name. One feed: 9,162 → 171. On Tokyo Toei all 156 findings were this false positive.

RTS_019 treated different operators' route numbers as duplicates. Two agencies each running a route "10" is ordinary; GTFS scopes name uniqueness to one route_type under one agency_id. One feed: 32 → 3, matching MobilityData exactly.

STP_030 counted entrances as a station's children. A vehicle only stops at a platform, so a station holding six entrances and no platform was silently accepted.

RTS_023 ignored route_desc that repeats the short name. It compared only against route_long_name; MobilityData checks both. On one feed all 436 of its findings were short-name matches and we reported none.

Changed

STM_014 findings are grouped per route, direction and segment. A single bad segment produced one finding per trip crossing it — on TriMet, 497 findings pointed at the same two segments.

DQ_016 reports one summary per file instead of one finding per row. Trailing whitespace is one producer habit — usually ", " as the separator — so it appears on every row of every file. One feed produced 2,361,873 findings (98.6% of its total, against MobilityData's 12) — the volume that exhausts browser memory. Detection is unchanged and still correct: RFC 4180 makes the space part of the field. That feed drops to 7 findings, its total from 2.4M to 43k.

Added

validate_with_today (WASM). The browser evaluated calendar rules against the machine's clock, so a run could not be reproduced and a diff mixed code changes with the date shift. The date can now be supplied explicitly, mirroring the CLI's --today.

Internal

  • RULES.md / .en / .ja are generated from the rule registry but nothing enforced regeneration and they had drifted; a test now ties them together.
  • ARC_029 (decompression guard) is proven end-to-end: a zip bomb returns the expected fatal, a legitimate small high-ratio file does not trip the guard.

Full changelog: https://github.com/ttezer/gtfs-analyzer/blob/v0.6.0/CHANGELOG.md