docs+frontend: Gemeinsam arbeiten in Roadmap und Werkbaum-Plan

- docs/ROADMAP.md: neuer Abschnitt „Gemeinsam an einem Diagramm arbeiten" in
  drei Stufen — Lesen teilen (?sourceUrl=, vorhanden), asynchron über Git
  (heute schon möglich, weil der Plan Text ist: git diff/blame sind lesbar;
  Ausbau = Backend committet jede Änderung), live tippen (Transport ist der
  kleinere Teil, das Zusammenführen gleichzeitiger Änderungen der eigentliche;
  Text-CRDT passt wegen D14 ohne eigene Merge-Logik). Notiert auch, warum Git
  direkt aus dem Browser kein Live-Sync ist (Sync auf Zuruf, CORS-Proxy nötig,
  Konfliktmarker mitten in der Notation) und was vor einer Entscheidung offen
  ist (erste Laufzeit-Abhängigkeit, Commit-Granularität, Rechte).
- docs/examples/example-werkbaum.werkbaum: passender Zweig „Working together
  on one plan" (94 Knoten, parst ohne Warnung).

Dabei aufgefallen: Das mitgelieferte Dokument wurde nur EINMAL angelegt — die
Ergänzung hätte niemanden erreicht, der die Seite schon geöffnet hatte.
`werkbaum-seeded` hält deshalb statt '1' den Fingerabdruck (FNV-1a) der
ausgelieferten Fassung; bei neuer Fassung wird der Text nachgezogen, aber nur
wenn der Nutzer ihn nicht bearbeitet hat. Gelöscht bleibt gelöscht.
`resetToDefaults()` setzt den Merker mit.

