Documentation That Publishes Itself, After I Say Yes
My homelab writes its own wiki pages. Every one of them still passes through a pull request I merge by hand, and publishing happens only from main.
The documentation problem in a homelab is not writing. It is that the writing is never worth doing at the moment you have the context, and by the time it is worth doing you no longer have the context.
So the pipeline works backwards from the artifact. The system notices a gap — a service with no page, a backup with no documented restore, a monitor pointing at nothing — drafts the page, and opens a pull request. Then it stops.
The chain
detect a gap -> a proposal record, in a runtime outbox, git-ignored
prepare -> a branch and a draft pull request, never merged
I review and merge -> the page lands on main
publish-on-merge -> the merged page appears in the wiki
Four steps, and I am step three. The step-two tool has no merge call in it at all — not a disabled one, not a flagged one. The capability is absent, which is a stronger guarantee than a switch set to off.
Publishing only ever reads main
The publisher refuses to run from anything but the default branch. This sounds like belt-and-braces until you consider what a wiki is for: it is the copy people read instead of reading the repo. A wiki page published from an unmerged branch is a claim about the system that no review ever approved, sitting in the place people go when they trust something.
Opting in is per-document — a page carries a flag saying it may be published after merge — and republication is deduplicated by content hash, so a merge that did not change a page produces no wiki write at all.
Three things the wiki's API taught me the hard way
Content only arrives through the import endpoint. Creating a page and updating a page both accept a body and both silently ignore it. So a republish is really delete, then reimport, which means the "update" path in my publisher is a destructive operation wearing a friendly name.
And the delete is a hard delete. No recycle bin, no soft flag. The first time I learned that, I learned it about a page I wanted.
Existence checks need a path, not a title. My first duplicate check asked "does a page with this title exist." Several of my pages are legitimately called "Backup and Restore" — one per service, nested under it. The check collided them, and the publisher concluded it could not safely update Markdown. The bug report said "page already exists"; the actual defect was that I had confused a leaf name for an identity.
That last one is a specific instance of a mistake I have now made in four different subsystems: a name is not an identity. Two hosts can both run a container called redis. Two services can both have a page called Backup and Restore. Any check that resolves a name without a scope will eventually merge two things that were never the same.
Why I did not automate the merge
Because the value of this system is that it notices, and noticing is cheap to verify while publishing is expensive to unpublish. Reviewing a generated page takes me under a minute — the diff is one new file and the citations are inline. Un-publishing something wrong from a wiki that people have already read takes considerably longer, and there is no command for the part where they have already read it.
Written by
Adrian Romo
Senior Backend Engineer building scalable Python APIs, AWS Lambda architectures, voice systems, and enterprise integrations.
Related
Keep reading
Six Posts a Day, and the Scheduler That Learned to Say When
A social pipeline that published one Reel a day and nothing else, because per-format quotas were ceilings and nothing was asking for the other formats.
Seconds of Work, Hours of Residency
My morning briefing started failing. Ollama was up and returned HTTP 500, because a 21-second image render was still holding 6.6 GB of VRAM hours later.
What Deserves Attention Today
My homelab produces one verdict each morning: something needs you, or nothing does. Getting the second half honest was much harder than the first.
Keep going
Where to next?
Browse more technical writing, see the engineering case studies, or reach out directly.