projax: social-Grouping legt personen-benannten [project]-Knoten an statt den bestehenden [contact] zu verlinken (z.B. 'Dania' vs Kontakt 'Dania Esser') #6
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
m hat's in mBrian bemerkt (2026-07-13): es gibt zwei "Dania"-Knoten, die wie ein Duplikat aussehen. Tatsächlich sind es zwei verschiedene Typen — und projax ist die Ursache:
dania-esser—type=[contact](id5ead81e9-437d-4175-a3ac-625b040b7331). Der echte Kontakt: Dania Esser, Hogan Lovells, Partnerin, Geburtstag, CardDAV, ~60with/references-Kanten (die ganze Beziehungs-Historie). Kanonisch.dania—type=[project](ide60e7d07-4b07-4aa4-b172-10c8f66a1f96,projax_origin=057ffcb7-7627-4423-9bc7-0dbefd1f3db0,metadata.projax.kind=project,status=active,child_of → social). Ein von projax automatisch erzeugter Gruppierungs-Knoten "Dania", unter demD's RaceTrackeinsortiert ist.racetrack(D's RaceTrack, ida211b814-7064-4ace-9e41-697eb1f41811,projax_origin=e33c246d-...,type=[project,mai-managed], Repom/racetrack,/home/m/dev/racetrack, tags[dev, social]) hängtchild_of → daniaundchild_of → dev.Root Cause
Wenn projax ein Projekt nach einer Person / einem
social-Tag gruppiert, erzeugt es einen neuen[project]-Knoten mit dem Personennamen (hier "Dania") statt den bereits existierenden[contact]-Knoten (dania-esser) zu referenzieren. Ergebnis: Doppelung, die in mBrian/Obsidian wie ein Dupe aussieht.Gewünschtes Verhalten (m's Entscheidung)
dania(personen-benanntes Projekt) soll weg.D's RaceTrackbekommt als "Zuhause" den Kontaktdania-esser— m: "kann ja dasselbe sein". Also: RaceTrack behältchild_of → dev, und wird mit dem Kontakt assoziiert (z.B.for/about → dania-esser), nichtchild_ofeiner personen-benannten Projekt-Gruppe.Fix (projax-seitig)
[contact]-Knoten per Name/Alias matchen und referenzieren (for/about/related_to), statt einen[project]-Knoten mit dem Personennamen zu minten. Nur eine echte Projekt-Gruppe anlegen, wenn kein passender Kontakt existiert.dania-Gruppe (057ffcb7...) sauber zurückziehen (soft-delete über projax' eigenen Pfad, damit kein mBrian↔projax-Desync entsteht).racetrackneu einordnen:child_of → daniaentfernen,child_of → devbehalten,for/about → dania-esser(Kontakt) setzen.Warum nicht in mBrian direkt fixen
Die Knoten sind projax-derived (
projax_origin,derived-from,management:[mai]). Ein reiner mBrian-Umbau würde beim nächsten projax-Sync überschrieben/neu erzeugt. Der Fix muss in der projax-Grouping-Logik passieren.Refs
dania-esser(5ead81e9-...)dania(e60e7d07-..., origin057ffcb7-...)racetrack(a211b814-..., origine33c246d-...)Read-Seite-Folgenotiz aus mBrian#77 (2026-07-14):
mai-managedist in mBrian kein type mehr — es ist jetzt ein Tag (tagged → tag-mai-managed) + steckt inmetadata.projax.management. Die scoped projax-Write-API hängt es nicht mehr als Co-Type an; Migration db/046 hat die 44 Bestandsknoten umgestellt.Falls projax je
type @> [mai-managed]liest, um mai-managed Projekte zu erkennen: künftig das Tagtag-mai-managedbzw.metadata.projax.managementlesen. Aktuell niedriges Risiko (projax läuft nicht aktiv als mai-Projekt).Root cause: refuted — there is no auto-grouping engine
Erste Aufgabe war, die Diagnose zu verifizieren statt sie zu bauen. Ergebnis: die im Issue behauptete Ursache existiert nicht.
Das tut projax nicht. Es gibt keinen Code-Pfad, der das könnte. Sweep über
cmd/ store/ web/ gitea/ caldav/ mcp/ internal/ db/:create_item(mcp/tools.go:886),/new-Form (web/server.go:1007), Task-Create (web/task.go:278). Alle nehmen Parents explizit entgegen und fehlern, wenn der Parent nicht existiert (mcp/tools.go:904). Keine mintet je einen Parent.[contact]-Knoten. Das Wort "contact" kommt im gesamten Go-Tree einmal vor — als Warnkommentar, sie nicht zu beschädigen (store/mbrian_writer.go:33).web/kanban.go:132-146);group_byist eine Render-Achse.mai.projects-Trigger — der spiegelt und landet bewusst auf Root ('{}'::uuid[],db/migrations/0008:182), leitet also gerade keinen Parent ab.Woher
daniawirklich kommtcreated_at = 2026-05-29 13:12:41.581— dieselbe Sekunde wie die übrigen migrierten Knoten (racetrack13:12:41.235, Kanten 13:12:42). Das ist der Phase-6-Snapshot-Import aus den altenprojax.items. Dazu: keine "Dania"-Zeile inmai.projects→ auch nicht trigger-erzeugt.daniaist ein Alt-Item, das m selbst von Hand angelegt hat, alsprojax.itemsnoch der Store war. Kein Sync-Artefakt. Fix #1 des Issues fällt damit weg — ich habe bewusst keine "Grouping-Engine" erfunden, um sie zu reparieren.Der Datenstand hat sich seit dem Filing geändert
Am 2026-07-13 13:38 (also nach dem Filing) ist bereits passiert:
daniaKnotendeleted_at 13:38:49) → aus projax' Tree verschwundenracetrack child_of daniaracetrack child_of devracetrack child_of dania-esser[project]als struktureller child eines[contact]Schritte 2+3 sind damit größtenteils erledigt — nur mit
child_ofstatt der gewünschten Assoziation.Blocker: projax kann Schritt 3 gar nicht ausführen
Das gewünschte Zielbild (
for/about/related_to→dania-esser) ist über projax' Write-Pfad nicht umsetzbar:child_of | projax-*→related_togibt 400 (mBriansrc/lib/server/projax.ts:288).[contact]-Target gibt 403 (mBriansrc/routes/api/projax/edges/+server.ts:19-27).dania-esserhat keinprojax_origin(verifiziert).forundaboutexistieren in mBrians rel-Vokabular gar nicht (0 Verwendungen).related_tohat 390.child_of → dania-esser-Kante auch nicht löschen.Das heißt: das lässt sich auch später nicht still aufräumen — es braucht eine Entscheidung. Zwei Optionen, beide bei m:
(a)
AddLink-Self-Edgeprojax-contactmit Metadata — heute vertragskonform, aber keine echte mBrian-Kante → in mBrian/Obsidian unsichtbar, was den Sinn des Issues ("den bestehenden Kontakt verlinken") verfehlt.(b) mBrian-seitig das Gate lockern:
related_toerlauben, wenn die Source projax-owned ist und das Target nicht (asymmetrisches Gate). Sachlich richtig, aber cross-repo — und es gibt eine Ownership-Garantie aus, die genau m's Kontakte/Journal schützt.Alle Datenschritte sind angehalten, bis m entscheidet.
Sweep (Schritt 4): es gibt einen zweiten
mama/ "Mama" (b8be1744-2dc6-4ecc-b27e-339ec15111b1) — live,child_of → social, leer (null Kinder), gleiche Migrations-Sekunde → identisches Alt-Muster.katrin-janßen-siebels(a763e8ef-...),aliases: ["Mama"]— ein Alias-Match, kein Titel-Match. (Falls (b) je kommt: Matching muss Aliases einschließen.)Nicht angefasst —
mamaist von #6 textlich nicht abgedeckt und es sind m's Daten.Was gefixt wurde (Code, mergebar unabhängig von der Entscheidung)
Echter Bug gefunden — der mBrian#77-Rest im Write-Pfad.
store/mbrian_writer.goschicktemai_managed: containsString(in.Kind, "mai-managed"). Seit #77 stehtmai-managednie intype[], und der Reader fülltItem.Kindaustype[]→ der Ausdruck war immer false. Folge: projax konnte gar keinen mai-managed-Knoten anlegen bzw. dietagged → tag-mai-managed-Kante nie anstoßen.Fix: Ableitung aus
Management— dieselbe Quelle, die der Read-Pfad schon nutzt (MaiOrphans → HasManagement("mai")). Invariante in den Live-Daten geprüft:management:["mai"]⇔ Tag-Kante gilt für 43/43 Knoten, null Abweichungen.Zur Read-Seite aus dem Brief: kein Live-
type @> [mai-managed]-Bug — die Lesepfade gehen überHasManagement. Der Treffer incmd/projax-snapshotliest die altenprojax.items(wokind[]noch gilt) und ist read-only korrekt.Dazu:
docs/design.md§2.5 hält jetzt fest, dass es keine Grouping-Engine gibt — damit die nächste Session dieselbe falsche Ursache nicht in sechs Monaten erneut filet.Commit:
2742038b76Nebenbefund: die Parity-Tests sind rot — durch den Hand-Fix
TestParityListAll(store=73 vs mbrian=66) undTestParitySpotChecks(dania: mbrian err=item not found but store found) failen. Pre-existing, gegen den Baseline-Commit verifiziert, nicht von diesem Change. Ursache ist aber genau das Obige:daniawurde in mBrian soft-deleted, während die altenprojax.itemses noch führen — die Parity-Suite spot-checkt ausgerechnetdania. Sobald m die Datenfrage entschieden hat, gehört der Spot-Check-Fixture nachgezogen; als eigenes Issue sinnvoll, wenn #6 anders ausgeht.Erledigt (2026-07-17) — aber die Diagnose im Issue war falsch
Wichtigster Punkt zuerst: der im Issue beschriebene Root Cause existiert nicht. Der Worker hat ihn geprüft, bevor er etwas gebaut hat, und widerlegt.
Es gibt keine Grouping-Engine
Vollständiger Sweep über
cmd/,store/,web/,gitea/,caldav/,mcp/,internal/,db/:create_item,/new-Form, Task-Create). Alle verlangen Eltern explizit und brechen ab, wenn der Elternknoten fehlt (mcp/tools.go:904). Keine mintet je einen Elternknoten.[contact]-Knoten. Das Wort "contact" kommt im gesamten Go-Baum einmal vor — als Warnkommentar, sie nicht zu beschädigen (store/mbrian_writer.go:33).web/kanban.go:132-146).mai.projects-Trigger — der landet auf ROOT (db/migrations/0008:182). Spiegelung, keine Gruppierung.Herkunft von
dania:created_at 2026-05-29 13:12:41.58— auf dieselbe Sekunde wie der übrige Phase-6-Snapshot-Import, und keine "Dania"-Zeile inmai.projects. Also Altbestand, den m selbst von Hand angelegt hat, alsprojax.itemsnoch der Store war. Kein Sync-Artefakt.Festgehalten in
docs/design.md§2.5 („There is no auto-grouping engine"), damit der nächste nicht dasselbe falsche Issue nochmal filet.Was tatsächlich zu tun war
dania— war bereits erledigt: m hat am 2026-07-13 13:38 selbst von Hand aufgeräumt (soft-deleted,racetrack child_of daniaentfernt). Das Issue war bei Aufgreifen schon überholt.mama(b8be1744-…) — heute zurückgezogen (soft-delete über projax eigenen Write-Pfad,deleted_at 2026-07-17 12:29:56). Vorher verifiziert: null Kinder, nichts ging verloren. Der echte Kontaktkatrin-janßen-siebelsträgt den Alias „Mama" ohnehin.racetrack— Endzustand verifiziert: hängt andev[project]unddania-esser[contact], beide live. Bleibt so (m: „leave as-is").Mitgenommener echter Bug
store/mbrian_writer.goschicktemai_managed: containsString(in.Kind, "mai-managed"). Nach mBrian#77 istmai-managedein Tag, kein Co-Type — der Ausdruck war immer false, projax konnte also nie einen mai-managed-Knoten anlegen. Jetzt ausManagementabgeleitet, konsistent mit der Read-Seite (MaiOrphans→HasManagement("mai")). Mit Tests.Commits
2742038— mai_managed aus Management ableiten + PRD-Notiz §2.5 (Details)29a989f, live deployed (healthz == HEAD)Kein
related_to-Umbau, kein Cross-Repo-Issue auf m/mBrian — per ms Entscheidung nicht nötig.Ich schließe nicht (nur m schließt).