Upgrading Rails 5 to Rails 8 with AI: What Broke After the Specs Went Green

We moved our internal Timesheet app, a legacy Rails application, from Ruby 2.4.10 and Rails 5.0.1 to Ruby 3.3.6 and Rails 8.1.3, with AI assisting the work throughout. We did it as a fresh-app transplant: build a clean Rails 8 app, move the old code into it, and get it running. The backend RSpec suite went green. bin/rails zeitwerk:check eager-loaded the configured application code without complaint.
Then we brought up the real stack for the first time: a development server, a seeded database, the React frontend, a real browser. Every request behind login returned a 500. The calendar failed. Monthly totals crashed. The 18 Playwright end-to-end tests run against that same live stack, so they only went green after those failures were fixed. The green suite had not been wrong. It had been silent.
This post is about that gap. What broke in a direct Rails 5 to Rails 8 transplant, why a green suite missed it, and how we verified the application’s highest-risk workflows after the migration. The app tracks hours, billing, reports, users, roles, and permissions, so quiet wrong answers matter more than loud crashes.
Why a fresh-app transplant instead of an incremental upgrade
The …
!-->artificial-intelligence ruby rails open-source troubleshooting
Adding Conversations to a Multi-Agent Travel Planner

Photo by Bimal Gharti Magar, 2026.
In a previous post, I walked through a multi-agent travel planner built on the Microsoft Agent Framework (MAF). It worked, but it was single-shot: one prompt produced one plan, and the conversation ended there. If you wanted to swap a city, trim a day, or ask a clarifying question, the only option was to write a new prompt from scratch.
This post is the follow-up. We will turn that one-shot pipeline into a real multi-turn conversation, while keeping the same five agents under the hood. Along the way we will look at how to feed chat history through a MAF workflow, how to avoid re-running the full pipeline on every follow-up, how to persist conversations to SQLite, and how to keep a single conversation from running two turns in parallel.
The source code is on GitHub.

What we will build
- A multi-turn conversation surface where each follow-up message refines the plan in place
- A small LLM router that decides which subset of agents needs to run for each turn
- SQLite-backed persistence so conversations survive process restarts
- A per-conversation async lock that returns 409 Conflict when two turns race
- A three-pane browser UI: conversation sidebar, chat, …
dotnet csharp artificial-intelligence programming
Interchange Redis Sessions

Photo by Josh Ausborne, 2022.
Interchange1 now supports storing user sessions in Redis2, an in-memory data store, as a core feature of Interchange 5.12. Sessions are where Interchange keeps client state that makes a catalog operate as a continuous experience–the shopping cart, form values, login status, and other data that persist from one request to the next. How and where that state is stored have a direct impact on a busy catalog’s performance, and Redis gives developers a fast, purpose-built option that sits alongside the storage backends Interchange has always offered.
Session storage in Interchange
By default, Interchange writes each session to a file on disk, and it has long been able to store sessions in a relational database instead by way of Vend::SessionDB, configured with the SessionType DBI and SessionDB directives. The database approach is the natural choice once a catalog is served by more than one Interchange server, since every server needs to read and write the same pool of sessions.
Relational databases certainly can function in this capacity, but a high-traffic session table is not where they shine. Every page view reads, writes, and locks a session …
interchange redis performance ecommerce
Building a web app using Rails 8 and Vue 3 with Vite

Photo by Jonathan Perlin, 2022.
When it comes to frontend development, Rails 8 offers many great options.
There’s of course Hotwire: the new little-to-no-JavaScript frontend framework that leverages server-side rendering, WebSockets, and Stimulus to deliver rich, SPA-feeling web apps.
For serving static assets to web browsers, including JavaScript, Rails has the Asset Pipeline, which helps with fingerprinting, caching, and exposing assets.
By default, the Rails Asset Pipeline is configured to use Import Maps (with the importmap-rails gem), which allows easy delivery and loading of JavaScript as modules, without the need for bundling and/or transpiling. That means that your development environment and build pipeline do not need Node.js, Yarn, or any other package manager or bundler. Rails takes care of everything using standard HTML features supported by all major browsers.
Hotwire works beautifully with this setup.
Now, if you need bundling and transpiling, the Rails Asset Pipeline can be configured to do so too. Instead of importmap-rails, you’d be installing the jsbundling-rails gem. This way you can use bundlers like Bun, esbuild, Rollup.js and Webpack to process …
ruby rails vue javascript
Reading the Code: Introducing CodeView

