18ae28f918
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.
125 lines
7.0 KiB
Markdown
125 lines
7.0 KiB
Markdown
---
|
|
type: types/concept.md
|
|
concept_type: problem
|
|
tags: [wikitool, frontmatter, tooling, idempotenz, repair]
|
|
created: 2026-08-31
|
|
modified: 2026-08-31
|
|
related: [wikitool, Denylist over Allowlist, Detect-Repair Asymmetry, Diff-Reviewable Agent Edits, Command Round-Trip Integrity]
|
|
sources: [Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31, Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]
|
|
confidence: 0.70
|
|
confidence_base: 0.70
|
|
provenance: sourced
|
|
summary: Defektklasse, in der ein Feld nur beim Anlegen der Seite schreibbar ist und danach unerreichbar bleibt, weil kein Mutationsbefehl es kennt und new nicht idempotent ist
|
|
---
|
|
# Write-Once Frontmatter Fields
|
|
|
|
**Typ:** Problem
|
|
|
|
## Definition
|
|
|
|
Ein Write-Once-Feld ist ein Frontmatter-Feld, das der Anlegebefehl schreibt und danach kein
|
|
Befehl mehr ändern kann. Es entsteht nicht durch eine Regel, sondern durch eine Lücke: das
|
|
Schema deklariert das Feld, das Gerüst füllt es, und die Mutationsbefehle decken es nicht ab.
|
|
Der Wert, den der erste Aufruf gesetzt hat, ist damit der endgültige.
|
|
|
|
Die drei Auswege, die einem Agenten dann bleiben, schließen sich gegenseitig aus. Handeditierung
|
|
ist das, was der Stack verhindern soll. Die Seite zu löschen und neu anzulegen zerreißt jede
|
|
Referenz, die schon auf sie zeigt - Wikilinks, Fußnoten-Zitate und die Referenz-Arrays
|
|
anderer Seiten hängen am Titel. Und der Anlegebefehl selbst ist nicht idempotent, lässt sich
|
|
also nicht einfach mit korrigierten Werten wiederholen. Das Fenster für den richtigen Wert ist
|
|
genau einen Befehl
|
|
breit[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
|
|
## Kernpunkte
|
|
|
|
- **Die Lücke ist eine Kombination, kein einzelner Defekt.** Erst Schema plus fehlender
|
|
Mutationsbefehl plus nicht-idempotentes `new` plus Referenzbindung an den Titel machen einen
|
|
Tippfehler dauerhaft. Jede dieser Eigenschaften für sich ist harmlos.
|
|
- **Sie trifft die Felder, die keiner Seite und keinem Seitentitel gehören.** `touch` deckte
|
|
die Felder ab, die die Seite selbst beschreiben (`modified`, `summary`, `provenance`,
|
|
`confidence_base`), `xref` die Seiten-Referenz-Arrays. `tags:`, `raw_files:` und `source_url:`
|
|
sind
|
|
keines von beidem[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
- **Der Beleg, dass es eine Rate ist und kein Unfall:** drei Fehlschläge in drei
|
|
aufeinanderfolgenden Ingests desselben Tages, an zwei verschiedenen Feldern, von drei
|
|
verschiedenen Agenten. Einer davon war ein nachgestelltes Komma im `--set
|
|
tags=`-Wert[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
- **Der Fall, an dem es sichtbar wurde:** [[Diff-Reviewable Agent Edits]] behielt nach einem
|
|
solchen Ingest dauerhaft nur `[agent-workflow]`. Der zuständige Agent prüfte alle drei
|
|
Auswege und verwarf jeden mit dem richtigen Grund - genau das Verhalten, das die Regeln
|
|
verlangen, und genau der Punkt, an dem sie ohne Werkzeug in eine Sackgasse
|
|
führen[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
- **Geschlossen in Stack `1.4.0` (Commit `dbe2f73`) durch `touch --set/--add/--remove`:**
|
|
schreibbar ist, was das Schema des Seitentyps deklariert, abzüglich einer kurzen Sperrliste
|
|
(siehe [[Denylist over Allowlist]]). `--add` und `--remove` arbeiten auf einzelnen Elementen
|
|
eines Listenfelds, `--remove` gelingt auch bei einem nicht vorhandenen Element und meldet
|
|
das - idempotent, weil ein Reparaturbefehl, der sich beim zweiten Lauf verweigert, nicht
|
|
skriptbar ist, aber nie still, weil ein stiller No-op wie eine gelungene Entfernung
|
|
aussieht[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
- **Die Klasse kehrte am selben Tag an einer anderen Feldgruppe wieder.** `new source --set
|
|
entities=…` schrieb die Referenz-Arrays einer Source-Seite genau einmal; `xref link-source`
|
|
fasste sie nicht an, `xref add` lehnte sie ab, und `touch` sperrt sie über seine Denylist.
|
|
Damit war eine Source-Seite nach dem Anlegen in ihren eigenen `entities:`/`concepts:`
|
|
unerreichbar - dieselbe Lücke wie bei `tags:`, nur an den Feldern, die eine andere
|
|
Zuständigkeit haben. Geschlossen mit `1.6.0` (Commit `ce03749`, Gitea-Issue #18), indem
|
|
`xref link-source` beide Richtungen schreibt[^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 gibt es nicht einmal zwingend einen Befund - ein falsches
|
|
`tags:` fällt keinem Check auf. Der `raw_files:`-Fall gehört zu beiden: er wird gemeldet
|
|
*und* war nicht reparierbar.
|
|
- **Der Existenzcheck bleibt am Feld, nicht am Schema.** Ein per `touch` geschriebenes
|
|
`raw_files:` wird gegen das Dateisystem geprüft wie beim Anlegen. Das ist I/O und keine
|
|
Datenform, also kann kein Schema es
|
|
ausdrücken[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31].
|
|
|
|
## Beispiele
|
|
|
|
- [[wikitool]] - `tags:` und `raw_files:` waren bis `1.4.0` nur beim Anlegen schreibbar
|
|
(Gitea-Issue #14, geschlossen)
|
|
- [[Diff-Reviewable Agent Edits]] - die Seite, die stundenlang unreparierbar war und den Fall
|
|
belegt
|
|
|
|
## Wann zu verwenden
|
|
|
|
- Beim Ergänzen eines Schema-Felds: prüfen, welcher Befehl es nach dem Anlegen noch ändert.
|
|
Gibt es keinen, ist das Feld write-once ausgeliefert.
|
|
- Bei der Bewertung eines nicht-idempotenten Anlegebefehls: die Frage ist nicht, wie oft er
|
|
falsch aufgerufen wird, sondern was ein einziger falscher Aufruf dauerhaft festschreibt.
|
|
|
|
## Wann NICHT zu verwenden
|
|
|
|
- Für Felder, die absichtlich unveränderlich sind, weil ihre Änderung eine andere Operation
|
|
ist: `type:` ändert Schema und Verzeichnis der Seite und gehört in den Seiten-Lebenszyklus,
|
|
`confidence:` ist abgeleitet und nicht autorisiert. Eine gesperrte Zuständigkeit ist keine
|
|
Lücke.
|
|
- Für generierte Dateien. Dass `kb/index.md` nicht von Hand geschrieben wird, ist Invariante 1
|
|
und kein Defekt.
|
|
|
|
## Verwandte Concepts
|
|
|
|
- [[Detect-Repair Asymmetry]]
|
|
- [[Denylist over Allowlist]]
|
|
|
|
## Beziehungen
|
|
|
|
- **trat auf in:** [[wikitool]]
|
|
- **gelöst mit:** [[Denylist over Allowlist]]
|
|
- **abgegrenzt gegen:** [[Detect-Repair Asymmetry]]
|
|
- **belegt durch:** [[Diff-Reviewable Agent Edits]]
|
|
- **abgegrenzt gegen:** [[Command Round-Trip Integrity]]
|
|
|
|
## Siehe auch
|
|
|
|
- [[wikitool]]
|
|
- [[Denylist over Allowlist]]
|
|
- [[Detect-Repair Asymmetry]]
|
|
- [[Diff-Reviewable Agent Edits]]
|
|
- [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
|
|
- [[Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31]]
|
|
- [[Command Round-Trip Integrity]]
|
|
|
|
## Fußnoten
|
|
|
|
[^s-conversation-write-once-frontmatter-fields-and-touch-set-session-2026-08-31]: [[Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31]]
|
|
[^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]]
|