Logbuch#homeos#backlog#tor#monitoring#docker
Backlog ohne Leichen: jeder offene Task bekommt einen Grund
Von Niclas Hennrich · veröffentlicht · geschehen am
Alternativen bewertet und einen Weg festgelegt. Gehört zum Vorhaben HomeOS — Control Center mit drei Säulen.
- Schwerste Seite im Polling-Audit (Schwelle 25)
- 9Requests/min
- Tor-Metrikserien nach dem Umbau lesbar
- 278
- Container-Neustarts statt einem
- 2
HomeOS ist mein selbst gebautes Control Center fürs Homelab — aus dem Infrastruktur-NOC gewachsen, inzwischen mit drei Säulen: Infrastruktur, Haus (Smart Home) und Family (Haushalt). Nach einem Gap-Audit am Vortag stand eine Liste offener, zurückgestellter und blockierter Aufgaben, die niemand mehr überblickte — ich auch nicht.
Was ich wollte: Nicht „alles abarbeiten". Sondern: Am Ende darf keine Zeile mehr offen sein, ohne dass klar ist, warum sie offen ist, was fehlt und was sie später wieder relevant macht. Vier Schubladen: READY (mache ich jetzt), WAITING_USER (braucht mich am Rechner — mit einer Karte: was, wo, warum, Risiko, Rückweg), DEFERRED_WITH_TRIGGER (zurückgestellt, mit benanntem Auslöser) und DROPPED (mit Grund). Alles, was in keine davon passt, ist eine Leiche.
Was dabei herauskam: Der größte Teil ließ sich schlicht bauen — Alert- und Log-Ansichten, Inline-Bearbeitung, Lauf-Historie für Automationen, PWA-Icons, solche Dinge. Interessanter waren die anderen drei Schubladen.
Eine Aufgabe galt als „Nutzeraktion" und lag deshalb still: ein Skript, das nur Root auf dem Homeserver installieren darf. Nach der Inventur war sie zu 95 % vorbereitbar — korrigiertes Skript, Diff, Backup, Validierungsplan. Der Permission-Classifier meines Coding-Agenten hat die Remote-Root-Installation blockiert, und das zu Recht: Root auf einem entfernten Host bleibt beim Menschen, da gibt es keinen Workaround. Übrig blieben zwei Befehle auf einer Karte. Die richtige Frage war nie „wer muss das tun?", sondern „wie viel davon kann ich trotzdem tun?".
Für die Zurückstellungen habe ich gemessen statt gemeint. Ein Event-Bus per SSE stand als „irgendwann" im Backlog. Ein Polling-Audit ergab: Die schwerste Seite liegt bei rund 9 Requests pro Minute, meine Schmerzgrenze bei 25. Das ist keine Meinung mehr, sondern eine Wiedervorlage mit eingebautem Trigger. cAdvisor auf dem Pi: drei Container, Load 0,02 — es gibt keine Frage, die er dort beantworten würde. Gestrichen, mit Grund.
Der Tor-Cluster: Mein Tor-Relay läuft als Container, und mehrere offene Punkte betrafen es — Metriken exportieren, IPv6-Lognoise abstellen. Die habe ich gebündelt, damit das Relay nur einmal neu startet; jeder Neustart kostet Konsens-Flags. Der Plan ging halb auf: Tor lädt die Zugriffsregel für den Metrik-Port per SIGHUP nicht neu. Zwei Reloads änderten nichts, erst ein zweiter Container-Neustart aktivierte die finale Policy. Wer Restarts minimieren will, muss die endgültige Konfiguration vor dem ersten Neustart komplett haben.
Die zweite Überraschung: Der Scrape aus dem Compose-Netz kam beim
Tor-Container nicht mit der Adresse des Hosts an, sondern mit der
Gateway-Adresse des Docker-Netzes — Masquerade. Die Zugriffsregel musste
beide kennen. Geklärt habe ich das nicht durch Nachdenken, sondern mit
netstat im Ziel-Container. Hinter NAT ist die Quell-IP eine Behauptung;
eine Access-Policy testet man gegen das, was tatsächlich ankommt, nie
gegen das, was man sich denkt.
Ergebnis: 278 Tor-Serien lesbar, Identität des Relays unverändert, Guard- und Stable-Flag nach dem Neustart erst einmal weg — das zeigt die Seite so an, wie es ist, statt es zu verstecken.
Was ich mitnehme: Ein Backlog altert besser, wenn jede Zurückstellung einen Messwert statt einer Meinung trägt. „SSE lohnt nicht" ist anfechtbar; „9 von 25" hat ein Verfallsdatum, das man ablesen kann. Und ein „User-Blocker" ist oft nur ein Rest-Blocker.