cat posts/2026-10-24-i-rebuilt-this-site-with-an-agent.md

I rebuilt this site with an agent

· 4 min read · web tools ai agents astro

If you’re reading this on the site and not in a feed reader, it looks different. As of this evening it’s a new site. Same address, same post URLs, same feed, and nothing you’d bookmarked should be broken. Everything else got replaced in one day, in one pull request, and I wrote very little of it.

Why now

The old site was Hugo with Wowchemy, the academic theme a lot of researchers use, because when I set it up years ago it was the quickest way to get a decent-looking personal page with a blog attached. The last real upgrade was in May 2023, when I moved Hugo and the theme forward and switched analytics to GA4. Since then the theme has gone quiet upstream, and every Hugo release made me less sure the next upgrade would build at all. The site was pinned to Hugo 0.111, which is old enough that I’d stopped wanting to touch it.

It also carried a lot of things I never used. The theme came with sections for publications, talks and slides, which a researcher needs and I don’t, and an /admin/ page for a browser-based CMS that had been broken for as long as I can remember. And there was a small but real bug: the www and bare-domain versions of the site disagreed about which one was canonical.

How it went

I started the agent in the old repo with a short brief: rebuild this, keep every post and every post URL, keep the feed working, and don’t apply anything I haven’t picked. Then it read the old repo and came back with a numbered plan. That’s the pattern for the whole day, and it’s how I review all agent work now. Every stage arrives as a numbered list of proposals with reasons, and I reply with the numbers I want. Nothing gets applied as a batch and reported afterwards.

The choices that came out of that:

  • Astro 7, as a static site. Posts stay Markdown files, and the file name is the URL, so /post/YYYY-MM-DD-slug/ didn’t change.
  • Catppuccin for color, Mocha in dark mode and Latte in light, following the system setting. I’ve used Catppuccin in my terminal and editor for a while, and I wanted the site to feel like the place I actually work.
  • A terminal on the home page. The top of the page is a fake terminal window, with whoami, a now.txt and a list of links, over a photo of Boston. In dark mode it’s the Back Bay at night, from above, and in light mode it’s the Back Bay skyline across the Charles on a sunny day. The photo for the other theme is lazy-loaded, so it never downloads.
  • Pagefind for search. It builds the index from the generated HTML at build time, and the browser downloads only the pieces of the index it needs, so there’s no search server and nothing to pay for.
  • Redirects for the old theme’s URLs. Tag and category pages, the demo sections, the old feed paths and the dead admin page all get a 301 to a live page. Post URLs and the competency matrix page didn’t move, so they don’t need one.

The feed stays at the same address, which was non-negotiable. I wrote about keeping my feeds when Google Reader died, and I’m not going to be the reason someone’s reader quietly stops updating.

The old posts

The oldest posts here came from my WordPress blog, written between 2006 and 2012, and they came over to Hugo years ago. They’re all still here, unedited, with a short notice at the top saying where they were first published, so nobody mistakes a 2007 opinion about Ruby for a current one. Some of them had images hosted on services that no longer exist. The agent went looking in the Wayback Machine and recovered six. Seven are gone for good, and those posts now show a placeholder saying what the image was.

The bits I wouldn’t have done myself

Two things got done that I’d have skipped if I’d been doing this by hand on a Saturday.

The domain doesn’t send or receive email, and until today nothing said so, which means anyone could send mail that claimed to be from it and many receiving servers would give it the benefit of the doubt. Now the DNS says it plainly: a null MX record, which says the domain accepts no mail; an SPF record of v=spf1 -all, which says no server is allowed to send for it; a DMARC policy of p=reject, which tells receivers to refuse anything that fails; and an empty DKIM key, so there are no valid signers. Those four records took ten minutes and close off a whole class of phishing that uses my name.

The other is the hosting config, done properly for once: security headers, including HSTS, and long-lived caching for the hashed asset files. The site builds and deploys on Netlify, which gave every revision of the pull request its own preview URL, and that’s where I did most of my actual reviewing.

For analytics I kept GA4, now loaded off the main thread, and added Cloudflare Web Analytics alongside it, which doesn’t use cookies. I’ll probably drop one of them eventually. I haven’t decided which.

What I actually did

I picked numbers. I decided what got deleted, which was most of what the theme had brought with it. I rewrote the bio, with the agent’s draft as a starting point and a lot of crossing out. I read every diff before it went in, and the whole thing merged as one pull request this evening.

What I didn’t do was write the Astro components, the redirect map, the CSS or the search integration. Ten years ago this would have been a month of weekends, and I’d have enjoyed it, and it would quite likely have stalled halfway through. This time the site I’d been meaning to fix since 2023 got fixed in a day, and most of my day was deciding.