Prosa ist kein Identifier: Link-Taxonomie als Enum, toolgeführte Blöcke als generierte Regionen, types/ nach Eigentum #40
Reference in New Issue
Block a user
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?
Der Befund
#39 hat die Eigentumsfrage richtig beantwortet und den Mechanismus stehen lassen, der sie überhaupt schwer gemacht hat. Der Stack benutzte an drei Stellen Prosa als Identifier:
## Beziehungen(Überschriftentext)hängt ab von(Label im Body-Bullet)related:{section.relationships}undPRE_CONVENTIONS_NAMESaus 3.0.0 waren die Kompensation dafür, nicht der Entwurf. Sie sind entfallen.Der Preis des Matchens auf Prosa stand schon im Repo: der Docstring von
provenance.split_cite_blockerzählt, wie acht Seiten Inhalt verloren, weil eine toolgeführte Region per Heuristik statt per Begrenzer gefunden wurde.Entscheidungen
Getroffen in der Sitzung vom 2026-09-02, im Anschluss an #39.
Kantenmodell: direktional
Die erzwungene Bidirektionalität (
kb/CONTRACT.md: "Every page links to what it mentions, in both directions",xref addschrieb beide Seiten) ist entfallen.Sie ist mit der per-Collection-Autorisierung logisch unverträglich: die läuft pro Quell→Ziel-Paarung und steht in der
COLLECTION.mdder Quelle. Schreibtxref adddie Gegenkante mit, entsteht eine Kante, deren Quellcollection eine andere ist — deren Regeln der Autor weder liest noch überblickt. Entweder das Werkzeug schreibt unautorisierte Kanten, oder die Regel "die Quellcollection entscheidet" löst sich auf.Der Navigationseinwand ("ich lande auf Hermes und will sehen, was davon abhängt") ist durch die Umstellung besser gelöst als vorher:
related:trägt maschinenlesbare Label, also ist die eingehende Liste ableitbar — gerendert vonwikitool links show, vollständig und ohne Pflege. Die erzwungene Gegenkante garantierte das nie, sie garantierte nur, dass jemand daran gedacht hat.Nicht in diesem Paket: der Articulation-Test und der
connect-Report-Workflow aus Commonplace. Die ändern, wie Ingest arbeitet, nicht wie Links gespeichert werden.Label sind Enum-Werte, nicht lokalisiert
- **depends_on:** [[Hermes]]steht so in einer deutschen Seite. Keine Anzeigetabelle, kein Vollständigkeitscheck, keine dreizehn Zeilen Instanzdaten. Der Enum-Wert ist der Anzeigetext.Umkehrbar: eine Anzeigetabelle bliebe jederzeit rein additiv nachrüstbar, weil der Enum-Wert der Identifier bleibt.
depends-on/required-bydepended-byist nicht grammatisch — "depend" ist intransitiv und verlangt "on"; das Passiv wäredepended-on-by. Die etablierte Umkehrung der Domäne istrequired-by(rpm; apt nennt es "Reverse Depends"). Beide erfüllen Commonplaces ADR-058-Invariantesource <label> target.Das bisherige
benötigtist entfallen — es war immer ein Synonym vonhängt ab von.Die Taxonomie
Sechs Register. Die ersten beiden sind neu und folgen dem Profil dieser Instanz (Infrastruktur, Architektur); die vier danach sind Commonplaces Katalog vollständig übernommen (alle 26).
depends-on·required-by·runs-on·hosts·uses·produces·consumes·maintains·ownsimplements·operationalized-from·mechanism·procedure·applies-when·operates-on·invokesextends·grounds·rests-on·enables·precondition·exemplifies·abstracted-from·contrasts·compares-with·contradicts·composition·part-ofsupersedes·derived-from·adapted-from·defined-inevidenced-by·is-evidence-forsee-also(letzte Instanz)35 Labels. Inverse nur, wo die Gegenrichtung eine eigene Primäraussage ist. Der Entwurf nannte zwei Paare; seit 4.1.0 sind es drei:
depends-on/required-by,runs-on/hostsundcomposition/part-of. Alles andere hat keins — die eingehende Sicht wird gerendert. Ein Inversenpaar macht die Gegenkante nicht zur Pflicht; es legt fest, welches Label sie trägt, wenn jemand sie schreibt.Wo was liegt:
instructions/link-taxonomy.md— der Katalog. Stack, Palette, bindet nichts.kb/<name>/COLLECTION.mdoutbound:— die autorisierte Teilmenge pro Quell→Ziel-Paarung. Instanz, bindet. (Commonplace ADR-019)lintprüftrelated:gegen diese Autorisierung.Ein Label hinzufügen ist eine Zeile Daten, keine Codeänderung.
Zur Migrationsabbildung: der Entwurf behauptete eine 1:1-Abbildung von dreizehn Labeln. Gemessen am Korpus war das falsch — 152 distinkte Label in 337 Bullets, davon 102 mit genau einem Vorkommen, dazu 555 nackte
## Siehe auch-Bullets. Der Lauf war deshalbassistedund redaktionell, ohne mechanischen Boden; die Messung steht im Kommentar vom 2026-09-02.Umsetzung
Reihenfolge, benannt statt nummeriert (Korrektur im ersten Kommentar): Abschnitt 1 → Abschnitt 4 → Abschnitte 2+3.
1. Angebotene Migrationen (
obligation:) — [x] erledigtZwei Achsen statt einer.
migration_kind:beschreibt wie die Arbeit läuft,obligation:ob sie laufen muss:required(Default)offeredchain()zählt nurrequired;offers()gibt den Rest. Korrektur gegen den Entwurf: Offers sind gegen das Applied-Ledger gebunden, nicht gegenkb_version— eine angenommene Offer bewegtkb_versiongerade nicht, also kann die Version nichts darüber aussagen, und ein unbeteiligter Pflichtschritt hätte jede Offer stillschweigend verschwinden lassen.migrate done <offer>schreibt einen Ledger-Eintrag ohne Versionsbewegung und ohne Reihenfolgeregel.kb_state.divergent_files()liest die sha256 pro Datei aus.wikitool-release.jsonund beantwortet "editiert oder nur empfangen".Nonestatt[]ohne Stamp — ein Entwicklungsbaum hat keinen, und "nichts abgewichen" wäre dort eine erfundene Antwort.4.
types/teilt sich entlangroot:— [x] erledigtentity,concept,source,comparison.template, adoptiert per Renameinstruction,lint-report,type-specdist exportschlüsselt die vierroot: kb-Type-Specs samt ihrer.schema.yamlals.templateum; abgeleitet austypes/, nicht gelistet. Damit ist die deutsche Prosa in den vier Page-Type-Specs korrekt statt Migrationsschuld.Der Stack nennt sein Minimum:
STACK_REQUIRED_TYPES = ("source",)— muss existieren, Schema mussraw_filesverlangen.STACK_REQUIRED_COLLECTIONSals separate Liste ist weg;stack_required_collections()leitet sie aus dembase_dirdessource-Typs ab.provenance._SOURCE_TITLE_PREFIXliesttitle_prefix:aus dem Type-Spec.Die Vorbedingung hält:
source_pages_by_raw_file,legacy_source_pagesundduplicate_raw_file_ownersfragen allepage.kind, also dasname:des Type-Specs — nicht Verzeichnis oder Titelpräfix. Die Ankermenge blieb so klein wie beschrieben.2+3. Label werden Enum, toolgeführte Blöcke werden generierte Regionen — [x] erledigt
Eine Korpusmigration, weil beide jede Seite anfassen.
Gelöscht, ersatzlos:
tools/chemenu/sections.py,heading_re, der Alias-Mechanismus,PRE_CONVENTIONS_NAMES,cite_block_heading,provenance.__getattr__, die{section.*}-Template-Variablen undxrefs Abschnittssuche. Kein Überschriftentext liegt mehr in Python.Neu:
blocks.py(Marker-Regionen<!-- wikitool:links -->/<!-- wikitool:footnotes -->),links.py,instructions/link-taxonomy.md,outbound:in denCOLLECTION.md,links showals abgeleitete Eingangssicht.Vier Korrekturen, die die Umsetzung erzwungen hat:
sections:fällt nicht weg. Die Region rendert ihre Überschrift mit, braucht also einen Text. Was wegfällt, ist das Matching — der Wert ist Anzeige, nicht Identifier. Von drei Slots auf zwei:linksundfootnotes.see-also-Region. Sie war die Spiegelhälfte des bidirektionalenxref add; unter direktionalen Kanten istsee-alsoein Label innerhalb der Links-Region.index rebuildrendert die Eingangssicht nicht. Eine Backlink-Liste pro Seite in einen Shard zu schreiben, der ohnehin eine Seitentabelle ist, verdoppelt ihn. Stattdessenlinks show --page, budgetbefreit wiesearch. Dazu: das gerenderte Bullet ist ein Wikilink, also zeigt Obsidians Backlink-Panel die Eingangssicht ohnehin.xrefgelaufen".5. Abschluss (4.1.0) — [x] erledigt
unlabelled_edgesundunauthorised_labelssind harte Fehler, gebunden ankb_versionstatt an ein Release-Datum: unterhalb 4.0.0 beratend, ab 4.0.0 hart. Das ist der Unterschied zum Weg vonlegacy_citation_markers, der in einer späteren Version umgelegt wurde und jede Instanz mit offener Migration auf rotes Lint setzte. Das Ledger kann die Frage inzwischen beantworten, also tut es das.Dazu die zwei Befunde des Migrationslaufs, die den Katalog betrafen:
outbound:ist an das Type-Spec gebunden (docs verifyprüft die Kombination), undcomposition/part-ofist das dritte Inversenpaar. Details im Abschlusskommentar.Akzeptanzkriterien
tools/—sections.pyundPRE_CONVENTIONS_NAMESexistieren nicht mehrrelated:trägt Label als Enum-Wert;lintprüft sie gegen dieoutbound:-Autorisierung der Quellcollectionxref addschreibt genau eine Kante; die eingehende Sicht ist gerendert, nicht gespeichertmigrate verifyinstructions/link-taxonomy.mdenthält alle 26 Commonplace-Labels plus die neun operativenmigrate statustrenntrequiredvonofferedund blockiert nie aufofferedmigrate statusmeldet, welche instanzeigenen Dateien von den Stamp-Hashes abweichen.templatedocs verifyprüftSTACK_REQUIRED_TYPESinstructions/dev/version-parts.md; Grenzübertritt gesetzt (4.0.0), Migrationsdokument vorhandenlinterzwingt das (nachgereichtes Kriterium aus dem Kommentar vom 2026-09-02)Vorgeschichte
Aus #39 heraus, Sitzung vom 2026-09-02. Verworfen wurden unterwegs: eine Slot-Tabelle im Type-Spec plus Rendering-Datei in der Instanz (Kompensation für eine Ownership-Grenze an der falschen Stelle),
kb/TEMPLATES.mdals eigene Instanzdatei (dito), und eine Anzeigetabelle für lokalisierte Label (unnötig, sobald der Enum-Wert selbst angezeigt wird).Ausgelagert
#43 — dem Katalog fehlt ein Register für Urheberschaft.
kind/decision,prio/waiting: der Korpus ist konsistent, alle betroffenen Kanten stehen aufsee-also, und der Auslöser ist das nächste Auftreten.Korrektur zur Reihenfolge. Der Satz "Reihenfolge: 4 vor 3" unter Umsetzung stammt aus der Nummerierung des Vorgesprächs und widerspricht der Nummerierung dieses Issues. Gemeint ist, benannt statt nummeriert:
obligation:) — zuerst, weil sie der Träger für alles Folgende sind.types/teilt sich entlangroot:— die Übergabe an die Instanz ist ohne diesen Träger unumkehrbar.Also: Abschnitt 1 → Abschnitt 4 → Abschnitte 2+3.
Zwischenstand: Abschnitte 1 und 4 stehen
Noch nicht publiziert,
VERSIONnoch auf3.0.0— der Bump kommt am Ende des Pakets.Vorbedingung geprüft, sie hält
Die im Issue offene Frage — löst der Provenance-Pfad über den Typ oder über Pfad/Präfix auf? — ist beantwortet:
source_pages_by_raw_file,legacy_source_pagesundduplicate_raw_file_ownersfragen allepage.kind != "source", also dasname:des Type-Specs. Die einzige Kopplung an eine Zeichenkette warprovenance._SOURCE_TITLE_PREFIX, und die ist jetzt aufgelöst (liesttitle_prefix:aus dem Type-Spec, mit dem alten Literal als Fallback für einen Baum ohne auflösbarensource-Typ — sonst würden bestehende Cite-IDs wandern).Die Ankermenge bleibt also so klein wie im Issue beschrieben.
Abschnitt 1 —
obligation:required|offered, Defaultrequired.chain()zählt nurrequired;offers()gibt den Rest.Eine Lücke, die ich beim Testen gefunden habe und die im Issue noch falsch stand: ich hatte Offers gegen
kb_versiongefiltert. Das ist falsch — eine angenommene Offer bewegtkb_versiongerade nicht, also kann die Version nichts darüber aussagen, ob sie angenommen wurde, und ein unbeteiligter Pflicht-Schritt hätte jede Offer stillschweigend verschwinden lassen. Offers sind jetzt gegen das Applied-Ledger gebunden, undmigrate done <offer>schreibt einen Eintrag dorthin, ohne die Version zu bewegen und ohne Reihenfolgeregel — eine Offer ist kein Glied der Kette, also gibt es nichts zu überspringen.Die Erkennungshälfte ist aktiviert:
kb_state.divergent_files()liest die sha256 pro Datei aus.wikitool-release.jsonund beantwortet „editiert oder nur empfangen".Nonestatt[]ohne Stamp — ein Entwicklungsbaum hat keinen, und „nichts abgewichen" wäre dort eine erfundene Antwort.Abschnitt 4 —
types/entlangroot:dist exportschlüsselt die vierroot: kb-Type-Specs samt ihrer.schema.yamlals.templateum;instruction,lint-reportundtype-specgehen verbatim. Abgeleitet austypes/, nicht gelistet — ein eigener Page-Typ der Instanz bekommt dieselbe Behandlung ohne Codeänderung.find_leaksverweigert die gefüllten Namen.STACK_REQUIRED_COLLECTIONSist als separate Liste weg:stack_required_collections()leitet sie aus dembase_dirdessource-Typs ab. Eine Instanz, diekb/sources/umbenennt und das im Type-Spec sagt, bleibt konsistent statt gegen eine hartkodierte Zeichenkette zu laufen.docs verifyprüft neuSTACK_REQUIRED_TYPES: es muss einen Type-Specname: sourcegeben, dessen Schemaraw_filesfordert. Mehr nicht.Damit ist die deutsche Prosa in den vier Page-Type-Specs erledigt — kein Übersetzungsschritt, keine Migrationsschuld. Verifiziert am vollen Replay: Export → frische englische Instanz →
doctor/docs verifygrün,new entityscaffoldet## Relationships/## See Alsoaus der eigenenkb/CONVENTIONS.md, und die## Beschreibung-Überschriften stehen in einer Datei, die dieser Instanz gehört und die sie übersetzen darf.838 Tests grün.
Als nächstes
Abschnitte 2+3 als eine Korpus-Migration: Label werden Enum, Kanten direktional, toolgeführte Blöcke werden generierte Regionen mit Markern.
Korrektur: die Migrationsabbildung im Issue-Text stimmt nicht
Der Abschnitt Die Taxonomie behauptet eine Abbildung „1:1 bis auf eine Zusammenlegung" von dreizehn Labeln. Gemessen am Korpus ist das falsch, und zwar deutlich.
152 distinkte Beziehungslabel in 337 Bullets.
kb/CONVENTIONS.mdlistet dreizehn; nichts hat je geprüft, ob sie eingehalten werden, und sie wurden es nicht. Die Top 20 decken 167 der 337 Bullets ab, 102 Label kommen genau einmal vor (Erfand,Gegenmittel zu,spiegelt das gleiche Muster wie,würde implementiert von, …). Die dokumentierte Liste deckt grob ein Sechstel.Dazu ein Anteil Gegenrichtungen, den ich unterschätzt hatte:
Verwendet von(20×),umgesetzt von,implementiert durch,Ersetzt durch,Erweitert durch. Unter dem direktionalen Modell sind das genau die Kanten, die nicht mehr gespeichert, sondern gerendert werden.Und
## Siehe auch555 nackte
- [[X]]-Bullets ohne Label — mehr als alle gelabelten Beziehungen zusammen. Die Spiegelhälfte der erzwungenen Bidirektionalität.Die 353 fallen mechanisch. Bei den 202 ist mechanisch nicht entscheidbar, ob jemand die Verbindung gemeint hat oder ob
xref addsie als Spiegel schrieb und die gelabelte Hälfte später verloren ging.Folge
migration_kindistassisted, nichtmechanical. Umfang: ~539 Einzelentscheidungen (337 gelabelte Bullets + 202 ungedeckte Siehe-auch-Kanten) über rund 140 Seiten, nachmigrate-corpus.mdalso drei bis vier Einheiten mit je eigenem Publish.Entschieden: redaktionell, nicht mit mechanischem Boden. Die Alternative wäre gewesen, die Top 20 per Tabelle abzubilden und den Rest auf
see-alsozu setzen — das hätte ~370 von ~539 Kanten mit dem schwächsten Label des Katalogs starten lassen, also genau denverwandt mit-Bodensatz reproduziert, den die Umstellung beendet, nur diesmal als dokumentierten Startzustand.Das Akzeptanzkriterium „Ein Label hinzufügen braucht keine Codeänderung" bleibt; neu dazu: die Migration ist erst fertig, wenn kein Bullet mehr ein Label außerhalb des Katalogs trägt und
lintdas erzwingt.Die Mechanik ist davon nicht blockiert und wird zuerst gebaut.
u0 steht — die Mechanik ist vollständig, keine Seite angefasst
856 Tests grün,
docs verify/instructions verify/doctorgrün, keine Hard-Error-Findings im Korpus.Gelöscht, ersatzlos
tools/chemenu/sections.pyexistiert nicht mehr. Mit ihm:heading_re, der Alias-Mechanismus,PRE_CONVENTIONS_NAMES,cite_block_heading,provenance.__getattr__, die{section.*}-Template-Variablen undxrefs Abschnittssuche (_section_bounds,add_bullet_to_section,add_relationship_bullet,add_see_also_bullet). Kein Überschriftentext liegt mehr in Python — bis auf zwei Fallback-Strings inconventions.DEFAULT_HEADINGS, und die sind rein kosmetisch: der Marker trägt die Identität der Region, also rendert ein falscher Default falsche Wörter statt Struktur zu zerlegen, und der nächste Write repariert es.Neu
blocks.py(Marker-Regionen:<!-- wikitool:links -->/<!-- wikitool:footnotes -->),links.py(gelabelte Kanten, liest beide Formen),instructions/link-taxonomy.md(35 Label),outbound:in allen vierCOLLECTION.md,links showals abgeleitete Eingangssicht.Vier Korrekturen am Entwurf, die die Umsetzung erzwungen hat
1.
sections:fällt nicht weg. Das Issue behauptet es. Falsch: die Region rendert ihre Überschrift mit, also braucht sie einen Text. Was wegfällt, ist das Matching — der Wert ist jetzt Anzeige, nicht Identifier, dieselbe Kategorie wielayout: {project: {title: Projekte}}. Von drei Slots auf zwei:linksundfootnotes.2. Es gibt keine
see-also-Region mehr. Sie war die Spiegelhälfte des bidirektionalenxref add; unter direktionalen Kanten istsee-alsoein Label innerhalb der Links-Region. Zwei Regionen statt drei.3.
index rebuildrendert die Eingangssicht nicht. Ich hatte das so ins Issue geschrieben und es beim Bauen verworfen: eine Backlink-Liste pro Seite in einen Shard zu schreiben, der ohnehin eine Seitentabelle ist, verdoppelt ihn und hilft niemandem. Stattdessenwikitool links show --page— Ausgangskanten ausrelated:, Eingangskanten über den Korpus berechnet, budgetbefreit wiesearch. Dazu der Punkt, den ich vorher übersehen hatte: das gerenderte Bullet- **depends-on:** [[Hermes]]ist ein Wikilink, also zeigt Obsidians Backlink-Panel die Eingangssicht für einen menschlichen Leser bereits von selbst.4. Der Orphan-Check meldet jetzt mehr. Direktionale Kanten heißen: eine Seite, die nur nach außen zeigt, ist tatsächlich unerreichbar. Das ist die Prüfung, die ihre Arbeit tut — sie misst Erreichbarkeit statt "ist
xrefgelaufen" —, aber es ist eine Verhaltensänderung, die u1–u4 sichtbar machen werden.Lint-Schärfe
malformed_edgesundunbalanced_markerssind hart ab sofort: keines beschreibt eine unkonvertierte Seite, nur eine kaputte.unlabelled_edgesundunauthorised_labelssind advisory bis zum Abschluss der Migration — sie beschreiben exakt das Fenster, für das.wikitool-kb.jsonexistiert. Die Beförderung zu Hard Errors ist Teil von u5, derselbe Weg, denlegacy_citation_markersgenommen hat.Die Zahl für u1–u4
480, nicht 337.
related:trägt mehr Einträge als der Body gelabelte Bullets hat — Frontmatter und Body waren unter dem alten Modell längst auseinandergelaufen, und niemand konnte es sehen, solange das Label nur in der Prosa stand. Das ist selbst ein Befund.Plan, Messwerte und die getroffenen Entscheidungen liegen in
work/link-taxonomy-migration/. Noch nicht publiziert;VERSIONsteht weiter auf3.0.0, der Bump gehört nach u5.u0 publiziert als
4.0.0—177c7e956 Dateien, +2.695/-753.
VERSIONauf4.0.0, Migrationsdokumentinstructions/migrations/4.0.0-link-taxonomy.md(assisted,required), Baum sauber.Dieser Commit ist die Baseline für u1–u4.
migrate verify --from 177c7e9vergleicht gegen einen Stand, in dem die Marker-Maschinerie existiert und noch keine Seite angefasst ist — von hier aus misst jede Einheit genau ihre eigene Arbeit.Warum der Bump vor der Korpusarbeit kam statt danach, wie ursprünglich geplant: CIs Version-Gate verweigert eine Stack-Änderung ohne Versionsbewegung, und u0 hat
tools/,types/,instructions/und vier Contracts angefasst. Die Einheiten u1–u4 fassen nurkb/an, brauchen also keinen weiteren Bump — und werden von CI ohnehin überpaths-ignoreausgeschlossen.Stand der Akzeptanzkriterien
tools/—sections.pyundPRE_CONVENTIONS_NAMESexistieren nicht mehrrelated:trägt Label als Enum-Wert;lintprüft gegenoutbound:der Quellcollectionxref addschreibt genau eine Kante; die eingehende Sicht ist gerendert (links show), nicht gespeichertmigrate verifyinstructions/link-taxonomy.mdenthält alle 26 Commonplace-Label plus die neun operativenmigrate statustrenntrequiredvonofferedund blockiert nie aufofferedmigrate statusmeldet, welche instanzeigenen Dateien von den Stamp-Hashes abweichen.templatedocs verifyprüftSTACK_REQUIRED_TYPESversion-parts.md, Grenzübertritt gesetzt, Migrationsdokument vorhandenOffen bleibt allein der Bestand: 480 ungelabelte Kanten über u1–u4, danach u5 (Beförderung der beiden Lint-Findings zu Hard Errors,
migrate done 4.0.0, Workshop schließen).Korpus-Migration abgeschlossen (Abschnitte 2 und 3)
Die Korpus-Hälfte dieses Issues ist durch.
kb_versionsteht auf4.0.0,lint --fail-on-errorunddocs verifysind grün, der Workshopwork/link-taxonomy-migration/ist geschlossen und gelöscht.Umfang: 152 Seiten, ~530 gelabelte Kanten, in fünf Einheiten über mehrere Sitzungen:
kb/entities/systems, tools, technologies — 57 Seiten, 199 Kantenb137359kb/entities/projects, people +kb/comparisons/— 16 Seiten, ~45 Kanten9e2f9bfkb/concepts/— 80 Seiten, ~250 Kantena35c94ekb/sources/— 0 Seiten (siehe unten)migrate done 4.0.0, Workshop-Close3f99d67Endstand
lint: 0unlabelled_edges, 0unauthorised_labels, 0malformed_edges, 0unbalanced_markers, 0broken_links, 0dangling_frontmatter_refs, 0schema_validation_errors. Damit ist Schritt 6 des Migrationsdokuments erfüllt — die beiden Findings können jetzt zu harten Fehlern promoted werden (nicht Teil dieses Laufs, siehe unten).Drei Befunde, die im Entwurf nicht standen
1.
comparisonundsourcehaben gar keinrelated:-Feld. Beide Type-Specs deklarieren nurpage_ref_fields: [entities]bzw.[entities, concepts];xref addverweigert dort. Dieoutbound:-Blöcke inkb/comparisons/COLLECTION.md(compares-with,contrasts,see-also) undkb/sources/COLLECTION.md(is-evidence-for,defined-in,see-also) autorisieren damit Label, die auf diesen Seiten strukturell nicht geschrieben werden können — die Autorisierung läuft ins Leere. Fürkb/sources/war das folgenlos (entities:/concepts:waren beim Ingest überxref link-sourcekorrekt gefüllt,migrate verify --path kb/sourcesmeldet 0 Befunde gegen die Baseline); beikb/comparisons/wurde das Label per Hand in die Prosa geschrieben. Entweder sollten die beiden Type-Specs einrelated:bekommen, oder dieoutbound:-Blöcke dort sollten weg — im jetzigen Zustand behauptet der Contract eine Fähigkeit, die es nicht gibt.2. Dem Katalog fehlt ein Register für Urheberschaft. Kein Label trägt „Person hat X erschaffen" oder „X baut auf der Arbeit von Y auf".
ownsdeckt fortlaufende Verantwortlichkeit ab (so benutzt fürVannevar Bush owns Memex,Rohit Gupta owns Agent Memory,E3DC GmbH owns E3DC), aber der einmalige historische Akt — Karpathy formuliert das LLM Wiki Pattern, Gupta erweitert Karpathys Arbeit — hat in Realization und Lineage nichts, was für eine Person autorisiert wäre: die Register sind concept↔concept oder concept↔entity, nie entity↔entity oder entity↔concept für Autorschaft. Alle diese Kanten stehen jetzt aufsee-also, nach Prüfung jedes einzelnen Registers. Kandidat für eine Katalog-Zeile (originates?authored-by?), falls das wiederkehrt.3.
part-of/compositionverhalten sich in der Praxis wie ein Inversenpaar, sind aber keins. Der Katalog nennt ausdrücklich nurdepends-on/required-byundruns-on/hostsals Paare mit eigener Gegenaussage. Bei Eltern-Kind-Strukturen (Consolidation Tiers und seine vier Ebenen, Implementation Spectrum und seine Level, Multi-Agent Collaboration und seine drei Komponenten) entsteht dadurch regelmäßig die Frage, ob die Gegenseitepart-ofschreiben darf, wenn das Elternteil schoncompositionhat. Regel im Lauf: nein — die zweite Seite bekommtsee-also. Das erzeugt sichtbar mehrsee-also, als der Entwurf wollte; ob das die richtige Auflösung ist, wäre eine bewusste Katalog-Entscheidung wert.Zwei Fehler im Lauf, beide selbst gefunden
lint --fullsunlabelled_edges-Bericht nach dem ersten u3-Durchlauf.Personalization Plane.mdentfernte ich eine inhaltlich eigenständige, mit Fußnote belegte Zeile mit, weil ich sie für ein bloßes Wikilink-Bullet hielt.migrate verifyfing das übercite-refs 2->1— der Marker-Paar- und Zähl-Invariant aus Abschnitt 3 dieses Issues hat also im ersten Ernstfall genau das getan, wofür er gebaut wurde.Dazu eine Selbstkorrektur: die Asymmetrie „
xref addschreibt nur A,xref removeräumt beide Seiten" habe ich in u3 als Erkenntnis notiert — sie steht wörtlich intools/CONTRACT.mdZeilen 43–44. Sie war nachzulesen, nicht zu entdecken; in u1 kostete das mehrere unnötig defensive Entscheidungen (die 37 Restkanten in u5 sind genau diese Vorsicht).Was an diesem Issue offen bleibt
Die Abschnitte 1 und 4 sind unberührt:
obligation: offered, der Stamp-Hash-Abgleich inmigrate status, die Aufteilung vontypes/entlangroot:undSTACK_REQUIRED_TYPES. Ebenso offen die Promotion vonunlabelled_edges/unauthorised_labelszu harten Fehlern — der Korpus erfüllt sie jetzt, der Schritt selbst ist eine eigene Stack-Änderung.torben referenced this issue2026-09-03 01:49:08 +00:00
Changelog: Body auf den Abschlussstand gezogen. Neu: Status-Zeile, Abschnitt 5. Abschluss (4.1.0), alle Kriterien abgehakt, das nachgereichte zwölfte Kriterium aus dem Kommentar vom 2026-09-02 aufgenommen, Abschnitt Ausgelagert mit #43. Korrigiert: die Reihenfolge steht jetzt benannt im Body statt nur im ersten Kommentar; die Inversenpaare sind drei statt zwei; die falsche 1:1-Migrationsabbildung ist durch die Messung ersetzt; die vier Umsetzungskorrekturen aus dem u0-Kommentar stehen im Body statt nur in der Historie. Entfernt: die widerlegte Behauptung,
sections:falle weg undindex rebuildrendere die Eingangssicht.Abschluss
Die letzten drei offenen Punkte sind als
4.1.0publiziert, Commitcfe925a. Damit ist dieses Issue vollständig.Was in diesem Lauf umgesetzt wurde
Die Beförderung der beiden Lint-Findings — aber gebunden statt umgelegt. Der Entwurf sagte "werden hart, nachdem die Migration aufgezeichnet ist", und das wäre als Konstante im Code genau der Weg von
legacy_citation_markersgewesen: in einer späteren Version umgelegt, und jede Instanz, die die Migration noch schuldete, lebte danach mit rotem Lint. Für 4.0.0 wäre das schlimmer gewesen, weilmigrate-corpus.mdeinen Lauf in Einheiten mit je eigenem Publish vorschreibt — einlint --fail-on-error, das dabei fehlschlägt, verweigert genau den Korpus, dessen Fortschritt es misst.Also
hard_error_keys()gegenkb_version: unterhalb 4.0.0 beratend, ab 4.0.0 hart, ohne Stamp-Datei bleibt alles hart (eine frische Instanz startet in der aktuellen Form, statt in sie hineinzumigrieren). Das ist der Punkt, an dem Abschnitt 1 dieses Issues sich auszahlt — das Ledger kann die Frage inzwischen beantworten, also muss keine Datumskonstante sie raten.HARD_ERROR_KEYSbleibt die vollständige Menge,hard_error_keys()liefert die jeweils geltende.Befund 1 — und er war folgenreicher als im Abschlusskommentar notiert. Dass
kb/comparisons/undkb/sources/Label autorisierten, die ihre Type-Specs strukturell nicht schreiben können, blieb nicht folgenlos: die einzige Comparison-Seite des Korpus trugals handgeschriebene Prosa — ohne Marker-Region, ohne Frontmatter-Deckung, für
lintunsichtbar, weilcomparisonkeinrelated:führte. Also ein Identifier zurück im Fließtext, geschrieben in u2, wenige Stunden nach dem Commit, der genau das beendet hatte. Eine leere Autorisierung liest sich als Lizenz; wer sie liest und keinen Träger findet, schreibt das Label in die Prosa.Aufgelöst nach dem, was die beiden Contracts jeweils selbst sagen — asymmetrisch, weil die beiden Fälle es sind:
comparisonrelated:inpage_ref_fieldsund Schemacompares-with-Kante gegen jedes Subjekt ist die eine Aussage, für die die Seite existiert;entities:ist die untypisierte Liste danebenkb/sources/outbound:-Block ersatzlosraw_files:,entities:,concepts:,[^cite-id]) und keine AutorenkantenDazu die Prüfung, die die beiden Hälften künftig zusammenhält:
docs verifymeldet einenoutbound:-Block auf einer Collection, in die kein Typ mitrelated:schreibt, und nennt beide Richtungen der Reparatur. Die Comparison-Seite trägt ihre zwei Kanten jetzt als deklarierte Kanten in einerwikitool:links-Region.Befund 3 —
composition/part-ofist das dritte Inversenpaar. Die u3-Regel ("die Gegenseite bekommtsee-also, weilpart-ofein Spiegel wäre") ist zurückgenommen: der Satz des Elternteils zählt seine Teile auf, der des Kindes benennt das Ganze, zu dem es gehört. Zwei Sätze, nicht einer zweimal. 16see-also-Kanten sind aufpart-ofrelabelt — Consolidation Tiers, Content Quality Control, Hybrid Search, Knowledge Graph, LLM Wiki Pattern, Memory Lifecycle, Multi-Agent Collaboration, Wine GE, farzaa gist und ihre Kinder.Präzisiert dabei, weil es sonst gegen "Richtung wird verfasst, nicht gespiegelt" liefe: ein Inversenpaar macht die Gegenkante nicht zur Pflicht. Es legt fest, welches Label sie trägt, wenn jemand sie schreibt. Zehn
composition-Kanten haben weiterhin keine Gegenkante, und das ist kein Befund — vor allem die sechs Ebenen des Implementation Spectrum, deren Zugehörigkeit zu einem Spektrum eine schwächere Aussage ist als die Teil-Ganzes-Beziehung, diepart-ofbehauptet.Was bewusst nicht umgesetzt wurde
Befund 2, das fehlende Register für Urheberschaft — ausgelagert nach #43,
kind/decision/prio/waiting. Es erweitert den Katalog, statt einen Widerspruch zu beheben, und der Zuschnitt (eigenes Register oder Lineage? ein Label oder zwei? Inversenpaar?) lässt sich an drei Fällen nur raten. Der Korpus ist in der Zwischenzeit konsistent: alle betroffenen Kanten stehen aufsee-also, keine trägt ein falsches Label.Der Versionsteil war eine Abwägung, keine Formsache. Der neue
docs verify-Check hätte eine bestehende 4.0.x-Instanz beim bloßen Kopieren der Maschinerie fehlschlagen lassen, weil ihrekb/sources/COLLECTION.mddenoutbound:-Block noch trägt — nachversion-parts.mdSchritt 1 ein Grenzübertritt. Erwogen und verworfen wurden eine5.0.0mit Pflichtmigration (zwei Zeilen löschen, dafür zahlt jede Instanz einen Major) und die Abstufung des Checks auf einendoctor-WARN (Drop-in, aber die Prüfung wäre schwächer als der Befund, den sie gefunden hat). Stattdessen ist die Ursache mitbeseitigt: die Collection-Contracts dieser Instanz sind angepasst,dist exportleitet dieCOLLECTION.md.templatedaraus ab, also liefert jede neue Distribution die korrigierte Form aus. Für eine bereits bestehende 4.0.x-Instanz bleibt eine Handbewegung, und sie steht namentlich inCHANGES.mdstatt versteckt zu sein.Nebenbefund, eigenes Issue
#44 — die
kb_dir-Fixture der Testsuite repointetconfig.ROOTnicht. Aufgefallen beim Bau der Gate-Tests: ein Test überschrieb das echte.wikitool-kb.jsondes Repos (zurückgeholt, Tests auf eine lokalerooted_kb-Fixture umgestellt). Die stillere Hälfte wiegt schwerer —lint_core._collection_of()löst gegenconfig.KB_DIRstatt gegen den übergebenen Baum auf, weshalbunauthorised_labelsin der Suite bis 4.1.0 faktisch nicht getestet war.Verifiziert
863 Tests,
docs verify,instructions verify,doctor,lint --fail-on-errorunddist exportgrün.migrate verify --from HEAD: 181 Seiten verglichen, 0 hinzugefügt, 0 entfernt, 18 Befunde — sämtlich Label-Wechsel im Frontmatter, keine Änderung an Wikilink- oder Zitatzahlen, keine Marker-Paar-Differenz.Anschluss laut #39: #28, danach #30.