Files
chemenu/kb/sources/transcripts/Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31.md
T
torben b138fd8e64
CI / verify (push) Successful in 53s
Release / release (push) Successful in 35s
move: source_type: Default streichen, unclassified als sichtbares Fach, layout: fuer source (schliesst #66)
Files changed:
- CHANGES.md
- VERSION
- instructions/dev/corpus-policy.md
- instructions/wiki-ingest/SKILL.md
- kb/index.md
- kb/log.md
- kb/sources/COLLECTION.md
- kb/sources/INDEX.md
- kb/sources/Source - AMD Powermanagement CPU.md
- kb/sources/Source - Arch Linux Cheat Sheet.md
- kb/sources/Source - Conversation - AGENTS.md Skill Restructuring Session 2026-08-04.md
- kb/sources/Source - Conversation - Auto Mode and Tool Choice Session 2026-08-31.md
- kb/sources/Source - Conversation - Comma Bug Budget Refund and Lint Report Path Session 2026-08-31.md
- kb/sources/Source - Conversation - ENVIRONMENT.md as an Optional Third Session-Level File Session 2026-08-31.md
- kb/sources/Source - Conversation - Gate Counting and Measured Calibration Session 2026-08-31.md
- kb/sources/Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31.md
- kb/sources/Source - Conversation - Issue Triage Labels and TODO Retirement Session 2026-08-31.md
- kb/sources/Source - Conversation - Nightly Drift-Check Workflow and doctor's Bootstrap Gap Session 2026-08-31.md
- kb/sources/Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31.md
- kb/sources/Source - Conversation - Versioning CI-CD and Content Migration Session 2026-08-30.md
- kb/sources/Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31.md
- kb/sources/Source - Copilot Skill Restructure Instructions.md
- kb/sources/Source - Docker Cheatsheet.md
- kb/sources/Source - Gitea Issue 41 - Issue Management and Label Scheme 2026-09-02.md
- kb/sources/Source - Gitea Issues 62-63 - status-incoming Label Introduction 2026-09-04.md
- kb/sources/Source - LLM Improvements Codex Analysis.md
- kb/sources/Source - LLM Improvements Production Agent Gaps 2026.md
- kb/sources/Source - LLM Improvements Sonnet Analysis.md
- kb/sources/Source - LLM Wiki Pattern.md
- kb/sources/Source - LLM Wiki v2.md
- kb/sources/Source - MCP Read Server Implementation Session 2026-09-02.md
- kb/sources/Source - Private-Instance Merge Correction and Issue 30 Session 2026-09-01.md
- kb/sources/Source - Public Release, Corpus Purge and History Squash Session 2026-09-01.md
- kb/sources/Source - Publish-Remote Gate and Issue Triage Session 2026-09-01.md
- kb/sources/Source - Version Part Nomenclature and Breaking Change Gate Session 2026-09-02.md
- kb/sources/Source - Wine.md
- kb/sources/Source - qmd - GitHub Repository.md
- kb/sources/analyses/Source - Copilot Skill Restructure Instructions.md
- kb/sources/analyses/Source - LLM Improvements Codex Analysis.md
- kb/sources/analyses/Source - LLM Improvements Production Agent Gaps 2026.md
- kb/sources/analyses/Source - LLM Improvements Sonnet Analysis.md
- kb/sources/articles/Source - AMD Powermanagement CPU.md
- kb/sources/articles/Source - LLM Wiki Pattern.md
- kb/sources/articles/Source - LLM Wiki v2.md
- kb/sources/documents/Source - qmd - GitHub Repository.md
- kb/sources/notes/Source - Arch Linux Cheat Sheet.md
- kb/sources/notes/Source - Docker Cheatsheet.md
- kb/sources/notes/Source - Wine.md
- kb/sources/trackers/Source - Gitea Issue 41 - Issue Management and Label Scheme 2026-09-02.md
- kb/sources/trackers/Source - Gitea Issues 62-63 - status-incoming Label Introduction 2026-09-04.md
- kb/sources/transcripts/Source - Conversation - AGENTS.md Skill Restructuring Session 2026-08-04.md
- kb/sources/transcripts/Source - Conversation - Auto Mode and Tool Choice Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Comma Bug Budget Refund and Lint Report Path Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - ENVIRONMENT.md as an Optional Third Session-Level File Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Gate Counting and Measured Calibration Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Issue Triage Labels and TODO Retirement Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Nightly Drift-Check Workflow and doctor's Bootstrap Gap Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Two Round-Trip Defects Found by an Ingest Session 2026-08-31.md
- kb/sources/transcripts/Source - Conversation - Versioning CI-CD and Content Migration Session 2026-08-30.md
- kb/sources/transcripts/Source - Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31.md
- kb/sources/transcripts/Source - MCP Read Server Implementation Session 2026-09-02.md
- kb/sources/transcripts/Source - Private-Instance Merge Correction and Issue 30 Session 2026-09-01.md
- kb/sources/transcripts/Source - Public Release, Corpus Purge and History Squash Session 2026-09-01.md
- kb/sources/transcripts/Source - Publish-Remote Gate and Issue Triage Session 2026-09-01.md
- kb/sources/transcripts/Source - Version Part Nomenclature and Breaking Change Gate Session 2026-09-02.md
- tools/CONTRACT.md
- tools/chemenu/lint_core.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_lint.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_provenance.py
- tools/chemenu/tests/test_touch.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/tests/test_xref.py
- types/source.md
- types/source.schema.yaml
- types/type-spec.md
- work/reclassify-source-types/README.md
- work/reclassify-source-types/plan.md
2026-09-08 20:38:15 +02:00

145 lines
8.9 KiB
Markdown

---
type: types/source.md
source_type: transcript
author: Claude Code (claude-opus-5)
raw_files: [raw/notes/Conversation Transcript - Write-Once Frontmatter Fields and touch --set Session 2026-08-31.md]
source_language: en
date: 2026-08-31
tags: [wikitool, cli, frontmatter, touch, schema, idempotenz, gitea]
entities: [wikitool, Chemenu, Gitea, AGENTS.md]
concepts: [Write-Once Frontmatter Fields, Denylist over Allowlist]
summary: 'Sitzung, die write-once-Frontmatterfelder reparierbar macht: touch bekommt --set/--add/--remove ueber eine Denylist statt einer Allowlist, ein idempotentes --remove und einen bewusst engen Scope (Stack 1.4.0, Gitea-Issue #14)'
---
# Source: Conversation - Write-Once Frontmatter Fields and touch --set Session 2026-08-31
**Autor:** Claude Code (claude-opus-5)
**Datum:** 2026-08-31
**Raw-Dateien:** raw/notes/Conversation Transcript - Write-Once Frontmatter Fields and touch --set Session 2026-08-31.md
**Typ:** Notes
## Zusammenfassung
Das Transkript ist eine zusammenfassende Rekonstruktion der Sitzung, kein wörtliches Protokoll.
Die zitierten Befehlsausgaben sind echt, Torbens drei Entwurfsentscheidungen sind samt der ihm
vorgelegten Optionen festgehalten, die Begründungen des Assistenten sind verdichtet. Es ist
eines von zwei Transkripten dieses Sitzungsabschnitts; das zweite behandelt die Zählregel des
Mass-Update Gate und die gemessene Kalibrierung des Iteration Budget und wird getrennt
eingelesen.
Gegenstand ist Gitea-Issue #14, ausgeliefert als `touch --set/--add/--remove` in Stack-Version
`1.4.0` (Commit `dbe2f73`, 9 Dateien, 674 Tests grün). Der Defekt, den es schließt: ein Feld,
das `new` einmal geschrieben hat, war danach nicht mehr erreichbar. `touch` kannte nur die
Felder `modified`, `summary`, `provenance` und `confidence_base`; Handeditierung ist genau das,
was der Stack verhindern soll; Löschen und Neuanlegen zerreißt jede bestehende Referenz auf die
Seite; und `new` ist nicht idempotent, das Zeitfenster für den richtigen Wert war also genau
einen Befehl breit.
Den bleibenden Wert der Sitzung tragen drei Entscheidungen, die Torben mit ausgewiesenen
Trade-offs vorgelegt wurden: Denylist statt Allowlist für die schreibbaren Felder, Ersetzen
plus `--add`/`--remove` für Listenfelder, und ein bewusst enger Auslieferungsschnitt, der
`raw rename` als Issue #16 abspaltet.
## Kernaussagen
- **Die Vorarbeit lag schon im Code.** `validate_fields()` in `touch.py` validiert **pro Feld**
statt pro Dokument - genau die Form, die ein `--set` braucht. Der Grund steht im Docstring:
eine Validierung über das ganze Dokument würde sich weigern, `modified:` auf einer Seite zu
bumpen, die aus einem unbeteiligten Grund ungültig ist, also auf der Seite, die Wartung am
dringendsten braucht.
- **Entscheidung 1 - Denylist statt Allowlist.** Schreibbar ist alles, was das Schema für den
Seitentyp deklariert, abzüglich einer kurzen begründeten Sperrliste. Das Argument, das den
Ausschlag gab: eine gepflegte Allowlist ist eine zweite Kopie des Schemas, und die Kopie ist
die Seite, die driftet - Invariante 8 aus `AGENTS.md`, angewandt auf eine Konstante. Der
Preis der Allowlist wäre gewesen, dass jedes neue Schema-Feld eine Codeänderung braucht.
- **Gesperrt sind vier Gruppen, jede mit dem Befehl benannt, dem das Feld gehört:** `type:`
ändert Schema *und* Verzeichnis der Seite und gehört nach `page-lifecycle.md`; `confidence:`
ist aus `confidence_base` abgeleitet und nicht autorisiert; `related:`, `sources:`,
`entities:` und `concepts:` gehören `xref`, weil ein blanker Frontmatter-Schreibvorgang die
Gegenrichtung und die Body-Bullets stehen ließe.
- **Entscheidung 2 - Ersetzen plus `--add`/`--remove`.** Reines Ersetzen wäre eine Regel
gewesen, hätte aber verlangt, für ein einzelnes Tag die ganze Liste zu nennen. Der Preis der
gewählten Variante sind drei Optionen statt einer.
- **Die Teilfrage, was `--remove` mit einem nicht vorhandenen Element tut, entschied der
Assistent selbst und wies das aus:** es gelingt und wird gemeldet. Idempotent wie
`xref remove`, weil ein Reparaturbefehl, der sich beim zweiten Lauf verweigert, nicht
skriptbar ist - aber nie stillschweigend, weil ein stiller No-op genauso aussieht wie eine
gelungene Entfernung, und genau so verbirgt sich ein vertippter Elementname.
- **Entscheidung 3 - enger Schnitt.** Nur `touch --set`; die Dateiverschiebung bleibt zweistufig
(`git mv`, dann `touch --set raw_files=…`). Die Alternative, `raw rename` mitzuliefern, hätte
Issue #14 vollständig geschlossen und den Zwischenzustand vermieden, zum Preis von `size/M`:
Rückwärtssuche über alle `raw_files:`-Referenzen, Verhalten bei mehreren Besitzern,
Contract-Zeilen für zwei Befehle. `raw rename` wurde Issue #16 (`prio/2`, `size/S`).
- **Zwei Kommandos, eine Implementierung.** `_coerce_set_value`, `_parse_set_fields` und
`_check_raw_files_exist` wanderten aus `new_page.py` nach `commands/_util.py` und verloren
ihren führenden Unterstrich. Ohne das hätte `touch --set` den Komma-Defekt aus Issue #12 am
ersten Tag geerbt; ein Test deckt genau diesen Fall ab, mit einer Rohdatei, deren Name ein
Komma enthält, referenziert über `\,` und als ein Pfad zurückgelesen.
- **Der Existenzcheck für `raw_files:` gilt auch für `touch`,** identisch zu dem, den `new`
ausführt. Er ist I/O und keine Datenform, also kann kein Schema ihn ausdrücken.
- **Die beiden Ablehnungen sind bewusst unterschiedlich formuliert.** Ein gesperrtes Feld ist
ein Routing-Problem, die Meldung nennt deshalb den zuständigen Befehl. Ein unbekanntes Feld
ist ein Tippfehler oder der falsche Seitentyp, die Meldung listet deshalb auf, welche Felder
die Seite tatsächlich hat - der Nutzwert liegt darin, zu erfahren, dass `tags` gemeint war.
- **Eine Falle im Testaufbau, einmal beseitigt.** `test_touch.py` rief den Typer-Callback direkt
mit vollständiger Argumentliste auf; drei neue Optionen brachen sieben Aufrufstellen mit
`TypeError: 'OptionInfo' object is not iterable`, weil ein direkt aufgerufener Callback für
jedes ausgelassene Argument ein `OptionInfo`-Objekt bekommt. Die Tests laufen jetzt über einen
`_touch(**overrides)`-Helper, der jede Option belegt; die nächste Option kostet eine Zeile
statt sieben.
- **Der Beleg am realen Korpus:** [[Diff-Reviewable Agent Edits]] war Stunden zuvor von einem
Ingest angelegt worden, dessen `--set tags=`-Wert ein Komma am Ende trug, worauf alles hinter
dem Trennzeichen verlorenging. Der Subagent hatte alle drei Auswege korrekt geprüft und
verworfen - `touch` konnte `tags:` nicht setzen, Handeditierung kommt Invariante 1 zu nahe,
`rm` plus `new` hätte die `concepts:`-Referenz der Source-Seite zerrissen. Die Seite behielt
`[agent-workflow]` dauerhaft, wegen eines Kommas. Mit `touch --add` trägt sie jetzt
`[agent-workflow, context-engineering, tooling]`.
- **Der zweite Aufruf desselben `--add` meldete "already up to date; nothing to change",** der
`--remove` eines nicht vorhandenen Elements meldete "not present, nothing removed" und endete
ebenfalls erfolgreich - die zugesagte Idempotenz, an der Kommandozeile gezeigt.
- **Dass dies eine Rate und kein Einzelfall war:** drei Fehlschläge in drei aufeinanderfolgenden
Ingests desselben Tages, an zwei verschiedenen Feldern, von drei verschiedenen Agenten. Einer
davon war ein nachgestelltes Komma.
- **Ergebnis:** `1.4.0` als MINOR (neue Fähigkeit, rückwärtskompatibel), Commit `dbe2f73` über
9 Dateien, 674 Tests grün in der normalen und in der gehärteten Umgebung, Issue #14
geschlossen mit den drei Entscheidungen im Protokoll, Issue #16 eröffnet.
## Aufgaben
- [ ] Gitea-Issue #16 - `raw rename`, das `git mv` und jede referenzierende Source-Seite in
einem Schritt erledigt (`prio/2`, `size/S`)
## Nicht übernommen
- **Die Modul- und Funktionsnamen der Testumbauten** über den `_touch`-Helper hinaus. Der
Umbau selbst ist eine dauerhafte Aussage über die Testschnittstelle, die einzelnen sieben
Aufrufstellen sind es nicht.
- **Der vollständige Wortlaut der beiden Fehlermeldungen.** Übernommen ist die Entwurfsregel
dahinter - Routing-Problem nennt den Befehl, Tippfehler nennt die vorhandenen Felder -, weil
der Wortlaut sich ändern kann und die Regel nicht.
- **Das Schwestertranskript desselben Sitzungsabschnitts** (Zählregel des Mass-Update Gate,
gemessene Kalibrierung des Iteration Budget). Es wird getrennt eingelesen und bekommt eine
eigene Source-Seite; hier stünde es unbelegt.
- **Die Einzelheiten der 674 Tests.** Übernommen sind die Gesamtzahl und die Testfalle, die
sich daran zeigte.
- **Issue #14 als eigene Seite.** Es ist geschlossen, und sein Ergebnis steht auf [[wikitool]],
[[Write-Once Frontmatter Fields]] und [[Detect-Repair Asymmetry]].
## Verwandte Entities
- [[wikitool]]
- [[Chemenu]]
- [[Gitea]]
- [[AGENTS.md]]
## Verwandte Concepts
- [[Denylist over Allowlist]]
- [[Detect-Repair Asymmetry]]
- [[Diff-Reviewable Agent Edits]]
## Beziehungen
## Siehe auch