Der Katalog bildet nur Tiefe 1 ab, aber es liegen Seiten auf Tiefe 2 #57
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?
Umgesetzt und publiziert am 2026-09-04, Commit
251e597, Stack-Kandidat4.8.0-beta.2. Aufgeworfen in der Sitzung zur Ordnerorganisation, neben #56 (move, erledigt), #59 (layout:fürconcept) und #58 (incoming/).Was das Problem war
index_build.group_pageslas genau zwei Ebenen unterkb/:Alles unterhalb von
parts[1]kollabierte in die Level-1-Area. Betroffen waren drei reale Seiten:Diese drei Verzeichnisse erschienen im Katalog nirgends; ihre Seiten standen in der Tabelle von
kb/entities/projects/, als lägen sie direkt darin. Ein eigener Shard war für sie strukturell unerreichbar —area.own_shardwird nur für Areas auf Ebene 1 gesetzt.Warum das ein Defekt und keine Wunschfunktion war: Doku und Realität widersprachen sich.
kb/CONTRACT.md§ Collections beschrieb genau eine Ebene und sagte nichts über eine zweite; der Baum hatte trotzdem eine. Der Katalog, der laut AGENTS.md Invariante 1 generiert und verlässlich ist, beschrieb den Baum an dieser Stelle falsch. Einen unterstützten Weg, wie die Verzeichnisse entstanden sein können, gab es nicht — sie waren von Hand angelegt.Ein Detail, das den Befund eingegrenzt hat: die Katalogzeilen sind
[[wikilinks]], keine Pfade (index_build._table). Der Katalog verlinkte also nicht ins Leere, er gruppierte nur falsch. Belegt durch den Publish:kb/index.mdund dieINDEX.md-Shards haben sich beim Hochziehen der drei Seiten nicht geändert.Entscheidung: (b), die drei Verzeichnisse auflösen
Der Alternativentwurf (a) —
group_pagesrekursiv über beliebige Tiefe, Shard-Schwelle pro Ebene — ist verworfen. Die drei Verzeichnisse gruppierten nach Owner (kfchou,vanillaflava,yugasun), eine Achse, die der Katalog an keiner anderen Stelle kennt und die aus keinem Frontmatter-Feld folgt. Jede andere Area im Baum kommt aus einem Subtype (entity_typeüberlayout:); diese drei kamen aus einer Ad-hoc-Entscheidung beim Anlegen. Den Katalog rekursiv zu machen, um eine Achse abzubilden, die nichts erzeugt und nichts prüft, kauft Komplexität für einen Einzelfall.Tiefe 1 ist damit geschriebene Grenze in
kb/CONTRACT.md§ Collections. Falls später eine echte zweite Ebene auftaucht — eine Collection, deren Areas selbst über die Schwelle wachsen — wird (a) neu aufgemacht, dann mit einem Grund, der aus dem Schema kommt.Was gebaut wurde
kb_scan.find_nested_pages(kb_dir, pages)—(title, page, depth)für jede Seite mehr als ein Verzeichnis unterhalb ihrer Collection. Reine Pfadtiefe, bewusst unabhängig von der Typauflösung:find_misplacedüberspringt eine Seite ohne oder mit unauflösbaremtype:, und genau die wäre sonst die verschachtelte Seite, die niemand meldet.Lint-Befund
nested_pages, mit Ist-Pfad und Tiefe — und hart, inHARD_ERROR_KEYS, anders alsmisplaced_pages. Begründung steht im Kommentarblock überHARD_ERROR_KEYS: eine fehlplatzierte Seite katalogisiert noch korrekt von der falschen Stelle aus, eine verschachtelte macht den generierten Katalog selbst falsch. Nicht migrations-gegatet, weil es keine Version gibt, ab der das erst falsch wird.index rebuildwarnt, statt abzulehnen.group_pagesfaltet unverändert wie zuvor; neu ist nur die Sichtbarkeit. Hart abzulehnen hätte auf jeder Fremdinstanz mit handverschachtelter Seite den Katalog blockiert — Handarbeit beim Upgrade, also die Major-Zeile ausversion-parts.mdstatt des geplanten PATCH, und ein Widerspruch zu #56s Entscheidung 2.TypeResolver.get_layoutvalidiertlayout: {dir: …}auf einen einzelnen Pfadabschnitt (kein/, kein\, nicht./.., nicht leer). Ohne das wäre die neue Regel über den einzigen unterstützten Weg brechbar geblieben: ein Type-Spec mitdir: projects/ownerhätte eine zweite Ebene erzeugt, dienewselbst schreibt.moveentfernt ein Verzeichnis, das es geleert hat (--pagewie--reconcile), symmetrisch zummkdir(parents=True)auf der Zielseite. Nicht im ursprünglichen Entwurf, aber ohne das hättenkfchou/,vanillaflava/,yugasun/ihren eigenen Fix überlebt: leer, für git unsichtbar, für einen verzeichnisbasierten Test sichtbar.Verschiebemechanik
Wie vorgesehen über
wikitool move --reconcileaus #56, nicht von Hand. Der Trockenlauf meldete exakt die drei Seiten und keine Kollision; die Stems sind verschieden, sie trafen unterkb/entities/projects/auf 11 bestehende Dateien ohne Überschneidung. Ein belegtes Ziel hättemoveohnehin verweigert statt still überschrieben.Was verifiziert wurde
pytest: 1008/1008 grün lokal (vorher 998; 10 neue Tests übertest_kb_scan.py,test_lint.py,test_index_build.py,test_type_resolver.py,test_page_ops.py).tools/wikitool docs verifyundinstructions verify: grün (51 Kommandos, 20 Instructions, 7 Skills).lint --fail-on-error: Exit 0, wedernested_pagesnochmisplaced_pagesnochduplicate_titles.migrate verify --from HEAD:compared == 182, added == 0, removed == 0, alle drei Seiten alsmovedgemeldet. Git hat sie unabhängig davon als 100%-Renames erkannt.find kb -mindepth 3 -type dliefert nichts.setup-instance-Replay gegen einen frischendist export. Der parallele Release-Lauf 179 lief folgenlos durch und legte korrekt keine Release an —4.8.0-beta.2ist ein Kandidat, neueste Release bleibtv4.7.4.Akzeptanzkriterien
kb/liegt tiefer alskb/<collection>/<area>/. Als bleibende Eigenschaft überlintstatt über pytest — siehe die Umformulierung unten.kb/entities/projects/erreichbar, mit unveränderten Titeln.find_duplicate_title_pathsmeldet keine Kollision (lintExit 0).migrate verify --from HEADbestätigt, dass die drei Seiten dieselben sind:compared == 182, added == 0, removed == 0, alle drei untermoved. Die Titel-Schlüsselung aus #56 stand, der Lauf hat also tatsächlich verglichen statt gezählt.kb/CONTRACT.md§ Collections schreibt Tiefe 1 als Grenze fest, mit der Begründung aus diesem Issue und dem Verweis auf den harten Lint-Befund.group_pagesfaltet eine Seite auf Tiefe 2 nicht mehr still:index rebuildwarnt,lintmeldet sie hart. Gewählt wurde „melden", nicht „ablehnen" — Begründung oben unter Was gebaut wurde.4.8.0-Kandidaten (max-wins gegen #56s MINOR-Bewegung), Heading jetzt4.8.0-beta.2.Umformulierung des ersten Kriteriums. Der Originaltext verlangte „ein Test läuft über den Baum". Gebaut ist stattdessen der harte
nested_pages-Befund, den CI in.gitea/workflows/ci.yml(Schritt Verify the development tree) bei jedem Push alswikitool lint --fail-on-errorgegen den echten Korpus laufen lässt; die Mechanik selbst deckt pytest über Fixtures ab. Grund:dist_cmdschließttools/chemenu/tests/nicht aus, ein pytest überconfig.KB_DIRwäre also in jeder ausgelieferten Instanz ein Korpus-Health-Check und würde dort rot, sobald jemand von Hand verschachtelt. Instanzgesundheit istlint/doctors Aufgabe, nicht die der Stack-Suite. Die geforderte Eigenschaft — dauerhaft geprüft, nicht einmalig aufgeräumt — ist damit erfüllt, an der richtigen Stelle.Was das für die Nachbarn heißt
layout:intypes/concept.mdjedir:einen einzelnen Pfadabschnitt tragen muss —get_layoutweist alles andere jetzt ab.raw/kennt diese Tiefengrenze nicht, dort ist die Tiefe ausdrücklich nicht das Problem.moves Verzeichnisaufräumen eine kleine Nachlieferung bekommen, die in seinem eigenen Paket noch nicht drin war.Body auf den Endstand umgeschrieben. Gegenüber dem Ausgangstext geändert:
group_pages/index rebuild,nested_pageshart statt advisory,layout:-dir-Validierung auf einen Pfadabschnitt,moveräumt geleerte Verzeichnisse ab.config.KB_DIR— Grund im Body (die Suite wird mitdist exportausgeliefert).kb/index.mdund die Shards sich beim Move nicht geändert haben.migrate verify, Mass-Update-Gate mit Freigabe).torben referenced this issue2026-09-08 17:32:39 +00:00