Moving CI from three hand-built self-hosted runners to ephemeral Actions Runner Controller pods on a small k3s cluster. The architecture is a Helm chart and an afternoon. The traps are a 50-byte MTU difference that resets every container a job starts, a chart that hardcodes the one flag you need, a runner image with no libatomic, and rootless BuildKit refusing to mount /proc.
Blog
Technical articles on engineering, research, and leadership.
Moving one small Next.js site from a CI job that SSHed into a box to a single-node k3s cluster reconciled by Flux. The interesting part is not the architecture; it is the traps: a StorageClass that disappears with a flag, a DHCP-supplied search domain that resolves Let's Encrypt to localhost, a Helm value that flattens to nothing, and an image-automation marker that fails silently when you add a word of prose to it.
Every cover on this blog is a cyberpunk neon infographic made with OpenAI's gpt-image-1. This is what happened when I tried to reproduce that exact style locally on a MacBook Pro M5 Max, with no API: which open models match the aesthetic, why none of them can render small legible text, and the composite workflow that closes the gap.
Fine-Tuning an Open-Weight Large Language Model for Kubernetes Troubleshooting on Apple Silicon
A reproducible, end-to-end pipeline that turns Qwen2.5-Coder-14B into a focused Kubernetes troubleshooting assistant, trained with MLX on a single MacBook Pro M5 Max and deployed through llama.cpp. The twist: every training example is authored by Claude Opus, making this a worked example of distilling a strong closed model into a specialized open-weight one.
Part two of fine-tuning Qwen2.5-Coder-14B into a Kubernetes troubleshooting assistant. The first run proved the pipeline on 47 examples and overfit instantly; the obvious fix was more data. This is what happened when I scaled the synthetic dataset from 65 to 2,053 examples, generated it with Claude Code subagents instead of a paid API, and watched the validation loss actually fall.
What I learned getting A/B OTA updates working on real hardware with RAUC and systemd-boot. Covers EFI boot entry failures, custom bootloader handlers, per-slot kernels, atomic ESP writes, and automatic rollback.