feat: Simplify fare transfer logic for 2026 fall fares changes - #3471
Merged
joshlarson merged 19 commits intoSep 3, 2026
Merged
Conversation
joshlarson
force-pushed
the
jdl/feat/simplify-fares-transfer-logic-for-2026-fall-rating
branch
from
September 3, 2026 12:17
9f5517c to
fd929d5
Compare
thecristen
approved these changes
Sep 3, 2026
thecristen
left a comment
Collaborator
There was a problem hiding this comment.
I think the logic is sound and the documentation is great! A few small comments.
joshlarson
had a problem deploying
to
dev-blue
September 3, 2026 20:53 — with
GitHub Actions
Failure
joshlarson
enabled auto-merge (squash)
September 3, 2026 20:53
joshlarson
deleted the
jdl/feat/simplify-fares-transfer-logic-for-2026-fall-rating
branch
September 3, 2026 21:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
Asana Ticket: 💸 🗺️ Update Trip Planner fares to reflect fare pilot starting 9/1
Implementation
%Fares.State{}that keeps track of the rider's journey so far. Each time a new leg is added to the%Fares.State{}, it uses the updated transfer logic to determine whether the new fare should be included in the 2-hour transfer window, when fares should be free (for free buses and free boarding at Logan, for instance), and when in-station transfers occur between routes that are all on the "paid" side of the fare gates.Fares.State.add_leg/2, and then callingFares.State.fare/1to extract the final fare at the end.Note
🤖 The meat of this PR was human-generated - I wrote the new tests and the
%Fares.State{}struct by hand. Much of the follow-on cleanup work was done by Copilot, including adding typespecs and docs.The commits that include
(robot)in the prefix were AI-generated; the others were hand-crafted.Screenshots
Alewife to Orient Heights
Old: Out-of-station subway transfer: 2x $2.40 = $4.80
New: Infinite subway-to-subway transfer: 1x $2.40
Alewife to Charlestown (Navy Yard)
Old: Subway-to-ferry transfer: $2.40 + $2.40 = $4.80
New: Infinite subway-to-ferry transfer: Just $2.40
Burlington Mall to Montello
Bus bus ferry bus bus
Old: Three bus fares (I don't actually know why) plus a ferry
New: Most of the bus legs, plus the ferry, are in a 2-hour transfer window, plus one bus trip outside of that: $9.75 + $1.70 = $11.45
Six-legged bus trip
Old: No 2-hour bus transfer window (this is a bug, FYI): $1.70
New: Last two legs are outside the 2-hour window: $1.70 + $1.70 = $3.40
Washington St @ Blue Hill Ave to Ashmont
23
Old: Regular bus (this is a bug, FYI): $1.70
New: Free!
19 -> RL
Noting this because that transfer happens at Fields Corner, and if we counted this transfer as a free in-station transfer, then we would incorrectly list a fare of $1.70. Old and new both correctly report $2.40.
Boston Logan Airport to Alewife
Flagging this as a fun use case where we need to care about in-station transfers explicitly, and can't just assume that we can ignore in-station transfers because of the infinite-subway-to-subway rule.
Boston Logan Airport to Highland Ave @ Tower St
Old: Erroneously counts the trip as free, because it starts out free, and then all of the transfers afterwards are normally free.
New: Correctly shows the transfer to the 90 bus as a regular fare, because boarding the SL1 at Logan and the in-station transfer at South Station are both free, and don't start any kind of transfer window.
How to test
Visit any of the above links, as well as any other complicated trips you can think of! Have fun!