When I understood how GTFS Schedule and GTFS Realtime could work together, I saw a matrix of useful questions about Montréal transit. GTFS Schedule supplied the planned side: routes, trips, stops, and timetables. GTFS Realtime could add live trip updates, vehicle positions, numeric delay, and optional occupancy information. A single date, a date range, or a wider period added another dimension. transit.yesid.dev came about in part from seeing how those dimensions could cross instead of treating each feed or metric as a separate fact.
Put a route on one axis and time on another, then ask where scheduled service and live observations diverge. Which routes are late across the chosen period? Does the pattern change when the date range changes? Where does available crowding information show a different pattern at a certain time? Which scheduled bus trips should be running now but have no matching live vehicle? Each question comes from a different intersection of planned service, live information, a product interpretation, and a time control. The matrix turns a list of fields into something I can examine.
Those questions require the source and product layers to stay separate. Delay is numeric, while early, on time, late, and severe are interpretations created by the product. Occupancy is optional and experimental, so it can be absent, incomplete, and not guaranteed to form a linear scale. Not reporting is separate: it is a product-derived signal for a scheduled bus trip that should be running now but has no matching live vehicle, not an official GTFS timing value.
I see an actual matrix. I see rows and columns. It is a visual thing. Granularity can be one part of the picture: one item, a group, or a wider level. Filters and the options they leave can be another. Decisions, database fields, and combinations occupy the same kind of visual space. The contents change with the subject, but the rows and columns remain visible to me.
For one decision, I can picture the options as rows and the constraints as columns. One filter narrows the options; another adds a condition. I can see which combinations remain. The exact entries depend on the decision, but I still see the relationships as a grid.
SQL fits that picture. A table gives each row a record and each column a field. Filters choose which records are in view, and a query can combine several conditions. Relations let me move from one record to related records when a single table does not explain enough. Granularity also changes the picture: a single record, a grouped result, and a wider set answer different questions. SQL gives precise names and operations to the rows, columns, filters, database fields, and combinations I see.
Accounting and SQL connect in my head. Before I worked as a SQL developer, I studied accounting. When an amount was uncertain, a date and an amount were a place to start. They were clues, not guaranteed unique keys, because another record could share both values. The surrounding context could be in cash flow, a budget, a financial statement, or a transaction. Sometimes the date could point toward the right account; sometimes the amount only narrowed the search. I could move through those records and ask where the amount appeared, what it related to, and whether another record explained it better. JOINs and normalization later gave me more precise tools and language for following relations in data. The personal connection is the act of tracing: the first value points somewhere, the related records narrow the uncertainty, and the full answer depends on context.
I remember a woman at a dishwasher job telling me, "You have two hands. Use both hands."
I kept that instruction. I still notice when one hand is idle and could already be helping. One hand can keep an action moving while the other starts the next one. Both hands can move in different directions toward different tasks. It did not stay at the dishwasher job; I carried it into other physical work. When I work or do something with my body, I look for that opening instead of waiting for one action to finish. It saves time, and I catch myself using the habit all the time. The change is physical and specific: notice the idle hand, give it part of the work, and let the two actions move together.
Data works because fields have definitions. A delay can be stored as a number, a date range has boundaries, and a product can group observations into stated categories. People are not hard parameters in the same way. You can collect the biggest metrics and still never fully measure a person. A score, category, or observation can describe something real, but it supports a limited claim.
The two-handed habit makes the difference clear. I can describe what changed: both hands work, actions move in different directions, and time is saved. Those measurements can describe the habit, but they cannot contain the person who taught it.
That is also how I work with AI: it can turn a conversation into structure, but I read every block from start to finish and make the final call.
This is chapter 3 of a six-chapter epic. Chapters 1–3: who I am. Chapters 4–6: what I build. Previous: How I learn: orbiting a system until it clicks · Next: AI-accelerated, human-owned: my actual workflow.
Need a system that stays editable?