AI doesn't replace me: how I work with it in dev and ops

A month of coding and running my homelab with an AI agent: what I delegate, what I keep, the written guardrails, and what it really changes, numbers and mistakes included.

7 min read#ai #claude-code #devops #homelab #workflow

For a month now, I have done nearly all my development and system administration with an AI agent, Claude Code. In twenty days, I built in my homelab a Proxmox cluster behind a pfSense firewall, with a WireGuard VPN, segmented network zones, a filtering DNS, monitoring with alerts, a SIEM, game servers and a Windows app released from 1.0.0 to 1.20.0. This site runs there too. Yet the agent decides nothing that matters. Here is how I work with it, what it really changes, where it breaks, and what I say to those who distrust it.

What I delegate, what I keep

The agent executes: it writes the code and the scripts, runs the commands over SSH, tests, then documents what it did. I keep everything that requires knowing what matters for the project: the architecture, the security tradeoffs, the priorities, and the go-ahead before every risky change.

Putting this site online is a good example. The agent laid out the options with their tradeoffs: opening port 443 or going through a Cloudflare tunnel, a VM or a container. I picked the tunnel and the VM, and signed off on the site's admin never going through the internet. It did the rest: the isolated network zone, the hardened VM, the deployment with automatic rollback, the monitoring and the docs. In one day.

The written contract

Each project has a CLAUDE.md file that the agent rereads at every session. It is the contract: the conventions, the access, and above all the rules. The portfolio's sets the technical choices I don't want to renegotiate with every feature. An excerpt:

## Key Patterns
- All animations must respect `prefers-reduced-motion`
- No rounded corners — everything is sharp/square
- Components use TypeScript strict — no `any` types
- Content reads go through `lib/content.ts`; copy lives in `lib/i18n/dictionaries/{fr,en}.json` (fr is the typed reference)

The homelab's reads more like an operations charter. Two rules as written there (translated from French), and a third in substance:

  • "Every intervention on the homelab must be documented in docs/ before the task counts as done."
  • "Never type a password: if an action needs a password, have the user do it."
  • No risky change without my agreement, one step at a time, with a check and a rollback.

The tool adds its own guardrails: some actions, like touching the firewall's inbound rules or deploying to production in some places, are refused to it. I then do them myself, from the list it prepares for me.

The cycle: spec, plan, ship, analyse, commit, prod

Every job follows the same path:

  1. Spec. I say what I want and why. The agent challenges the request before writing a line: for whom, which edge cases, is there something simpler? Out comes a spec with acceptance criteria.

  2. Plan. The spec becomes an execution plan: the files touched, the order of the tasks, how each one is checked.

  3. Ship. The agent implements, following the spec as a contract, until every criterion passes.

  4. Analyse. Several agents test and review the result, each on its own: unit tests, a security review, and a reviewer who hasn't seen the implementation. Its role, in .claude/actions/analyze.md:

    You are an **external reviewer** with a product perspective. You have NOT been
    involved in the Plan or Ship phases. You evaluate objectively, by the numbers.
  5. Commit. One commit per logical step, with a message that says why.

  6. Prod. Push and deploy. This site only serves a new version after a health check, and falls back to the previous one on its own if it doesn't answer.

The homelab holds 22 specs and 20 plans, written before the big jobs. That is where my energy goes: a good spec takes thought, and the agent handles the execution.

The numbers, honestly

I have no control group: these are estimates. Roughly, I go about four times faster, with code about twice as optimized.

The speed shows in the homelab's history: 652 commits, 247 journal entries and nearly 10,000 lines of documentation in twenty days, alongside my studies.

"Optimized", to me, mostly means: more problems found and fixed before going live. On this portfolio, the reviews caught an email validation regex that could freeze the server for about thirty seconds, an open redirect flagged by an automated security review right after the commit, and a 4.9 MB portrait served as is, brought down to 80 KB. On my own, I wouldn't have taken the time to look for half of these problems.

The mental load, moved elsewhere

The real gain isn't typing less. It is no longer keeping in my head every command's options, a firewall rule's syntax or the order of a CSP's headers. That room goes to designing the stack, splitting up the project, writing clear specs. And since every intervention is documented as it happens, I find everything three weeks later: why that choice, which command, which trap.

Where it breaks

The agent is fast and confident, including when it's wrong. My method exists for that.

At the end of September, it opened access to my dashboard from my home router's network, limiting the port forward to local addresses. Except my router presents internet traffic with its own local address: the dashboard was exposed to the internet. It had only tested from home. I'm the one who spotted it. The access was removed right away, and two rules were born: never filter on the router's network on the WAN side, and always test from outside. This site's go-live was checked from outside before being called done.

On the very day of that go-live, to stop a test tunnel, it killed every ssh process on my PC by name, a deployment in progress included. No harm done: a new version is only served after a health check. But the rule is now written: stop a process by its ID. A bit earlier, it had created the VM with a default CPU type that was too old: an image library refused to load, and the site served its images at full size, without a single error. A measure of the images' weight, during the checks, is what showed it.

Every mistake ends up in the journal, and most of them become a rule.

"AI leaves security holes": my answer

In cybersecurity, many people distrust AI: it makes mistakes, it leaves holes. True, it still makes some, as the previous section shows. But it is far less fallible than we are. The human factor means slips of attention, silly mistakes that cost a lot, fixes pushed back to later. AI can get things wrong, but it never neglects the work: no task is too big or too boring for it. Rereading every route, testing every edge case, running a security review after every commit: that is exactly what a tired human skips, and what it does every time. That is how we get more secure products today, with batteries of tests no team would have time to write by hand. And the time saved, I put back where humans remain essential: reviewing security.

What I noticed most: when the upstream work is done well, when the spec sets a clear scope, a model like Opus 5.5 very rarely strays or errs. My three incidents have one thing in common: a rule that wasn't written yet. Testing from outside, stopping a process by its ID, setting the CPU type: they are now in the contract, and the first one served for this site's go-live. In code as in supervision handed to agents, the problem is rarely the machine. It is the frame the human gives it, or doesn't.

Yesterday's security holes came from humans. So will tomorrow's, not from the machine.

What I take away

The agent doesn't replace me: it doesn't know what matters for my project, nor which risk I accept. It does the rest faster than me, and better documented. What I would change: write the guardrails on day one, not after the first incident.

Back to the blog