I did not start this project because I needed another software tool. I started it because I was frustrated with the one I was already using.
For signal warrants, I had been using the MUTCD Warrants Module of the HCS 2025 suite, and I did not enjoy it. It had real limitations for the way I wanted to work. The number of hours felt constrained, it could not evaluate rolling hours the way I wanted, and the overall UI and UX were not inviting. It felt like the kind of software you pay for because you have to, not because you like using it.
That frustration was a big part of my motivation. I thought about how I wished this process could be cleaner, more transparent, and more pleasant. I always liked coding and automation and tried to keep up with it as much as I could, even if that is not my main professional identity. Then AI tools, Codex, Claude Code and all these new software development workflows started becoming more accessible. I built a few small apps before this and loved it. So there was no excuse anymore, I decided to build something more directly connected to my work. Something that solved a problem I actually had. And if I was having these issues with existing signal warrant software, I was sure other engineers probably were too. That made the idea feel more useful. I also liked the thought of making it free so anyone could use it, instead of locking another basic engineering workflow behind paid software.
That was the start of the Signal Warrants app.
The first decision was to focus on the rules engine before the interface. The app could not just look good. The logic had to be defensible. We started with Warrant 1, the 8-Hour Vehicular Volume warrant. That immediately brought up detailed questions. How should reduced thresholds be handled? Should 70% thresholds be allowed? How should the 80% combination threshold be shown? Should right turns from the minor street be included or excluded? How should the major and minor streets be selected?
These were not cosmetic details. They controlled the result, which made one principle clear early on: the app should keep warrant status separate from engineering judgment. It can say whether a warrant is satisfied (or is “met”) under the selected assumptions. Also it should never say that a satisfied warrant automatically means a signal should be installed, or that an unsatisfied warrant ends the discussion.
The hourly volume logic was one of the first real friction points. The input data generally is in 15-minute intervals, but the warrant is based on hours. At one point, the concern was for the app to not simply group records in fixed blocks, such as records 1 through 4, then 5 through 8, etc… That would be easy, but not good enough. I had to think about actual time continuity, rolling hours, and making sure selected hours did not overlap either.
The user interface came after the logic, but it was still tied to technical decisions. The app needed an intersection diagram, street names, major and minor street selection, lane counts, speed inputs, volume tables, threshold outputs, and a report section. Each of those created questions.
The early version assumed a standard four-leg intersection with NB, SB, EB, and WB approaches. That worked for many cases, but what about a three-leg intersection? What if a major-street left-turn movement should be analyzed under a separate MUTCD-allowed approach? I simply documented it for future architecture and took one step at a time.
A lot of the work was practical and repetitive. The count table needed to be easier to use. The time column needed to stay visible. Numeric fields needed to be smaller and cleaner. I wanted the results to show the warrant status first not show confusing “satisfied by” language if it’s not even satisfied! The report needed to be clear enough that someone could understand the conclusion without digging through the code or raw data.
I also had to learn how to manage the development process itself to avoid wasting time or quota usage on broad prompts. Over time, I learned to settle into a better workflow (not sure if that is the best though!): think the logic first, create Git branch, use a narrow prompt to develop, review the change, run tests, commit, PR, address comments, and merge. That workflow was not fast in the flashy sense, but it was controlled. It helped keep the app from turning into a pile of disconnected changes. I am sure at this point agents are doing all of this automated and ordering through the whole pipeline with other agents taking care of all the back and forth I still had to do manually for not knowing any better, but well, one step at a time…
There were plenty of issues along the way. Sometimes sample data did not behave the way I expected. For sample data meeting Warrant 4, I noticed pedestrian volumes were showing, but vehicle volumes were still zero, which made the result look suspicious. For Warrant 7, I questioned whether the crash history section repeated too much language, so then revised the display to make angle and pedestrian crash information clearer. Some questions were about interpretation. I asked whether 10 fatal crashes at an intersection would automatically satisfy Warrant 7. That forced the logic back to the actual warrant criteria. Severe crashes matter, but the warrant still has defined conditions. The app needed to follow the criteria, not just react to the seriousness of the crash history.
My questions changed as the project moved forward. At first, they were broad and about the general structure, order of operations, and presentation of the warrants logic. Later, they became much more specific: which field should control this result, where should this threshold appear, is this label misleading to the user, and does the report language match the analysis, and so on…
I am not a software engineer, but I became better at guiding the work. I learned to move from “this feels wrong” to “this specific behavior needs to change.” The app also grew beyond Warrant 1. Additional warrants brought new problems. Then there were the finishing details that had nothing to do with warrant logic but still mattered. Those details showed me that building an app does not really end when the calculation works. If the tool is going to be shared, it also has to be presentable and understandable. I worked on the UI along the way but the UX mattered too. The process was not smooth. GitHub comments came back on layout issues. Some branches had to be handled carefully. Some ideas had to be postponed. Some things had to be redone. There were times when the conversation itself became slow and it made sense to start a new one just to keep working efficiently.
That is the real version of the project: build, test, notice something wrong, rethink, revise, and test again. The app is still not perfect, at least not from my view. I already know there are things to improve, including better three-leg intersection support, more explicit active approach modeling, a Warrant 1 threshold evaluation matrix, and more QA around lane category interpretation. More issues will probably show up as the app is used on real examples.
But the point is the app exists now, and that matters. It started as a practical idea based on a real professional need, and step by step it became a working web app. It took time, detailed questions, technical judgment, and a lot of small corrections. I also did not know everything at the beginning and had to learn enough to keep moving. That process never ends for me, I believe.
And I am proud of it, not because the app is in a perfect shape or it replaces the normal way of doing things. I am proud because I started something useful, stayed with it through the messy parts, and finished making a tool that can actually help me and others in our professional work.


Leave a Reply