"Completed" does not mean fixed
Toronto's 311 system is marking requests as 'Completed' when nothing was fixed and the issue was sent to someone else. That is not a closed loop. That is a relabeled problem.
What I'm building, what I'm learning, and why civic tech matters.
Toronto's 311 system is marking requests as 'Completed' when nothing was fixed and the issue was sent to someone else. That is not a closed loop. That is a relabeled problem.
The City of Toronto presented its plan to modernize 311. Submit and track on your phone, AI, closing the loop. The target is 2027. SolveTO has done all of it since February. So I am not here to fight. I am here with an offer: do not build it twice.
A campus, a business district, a hospital ground. Each one is a small town with sidewalks, lights, benches, and people who notice when something breaks. They deserve the same tool a city uses to stay accountable.
You report a pothole. The city fixes it. Nobody ever tells you. That silence is why people stop reporting, and it is the part of SolveTO I am building next.
Singapore's OneService app covers their entire country with one login. Canada has nothing like it. Building one platform across Canadian cities is not a technical problem. It is a choice.
SolveSAUGA went live in Mississauga today. Same flow as SolveTO in Toronto. One platform, one login, one feed across the GTA. This is what civic infrastructure should feel like.
311 doesn't know if your bus route is cancelled. TTC doesn't know if your stop bench is broken. You're supposed to check two apps and figure it out yourself. We connected them.
The UN E-Government Development Index ranks 193 countries on how well they use digital technology to serve citizens. Canada is #47. Denmark is #1. The distance between them is not money or talent. It is a choice.
Toronto's council voting records are public — sitting on open data, buried in PDFs written for procedure, not for people. SolveTO makes them readable.
A one-character bug caused 55 silent failures in two days. Solid Queue's recurring.yml passes args as a positional hash, but Ruby 3.3 won't auto-convert that to keyword arguments. Here's the fix and what it taught me about monitoring.
Get occasional updates on what we're building and how Toronto is improving.
Or read the open letter from the founder.