aliases sind ein totes Feld: drei Read-Pfade, kein einziger Write-Pfad, null Daten #7
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
aliaseswird überall gelesen, kann aber nirgends gesetzt werden. Live-Check (2026-07-17,main@bcf3412): alle 88 Items haben"aliases":[]— nicht als Zufall, sondern weil es keinen Schreibweg gibt.Aufgefallen beim Triage von #1: m will dort
Mentalmit AliasPsychologie. Das Projekthealth.mentalist angelegt — der Alias ist nicht setzbar.Belege
Read-Pfade (alle vorhanden, alle laufen ins Leere):
store/store.go:837— Suche matchtexists (select 1 from unnest(u.aliases) a where a ilike ...)store/store.go:891— Ranking-Bucket 3 ist explizitalias(zwischen title-contains und content)web/tree_filter.go:333— Tree-Filter iteriertit.Aliasesmcp/tools.go:631,678— MCP gibtaliasesin jedem Item zurückWrite-Pfade (keine):
mcp__projax__create_item— keinaliases-Parametermcp__projax__update_item— keinaliases-Parametergrep -n "aliases" web/templates/*.tmpl→ null Trefferstore/mbrian_writer.go— sendetaliasesin keinem PayloadDer Kicker: die scoped mBrian-Write-API kann es längst. Laut Vertrag in
store/mbrian_writer.go:36-37(m/mBrian#73):aliases?ist auf beiden Endpoints akzeptiert. Der projax-Writer schickt es einfach nie. Das ist kein API-Gap wie G1/G2/G3 — die Server-Seite ist fertig, nur die Client-Seite fehlt.Scope
store/mbrian_writer.go:aliasesin den POST- und PATCH-Payload aufnehmen (die API nimmt es schon — kein Cross-Repo-Ask nötig).aliasesals optionalen Parameter aufcreate_item+update_item.Psychologieaufhealth.mentalsetzen → schließt die letzte offene Anforderung aus #1.Constraints
/api/projax-Surface (Phase-6-Vertrag) — kein rohes mBrian-SQL, sonst reißt derprojax_origin-Ownership-Vertrag (m/mBrian#73).Verify
go build ./...+go vetclean. Live: Alias auf einem Item setzen → Suche findet das Item über den Alias (Bucket 3) → Tree-Filter matcht ihn. Deploy-verify per CLAUDE.md (healthz-SHA == HEAD).Bekanntes Rauschen:
TestProjectFilter*/TestTimeline*inweb/sind vorbestehender Route-Drift — nicht Teil dieses Issues.Refs
Psychologieaufhealth.mental(Auslöser)store/mbrian_writer.go:36-37— die API-Signatur, diealiases?längst zusagtErledigt — aliases hat jetzt einen Write-Pfad
Commit:
e859a98cd0Branch:
mai/apollo/issue-7-aliases-write(gepusht, wartet auf head-Merge)Was drin ist
store/mbrian_writer.go—aliasesist jetzt im Node-POST und im PATCH-Payload. Diff bleibt bewusst auf die zwei Payload-Zeilen beschränkt (icarus ist parallel in derselben Datei auf #6).mcp/tools.go— optionaleraliases-Parameter aufcreate_item+update_item.Psychologieaufhealth.mentalgesetzt — siehe unten. Schließt die letzte offene Anforderung aus #1.Bonus: der Legacy-Writer + zwei stille Datenverlust-Fallen
projax.items.aliasesexistiert seit0001_init.sql:23als Spalte, der Legacy-*Storehat sie nur nie geschrieben. Jetzt schreibt er sie — kein halbtotes Feld auf dem Fallback-Pfad (der greift, wennPROJAX_MBRIAN_API_URLnicht gesetzt ist).Updateist full-replace. Jeder Caller, der ein einzelnes Feld ändert, muss die aktuellen Aliases mitschicken, sonst löscht ein Tag-Toggle sie still weg. Entsprechend nachgezogen:updateInputFromItem(bulk chip edits) und derupdate_item-Patch im MCP.Parse-Regeln: Aliases ≠ Tags
parseCSV(Tags) lowercased und splittet auch an Leerzeichen. Für Aliases falsch — ein Alias ist ein Name, kein Token:Psychologiedarf nicht zupsychologiewerden (du hast in #1 explizit die Großschreibung verlangt)Mental Healthdarf nicht in zwei Aliases zerfallenDeshalb
parseAliasCSV: splittet nur an Kommas, erhält Groß-/Kleinschreibung, dedupliziert case-insensitiv (Suche + Tree-Filter matchen ohnehin perilike/ToLower, zwei Schreibweisen wären ein toter Duplikat-Eintrag). Das Eingabeformat bleibt identisch zu Tags — nur die Parse-Regeln unterscheiden sich. Unit-Test:web/alias_form_test.go.Rename-Interaktion (geprüft, nicht vermutet)
mBrians PATCH-Handler ruft
renameSlug(hängt den alten Slug als Alias an) nachupdateNodeauf (src/routes/api/projax/nodes/[id]/+server.ts:50-59). Unser Alias-Write landet also zuerst, der Cascade-Append danach — ein Slug-Rename kann den Alias-Write nicht überschreiben. Kein Handlungsbedarf.Außerdem gegengeprüft statt dem Vertragskommentar zu glauben:
buildCreateInput/buildUpdateInputinsrc/lib/server/projax.ts:175,235-238akzeptierenaliasestatsächlich auf beiden Endpoints. Server-Seite war wie beschrieben fertig.Verify
go build ./...+go vet ./...clean. Die 10TestProjectFilter*/TestTimeline*-Failures habe ich gegen einen gestashten Tree gegengeprüft — identisches Failure-Set vor und nach meiner Änderung, also vorbestehender Route-Drift. Wichtig war das, weilTestTimelineExcludeDetailFormShowsCheckboxesdetail.tmplanfasst, die ich geändert habe — auch die failt vorher wie nachher.Live-Round-Trip (gegen die deployte Read-Seite, die ich nicht angefasst habe):
Geschrieben über den echten
MBrianWritergegen die scoped/api/projax-Surface — kein rohes mBrian-SQL,projax_origin-Ownership unangetastet. Titel/Slug/Status/Parents/Content nach dem full-replace unverändert.Die Suche nach
Psychologiefindet das Item — aber das ist kein Beweis, weilPsychologieauch imcontent_mdsteht. Sauber nachgewiesen mit einem Token, das ausschließlich inaliasesexistiert:Gefunden über den Alias, nicht über Titel/Slug/Content. Probe-Alias danach wieder entfernt; live steht jetzt exakt
aliases:["Psychologie"].Befund: der Bucket-3-Beleg im Issue gilt für den Legacy-Pfad
Eine Korrektur zur Beweislage — kein Blocker, aber du solltest es wissen:
Die im Issue zitierte Ranking-Logik (
store.go:891, Bucket 3 = alias) läuft gegenprojax.items_unified. Produktion läuft aberPROJAX_BACKEND=mbrian, undhealth.mentalliegt nur inmbrian.nodes—items_unifiedliefert für die id null Zeilen. Der live genutzte Suchpfad istMBrianReader.Search(store/mbrian.go:670), und der ist ein flacher Substring-Match überitemMatchesSubstring, sortiert nach Slug — ohne jedes Ranking. Aliases werden dort gematcht (deshalb der Beweis oben), aber Buckets gibt es auf dem mBrian-Backend schlicht nicht.Heißt: „Alias landet in Bucket 3" trifft auf den Legacy-Pfad zu, nicht auf Produktion. Das Feature dieses Issues funktioniert vollständig; nur die Ranking-Zusage ist auf dem mBrian-Backend ein Read-Seiten-Gap. Wenn dir Ranking wichtig ist (Alias-Treffer vor Content-Treffern), ist das ein eigenes Issue auf der Read-Seite — ich fasse sie hier vertragsgemäß nicht an.
Deploy
Live ist noch
bcf3412. Deploy-Verify (healthz-SHA == HEAD) nach dem head-Merge. Der Alias ist jetzt schon gesetzt und über die deployte Read-Seite auffindbar — der Alias lebt in den Daten, nicht im Binary.