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.
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
---
|
||||
type: types/concept.md
|
||||
concept_type: pattern
|
||||
tags: [wikitool, cli, idempotenz, tooling, datenintegritaet]
|
||||
created: 2026-08-31
|
||||
modified: 2026-08-31
|
||||
related: [wikitool, Self-Healing, Detect-Repair Asymmetry, Green Suite Blind Spot, Write-Once Frontmatter Fields]
|
||||
sources: [Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]
|
||||
confidence: 0.70
|
||||
confidence_base: 0.70
|
||||
provenance: sourced
|
||||
summary: Anforderung, dass zwei Befehle auf derselben Datei in jeder Reihenfolge zusammenpassen und jeder erzeugte Zustand einen Gegenbefehl hat - 2026-08-31 in wikitool zweimal verletzt
|
||||
---
|
||||
# Command Round-Trip Integrity
|
||||
|
||||
**Typ:** Pattern
|
||||
|
||||
## Definition
|
||||
|
||||
Command Round-Trip Integrity ist die Anforderung, dass zwei Befehle, die dieselbe Datei
|
||||
schreiben, in jeder Reihenfolge zusammenpassen und dass ein Befehl, der einen Zustand erzeugt,
|
||||
einen Gegenbefehl hat, der ihn vollständig zurücknimmt. Verletzt ist sie in zwei Formen: die
|
||||
**Reihenfolge entscheidet über den Inhalt** - der zweite Aufruf zerstört, was der erste
|
||||
geschrieben hat -, oder ein Befehl erzeugt einen Zustand, den **kein anderer Befehl mehr
|
||||
erreicht**.
|
||||
|
||||
Beide Formen sind auf Kommandoebene unsichtbar. Jeder einzelne Aufruf gelingt, meldet Erfolg
|
||||
und tut für sich genommen das Richtige; der Schaden entsteht erst aus der Kombination. In einem
|
||||
Stack, dessen Regeln jede Handeditierung ausschließen, ist die zweite Form die schwerere: eine
|
||||
Seite, die kein Befehl mehr reparieren kann, ist eine Sackgasse.
|
||||
|
||||
## Kernpunkte
|
||||
|
||||
- **Der Anlassfall, Form 1 (Reihenfolge):** `split_cite_block()` in [[wikitool]] nahm alles von
|
||||
der Überschrift `## Fußnoten` bis zum Dateiende als Fußnotenblock und behielt daraus nur die
|
||||
Zitatdefinitionszeilen. Weil `xref add` seine Abschnitte ans Dateiende hängt, entschied allein die
|
||||
Reihenfolge von `xref add` und `cite add`, ob eine Seite ihre Querverweise behielt. Betroffen
|
||||
waren `cite add`, `cite sync` und `rename`; 8 Seiten mit 74 Zeilen standen in der gefährdeten
|
||||
Position[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Der Anlassfall, Form 2 (kein Gegenbefehl):** `xref add` schrieb auf einer Source-Seite ein
|
||||
`related:`, das `types/source.md` nicht deklariert, und `strip_frontmatter_ref()` räumte nur
|
||||
deklarierte Felder. `xref remove` konnte den Rest also nicht entfernen - ein Kommando erzeugte
|
||||
einen Zustand, den ein anderes nicht rückgängig machen konnte[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Die Reparatur ordnet die Ausgabe, statt die Aufrufer zu disziplinieren.** Der Fußnotenblock
|
||||
endet seit `1.5.1` an der nächsten Überschrift und wird immer zuletzt gerendert. Damit muss
|
||||
`xref add` sein Anhängen am Dateiende nicht ändern: der Widerspruch ist aufgelöst, nicht
|
||||
umgangen. Eine Regel „erst `xref`, dann `cite`" wäre eine Regel gewesen, an die sich jeder
|
||||
künftige Aufrufer hätte erinnern müssen[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Daraus folgt Selbstheilung.** Weil der Block immer zuletzt ausgegeben wird, bringt die erste
|
||||
Zitatoperation eine bereits verrutschte Seite von selbst wieder in Ordnung. Der Fix repariert
|
||||
nicht nur künftige Aufrufe, sondern den bestehenden Korpus im laufenden Betrieb - siehe
|
||||
[[Self-Healing]][^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Der Beleg ist Byte-Gleichheit, nicht ein grüner Test.** Nach `xref remove` und
|
||||
anschließendem `xref link-source` kam die referenzierende Concept-Seite byteidentisch aus dem
|
||||
Zyklus zurück. Erst das zeigt, dass die beiden Kommandos Inversen sind; ein Test, der nur
|
||||
prüft, dass hinterher wieder eine Referenz dasteht, würde eine umformatierte Seite
|
||||
durchlassen[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Vor dem Schreiben beide Seiten prüfen.** `xref add` validiert seit `1.6.0` beide Seiten,
|
||||
bevor es eine schreibt, damit eine Ablehnung keine halbe Verknüpfung hinterlässt. Eine
|
||||
abgebrochene bidirektionale Operation ist selbst ein Zustand ohne Gegenbefehl[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Die Feldwahl folgt der Collection, nicht einer Tabelle.** `xref link-source` legt ein Ziel
|
||||
aus `kb/entities/` in `entities:` und eines aus `kb/concepts/` in `concepts:` ab. Das
|
||||
Verzeichnis ist der Feldname, also braucht eine neue Collection keine Codeänderung, sondern
|
||||
einen Typ, der das passende Feld deklariert. Eine Typ-zu-Feld-Zuordnung wurde verworfen, weil
|
||||
sie eine zweite Kopie dessen wäre, was die Type-Specs schon sagen[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31].
|
||||
- **Abgrenzung zu [[Detect-Repair Asymmetry]]:** dort meldet ein Check einen Defekt, für den es
|
||||
keinen Reparaturbefehl gibt. Hier meldet niemand etwas - jeder beteiligte Aufruf endet mit
|
||||
Erfolg, und der Defekt zeigt sich erst an dem, was hinterher in der Datei fehlt.
|
||||
|
||||
## Beispiele
|
||||
|
||||
- [[wikitool]] - `cite add`/`xref add` (Gitea-Issue #17, geschlossen mit `1.5.1`) und
|
||||
`xref add`/`xref remove` auf einer Source-Seite (Issue #18, geschlossen mit `1.6.0`)
|
||||
- [[Self-Healing]] - die Eigenschaft, die aus der gewählten Reparatur folgt
|
||||
- [[Write-Once Frontmatter Fields]] - der Endzustand, wenn der Gegenbefehl fehlt, statt nur
|
||||
falsch zu greifen
|
||||
|
||||
## Wann zu verwenden
|
||||
|
||||
- Beim Entwurf eines Befehls, der eine Datei schreibt, die schon ein anderer Befehl schreibt:
|
||||
beide Reihenfolgen durchspielen, nicht nur die geplante.
|
||||
- Bei jedem Befehl, der einen Zustand *erzeugt*: benennen, welcher Befehl ihn wieder entfernt,
|
||||
und den Zyklus einmal vollständig durchlaufen - der Vergleich ist Byte-Gleichheit.
|
||||
- Bei einer Ablehnung, die auf ein anderes Kommando verweist: sie ist eine Behauptung über
|
||||
dessen Fähigkeiten und gehört mit dem Test ausgeliefert, der sie belegt (siehe
|
||||
[[Denylist over Allowlist]]).
|
||||
|
||||
## Wann NICHT zu verwenden
|
||||
|
||||
- Für Befehle, die bewusst nicht umkehrbar sind, weil die Umkehrung eine andere Operation ist:
|
||||
`publish` schreibt Historie, und die Rücknahme eines Commits ist ein eigener Vorgang, keine
|
||||
fehlende Inverse.
|
||||
- Als Argument gegen anhängende Schreibvorgänge überhaupt. Das Problem war nicht das Anhängen
|
||||
am Dateiende, sondern ein Leser, der alles dahinter als seinen Bereich betrachtete.
|
||||
|
||||
## Verwandte Concepts
|
||||
|
||||
- [[Detect-Repair Asymmetry]]
|
||||
- [[Self-Healing]]
|
||||
- [[Green Suite Blind Spot]]
|
||||
|
||||
## Beziehungen
|
||||
|
||||
- **tritt auf in:** [[wikitool]]
|
||||
- **erzeugt:** [[Self-Healing]]
|
||||
- **abgegrenzt gegen:** [[Detect-Repair Asymmetry]]
|
||||
- **wird begünstigt durch:** [[Green Suite Blind Spot]]
|
||||
- **abgegrenzt gegen:** [[Write-Once Frontmatter Fields]]
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
|
||||
- [[wikitool]]
|
||||
- [[Self-Healing]]
|
||||
- [[Detect-Repair Asymmetry]]
|
||||
- [[Green Suite Blind Spot]]
|
||||
- [[Write-Once Frontmatter Fields]]
|
||||
|
||||
## Fußnoten
|
||||
|
||||
[^s-conversation-two-round-trip-defects-found-by-an-ingest-session-2026-08-31]: [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
|
||||
Reference in New Issue
Block a user