There’s a shift happening in how software gets built. A few years ago, if you developed a feature, you’d typically read every line of it shipped, maybe more than once. But now, you give a prompt to Claude or Cursor or Codex, watch a wall of code stream into your editor, run the tests, and ship.
This sounds often fine. Sometimes it’s better than fine, as AI catches edge cases, writes more tests, and applies patterns we’d be too lazy to apply by hand. But something quietly gets lost; nobody reads the code in detail anymore. Not the human, who trusted the AI. Not the AI, which already moved on to the next task. The code exists. It works on the happy path. And it slowly accumulates the kind of small wrongs that compound into the kind of large incidents nobody can debug at 2am.
CodeView is a small tool that is made to surface those small wrongs. It’s a code health dashboard built specifically for AI-assisted codebases, the situation where the code is technically yours but nobody has ever read it.
What CodeView Is and What It Isn’t
CodeView is a starting point for reviewing your codebase, not a final verdict. I want to put that up front, because …
security artificial-intelligence tools
Applying Domain-Driven Design in Practice

Photo by Josh Ausborne, 2007.
This is part 4 of a series of blog posts on Domain-Driven Design:
Domain-Driven Design is an approach to software development that focuses on, as Eric Evans puts it, “tackling the complexity in the heart of software”. And what is in the heart of software? The business domain in which it operates. Or more specifically: a model of it, made of code. That is, the code that implements the business logic that comes into play when solving problems within the realm of a particular business activity.
DDD is not just about writing code though. It’s a whole methodology that touches on business needs, requirements gathering, organizational dynamics, high level architectural design, and lower level patterns for implementing software intensive systems.
As a result, DDD offers a treasure trove of concepts, patterns and tools that can be applied to any software project, regardless of the size and complexity.
In this series of blog …
software architecture design books
Solving High-Resolution Video Stutter with GStreamer Hardware Acceleration

Photo from the VisionPort website.
In April, a client at Auburn University reached out to VisionPort Support to ask us to look into an issue with video playback for an upcoming presentation. They were running into performance issues attempting to play a video matching the full resolution of the seven-screen video wall, across all screens.
We have other clients playing video across all screens normally, on the same hardware and software, with no issue, so this was a strange report to the team. The seemingly simple request ended up leading us down a rabbit hole into how video playback works on the VisionPort platform and ultimately led to some serious modernization of our video rendering stack, the process of which we would like to share with you today.
Why was a system designed to play high-resolution video seamlessly across seven screens performing so poorly?
The System: A GStreamer Pipeline
The VisionPort video player is a custom application built on top of the GStreamer framework, initially developed to synchronize video across separate computers on our legacy Liquid Galaxy hardware configurations.
Each instance of the player renders a single video. This can be the full …
video visionport hardware ubuntu
Building a Multi-Agent Travel Planner with Microsoft Agent Framework and .NET

Photo by Seth Jensen, 2022.
Large language models can answer travel questions well enough, but a single prompt is rarely enough to produce a plan you can trust end to end. Budget math can drift, travel times can be unrealistic, and a confident recommendation may not be grounded in the data the model actually saw.
One way to improve that is to split the work across specialized agents. In this project, one agent researches the destination, another builds the itinerary, another checks the budget, another audits the result, and the last one turns everything into a polished response.
In this post, we will build that workflow in .NET 10 using the Microsoft Agent Framework (MAF). The project supports both local Ollama models and Anthropic through a shared IChatClient abstraction, exposes a Web API with a streaming endpoint, and includes evaluation tests using Microsoft.Extensions.AI.Evaluation.
The source code is available on GitHub.
What we’ll build
- A sequential multi-agent pipeline: Researcher -> Planner -> Accountant -> Auditor -> Aggregator
- Provider-swappable LLM integration with Ollama and Anthropic
- Deterministic validation tools for budget, timing, groundedness, …
dotnet csharp artificial-intelligence programming