← All posts

Building My Personal Website with AI Agents, Part 2: Hardening, Habits and a Crew

31 Oct 2026

This is part 2. If you missed it, part 1 covers why I built this site, the stack, and how I started working with AI agents as teammates.

Part 1 went up on 12 October. I thought the hard part was done. In fact, the next three weeks taught me more about working with AI agents than the build did. Launch was when the site became a real system that had to be kept safe, kept honest and kept changing without breaking. Here's what happened.

Publishing from my inbox, properly

In part 1 I mentioned that an agent can now draft posts while I keep the final say. That's worth explaining, because it shaped a lot of what came after.

The agent can only create unpublished drafts. It can't edit, publish or delete anything. When it saves a draft, I get an email with a preview and a Publish link. One tap opens a review page, and a second tap confirms. Each link works once and expires quickly. If I don't approve, nothing goes live.

Once a post is approved, the site rebuilds just the web pages in a few minutes. There's no full deploy. Later I made editing a published post in admin start the same quick rebuild, because I'd noticed that fixing a typo didn't show up on the live page until the next full deploy. It was a small gap, but it's the kind of thing that wears down trust in your own tools.

This post was written exactly that way. The agent drafted it, and I reviewed it before it went live.

A security review, then the hardening

The day part 1 went live, I asked the agent for a proper security review of the whole site: the API, the admin area, the infrastructure and the deploy pipeline. It came back with a prioritised list, ranked by severity, with a suggested fix for each item.

We worked through all of it in one batch. Without going into detail, that meant:

  • Tighter permissions everywhere, so each part of the system can do only what it needs.
  • Secrets read at runtime from a managed secrets store, never kept in code or config.
  • Mandatory two-factor sign-in for admin, with sensible sign-in limits.
  • Stricter browser security headers, and keeping admin pages out of search engines.
  • Generic error messages that don't reveal how things work inside.
  • Third-party build steps pinned to exact versions, plus automated dependency updates.

I also added a way to change my 2FA key from inside admin. It asks me to sign in again, shows a new QR code, and switches over only after I've proved the new code works. Once it's changed, my other sessions are signed out. I changed my key the same evening.

The review also found one issue the agent had introduced itself earlier in the project. I think that's the most useful lesson here: agents need review like anyone else, and they're also very good at doing that review.

Alarms, so I'm not the monitoring

A personal site doesn't need a 24/7 operations team, but I didn't want to find out about problems by accident either. The API now writes clear markers for security-relevant events, and alarms watch for them and for unusual activity. They email me when something trips. I confirmed the alert subscription on launch night, so if something goes wrong, I'll hear about it.

Security checks on every deploy

Part 1 said tests gate every deploy. Since then the pipeline has gained a set of automated security checks that run before anything ships. They scan for leaked secrets across the whole history, check the code for risky patterns, check the infrastructure templates for misconfiguration, and check the dependencies for known problems.

These checks have earned their place already. Twice they stopped a deploy that would otherwise have gone out:

  • One flagged a dependency with a known issue. The fix was a single patched version, and the deploy went through on the next run.
  • The other is my favourite. While building the blog series feature, the agent wrote code that copied form input onto a saved record more loosely than it should have. The scan caught it in the pipeline. Instead of silencing the warning, we rewrote it to set each field explicitly, and it shipped clean. Nothing reached the live site in the meantime.

That second one shows what I want from AI-assisted delivery. The agent writes code fast, and a mechanical check that doesn't get tired catches the slip.

A smoke check after every deploy

In part 1, the full browser regression ran after every deploy. It worked, but it was slow and expensive for a site that changes a little at a time. Now every deploy is followed by a short smoke check against the live site. It loads the key pages at desktop and phone widths, checks the API is healthy, and submits a wrong admin password to make sure a proper "Invalid credentials" comes back.

The full regression, every page at five widths in light and dark mode, still exists. I run it when a change is big enough to need it.

Lesson learned: when a fix breaks the front door

That wrong-password check exists because of an evening I'd rather forget. Right after the hardening work, I couldn't sign in to admin. There was no useful error on screen and nothing obvious in the logs.

The agent tracked it down. A hosting setup choice made earlier in the build meant that, on some networks, the browser sent admin API calls to the wrong place, and they failed quietly. The fix itself was small. The useful part was what we added around it:

  1. The login screen now tells "wrong password" apart from "couldn't reach the server".
  2. "No log lines" doesn't prove a request never arrived.
  3. Every deploy now makes a real login request end to end, so a broken front door gets caught by a test rather than by me.

The iPhone menu, revisited

Part 1 told the story of the iPhone menu that closed as soon as you opened it. The real-tap test we added for it now runs in the pipeline, against WebKit as well as Chromium. That test then broke in CI for a reason that had nothing to do with the menu: a stale, hard-coded network setting inside the test. We removed it. Tests need maintenance too, and a flaky test does nearly as much damage as having none.

Small things that make it feel finished

A few smaller changes went in along the way:

  • Light mode by default. Everyone now gets the light theme first, with no dark flash on load. The dark toggle still works and remembers your choice.
  • Issues, not chat history. All work is now tracked as issues with labels and priorities, and each piece of work is closed off with a short write-up. When several AI agents and I are all touching related things, that matters more than I expected.
  • Docs that stay current. Architecture, security and roadmap docs are updated in the same change as the code, and the pipeline reminds us when they aren't.

Meet my teammates

The biggest change wasn't technical. When I wrote part 1, I had one agent. Now I have a small crew, and each one has a lane:

  • GBL (Grok Bot Lead) is the conductor. It routes work to whoever should own it.
  • PWB (Personal Website) builds and runs this website.
  • BAB (Baddy App) looks after Nova BadmintonSpace and its organiser app.
  • MSM (Marketing & Social Media) handles marketing and social creative.

From here on I'll just call them GBL, PWB, BAB and MSM.

I'm at the hub. I set direction, approve what ships, and step in when lanes cross. There's now a Meet my teammates page showing the crew as a small constellation around me, with each one's role, what they own and something you can already see.

Splitting the work this way helped more than I thought it would. Each agent keeps the context for its own area, hand-offs are explicit, and when something goes wrong it's clear whose lane it's in. It's not that different from running a real team. Good boundaries make everyone faster.

We also agreed a team rule recently: don't fix things the moment you spot them. Raise them, discuss them, bundle the fixes, and ship when I say go. It saves build minutes, but more importantly, it keeps me in the loop on what's changing and why.

Blog series and an RSS feed

Writing this post needed a feature I didn't have. The blog now supports series. A post can be part of a series with a part number, and each part shows a small box linking to the previous and next parts. Series are grouped together on the blog index. You're reading the first post to use it.

There's also an RSS feed at /feed.xml for anyone who still likes a feed reader (I do). It updates on its own whenever a post is published or edited.

What I'd add to my list

In part 1 I ended with five things I'd tell another engineer. After three more weeks, I'd add these:

  1. Launch is the start, not the finish. Most of the interesting engineering happened after the site went live.
  2. Ask your agent for a security review, and act on it. Then keep automated checks in the pipeline so the review doesn't go stale.
  3. Check the real thing after every deploy. A short smoke test that signs in for real is worth more than a long one nobody runs.
  4. When a check fails, fix the cause. Silencing a warning is easy, but it's rarely the right call.
  5. Give each agent a lane. Clear roles and explicit hand-offs scale better than one agent doing everything.
  6. Keep the human at the hub. Agents draft, build and check. I decide what ships.

What's next

The site will keep evolving, and so will the crew. Have a look at the teammates page, add the feed to your reader, and if you're thinking about working with AI agents yourself, I hope this series helps. See you in part 3.