There was an error while loading. Please reload this page.
Record parent-agency fan-out as a confirmed Implementation Decision search-stop emits one references.stops entry per (parent station, resolving agency) pair when a station is shared across agencies, rather than legacy's single agency-stable entry. Traced why legacy's mechanism (AgencyAndId assigned per stop at bundle-ingestion time) doesn't transfer to Maglev: Maglev ingests one static bundle, not several federated ones, and the stops table has no agency_id column at all (matching raw GTFS's own stops.txt). The scenario is still real, not hypothetical, since one bundle's agency.txt can define multiple agencies whose routes share a stop_id. Cited the reviewer comment (PR #1221) that explicitly offered this per-(parent, agency) approach as an acceptable fix for the bug it replaced, and recorded the reconsideration fallback (pick one canonical agency per parent, as already done for routeless stops) per the page's existing Implementation Decisions format. Checked whether this fan-out pattern is reused elsewhere: it isn't, because no other multi-agency-capable endpoint currently populates parent stations at all (stops-for-location, trips-for-location, trips-for-route all hardcode parent to empty string) - so this stays a single-page decision rather than a shared doc.
Document stop direction inference as a shared algorithm Eight endpoint pages described data.*.direction as a bare GTFS passthrough ("absent when the feed does not supply it"), but both legacy Java (GenerateNarrativesTask.computeStopDirection) and Maglev (AdvancedDirectionCalculator) infer a direction from shape geometry when the feed omits one, using the same vector-averaging algorithm and the same 0.7 standard-deviation rejection threshold. Traced and cited the Java source directly rather than assuming Maglev's behavior was novel. Added Stop-Direction-Calculation.md as a single source of truth for the algorithm (legacy steps, Maglev's port, and the one confirmed intentional deviation: an epsilon-based near-zero check replacing Java's largely-inert exact == 0.0 comparison), and pointed every affected page at it instead of duplicating the explanation. Linked from OBA-API-Specs.md under a new Shared Algorithms section. Affected pages: stop, stops-for-agency, search-stop, stops-for-location, stops-for-route, arrival-and-departure-for-stop, arrivals-and-departures-for-stop, trips-for-location. block/{id} also calls the same code path but has no wiki spec page yet.
Document code fallback on search-stop's stop entries search-stop.md left data.list[].code undocumented for the no-code case, unlike stop.md and stops-for-agency.md. Traced the legacy call chain (BundleSearchServiceImpl -> TransitDataService.getStop() -> StopBeanServiceImpl.fillStopBean) to confirm search-stop's suggestion index is built from the same StopBean construction path as the single-stop endpoint, so the same getBestName() fallback to the entity ID applies here too. Not a Maglev deviation, just a gap.
Record tripId/activeTripId interlining decision for trips-for-route Java always conflates data.list[].tripId with status.activeTripId, schedule, and situationIds — all four are populated from the same active-trip instance with no route-based filtering (verified against TripStatusBeanServiceImpl at the pinned commit). PR #1256 (closing #1254) deliberately decouples them: tripId now resolves to the queried-route trip that caused the block to be selected, while status.activeTripId keeps reflecting whatever trip the vehicle is actually running. Correct the Main Success Scenario and the four affected field descriptions (tripId, situationIds, schedule.stopTimes, status.activeTripId) to describe Java's actual conflated behaviour first, each pointing to the new Implementation Decisions entry where Maglev diverges — matching the maxCount entry's existing pattern of documenting the decision once and cross-referencing it from the spots it affects.
Remove maxCount from trips-for-route Documented the decision to remove the maxCount param. This param is parsed but ignored by the legacy impl. The parameter does not make sense for this endpoint. It was likely included by legacy unintentionally via a shared path.
Record DC-6c decision: preserve search/stop limitExceeded ordering Split DC-6 into per-endpoint sub-decisions (DC-6a/6b/6c) since the three bundled truncation bugs have independent root causes and were being decided separately. Records the search/stop case (DC-6c) as Preserve, decided alongside PR #1220, since correctly fixing it would require evaluating the route-type filter against the full raw match set before truncation rather than just the current page - adding real query cost or fetch-loop complexity for a discrepancy already documented in the search-stop spec and not consumed by any client today. routes-for-location (DC-6a) and stops-for-location (DC-6b) remain undecided.
Updated GTFS Flex Support (markdown)
Updated OBA API Specs (markdown)
Created GTFS Flex Support (markdown)
Updated _Sidebar (org)
docs(agencies-with-coverage): note maxCount/limitExceeded fix as deliberate deviation
docs(search-stop, search-route): note no-match 200 as deliberate deviation Both endpoints' legacy behavior (return HTTP 404 with the standard error envelope when a search matches nothing) stays the documented spec. Add an Implementation Decisions entry to each (creating the section on search-route.md, which didn't have one) explaining that Maglev instead treats a no-match query as a successful, empty result (HTTP 200, data.list: []), and cross-reference it with pointers from Minimal Guarantees, Extensions, and the Response Structure fields that describe the legacy 404 behavior.
docs(trips-for-location): record bounding-box clamping fix as Implementation Decision Cross-links the Extensions 3a/3b scenarios and both Suspected Defects entries to a new Implementation Decisions entry documenting that BoundsFromParams deliberately fixes the legacy zero-area-collapse and unclamped-span bugs by clamping to the 20,000 m max radius.
docs(trip-for-vehicle): record next-calendar-day serviceDate for late-evening requests BlockFinder.getPossibleServiceDates checks the next day when the request falls after 20:00 local time, in addition to the previous day before 04:00 already documented. Neither the Main Success Scenario nor the serviceDate field description mentioned the next-day case.
docs(trips-for-location, trips-for-route): record previous-calendar-day serviceDate for past-midnight trips Both endpoints share trip-for-vehicle's block-resolution path (BlockStatusServiceImpl/BlockCalendarServiceImpl), which already resolves the correct previous-day service date for trips extending past midnight. trip-for-vehicle.md documented this; these two specs didn't.
docs(search-stop): record route-reference sort as intentional cross-endpoint deviation Maglev sorts data.references.routes with the same natural-sort, shortName->longName->agencyId->id comparator used on stop and schedule-for-stop, rather than legacy search-stop's own plain lexicographic shortName->id comparator. Favors one consistent sort rule across endpoints over per-endpoint conformance with legacy.
docs(search-stop): record includeReferences=false as an intentional deviation Maglev returns an empty-but-present references block instead of reproducing the legacy NullPointerException/null-body bug (Suspected Defect #1). Adds the missing Implementation Decisions entry and cross-references it from the defect writeup.
docs: record trip-less vehicle inclusion (Extension 5a) as not implemented Maglev drops trip-less vehicles from vehicles-for-agency entirely rather than including them with tripId/tripStatus absent. An attempted fix (#1129) surfaced unresolved problems with ingestion-time filtering, multi-agency feed attribution, and query-time feed access, so the gap was closed as won't-fix (#1128). Records the decision and outlines the ingestion-time approach that would be needed if revisited.
docs: clarify schedule-for-stop references block is always present includeReferences=false was described as omitting data.references entirely. In practice (and consistent with route.md/stop.md and the legacy BeanFactoryV2 behavior), the block stays present with empty lists. Tightened three spots: the request-param schema, the prose description, and the envelope's data.references description.
docs: record lastUpdateTime/lastLocationUpdateTime emit 0 in Maglev The legacy Java implementation omitted these fields from TripStatus responses when no real-time update had been received. Maglev emits 0 instead, using the shared TripStatus struct across all endpoints to avoid per-endpoint omission complexity. Add Implementation Decisions entries to trip-details, trip-for-vehicle, and vehicles-for-agency documenting the deviation. Cross-reference from each field description that specifies legacy absent behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: record outOfRange=true (Extension 4a) implementation decision for vehicles-for-agency Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: record ageInSeconds=0 implementation decision for vehicles-for-agency Closed by PR OneBusAway/maglev#1108. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: record agency namespace validation decisions for stop endpoint Document that Maglev enforces agency namespace correctness on /stop: a request for a stop not served by the requested agency returns 404, whereas the legacy implementation ignores the agency prefix entirely. Also document the orphaned-stop fallback (any agency that exists in the DB is accepted when the stop has no routes). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: stops-for-agency — record implementation decision for full parent station records The legacy implementation adds a minimal record for parent stations in references.stops. Maglev expands this to a full stop record (including routeIds and staticRouteIds), consistent with how the stop and arrivals-and-departures-for-stop specs define stop records in references. Updated Extension 3a to point to the new implementation decision. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop block/block-instance endpoint from Maglev API specs The block endpoint is not being implemented in Maglev. Remove the spec, index entries, cross-references from trip.md, and related defect workshop entries (DC-4b, DC-18). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: record DC-2 and DC-3 decisions for schedule-for-route 510 responses DC-2: Both "no service" responses change from code 510 to code 200 with the reason in the text field. HTTP 404 was rejected because the route exists in both cases. Client impact analysis confirmed no client inspects code 510 or the text field. DC-3: ServiceDateOutOfRange gains the same partial data body that NoServiceThatDay already had, making both responses structurally consistent. Eliminates a DecodingError in the iOS client. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs: add implementation decision for validation-error body format on schedule-for-route Record that Maglev wraps field errors in the standard OBA response envelope rather than returning the bare Struts fieldErrors body, consistent with all other Maglev validation errors (DC-4a). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated OBA API Defect Workshop (markdown)