15% of concordia.ca in a day

Bringing the Stingers site into Concordia's web platform in a day, built on years of experiments.

A miniature running track on a lamp-lit wooden desk, with an additional lane unrolling alongside the completed oval.

In late October, the website of the Concordia Stingers, our university’s varsity teams, had to come off its server on short notice. It was the middle of the fall season. Fans use it to check schedules and scores, buy tickets, enter the 50/50 draw at home games (a raffle where the winner takes half the pot), register their kids for camps, and donate. The Athletics team posted to it almost every day.

The Stingers site ran on its own system, separate from Concordia’s web platform, which powers concordia.ca. We hadn’t expected to bring it onto that platform right away, and I’d never worked on the site. In my experience, moving this much content takes months. When I was asked for an estimate, I offered to move all of it there in a day.

I started on a Monday at noon. By lunchtime on Tuesday it was live on concordia.ca, inside Adobe Experience Manager (AEM), the university’s content management system (CMS). It was the most exciting day of work I’ve had in a long time.

The Stingers site alone is about 14,600 pages in English and French, with news going back to 2005, rosters and results for every team, and the Hall of Fame, plus more than 6,500 photos and documents. For scale, concordia.ca had about 98,000 pages before the move, so the Stingers pages added about 15% in a day.

I split the work into pieces and gave each one to its own agent in Claude Code or Codex, sometimes several at once, with one model reviewing another’s. I had them write the tools this migration needed: builders that turned the old data into pages, checkers for every page and link, and scripts that published to AEM. I set up each run with a specific task and the context it needed (our team’s notes on how AEM works and the decisions made so far on the project), then let it work, sometimes for hours, while I moved on to the next piece.

AI made mistakes I had to catch, some its own, some my decisions carried out faster than I could review them. When something was off, I fixed the cause, in the instructions or the tools, so the next run got it right everywhere instead of page by page. Once the build passed on our test servers, IT installed it on the production servers.

A few things were still missing at launch, and I closed those gaps the same afternoon. By the evening the public site was complete, including its legal and language obligations, ticket sales, and the content fans and donors rely on. Concordia holds every page on its site to a high accessibility standard, so the Stingers pages went through the same checks and came out more accessible than they were before the move. Getting that far that fast came from earlier projects layered on top of each other, none of them about this site. Together, they’re why I was confident it could be done in a day.

The layers underneath

Knowing the platform. I’ve worked hands-on in AEM for more than a decade, through several major upgrades. The one under way now has me working through AI every day, updating the system and testing it from every angle. That experience carried over. I could tell AI up front what our system would and wouldn’t accept, and quickly catch anything it built that wouldn’t work in AEM.

The old site was another matter. It was written in a different programming language, with its own database and admin tool. I started from a backup of the server and an export of its database. Together with the Wayback Machine (the web’s archive), those were enough to rebuild the site.

Rebuilding old sites. In the spring, I wrote about two side quests, bringing an old project back to life with AI. The first was Concordia’s first website, rebuilt from the Wayback Machine for April Fool’s. The second was Lounge37, a street art and photography site I ran with friends in the early 2000s: more than 7,000 images in 270 categories, a news archive, interviews, and a store. Technically, it was this exact project six months early: a PHP site too old to run, rebuilt from its original code, a 2007 database export, and archived copies of the pages. The only thing at stake then was a few friends’ nostalgia.

The Stingers site came with exactly the same three things. What mattered was the structure and the content it held: the database had every story, roster and result, the backup had the hand-written pages, and the archive showed what each page looked like. My old experiment had been the rehearsal without my knowing it. I’d already been through the process once. I knew it wouldn’t work on the first try, and I was comfortable with the rounds it would take to get there.

A shared memory. Since February, my team has kept what we call the Greenhouse: plain-text files holding our decisions and what we’ve learned about the system, for both people and AI to read. It grew out of the memory I’ve been building for AI. Each new session could start with that context. The Stingers project kept the same discipline from its first hour: decisions written down as they were made, each release build checked before the next, and a handoff file any new session could pick up from. That’s what made it safe to leave a run alone for hours, and it’s where each lesson went, into the notes and the tools, so the next run started from a better place than the last.

In September I wrote about the decisions our own system runs on: things that look like mistakes in the code but preserve behaviour people rely on. Ours are written down in the Greenhouse now. On the Stingers site, those decisions lived with the people who used it and in the configuration of a server I didn’t have running, so I’m recording them the same way: in the project’s notes, next to how the site is built and how to update it, and in 38 GitHub issues for everything I’ll come back to. The next person, or the next run, won’t have to rediscover them.

Checking every page, not a sample. In the two months before, I built the sitemap of concordia.ca’s public pages, then a tool that reads it every morning. It finds what changed since yesterday and checks those pages the way our team and the platforms we use would: links, accessibility, spelling, our style and brand rules, our bilingual glossary, and an AI review of each page next to its other-language version. It can also sweep the whole site.

To build it, I worked through how each of those checks is done today, by people and by our existing tools, and turned it into one run that AI agents carry out on our public pages, with the results going into the apps our team already works in. I’d been tuning it for weeks to what matters on our site: which checks to trust, and how to label, prioritize and address what they find. So I knew what it catches and what it misses.

What I ran on the Stingers site before publishing, comparing each page type with the old site on desktop and phone, grew out of that work rather than being built for the occasion.

That’s how experiments stack up: each one left a tool, a habit or a record behind, and the Stingers move drew on all of them at once.

Rethinking how we work with the CMS

Nothing in the move went through the CMS’s user interface, the dialogs and forms authors normally edit content through. AI wrote the pages straight into AEM, sending the same requests the editor’s Save button sends, and I reviewed samples while my audit tool went over every page. The imports ran at about 20 pages a second. Publishing the whole site took under two hours, and a full check of every page and link under an hour. In my experience, moving even a few hundred pages into AEM through its interface by hand can take weeks. I’d been experimenting with this kind of editing for a while, a page or a table at a time, and never anywhere near this scale. The Stingers site was the first test at full size, and it held up. It convinced me: for work like this, the user interface is no longer the quick and easy route.

The next layer

Moving the site into AEM was the point, not just the fastest fix: a one-off system on its own server became part of the platform the university already runs, secures and connects to its other channels. For Athletics, who lost a site they knew inside out, I’ve made a point of showing what that opens up, not only fixing what broke: editing their own pages like any Concordia site, everything that comes with the platform (templates, accessibility-tested components, tags, the university’s search engine, monitoring and backups), and content entered once that can show up anywhere we choose, from concordia.ca to newsletters and the Concordia app.

The plan had two phases from the first day: bring the site back as it was, then give Athletics a way to edit it in AEM themselves. Knowing the second was coming, I planned it right away: new components for schedules, rosters and player profiles, and the move of the content into them. The same tools, checks and release builds that moved the site will build, test and migrate it. The next phase doesn’t start from zero: it starts with tools and checks that already worked across the whole site, so I expect most new pieces to take a few runs rather than becoming projects of their own. What matters after that is making sure Athletics is comfortable using them. When the Athletics team is posting their own updates again, the project is done.

None of the experiments behind the move were about the Stingers, but each one left something the next one started from. Those layers are why I could offer to do it in a day. In a talk in June, I said that the durable skill isn’t any one tool, it’s the experimenting itself. I’d seen it pay off before, but never at this scale.

So I’ll keep taking on side quests without knowing what they’re for, and I’ll keep pushing each project a little past where it needs to go. That extra work can pay off months later, on a project I couldn’t have anticipated. Every project I finish is also where the next one starts.