Lessons
What each build taught
The last layer of the map. Each lesson is tied to the project that taught it, so none of them float free as advice.
Validate results
A convincing optimisation result still needs evidence. Explainable scoring and validation exist so a plausible answer is never mistaken for a correct one.
From UMA Companion — The optimiser is where a plausible result is most tempting to trust, so it had to be explainable and checked. Read: A Year Building UMA Companion: Why I Sunset the Project
Data boundaries
An early database update could overwrite user data. Separating catalogue tables from user tables made the boundary safe, and uncertain OCR input needs the same explicit treatment.
From UMA Companion — A database update that wiped saves is what forced the catalogue/user split. Read: A Year Building UMA Companion: Why I Sunset the Project
Architecture by use
Architecture becomes clear through use, so a rewrite that captures earlier lessons can be worth it.
From UMA Companion — Three generations (Python prototype, PySide6, Rust and TypeScript) each came from what the previous one taught. Read: A Year Building UMA Companion: Why I Sunset the Project
Knowing when to stop
When maintenance cost outweighs remaining value, ending a project can be the sound product decision. Finished work stays documented.
From UMA Companion — Official in-game guidance reduced the remaining value while the maintenance load stayed the same. Read: A Year Building UMA Companion: Why I Sunset the Project
Baseline first
Before redesigning something you only have the output of, snapshot it, hash it and rebuild it until it matches. Then change things.
From This website — Twenty published files were rebuilt byte for byte before any design change. Read: Recovering a site when only the HTML remains
Reversible steps
Stage the move, verify before changing paths, and keep the old system powered off but intact until the new one has proved itself.
From Media, with fewer boundaries — The TrueNAS VM stayed intact and powered off as a rollback during validation. Read: Why I Moved Plex and Jellyfin from TrueNAS to Debian
Storage ownership
A dedicated NAS is not wrong. Here, letting the VM that uses the storage also own it removed a whole class of permission problems.
From Media, with fewer boundaries — NFS permissions and cache writes crossed too many boundaries; owning storage locally made them visible in one place. Read: Why I Moved Plex and Jellyfin from TrueNAS to Debian
Placement matters
Where a service runs can matter as much as how it runs. Independent hardware shrinks what a maintenance window can affect; it is not redundancy and not a backup.
From A separate home for DNS — Rebooting the main host used to take DNS down; separate hardware removed that coupling. Read: Monitoring the Homelab with Beszel
Map is not a recovery plan
Useful documentation distinguishes an operating map (what runs where) from a recovery plan (how to get it back). This site is the first; the second is a separate job.
From The homelab, made understandable — The homelab write-up draws this line explicitly.