Files
chemenu/kb/sources/Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31.md
T
torben 18ae28f918
CI / verify (push) Failing after 32s
Release / release (push) Successful in 38s
Chemenu 2.1.0 - deterministischer Wissenskompiler
Chemenu kompiliert Rohnotizen zu einem verlinkten, quellengebundenen Wiki:
raw/ -> types/ + tools/ -> kb/ -> reports/. Was mechanisch ist, macht
tools/wikitool; was Urteil braucht, macht ein Agent unter Contracts, deren
Grenzen in Code durchgesetzt sind statt im Prompt.

Dieser Commit ist der Startpunkt der oeffentlichen Historie. Die vorherige
Entwicklung fand in einer privaten Instanz statt und ist nicht Teil dieses
Repositorys; ihre Erzaehlung steht vollstaendig in CHANGES.md, das mit 44
Eintraegen von 0.1.0 bis 2.1.0 erhalten geblieben ist.

Der mitgelieferte Korpus ist ein Testbett und eine Demo: 170 Seiten ueber den
Stack selbst - Gates, Lint, Versionierung, Suche, das Wiki-Muster. Er
dokumentiert das Werkzeug mit den eigenen Mitteln des Werkzeugs.

Lizenz: AGPL-3.0 fuer den Stack (tools/, types/), CC-BY-4.0 fuer die Inhalte.
Die Grenze zwischen beiden ist der Dateiplan, den dist export berechnet -
siehe NOTICE.
2026-09-01 16:26:14 +02:00

147 lines
9.6 KiB
Markdown

