nested_pages: Katalogtiefe 1 durchgesetzt, layout:-dir validiert, move raeumt geleerte Verzeichnisse - die drei #57-Seiten hochgezogen (schliesst #57)
CI / verify (push) Successful in 1m0s
Release / release (push) Successful in 37s

Files changed:
- CHANGES.md
- VERSION
- kb/CONTRACT.md
- kb/entities/projects/kfchou/wiki-skills.md
- kb/entities/projects/llm-wiki-skills.md
- kb/entities/projects/vanillaflava/wiki-skills-vanillaflava.md
- kb/entities/projects/wiki-skills-vanillaflava.md
- kb/entities/projects/wiki-skills.md
- kb/entities/projects/yugasun/llm-wiki-skills.md
- kb/log.md
- tools/CONTRACT.md
- tools/chemenu/commands/index_build.py
- tools/chemenu/commands/page_ops.py
- tools/chemenu/kb_scan.py
- tools/chemenu/lint_core.py
- tools/chemenu/tests/test_index_build.py
- tools/chemenu/tests/test_kb_scan.py
- tools/chemenu/tests/test_lint.py
- tools/chemenu/tests/test_page_ops.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/type_resolver.py
This commit is contained in:
2026-09-04 23:19:30 +02:00
parent 9e414319b8
commit 251e597c63
18 changed files with 331 additions and 10 deletions
+67 -1
View File
@@ -35,13 +35,14 @@ dev-checkout concern - readable here, never shipped as something to parse.
---
## 4.8.0-beta.1 - 2026-09-04 - page move: eine kb-Seite folgt ihrem Subtype ins Verzeichnis, das ihr Type-Spec berechnet
## 4.8.0-beta.2 - 2026-09-04 - kb/CONTRACT.md: Tiefe 1 als Grenze - Katalog liest nur eine Area-Ebene
**Author:** Torben Nehmer
<!-- wikitool:bumps -->
- status/incoming: menschliche Stubs werden ausgearbeitet, nie so umgesetzt
- page move: eine kb-Seite folgt ihrem Subtype ins Verzeichnis, das ihr Type-Spec berechnet
- kb/CONTRACT.md: Tiefe 1 als Grenze - Katalog liest nur eine Area-Ebene
<!-- /wikitool:bumps -->
Das Label `status/incoming` gibt es seit heute in Gitea: der Mensch legt einen
@@ -151,6 +152,71 @@ move`), `tools/CONTRACT.md`, `instructions/page-lifecycle.md`,
verschobene Seite unverändert (Identität ist der Titel, nicht der Ort),
vorwärts reines Überkopieren.
**Katalogtiefe** (#57): `index_build.group_pages` las bislang genau zwei
Pfadsegmente unter `kb/` (`parts[0]` als Collection, `parts[1]` als Area) und
faltete alles darunter still in die Level-1-Area. Real betroffen waren die
drei Seiten aus #56s Befund, `kb/entities/projects/{kfchou,vanillaflava,
yugasun}/*.md` — im generierten Katalog nicht als eigener Ort sichtbar,
sondern als läge jede direkt in `entities/projects/`. `kb/CONTRACT.md` §
Collections beschrieb bis heute nur eine Ebene, ohne eine zweite
auszuschließen; der Baum hatte trotzdem eine, handplatziert, ohne
unterstützten Weg dorthin.
Entscheidung war (b) aus dem Issue: die drei Verzeichnisse auflösen statt den
Katalog rekursiv zu machen. Die Gruppierungsachse dahinter — Owner
(`kfchou`/`vanillaflava`/`yugasun`) — kommt aus keinem Frontmatter-Feld und
aus keinem Type-Spec, sondern aus einer Ad-hoc-Entscheidung beim Anlegen; sie
verdient keine zweite Verzeichnisebene. Tiefe 1 ist jetzt geschriebene Regel
in `kb/CONTRACT.md` § Collections, mit dieser Begründung.
Vier Stücke setzen das um:
- **`kb_scan.find_nested_pages`** liefert `(title, page, depth)` für jede
Seite mehr als ein Verzeichnis unterhalb ihrer Collection — reine
Pfadtiefe, unabhängig davon, ob der Typ auflöst, damit auch eine Seite mit
kaputtem `type:` nicht durchrutscht.
- **`lint`** bekommt den Befund **Nested Pages**, und anders als
`misplaced_pages` **hart**: eine fehlplatzierte Seite katalogisiert noch
korrekt von der falschen Stelle aus, eine verschachtelte macht den
*generierten* Katalog selbst falsch, und es gibt keine Version, ab der das
toleriert würde.
- **`index rebuild`** lehnt eine verschachtelte Seite nicht ab, sondern warnt
(Entscheidung aus der Session: melden statt verweigern, damit ein
Fremdinstanz-Upgrade mit handverschachtelten Seiten nicht hart bricht) —
`group_pages` faltet weiterhin wie zuvor, die Warnung ist die neue
Sichtbarkeit, nicht eine Verhaltensänderung der Faltung selbst.
- **`TypeResolver.get_layout`** validiert `layout: {dir: ...}` jetzt auf
einen einzelnen Pfadabschnitt (kein `/`, kein `\`, kein `.`/`..`, nicht
leer) und schlägt fehl statt eine zweite Ebene über den einzigen
unterstützten Weg — ein Type-Spec — entstehen zu lassen.
Ein fünftes Stück, das das Issue selbst nicht explizit forderte, aber die
`move`-Mechanik aus #56 sonst mit toten Verzeichnissen zurückgelassen hätte:
**`move`** (`--page` wie `--reconcile`) entfernt jetzt ein Verzeichnis, das es
durch den Wegzug seiner letzten Seite geleert hat — symmetrisch zum
`mkdir(parents=True)` auf der Zielseite. Ohne das hätten `kfchou/`,
`vanillaflava/`, `yugasun/` den eigenen Fix überlebt, leer und für git
unsichtbar, aber für einen verzeichnisbasierten Test sichtbar.
Auf dieser Instanz angewendet: `wikitool move --reconcile` hat die drei
Seiten nach `kb/entities/projects/` gezogen und die drei leeren
Owner-Verzeichnisse mitentfernt. `migrate verify --from HEAD` bestätigt
`compared == 182, added == 0, removed == 0`, alle drei als `moved` markiert.
Titelkollision trat wie im Issue erwartet keine auf.
Geändert: `tools/chemenu/kb_scan.py` (`find_nested_pages`),
`tools/chemenu/lint_core.py` (`nested_pages`, `HARD_ERROR_KEYS`),
`tools/chemenu/commands/index_build.py` (Rebuild-Warnung),
`tools/chemenu/type_resolver.py` (`get_layout`-Validierung),
`tools/chemenu/commands/page_ops.py` (`_rmdir_if_emptied`), `tools/CONTRACT.md`,
`kb/CONTRACT.md` § Collections, plus die drei realen Seiten unter
`kb/entities/projects/`. PATCH: reine Codeänderung ohne Schnittstellenwechsel,
gefaltet in den offenen `4.8.0`-Kandidaten (max-wins gegen die MINOR-Bewegung
aus #56); die drei bewegten Seiten sind Korpus dieser Instanz, kein
ausgelieferter Inhalt.
Schließt #57.
---
## 4.7.4 - 2026-09-04 - bootstrap.md nennt den session-id-WARN nach frischem Bootstrap explizit als erwartet