Verifiziert im Browser, vier Fälle: alte unveränderte Fassung wird nachgezogen
(98 Zeilen, neuer Zweig da); selbst geänderter Text bleibt unangetastet;
gelöschtes Dokument kehrt nicht zurück; frischer Zustand zeigt die neue
Fassung (89 sichtbare Knoten, keine Warnung). Vitest 37/37.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-07-27 14:19:49 +02:00
co-authored by Claude Opus 4.8
parent e160015fc7
commit 68abdc6625
5 changed files with 105 additions and 19 deletions
+16 -6
View File
@@ -649,9 +649,19 @@ Nutzerdaten. (Die erste Fassung hieß durch einen Tippfehler „Werkbank";
ausgelieferte ist, damit eine eigene Umbenennung stehen bleibt.) Der Reset (D22) setzt jetzt **beide** mitgelieferten Dokumente auf
ihren Auslieferungsstand zurück; eigene Dokumente bleiben weiterhin unangetastet.
**Offen:** Der Text wird nach dem Anlegen nicht mehr aktualisiert. Erscheint
später eine neuere Fassung des Plans, sieht sie nur, wer das Dokument löscht und
zurücksetzt oder den `?sourceUrl=`-Link öffnet. Ein Ausbau könnte in
`werkbaum-seeded` statt '1' eine Versionsnummer ablegen und ein **unverändertes**
Dokument nachziehen (bearbeitete nie) — dieselbe Adoptions-Regel wie beim
Beispiel in D22.
**Nachziehen bei neuer Fassung (nachgereicht).** Zuerst wurde der Text nur
einmalig angelegt — eine spätere Ergänzung des Plans erreichte niemanden mehr.
Das fiel sofort auf, als der Plan um den Abschnitt „gemeinsam arbeiten"
(ROADMAP) wuchs. `werkbaum-seeded` hält deshalb nicht mehr '1', sondern den
**Fingerabdruck** (FNV-1a) der zuletzt ausgelieferten Fassung. Beim Laden gilt:
- kein Merker → Dokument einmalig anlegen (auch für Bestandsnutzer);
- Merker ≠ aktueller Fingerabdruck **und** der Text des Nutzers hat noch genau
den gemerkten Fingerabdruck → Text nachziehen;
- Text **verändert** → nie anfassen (dieselbe Adoptions-Regel wie beim Beispiel
in D22: nur Unverändertes wird adoptiert);
- Dokument gelöscht → bleibt gelöscht.
Der Altwert `'1'` aus der ersten Fassung sagt nichts über den Textstand; dort
wird bewusst nichts überschrieben, nur der Merker ersetzt. Wer aus dieser kurzen
Zwischenfassung kommt, holt den aktuellen Stand über den Reset.
+40
View File
@@ -44,6 +44,46 @@ in laufender Entwicklung, Integrationsfähigkeit erklärtes Ziel — noch zu
jung als Plattform-Ziel. Companion-App so schneiden, dass ein späterer
Umzug Taiga → Tenzu nur den API-Adapter betrifft.
## Gemeinsam an einem Diagramm arbeiten
Ziel: mehrere Personen ändern denselben Plan. Drei Stufen, aufeinander
aufbauend — die dritte lohnt nur, wenn wirklich gleichzeitig gearbeitet wird.
**1. Lesen teilen — vorhanden.** `?sourceUrl=` (D23) zeigt eine entfernte
Textdatei an; die Quelle wird anderswo gepflegt. Einbahnstraße, aber ohne
jeden Server.
**2. Asynchron ändern über Git — heute schon möglich, ohne eine Zeile Code.**
Die `.werkbaum`-Datei (D24) liegt im Repository, wird per Pull Request geändert
und per `?sourceUrl=` angezeigt. Weil der Plan **Text** ist (D14), sind
`git diff` und `git blame` tatsächlich lesbar („wer hat *Payment provider* auf
`[!]` gesetzt?"). Für einen Plan, der sich pro Woche und nicht pro Sekunde
ändert, ist das oft die passendere Antwort — mit Review und Historie obendrauf.
Ausbau: Das Backend (D13) legt jede Änderung als Commit ab und bekommt
Historie, Wiederherstellung und Verzweigungen für Szenarien geschenkt.
*Git direkt aus dem Browser* ist technisch möglich (`isomorphic-git` spricht das
HTTP-Smart-Protokoll), taugt aber nicht als Live-Sync: Es synchronisiert auf
Zuruf statt fortlaufend, braucht wegen fehlender CORS-Header einen Proxy (SSH
scheidet im Browser ohnehin aus), und ein Konflikt landet als
`<<<<<<<`-Markierung mitten in der Notation — der Parser sähe kaputte Zeilen.
**3. Live gemeinsam tippen — offen.** Der **Transport** ist das kleinere
Problem (WebSocket; SSE + POST oder WebRTC als Alternativen). Die eigentliche
Frage ist, was passiert, wenn zwei Personen **dieselbe Zeile** ändern: Naives
„jede Änderung sofort in beide Richtungen" führt zu Textsprüngen unter dem
Cursor und verlorenen Zeichen. Erprobte Antworten sind **Operational
Transformation** (Google Docs) und **CRDTs**. Für Werkbaum fällt die Wahl
leicht, weil D14 das Format auf puren Text festgelegt hat: Ein Text-CRDT
(`Y.Text` in Yjs, oder Loro) passt ohne eigene Merge-Logik darauf; Cursor und
Anwesenheit fallen als Beigabe ab. **Eigene Merge-Algorithmen sind hier kein
Betätigungsfeld** — das Problem ist gelöst.
Offene Punkte vor einer Entscheidung: Yjs wäre die **erste
Laufzeit-Abhängigkeit** überhaupt (CLAUDE: nicht ohne Rückfrage); wie CRDT-
Zustand und Git-Historie zusammenspielen (Commit-Granularität — nicht jeder
Tastendruck ein Commit); und wer bei einem Backend eigentlich was darf
(Rechte, siehe „Accounts" im Werkbaum-Beispielplan).
## Kleinere Ideen
- Deterministische Pastellfarbe pro `@name` (Personen wiedererkennen).
- Sichtbare Anmerkungen am Knoten (eigene Syntax, getrennt von `%%`).
+15
View File
@@ -58,6 +58,21 @@
- [?] Accounts and permissions (L)
| [?] Single user, one token (S)
| [?] Log in with OIDC (L)
- [?] Working together on one plan (XL)
- [ ] Git as the shared store (L)
| [ ] A file in a repository, changed by pull request (S) %% works today, no code
| [?] The backend commits every change (L)
- [?] History and restore (M)
- [?] Diff between two versions (S)
- [?] Who changed this line (S)
- [?] A branch per scenario (S)
- [?] Live editing, several people at once (XL)
- [ ] Transport over a websocket (S) %% the easy half
- [!] Merging simultaneous edits (L) %% the actual work
| [?] Text CRDT — the plan is plain text, so it fits (L)
| [?] Operational transformation (XL)
- [?] Cursors and who else is here (S)
- [-] A merge algorithm of our own (XL) %% solved problem, do not reinvent
- [?] Mermaid plugin (XL)
- [!] A layout engine of its own (XL) %% measure, place, route — the real work
- [ ] Measure node sizes (M)