---
type: types/source.md
source_type: notes
author: Claude Code (claude-opus-5)
raw_files: [raw/notes/Conversation Transcript - Two Round-Trip Defects Found by an Ingest Session 2026-08-31.md]
source_language: en
date: 2026-08-31
tags: [wikitool, cite, xref, footnotes, schema, tests, gitea]
entities: [wikitool, Chemenu, Gitea]
concepts: [Command Round-Trip Integrity, Green Suite Blind Spot, Detect-Repair Asymmetry, Write-Once Frontmatter Fields, Denylist over Allowlist]
summary: 'Sitzung, die zwei Datenintegritaetsdefekte in wikitool findet und behebt: cite add loeschte Inhalt hinter dem Fussnotenblock (1.5.1, #17) und die Ref-Arrays einer Source-Seite waren unerreichbar (1.6.0, #18) - beide unter vollstaendig gruener Testsuite'
---
# Source: Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31
**Autor:** Claude Code (claude-opus-5)
**Datum:** 2026-08-31
**Raw-Dateien:** raw/notes/Conversation Transcript - Two Round-Trip Defects Found by an Ingest Session 2026-08-31.md
**Typ:** Notes
## Zusammenfassung
Das Transkript ist eine zusammenfassende Rekonstruktion der Sitzung, kein wörtliches Protokoll;
die zitierten Befehlsausgaben und die gemessenen Zahlen sind echt. Gegenstand sind zwei
Datenintegritätsdefekte in [[wikitool]], beide am 2026-08-31 gefunden und am selben Tag
behoben. Der erste: `cite add` löschte jeden Inhalt hinter dem Fußnotenblock (Gitea-Issue #17,
Stack `1.5.1`, Commit `bb4123b`). Der zweite: die Referenz-Arrays einer Source-Seite waren nach
dem Anlegen unerreichbar, während `xref add` dort ein undeklariertes `related:` schrieb, das
`xref remove` nicht mehr räumen konnte (Issue #18, `1.6.0`, Commit `ce03749`). Beide waren
`prio/1`.
Beide Befunde stammen aus einem Ingest: ein Subagent meldete, worauf er gestoßen war. Der
Bericht wurde nicht übernommen, sondern am Code nachgestellt, und die Prüfung erweiterte den
Umfang beide Male. Zwischen Befund und Reparatur lagen zwei Issues - was offen ist, gehört in
den Tracker, bevor Code angefasst wird.
Die Verallgemeinerung, die die Sitzung über sich selbst zieht, ist die dauerhaftere Aussage:
beide Defekte lebten unter einer vollständig grünen Testsuite, weil nie ein Test das falsche
Verhalten festgehalten hatte. Eine Suite prüft, wovon sie weiß.
## Kernaussagen
- **Defekt 1, der Mechanismus.** `split_cite_block()` nahm alles von der Überschrift
`## Fußnoten` bis zum Dateiende als Block und behielt daraus nur die Zitatdefinitionszeilen; jeder
Aufrufer setzte die Seite anschließend als `head + gerenderter Block` wieder zusammen. Da
`xref add` seine Abschnitte ans Dateiende hängt, entschied allein die Reihenfolge der beiden
Kommandos, ob eine Seite ihre Querverweise behielt.
- **Der Umfang wurde gemessen, nicht geschätzt:** 8 Seiten mit zusammen 74 Zeilen standen in
der gefährdeten Position, [[Detect-Repair Asymmetry]] mit 14 Zeilen am schlimmsten. Der
laufende zweite Ingest wurde an dieser Stelle angehalten, weil er `cite add` auf Seiten aus
genau dieser Liste aufgerufen hätte.
- **Zwei weitere Befehle waren betroffen, die das Issue nicht genannt hatte.** `rename`
benutzt denselben Codepfad und hätte denselben Inhalt gelöscht. Und eine Fußnotenreferenz, die nur in
einem Abschnitt *hinter* dem Block stand, galt als unreferenziert, worauf
`cite sync` seine Definition als verwaist gelöscht hätte - ein zweiter Verlustpfad mit
derselben Ursache.
- **Der Fix macht die Seite selbstheilend.** Der Block endet jetzt an der nächsten Überschrift
statt am Dateiende, alles dahinter wird auf den Kopf zurückgefaltet, und der gerenderte Block
wird immer zuletzt ausgegeben. Damit bringt die erste Zitatoperation eine verrutschte Seite
von selbst wieder in Ordnung, und `xref add` darf weiter am Dateiende anhängen: der
Widerspruch zwischen beiden Kommandos ist aufgelöst statt umgangen.
- **Loser Text im Block wird gerettet, nicht abgelehnt.** Das dritte Akzeptanzkriterium des
Issues verlangte einen Abbruch. Das wurde mit Begründung abgelehnt: derselbe Codepfad läuft
unter `lint` und `corpus_diff`, wo eine Ausnahme das *Lesen* der Seite verweigern würde,
statt den Befund zu melden.
- **Der Test wurde rot bewiesen, bevor ihm geglaubt wurde.** Statt zu behaupten, der neue Test
hätte den Defekt gefangen, wurde die alte Implementierung rekonstruiert und gegen ihn laufen
gelassen: `ALTER Code -> Beziehungen erhalten: False`, `NEUER Code -> Beziehungen erhalten:
True`.
- **Der Korpus wurde repariert und nachgemessen.** `cite sync --all` normalisierte elf Seiten -
die acht gefährdeten plus drei, die nur neu sortiert werden mussten. Danach: 0 Seiten mit
Inhalt hinter dem Block, bei je Seite unveränderter Zahl an Zitatdefinitionen und Bullets.
Die Zeilendifferenz im Diff kam vom neu umbrochenen `summary:`, nicht von verlorenem Inhalt.
- **Defekt 2, drei Symptome mit einer Ursache.** `xref_link_source` schrieb nur die Zielseiten
und nie die eigenen Arrays der Source-Seite. `types/source.md` deklariert
`page_ref_fields: [entities, concepts]`, das von `xref add` dort geschriebene `related:` war
also undeklariert. Und `strip_frontmatter_ref()` räumte nur deklarierte Felder. Ein Kommando
erzeugte damit einen Zustand, den ein anderes nicht rückgängig machen konnte.
- **Die Feldwahl folgt der Collection, nicht einer Tabelle.** `kb/entities/` bekommt
`entities:`, `kb/concepts/` bekommt `concepts:`; das Verzeichnis *ist* der Feldname. Eine
neue Collection braucht hier deshalb keine Codeänderung, sondern einen Typ, der das passende
Feld deklariert. Eine Typ-zu-Feld-Zuordnung wurde genau deswegen verworfen: sie wäre eine
zweite Kopie dessen, was die Type-Specs bereits sagen.
- **`xref add` prüft beide Seiten, bevor es eine schreibt,** damit eine Ablehnung keine halbe
Verknüpfung hinterlässt; die Meldung nennt die Felder, die der Typ tatsächlich deklariert.
`xref remove` fegt undeklarierte Reste mit Feldnamen aus den Type-Specs und löscht den
Schlüssel ganz, sobald er leer ist - `related: []` würde die Seite weiter an der Validierung
scheitern lassen.
- **Der Beleg, dass die beiden Kommandos Inversen sind:** die referenzierende Concept-Seite kam
byteidentisch aus dem Zyklus zurück, nachdem `xref remove` die Rückreferenz beidseitig
geräumt und `xref link-source` sie exakt wiederhergestellt hatte. Repariert wurde
ausschließlich mit dem Werkzeug, ohne `rm --yes` und ohne Handeditierung von Frontmatter.
- **Die Denylist aus `1.4.0` war richtig, ihr Verweisziel nicht.** Sie lehnte
Seiten-Referenz-Felder mit dem Hinweis ab, `xref add` und `xref remove` seien dafür zuständig -
eine ungeprüfte Behauptung über die Fähigkeiten eines anderen Kommandos, und für genau die
Felder einer Source-Seite falsch. Eine Ablehnung, die auf ein anderes Kommando verweist,
gehört mit einem Test ausgeliefert, der zeigt, dass jenes Kommando den Fall abdeckt.
- **Beide Defekte lebten unter einer vollständig grünen Suite.** 678 Tests waren grün, bevor
die Zitat-Tests geschrieben wurden; 67 Gate-Tests waren grün vor der Zählungsänderung
desselben Tages. In keinem der beiden Fälle hatte je ein Test das falsche Verhalten
festgehalten, und genau so hat es überlebt. Der Befund stützt die Prämisse von Gitea-Issue #8.
- **Ein Bericht aus zweiter Hand wurde nachgestellt statt übernommen.** Die Befunde des
Subagenten wurden am Code nachvollzogen, bevor irgendetwas geändert wurde, und die Prüfung
erweiterte den Umfang zweimal: beim ersten Defekt um `rename` und den `cite sync`-Verlustpfad,
beim zweiten um die Feststellung, dass `xref remove` das undeklarierte Feld gar nicht
erreichen konnte.
- **Beide Befunde wurden als Issues abgelegt, bevor Code angefasst wurde** (#17, #18), nach
`instructions/capture-session.md`: was noch offen ist, gehört in den Tracker und nicht in ein
Transkript oder in jemandes Kopf.
- **Ergebnis:** `1.5.1` als PATCH und `1.6.0` als MINOR, Commits `bb4123b` und `ce03749`, 689
Tests grün in der normalen und in der gehärteten Umgebung (11 neue), 8 Seiten entschärft und
normalisiert, der Schema-Fehler auf `main` repariert, Issues #17 und #18 geschlossen.
## Aufgaben
- [ ] Gitea-Issue #8 - die Prämisse „eine Suite prüft nur, wovon sie weiß" ist mit dieser
Sitzung belegt; das Issue selbst bleibt offen
## Nicht übernommen
- **Die Liste der acht gefährdeten Seiten.** Übernommen sind die Zahl, die Zeilensumme und die
am stärksten betroffene Seite. Die Liste beschreibt einen Zustand, den `cite sync --all` im
selben Lauf beseitigt hat, und wäre ab dem Reparaturcommit falsch.
- **Der Wortlaut der Ablehnungsmeldung von `xref add`.** Übernommen ist die Entwurfsregel
dahinter - beide Seiten prüfen, bevor eine geschrieben wird, und auf das zuständige Kommando
routen -, weil der Wortlaut sich ändern kann und die Regel nicht.
- **Die Einzelheiten der elf neuen Tests.** Übernommen sind die Gesamtzahl 689 und die
Vorgehensweise, den Test gegen die rekonstruierte alte Implementierung rot zu beweisen.
- **Die interne Modul- und Funktionsstruktur** über `split_cite_block()`, `xref_link_source()`
und `strip_frontmatter_ref()` hinaus. Diese drei tragen die Erklärung des Defekts; die
übrigen Aufrufstellen sind Implementierungsdetail und ändern sich.
- **Issues #17 und #18 als eigene Seiten.** Beide sind geschlossen; ihr Ergebnis steht auf
[[wikitool]], [[Command Round-Trip Integrity]] und [[Green Suite Blind Spot]].
## Verwandte Entities
- [[wikitool]]
- [[Chemenu]]
- [[Gitea]]
## Verwandte Concepts
- [[Command Round-Trip Integrity]]
- [[Green Suite Blind Spot]]
- [[Detect-Repair Asymmetry]]
- [[Write-Once Frontmatter Fields]]
- [[Denylist over Allowlist]]