feat(tools): mirror-docs — Liste geteilter Dokumente per Timer nach git spiegeln (D88-Nachtrag 3)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c87cf6212d
commit
2e408d956c
@@ -7638,6 +7638,63 @@ Haupttext gelten fort; neu geprüft außerdem: flaglos außerhalb jedes
|
||||
Worktrees schreibt anstandslos, `--git-commit` dort lehnt mit klarer
|
||||
Meldung ab.
|
||||
|
||||
**Nachtrag 3 — `mirror-docs`: ein Timer auf dem Backend-Host spiegelt eine
|
||||
Liste von Dokumenten in einen eigenen Branch (2026-09-04).** Anlass war der
|
||||
zweite Datenverlust an demselben geteilten Dokument: Am 3.9. um 19:03 schrieb
|
||||
ein Fenster mit veralteter Schattenkopie den Stand vom Vorabend als Volltext
|
||||
zurück — die Server-Historie hatte den ganzen Tag (Version 659 war der letzte
|
||||
gute Stand, byte-genau wiederhergestellt), der Git-Spiegel aber nicht: Er lief
|
||||
von Hand, und der letzte Lauf lag vor der verlorenen Arbeit. Ein Spiegel, der
|
||||
nur läuft, wenn jemand daran denkt, ist an dem Tag nicht da, an dem man ihn
|
||||
braucht.
|
||||
|
||||
**Der Spiegel läuft auf dem Backend-Host, nicht auf dem Laptop.** Der Server
|
||||
ist rund um die Uhr an, `Linger=yes` ist gesetzt (D77), und er holt das
|
||||
Dokument von `127.0.0.1:9080` ohne den Proxy. Ein Timer auf dem Laptop hätte
|
||||
nur die Stunden abgedeckt, in denen der zu ist — mit `Persistent=true` zwar
|
||||
nachgeholt, aber nach der Lücke, nicht davor. Gebaut als systemd-User-Timer
|
||||
(`werkbaum-mirror.timer`, alle 15 Minuten, `Persistent=true`) neben der
|
||||
Backend-Unit; der Service ruft `mirror-docs --push`.
|
||||
|
||||
**`tools/mirror-docs` ist die Schleife um `pull-doc`, nicht sein Ersatz.** Es
|
||||
liest eine Liste (`documents.list`: je Zeile UUID oder URL und Pfad im Repo),
|
||||
ruft je Zeile `pull-doc --git-commit` und pusht einmal am Ende — nur, wenn ein
|
||||
Commit entstanden ist. Jede Zeile läuft für sich: Ein gescheiterter Abruf
|
||||
bricht die übrigen nicht ab, steht aber auf stderr, und der Lauf endet mit 1,
|
||||
damit das Journal des Timers den Fehler zeigt, statt still zu bleiben.
|
||||
Nachgemessen lokal: eine Fehlerzeile in der Liste kostet genau ihr Dokument,
|
||||
die beiden anderen werden committet; der zweite Lauf ohne Änderung committet
|
||||
nichts und endet mit 0.
|
||||
|
||||
**Eine Liste statt „alle Dokumente des Servers“.** Die Dokumentenliste
|
||||
verlangt das Master-Passwort (D76-Nachtrag 6), und auf dem Server liegt davon
|
||||
nur der Hash. Für den Cron müsste das Klartext-Passwort dorthin, nur damit er
|
||||
eine Liste bekommt, die er um Dateinamen ohnehin ergänzen müsste. Eine Zeile
|
||||
je Dokument ist der ehrlichere Preis: kein Geheimnis mehr auf dem Host, und
|
||||
Probe-Dokumente bleiben von selbst draußen.
|
||||
|
||||
**Ein Branch, viele Dateien.** Der Spiegel committet blind, also auf einen
|
||||
eigenen Branch `werkbaum-mirror`, den man bei Bedarf nach `main` mergt — nicht
|
||||
auf `main` mit den Hand-Commits dazwischen, sonst kollidiert der Server-Push
|
||||
mit dem lokalen Stand und der Timer bleibt hängen. Beim ersten Lauf von Hand
|
||||
war der Stand auf dem gerade ausgecheckten Feature-Branch gelandet; genau
|
||||
das soll ein Timer nicht tun. Ein Branch je Werkbaum wäre eine dritte Spalte
|
||||
in der Liste, wenn ihn je jemand braucht.
|
||||
|
||||
**Ein eigener Deploy-Key, ein Sparse-Checkout.** Auf dem Server liegt ein
|
||||
Schlüssel des Backend-Logins; der bekommt nicht nebenbei Schreibrecht auf ein
|
||||
privates Notizen-Repo. Der Spiegel hat seinen eigenen ed25519-Schlüssel
|
||||
(`~/.ssh/werkbaum-mirror`, Host-Alias `notes-mirror` mit `IdentitiesOnly`),
|
||||
als Deploy-Key mit Schreibrecht nur für dieses eine Repo. Geklont wird mit
|
||||
`--filter=blob:none` und Sparse-Checkout auf das Zielverzeichnis — auf dem
|
||||
geteilten Host liegen so nur die gespiegelten Dateien, nicht das ganze Repo
|
||||
(5,7 MB getrackt, 666 MB Arbeitsverzeichnis lokal).
|
||||
|
||||
**Das Notes-Repo ist dabei nach Gitea gezogen** (`mi/notes` auf
|
||||
`git.javagil.de`, alle vier Branches; `origin` ist Gitea, GitHub bleibt als
|
||||
`github` — dieselbe Aufteilung wie D95). Der Deploy-Key gilt je Repo, also
|
||||
zuerst der Umzug, dann der Schlüssel, statt beides zweimal.
|
||||
|
||||
## D89 — Zwei Stunden verlorene Arbeit: vier Netze gegen den stillen Live-Verlust
|
||||
Der Vorfall (2026-08-27 vormittags, gemeldet vom Nutzer): Zwei Stunden Arbeit
|
||||
an einem geteilten Dokument (`?live=`, PWA) waren weg — die Server-Historie
|
||||
|
||||
Reference in New Issue
Block a user