Personal Stack

3 minstack, toolingUpdated

Contents
  1. AI coding
  2. Guardrails in practice
  3. Homelab
  4. VPS / infra

Every tool in this stack had to earn its keep. I run a small homelab, a production VPS, and an increasingly agent-driven coding workflow — and I’d rather spend an evening removing a moving part than adding one that “might be useful later.” This page is the current state of that stack, in three groups: AI coding, homelab, and VPS/infra.

AI coding

The core idea is agents with strong guardrails, not agents left to wander. Every repository carries an AGENTS.md that encodes conventions, validation commands and scope limits, so an agent starting cold in any project already knows how that project wants to be touched. It is a plain, tool-neutral file: Claude Code, OpenCode and every unattended worker read the same one.

The guardrail isn’t there to slow the agent down — it’s there so a fast agent doesn’t have to be a careless one.

The work itself runs on a Mac mini that stays on. The laptop is a client; agents outlive it. Four ways start agent work, a warden loop drives unattended items from signal to merged and verified, and the rest of the wiring is a separate piece: Agent Infrastructure.

Guardrails in practice

  • Global rules for code style, commit conventions and dependency hygiene apply everywhere
  • Per-project rules narrow scope with paths: frontmatter
  • Validation always runs through the repo’s own make check, never ad hoc commands
  • Hooks, not reminders, enforce the hard stops: protected branches, Docker through Makefile targets only
  • Research is required before touching an unfamiliar external API — no coding from memory1

Homelab

The homelab exists to make self-hosting boring — reproducible, monitored, and recoverable without me remembering what I did six months ago. A Proxmox cluster hosts the VMs, TrueNAS handles storage, and everything that runs a service does so through Docker Compose with the same shape of Makefile across repos:

// scripts/deploy.ts — the shape every repo's deploy target follows
async function deploy(service: string): Promise<void> {
await healthCheck(service);
await rollOne(service);
await waitForReady(service);
}

That consistency is the actual payoff: I can drop into any repo and already know how to bring it up, tear it down, or check its logs.

VPS / infra

Production runs on a Hetzner VPS behind Traefik, with Rollhook handling zero-downtime rolling deploys triggered by webhook. Observability runs through ClickStack (ClickHouse and HyperDX) for logs, traces and alerts — one store for all three, and the alerts feed the agent loop directly.

Layer Tool Why
Deploys Rollhook Rolling restarts, no dropped requests
Routing Traefik Automatic TLS, simple config
Telemetry ClickStack / HyperDX Logs, traces and alerts in one place

The common thread across all three groups is the same: fewer moving parts, each one well understood, each one replaceable without replacing everything around it.

Footnotes

  1. This is the research-first rule in practice — treat any library API touched after the model’s training cutoff as unverified until checked against current docs. ↩