raw accept: Datums-Shard statt Typverzeichnis, plus fidelity/authority am Drop-Punkt - Paket B #67

Closed
opened 2026-09-08 17:31:49 +00:00 by torben · 5 comments
Owner

Aus der Architekturdiskussion vom 2026-09-08. Paket B von vier: A ist #66, C ist #68, D ist #69.

Erledigt und geschlossen am 2026-09-09. Drei Publishes, ein Kandidat (4.8.0-beta.8):

# Was Commit
1/3 Code, Verträge, Instruction f4353cc (+ Doku-Nachzug d9af88f)
2/3 Backfill über die 29 Bestands-Source-Seiten 00220f8
3/3 Belegzeile im Changelog, Workshop geschlossen 46dfee0

Der Befund, aus dem das Paket entstand

raw/s Unterverzeichnisse trugen keinen Vertrag. raw/CONTRACT.md enthielt keine einzige Klausel, die pro Unterverzeichnis unterschiedlich galt — Unveränderlichkeit, Untrusted-Content-Regel, Ganz-oder-gar-nicht-Ersetzung, Coverage-Erwartung waren universell. Die vier Ordner (articles/, documents/, notes/, assets/) trugen einen Namen, keine Regel, und keine der drei Gegenleistungen, die einen Verzeichnis-Split rechtfertigen, war eingelöst: raw/ wird nie durchgeblättert (Zugriff läuft über raw_files:, sources trace, sources coverage; die browsbare Fläche ist das generierte kb/sources/INDEX.md), es gab null verzeichnis-lokale Konventionen, und alle vier verrotteten gleich schnell (nämlich gar nicht).

Dem stand eine reale Kosten gegenüber: der Mensch traf beim Ablegen in incoming/<typ>/ eine Routing-Entscheidung, deren einzige Wirkung war, danach von Hand nach source_type abgeschrieben zu werden. Genau darüber entstand der in #66 korrigierte Bias — raw/notes/ hielt laut altem Contract-Text „Gesprächsprotokolle", und von den 25 Dateien dort waren 16 Transkripte, 4 LLM-Analysen, 2 Tracker-Exporte und 3 tatsächliche Notizen. Das Sammelbecken entstand im Raw-Layer und wurde nach kb/ durchgereicht.

Der Drop-Punkt erhob das Einzige, was später fehlt. Zwei unabhängige Achsen, die gegenläufig laufen: fidelity (wie treu ist die Erfassung) und authority (was darf das Material über seinen Gegenstand behaupten). Ein Chat-Transkript ist verbatim+reporting, eine LLM-Analyse über denselben Gegenstand secondhand+opinion; Systemdoku und Webartikel sind beide published, aber normative gegen reporting. Beide Achsen bestehen den Worked-case-Test über vier heterogene Domänen, source_type besteht ihn nicht — deshalb sind diese zwei Stack-Vokabular und source_type bleibt Instanzsache (#68):

Domäne normative reporting opinion
Privat-Projekte Systemdoku, Spec Session-Transkript LLM-Analyse
Verein und Verband Satzung, Spielordnung Sitzungsprotokoll, Spielbericht Trainermeinung, Forum
Produktentwicklung Spec, Vertrag Meeting-Protokoll Marktstudie
RPG-Gamemaster Regelwerk Session-Log Forendiskussion zur Regelauslegung

Die vier Entscheidungen (Operator, 2026-09-08)

Alle vier wurden vor der Umsetzung getroffen, alle vier wie empfohlen — die Vorbereitungssitzung hatte sie als offen markiert, weil der ursprüngliche Body sie stillschweigend übersprungen hatte.

3a — Wer trägt die zwei Werte von raw accept bis new source? Übergabe per Meldung. Der Body hatte vorausgesetzt, dass raw accept die Felder schreibt; das kann es ohne --page nicht, weil die Source-Seite erst in wiki-ingest Schritt 6 entsteht. Umgesetzt: mit --page schreibt es direkt auf die Zielseite (fill-once-geprüft), ohne --page druckt es die fertige new source --set fidelity=… --set authority=…-Folgezeile, und new source verweigert seinerseits ohne beide Werte. Verworfen: ein Handoff-Datensatz (neue maschinengelesene Datei mit Form, Lebensdauer und Aufräumregel für zwei Strings) und „Pflicht nur bei new source" (verfehlt den Drop-Punkt, weil dann erst gefragt würde, nachdem der Agent die Quelle gelesen hat und plausibel raten kann).

3b — UNSETTABLE gegen den Backfill. Fill-once statt Denylist. Der Body verlangte beide auf touch.pys Denylist und einen Backfill über den Bestand; das schließt sich aus, weil migrate-corpus.md Frontmatter ausdrücklich über touch schreibt und Invariante 1 die Handkorrektur verbietet — mit Denylist gäbe es keinen erlaubten Schreibweg. Umgesetzt: touch --set schreibt ein Capture-Feld nur, solange es fehlt, und verweigert, sobald ein abweichender Wert steht. Verworfen: ein Sonderpfad nur für diese Migration, der genau einmal benutzt und danach dauerhaft mitgeschleppt worden wäre.

3c — Wo steht die Feldliste? Im Type-Spec. types/source.md deklariert capture_fields: [fidelity, authority], TypeResolver.get_capture_fields liest sie, drei Kommandos nutzen sie — statt dreifacher Hardcodierung (Invariante 8).

5a — Die Schwellentabelle und wem sie gehört. Stackseitig, in kb/CONTRACT.md. „Keine Formel" heißt nicht „keine Schwelle" — ohne eine feuert der Befund nie. Die Felder sind Stack-Vokabular, die Schwelle ist beratend, und eine Instanz, die sie anders will, ignoriert einen Hinweis statt eine Regel zu brechen. Verworfen: die Werte aus kb/CONVENTIONS.md lesen (hätte ein neues maschinengelesenes Format plus docs verify-Check gekostet, und die Felder gehören nicht der Instanz).

Versionsteil — MINOR. Drei Bedingungen, alle geprüft und im Changelog benannt: raw accept toleriert weiterhin ein incoming/<irgendwas>/; fidelity/authority gehen nicht in required: (sonst grenzüberschreitend nach version-parts.md § Katalog, „A type-spec's required fields"); die zwei neuen Pflichtflags sind dieselbe Einstufung, die #66s new source-Verweigerung im selben Kandidaten bekam.

Was gebaut wurde

Datums-Shard. raw accept schreibt nach raw/YYYY/MM/<stem> bzw. raw/YYYY/MM/<stem>/ für Bündel, berechnet aus dem Annahmedatum. raw_files: ist ein Identifier (Invariante 2), ein Shard darf also nie rebalancieren — damit fällt „nach Anzahl" aus, und zulässig bleibt nur eine reine Funktion von etwas Unveränderlichem. Das Accept-Datum ist zusätzlich append-only und hält als einziges fest, wann der Korpus etwas gelernt hat. incoming/ ist flach; ein Unterverzeichnis wird toleriert und ignoriert statt inspiziert.

Bündelort beim Hineinwachsen einer Bestandsdatei: am Elternverzeichnis der bestehenden Datei, nicht im heutigen Shard — ein Bündel aus altem und neuem Erfassungsdatum hätte keine eindeutig richtige Adresse.

Altbestand unbewegt. raw/s Layout war nirgends versioniert (.wikitool-kb.json beschreibt die kb/-Form, corpus_diff.py vergleicht raw_files als Wert), also gab es keine „zwei Korpusformen" zu versöhnen. Die vier alten Verzeichnisse bleiben gültige Pfade und --replaces-Ziele. Die Stem-Eindeutigkeit aus #64 gilt jetzt global über raw/, strukturell unterschieden (4-stelliges Jahr) statt über eine hartkodierte Liste alter Typnamen.

Capture-Felder. Im Schema ohne default: und nicht in required:; Pflicht im Werkzeug. unknown ist backfill-only — weder raw accept noch new source dürfen es schreiben, nur touch. raw accept --replaces ist der einzige Weg, einen bereits gesetzten Wert zu überschreiben, weil eine korrigierte Erfassung eine neue Edition der Quelle ist und keine Bearbeitung der Seite.

Beratender lint-Befund confidence_exceeds_source_standing, nicht in HARD_ERROR_KEYS, mit stackseitiger Obergrenzentabelle (Minimum aus beiden Spalten: reporting 0.8, opinion 0.6, secondhand/nontextual 0.7; normative/verbatim/published/unknown ohne Obergrenze). Keine Formel, weil confidence bereits aus confidence_base abgeleitet wird und eine zweite Ableitung zwei widersprechende Antworten auf dieselbe Frage ergäbe — und weil Autorität eine Obergrenze ist, unter der eine Seite durch unabhängige Prüfung liegen darf, kein Determinant.

Aufgeräumt. dist_cmd.RAW_SUBDIRS, docs_verify.check_raw_subdirs/documented_raw_subdirs/RAW_DIR_CELL_RE, die Routing-Tabelle in raw/CONTRACT.md, die Ignore-Kanarie (incoming/documents/probe.pdfincoming/probe.pdf), die docs verify-Zeile in tools/CONTRACT.md, der .gitignore-Kommentarblock, instructions/bootstrap.md. dist export seedet jetzt raw/.gitkeep + incoming/.gitkeep statt acht Typ-Verzeichnisse. Menschendoku nachgezogen: README.md (Verzeichnisbaum, Ingest-Ablauf, Beispiel).

Der Backfill (Publish 2/3)

29 Seiten, nicht 31. Die 31 waren eine Fehlzählung in der Vorbereitungssitzung — find kb/sources -name '*.md' zählt INDEX.md und COLLECTION.md mit. 29 deckt sich mit #66s Changelog und den 29 Raw-Dateien.

Der Lauf hielt eine engere Regel als der laufende Betrieb, weil ein nachgetragener Wert erschlossen ist und nicht erhoben: ein echter Wert nur dort, wo die Art des Artefakts ihn aus dem Material selbst festlegt, sonst unknown.

Kombination n Warum
verbatim + reporting 18 16 Gesprächstranskripte, 2 Tracker-Exporte („Wörtliche Kopie des Issue-Threads" laut Rohdatei); beide Protokoll, nicht Festlegung
secondhand + opinion 3 LLM-Analysen; eine davon nennt sich im Kopf selbst „Aspekt aus einer externen Analyse"
published + reporting 2 heise-Meldung, LLM-Wiki-v2-Blogpost („was wir beim Betrieb gelernt haben")
published + normative 1 Karpathys Idea-File — das definierende Dokument seines eigenen Gegenstands
verbatim + normative 1 qmd-README; die Rohdatei deklariert ihre Treue selbst
unknown + normative 1 Anweisungsdokument: Direktive des Repo-Eigners, aber weder Mitschnitt noch Veröffentlichung noch Wiedergabe
unknown + reporting 3 eigene Cheat Sheets; der Operator ist für Arch, Docker und Wine nicht zuständig

fidelity: unknown auf 4 von 29, authority: unknown auf 0. Die Asymmetrie ist das Ergebnis, nicht ein Mangel: die Zuständigkeitsfrage war überall aus dem Material beantwortbar, die Erfassungstreue nicht — der Enum hat keinen Wert für ein originär geschriebenes Artefakt. Genau die Grenze, die unknown markieren soll.

Der Fund, den der neue Befund produziert hat

Nach dem Backfill melden 67 von 152 Seiten mit confidence_base mehr Konfidenz, als ihre Quellenlage trägt — 47 gegen die 0.8-Grenze (reporting), 20 gegen die 0.6-Grenze (opinion); betroffene Werte 21× 0.95, 19× 0.90, 9× 0.85, 15× 0.80.

Das ist kein Fehlalarm und war auch nicht in diesem Paket zu beheben. Der Korpus ist zu gut der Hälfte aus Gesprächstranskripten kompiliert, und die Rubrik in kb/CONVENTIONS.md lässt Quellenzahl (+0.2 je Quelle, max +0.6) und Aktualität (+0.2) allein bis 0.95 laufen, während der Autoritätsterm (+0.1) der kleinste Summand ist. Ob daraus folgt, dass 67 Seiten überbewertet sind oder dass die 0.8-Grenze für einen selbstdokumentierenden Korpus zu eng ist, ist eine Entscheidung — sie liegt als Messung am Stub #60, der genau diesen Verdacht ohne Zahlen aufgeschrieben hatte. #60 bleibt status/incoming und wurde nicht ausgearbeitet.

Die Transkripte wurden ausdrücklich nicht auf normative hochgestuft, nur damit der Report leiser wird — das wäre Tuning der Daten auf den Check.

Verifiziert

  • 1076 pytest, docs verify, instructions verify grün.
  • migrate verify --from HEAD --path kb/sources: 29 verglichen, 0 added/removed/moved, 0 findings — keine Wikilink-, Zitat-, Fußnoten- oder H1-Zahl angefasst.
  • lint --fail-on-error Exit 0, keine harten Fehler; sources coverage 0 unbeanspruchte Dateien, 0 gebrochene Referenzen, 0 Legacy-Seiten.
  • CI-Runs 152/153/154/155 grün, darunter der setup-instance-Replay gegen einen frischen dist export („The distribution works as a fresh instance") und der nächtliche Drift-Check. Run 156 (46dfee0, reine Prosa) lief beim Schließen noch.
  • Manueller End-to-End-Smoke-Test gegen einen isolierten CHEMENU_ROOT: Promotion nach raw/2026/09/, gedruckte Folgezeile, new source, touch-Verweigerung.

Akzeptanzkriterien

  • raw accept schreibt nach raw/YYYY/MM/<stem>; incoming/ flach gelesen, Unterverzeichnis ignoriert statt verweigert.
  • Stem-Eindeutigkeit (#64) global über raw/; Test mit gleichem Stem in zwei Shards.
  • Bündel aus einer Bestandsdatei entsteht am Elternverzeichnis dieser Datei; Test mit einer Datei unter raw/notes/.
  • Kein Bestandsfile in raw/ bewegt; sources coverage weiterhin null unbeanspruchte Dateien.
  • fidelity/authority im Schema, ohne default:, nicht in required:; raw accept und new source verweigern ohne beide, mit Test.
  • raw accept --fidelity unknown und new source --set fidelity=unknown verweigert; nur touch schreibt unknown, mit Test.
  • Capture-Feld per touch --set schreibbar solange es fehlt, verweigert sobald es steht — Test für beide Richtungen.
  • raw accept ohne --page druckt die fertige new source-Folgezeile mit beiden Werten.
  • types/source.md deklariert capture_fields:; raw_cmd.py/new_page.py/touch.py lesen sie vom Type-Resolver.
  • Alle 29 (nicht 31) Source-Seiten tragen beide Felder; 4 tragen fidelity: unknown, und das steht im Changelog.
  • lint meldet den Befund beratend, Schwellentabelle in kb/CONTRACT.md; 67 Fälle im Korpus belegen ihn.
  • dist_cmd.RAW_SUBDIRS, check_raw_subdirs, Routing-Tabelle und Ignore-Kanarie entfernt bzw. nachgezogen; docs verify grün.
  • raw/CONTRACT.md beschreibt Shard, Capture-Felder und Verweigerungsregel; tools/CONTRACT.md nennt den entfallenen Check nicht mehr.
  • Ingest-Skill hat den Dialogschritt für unklare Achsen, in Schritt 1 und Schritt 6.
  • Changelog benennt Versionsteil und alle drei MINOR-Bedingungen.

Was daraus offen weiterläuft

  • #60 (status/incoming) trägt jetzt die Messung zur Konfidenz-Kalibrierung als Notiz. Nicht ausgearbeitet, nicht triagiert — bewusst.
  • docs/ wurde auf Veralterung geprüft und ist aktuell: pipeline-rationale.mds incoming/-Absatz beschreibt die Vertrauensgrenze (Promotion nach raw/), die unverändert gilt; ownership-and-templates.mds Eigentümerlinie ist genau die, nach der die Schwellentabelle stackseitig und die Rubrik instanzseitig liegt.
  • Der Workshop work/backfill-capture-fields/ ist geschlossen und gelöscht; seine dauerhaften Schlüsse stehen in den 29 Seiten selbst und im Changelog-Eintrag.
Aus der Architekturdiskussion vom 2026-09-08. **Paket B** von vier: A ist #66, C ist #68, D ist #69. **Erledigt und geschlossen am 2026-09-09.** Drei Publishes, ein Kandidat (`4.8.0-beta.8`): | # | Was | Commit | |---|---|---| | 1/3 | Code, Verträge, Instruction | `f4353cc` (+ Doku-Nachzug `d9af88f`) | | 2/3 | Backfill über die 29 Bestands-Source-Seiten | `00220f8` | | 3/3 | Belegzeile im Changelog, Workshop geschlossen | `46dfee0` | ## Der Befund, aus dem das Paket entstand **`raw/`s Unterverzeichnisse trugen keinen Vertrag.** `raw/CONTRACT.md` enthielt keine einzige Klausel, die pro Unterverzeichnis unterschiedlich galt — Unveränderlichkeit, Untrusted-Content-Regel, Ganz-oder-gar-nicht-Ersetzung, Coverage-Erwartung waren universell. Die vier Ordner (`articles/`, `documents/`, `notes/`, `assets/`) trugen einen Namen, keine Regel, und keine der drei Gegenleistungen, die einen Verzeichnis-Split rechtfertigen, war eingelöst: `raw/` wird nie durchgeblättert (Zugriff läuft über `raw_files:`, `sources trace`, `sources coverage`; die browsbare Fläche ist das generierte `kb/sources/INDEX.md`), es gab null verzeichnis-lokale Konventionen, und alle vier verrotteten gleich schnell (nämlich gar nicht). Dem stand eine reale Kosten gegenüber: der Mensch traf beim Ablegen in `incoming/<typ>/` eine Routing-Entscheidung, deren einzige Wirkung war, danach von Hand nach `source_type` abgeschrieben zu werden. Genau darüber entstand der in #66 korrigierte Bias — `raw/notes/` hielt laut altem Contract-Text „Gesprächsprotokolle", und von den 25 Dateien dort waren 16 Transkripte, 4 LLM-Analysen, 2 Tracker-Exporte und 3 tatsächliche Notizen. Das Sammelbecken entstand im Raw-Layer und wurde nach `kb/` durchgereicht. **Der Drop-Punkt erhob das Einzige, was später fehlt.** Zwei unabhängige Achsen, die gegenläufig laufen: `fidelity` (wie treu ist die *Erfassung*) und `authority` (was darf das Material über seinen *Gegenstand* behaupten). Ein Chat-Transkript ist `verbatim`+`reporting`, eine LLM-Analyse über denselben Gegenstand `secondhand`+`opinion`; Systemdoku und Webartikel sind beide `published`, aber `normative` gegen `reporting`. Beide Achsen bestehen den Worked-case-Test über vier heterogene Domänen, `source_type` besteht ihn nicht — deshalb sind diese zwei Stack-Vokabular und `source_type` bleibt Instanzsache (#68): | Domäne | normative | reporting | opinion | |---|---|---|---| | Privat-Projekte | Systemdoku, Spec | Session-Transkript | LLM-Analyse | | Verein und Verband | Satzung, Spielordnung | Sitzungsprotokoll, Spielbericht | Trainermeinung, Forum | | Produktentwicklung | Spec, Vertrag | Meeting-Protokoll | Marktstudie | | RPG-Gamemaster | Regelwerk | Session-Log | Forendiskussion zur Regelauslegung | ## Die vier Entscheidungen (Operator, 2026-09-08) Alle vier wurden vor der Umsetzung getroffen, alle vier wie empfohlen — die Vorbereitungssitzung hatte sie als offen markiert, weil der ursprüngliche Body sie stillschweigend übersprungen hatte. **3a — Wer trägt die zwei Werte von `raw accept` bis `new source`?** *Übergabe per Meldung.* Der Body hatte vorausgesetzt, dass `raw accept` die Felder schreibt; das kann es ohne `--page` nicht, weil die Source-Seite erst in `wiki-ingest` Schritt 6 entsteht. Umgesetzt: mit `--page` schreibt es direkt auf die Zielseite (fill-once-geprüft), ohne `--page` druckt es die fertige `new source --set fidelity=… --set authority=…`-Folgezeile, und `new source` verweigert seinerseits ohne beide Werte. Verworfen: ein Handoff-Datensatz (neue maschinengelesene Datei mit Form, Lebensdauer und Aufräumregel für zwei Strings) und „Pflicht nur bei `new source`" (verfehlt den Drop-Punkt, weil dann erst gefragt würde, nachdem der Agent die Quelle gelesen hat und plausibel raten kann). **3b — `UNSETTABLE` gegen den Backfill.** *Fill-once statt Denylist.* Der Body verlangte beide auf `touch.py`s Denylist **und** einen Backfill über den Bestand; das schließt sich aus, weil `migrate-corpus.md` Frontmatter ausdrücklich über `touch` schreibt und Invariante 1 die Handkorrektur verbietet — mit Denylist gäbe es keinen erlaubten Schreibweg. Umgesetzt: `touch --set` schreibt ein Capture-Feld nur, solange es fehlt, und verweigert, sobald ein abweichender Wert steht. Verworfen: ein Sonderpfad nur für diese Migration, der genau einmal benutzt und danach dauerhaft mitgeschleppt worden wäre. **3c — Wo steht die Feldliste?** *Im Type-Spec.* `types/source.md` deklariert `capture_fields: [fidelity, authority]`, `TypeResolver.get_capture_fields` liest sie, drei Kommandos nutzen sie — statt dreifacher Hardcodierung (Invariante 8). **5a — Die Schwellentabelle und wem sie gehört.** *Stackseitig, in `kb/CONTRACT.md`.* „Keine Formel" heißt nicht „keine Schwelle" — ohne eine feuert der Befund nie. Die Felder sind Stack-Vokabular, die Schwelle ist beratend, und eine Instanz, die sie anders will, ignoriert einen Hinweis statt eine Regel zu brechen. Verworfen: die Werte aus `kb/CONVENTIONS.md` lesen (hätte ein neues maschinengelesenes Format plus `docs verify`-Check gekostet, und die Felder gehören nicht der Instanz). **Versionsteil — MINOR.** Drei Bedingungen, alle geprüft und im Changelog benannt: `raw accept` toleriert weiterhin ein `incoming/<irgendwas>/`; `fidelity`/`authority` gehen **nicht** in `required:` (sonst grenzüberschreitend nach `version-parts.md` § Katalog, „A type-spec's required fields"); die zwei neuen Pflichtflags sind dieselbe Einstufung, die #66s `new source`-Verweigerung im selben Kandidaten bekam. ## Was gebaut wurde **Datums-Shard.** `raw accept` schreibt nach `raw/YYYY/MM/<stem>` bzw. `raw/YYYY/MM/<stem>/` für Bündel, berechnet aus dem Annahmedatum. `raw_files:` ist ein Identifier (Invariante 2), ein Shard darf also nie rebalancieren — damit fällt „nach Anzahl" aus, und zulässig bleibt nur eine reine Funktion von etwas Unveränderlichem. Das Accept-Datum ist zusätzlich append-only und hält als einziges fest, wann der Korpus etwas gelernt hat. `incoming/` ist flach; ein Unterverzeichnis wird toleriert und ignoriert statt inspiziert. **Bündelort beim Hineinwachsen einer Bestandsdatei:** am Elternverzeichnis der bestehenden Datei, nicht im heutigen Shard — ein Bündel aus altem und neuem Erfassungsdatum hätte keine eindeutig richtige Adresse. **Altbestand unbewegt.** `raw/`s Layout war nirgends versioniert (`.wikitool-kb.json` beschreibt die `kb/`-Form, `corpus_diff.py` vergleicht `raw_files` als Wert), also gab es keine „zwei Korpusformen" zu versöhnen. Die vier alten Verzeichnisse bleiben gültige Pfade und `--replaces`-Ziele. Die Stem-Eindeutigkeit aus #64 gilt jetzt global über `raw/`, strukturell unterschieden (4-stelliges Jahr) statt über eine hartkodierte Liste alter Typnamen. **Capture-Felder.** Im Schema ohne `default:` und nicht in `required:`; Pflicht im Werkzeug. `unknown` ist backfill-only — weder `raw accept` noch `new source` dürfen es schreiben, nur `touch`. `raw accept --replaces` ist der einzige Weg, einen bereits gesetzten Wert zu überschreiben, weil eine korrigierte Erfassung eine neue Edition der Quelle ist und keine Bearbeitung der Seite. **Beratender `lint`-Befund** `confidence_exceeds_source_standing`, nicht in `HARD_ERROR_KEYS`, mit stackseitiger Obergrenzentabelle (Minimum aus beiden Spalten: `reporting` 0.8, `opinion` 0.6, `secondhand`/`nontextual` 0.7; `normative`/`verbatim`/`published`/`unknown` ohne Obergrenze). Keine Formel, weil `confidence` bereits aus `confidence_base` abgeleitet wird und eine zweite Ableitung zwei widersprechende Antworten auf dieselbe Frage ergäbe — und weil Autorität eine Obergrenze ist, unter der eine Seite durch unabhängige Prüfung liegen darf, kein Determinant. **Aufgeräumt.** `dist_cmd.RAW_SUBDIRS`, `docs_verify.check_raw_subdirs`/`documented_raw_subdirs`/`RAW_DIR_CELL_RE`, die Routing-Tabelle in `raw/CONTRACT.md`, die Ignore-Kanarie (`incoming/documents/probe.pdf` → `incoming/probe.pdf`), die `docs verify`-Zeile in `tools/CONTRACT.md`, der `.gitignore`-Kommentarblock, `instructions/bootstrap.md`. `dist export` seedet jetzt `raw/.gitkeep` + `incoming/.gitkeep` statt acht Typ-Verzeichnisse. Menschendoku nachgezogen: `README.md` (Verzeichnisbaum, Ingest-Ablauf, Beispiel). ## Der Backfill (Publish 2/3) **29 Seiten, nicht 31.** Die 31 waren eine Fehlzählung in der Vorbereitungssitzung — `find kb/sources -name '*.md'` zählt `INDEX.md` und `COLLECTION.md` mit. 29 deckt sich mit #66s Changelog und den 29 Raw-Dateien. Der Lauf hielt eine engere Regel als der laufende Betrieb, weil ein nachgetragener Wert *erschlossen* ist und nicht *erhoben*: ein echter Wert nur dort, wo die Art des Artefakts ihn aus dem Material selbst festlegt, sonst `unknown`. | Kombination | n | Warum | |---|---:|---| | `verbatim` + `reporting` | 18 | 16 Gesprächstranskripte, 2 Tracker-Exporte („Wörtliche Kopie des Issue-Threads" laut Rohdatei); beide Protokoll, nicht Festlegung | | `secondhand` + `opinion` | 3 | LLM-Analysen; eine davon nennt sich im Kopf selbst „Aspekt aus einer externen Analyse" | | `published` + `reporting` | 2 | heise-Meldung, LLM-Wiki-v2-Blogpost („was wir beim Betrieb gelernt haben") | | `published` + `normative` | 1 | Karpathys Idea-File — das definierende Dokument seines eigenen Gegenstands | | `verbatim` + `normative` | 1 | qmd-README; die Rohdatei deklariert ihre Treue selbst | | `unknown` + `normative` | 1 | Anweisungsdokument: Direktive des Repo-Eigners, aber weder Mitschnitt noch Veröffentlichung noch Wiedergabe | | `unknown` + `reporting` | 3 | eigene Cheat Sheets; der Operator ist für Arch, Docker und Wine nicht zuständig | **`fidelity: unknown` auf 4 von 29, `authority: unknown` auf 0.** Die Asymmetrie ist das Ergebnis, nicht ein Mangel: die Zuständigkeitsfrage war überall aus dem Material beantwortbar, die Erfassungstreue nicht — der Enum hat keinen Wert für ein originär geschriebenes Artefakt. Genau die Grenze, die `unknown` markieren soll. ## Der Fund, den der neue Befund produziert hat Nach dem Backfill melden **67 von 152 Seiten** mit `confidence_base` mehr Konfidenz, als ihre Quellenlage trägt — 47 gegen die 0.8-Grenze (`reporting`), 20 gegen die 0.6-Grenze (`opinion`); betroffene Werte 21× 0.95, 19× 0.90, 9× 0.85, 15× 0.80. Das ist kein Fehlalarm und war auch nicht in diesem Paket zu beheben. Der Korpus ist zu gut der Hälfte aus Gesprächstranskripten kompiliert, und die Rubrik in `kb/CONVENTIONS.md` lässt Quellenzahl (+0.2 je Quelle, max +0.6) und Aktualität (+0.2) allein bis 0.95 laufen, während der Autoritätsterm (+0.1) der kleinste Summand ist. Ob daraus folgt, dass 67 Seiten überbewertet sind oder dass die 0.8-Grenze für einen selbstdokumentierenden Korpus zu eng ist, ist eine Entscheidung — sie liegt als Messung am Stub **#60**, der genau diesen Verdacht ohne Zahlen aufgeschrieben hatte. #60 bleibt `status/incoming` und wurde nicht ausgearbeitet. Die Transkripte wurden ausdrücklich **nicht** auf `normative` hochgestuft, nur damit der Report leiser wird — das wäre Tuning der Daten auf den Check. ## Verifiziert - 1076 pytest, `docs verify`, `instructions verify` grün. - `migrate verify --from HEAD --path kb/sources`: 29 verglichen, 0 added/removed/moved, **0 findings** — keine Wikilink-, Zitat-, Fußnoten- oder H1-Zahl angefasst. - `lint --fail-on-error` Exit 0, keine harten Fehler; `sources coverage` 0 unbeanspruchte Dateien, 0 gebrochene Referenzen, 0 Legacy-Seiten. - CI-Runs 152/153/154/155 grün, darunter der `setup-instance`-Replay gegen einen frischen `dist export` („The distribution works as a fresh instance") und der nächtliche Drift-Check. Run 156 (`46dfee0`, reine Prosa) lief beim Schließen noch. - Manueller End-to-End-Smoke-Test gegen einen isolierten `CHEMENU_ROOT`: Promotion nach `raw/2026/09/`, gedruckte Folgezeile, `new source`, `touch`-Verweigerung. ## Akzeptanzkriterien - [x] `raw accept` schreibt nach `raw/YYYY/MM/<stem>`; `incoming/` flach gelesen, Unterverzeichnis ignoriert statt verweigert. - [x] Stem-Eindeutigkeit (#64) global über `raw/`; Test mit gleichem Stem in zwei Shards. - [x] Bündel aus einer Bestandsdatei entsteht am Elternverzeichnis dieser Datei; Test mit einer Datei unter `raw/notes/`. - [x] Kein Bestandsfile in `raw/` bewegt; `sources coverage` weiterhin null unbeanspruchte Dateien. - [x] `fidelity`/`authority` im Schema, ohne `default:`, **nicht** in `required:`; `raw accept` und `new source` verweigern ohne beide, mit Test. - [x] `raw accept --fidelity unknown` und `new source --set fidelity=unknown` verweigert; nur `touch` schreibt `unknown`, mit Test. - [x] Capture-Feld per `touch --set` schreibbar solange es fehlt, verweigert sobald es steht — Test für beide Richtungen. - [x] `raw accept` ohne `--page` druckt die fertige `new source`-Folgezeile mit beiden Werten. - [x] `types/source.md` deklariert `capture_fields:`; `raw_cmd.py`/`new_page.py`/`touch.py` lesen sie vom Type-Resolver. - [x] Alle **29** (nicht 31) Source-Seiten tragen beide Felder; 4 tragen `fidelity: unknown`, und das steht im Changelog. - [x] `lint` meldet den Befund beratend, Schwellentabelle in `kb/CONTRACT.md`; **67 Fälle im Korpus** belegen ihn. - [x] `dist_cmd.RAW_SUBDIRS`, `check_raw_subdirs`, Routing-Tabelle und Ignore-Kanarie entfernt bzw. nachgezogen; `docs verify` grün. - [x] `raw/CONTRACT.md` beschreibt Shard, Capture-Felder und Verweigerungsregel; `tools/CONTRACT.md` nennt den entfallenen Check nicht mehr. - [x] Ingest-Skill hat den Dialogschritt für unklare Achsen, in Schritt 1 und Schritt 6. - [x] Changelog benennt Versionsteil und alle drei MINOR-Bedingungen. ## Was daraus offen weiterläuft - **#60** (`status/incoming`) trägt jetzt die Messung zur Konfidenz-Kalibrierung als Notiz. Nicht ausgearbeitet, nicht triagiert — bewusst. - `docs/` wurde auf Veralterung geprüft und ist aktuell: `pipeline-rationale.md`s `incoming/`-Absatz beschreibt die Vertrauensgrenze (Promotion nach `raw/`), die unverändert gilt; `ownership-and-templates.md`s Eigentümerlinie ist genau die, nach der die Schwellentabelle stackseitig und die Rubrik instanzseitig liegt. - Der Workshop `work/backfill-capture-fields/` ist geschlossen und gelöscht; seine dauerhaften Schlüsse stehen in den 29 Seiten selbst und im Changelog-Eintrag.
torben added the prio/plannedsize/Larea/kbarea/corpuskind/build labels 2026-09-08 17:31:49 +00:00
torben added kind/decision and removed kind/build labels 2026-09-08 18:54:40 +00:00
Author
Owner

Changelog: Body gegen den Baum gelesen (Vorbereitungssitzung 2026-09-08), Analyse unverändert, Umsetzungsteil nachgezogen. Neu bzw. korrigiert:

  • Reihenfolge: Die Kopplung des Backfills an #66s work/-Lauf ist überholt — #66 ist geschlossen, reclassify-source-types abgeschlossen, work/ leer. Der Backfill bekommt einen eigenen Lauf; dafür eine dreiteilige Abfolge mit getrennten Publishes ergänzt.
  • Punkt 3: fidelity/authority gehen nicht in required: — sonst ist die Änderung nach version-parts.md § Katalog grenzüberschreitend. Als zweite MINOR-Bedingung in den Versionsteil aufgenommen; dritte Bedingung (neue Pflichtflags an raw accept) neu benannt.
  • 3a neu, offen: raw accept kann die Felder ohne --page gar nicht schreiben — die Source-Seite entsteht erst in wiki-ingest Schritt 6. Drei Trägeroptionen, Empfehlung (a).
  • 3b neu, offen: UNSETTABLE und der Backfill schließen sich aus (migrate-corpus.md schreibt Frontmatter per touch). Vorschlag: Fill-once statt Denylist.
  • 3c neu: Capture-Felder im Type-Spec deklarieren statt an drei Stellen hartkodieren.
  • 5a neu, offen: „Keine Formel" braucht trotzdem eine Schwellentabelle; Vorschlag stackseitig, mit der Ownership-Frage gegen kb/CONVENTIONS.md benannt.
  • Punkt 1: Bündelort beim Hineinwachsen einer Bestandsdatei entschieden (Elternverzeichnis der Bestandsdatei).
  • Punkt 6: Trefferliste aus dem Baum vervollständigt — u. a. dist_cmd.py:419 (.gitkeep-Seeding), die Ignore-Kanarie incoming/documents/probe.pdf, tools/CONTRACT.md:74, drei Testdateien.
  • Akzeptanzkriterien entsprechend erweitert (Fill-once beidseitig, Bündelort, unknown-Verweigerung, required:-Ausschluss).

Re-Label: kind/buildkind/decision. Vier Entscheidungen (3a, 3b, 5a, Versionsteil-Bedingung 3) liegen beim Operator und blockieren den ersten Commit; danach zurück auf kind/build.

**Changelog:** Body gegen den Baum gelesen (Vorbereitungssitzung 2026-09-08), Analyse unverändert, Umsetzungsteil nachgezogen. Neu bzw. korrigiert: - **Reihenfolge:** Die Kopplung des Backfills an #66s `work/`-Lauf ist überholt — #66 ist geschlossen, `reclassify-source-types` abgeschlossen, `work/` leer. Der Backfill bekommt einen eigenen Lauf; dafür eine dreiteilige Abfolge mit getrennten Publishes ergänzt. - **Punkt 3:** `fidelity`/`authority` gehen **nicht** in `required:` — sonst ist die Änderung nach `version-parts.md` § Katalog grenzüberschreitend. Als zweite MINOR-Bedingung in den Versionsteil aufgenommen; dritte Bedingung (neue Pflichtflags an `raw accept`) neu benannt. - **3a neu, offen:** `raw accept` kann die Felder ohne `--page` gar nicht schreiben — die Source-Seite entsteht erst in `wiki-ingest` Schritt 6. Drei Trägeroptionen, Empfehlung (a). - **3b neu, offen:** `UNSETTABLE` und der Backfill schließen sich aus (`migrate-corpus.md` schreibt Frontmatter per `touch`). Vorschlag: Fill-once statt Denylist. - **3c neu:** Capture-Felder im Type-Spec deklarieren statt an drei Stellen hartkodieren. - **5a neu, offen:** „Keine Formel" braucht trotzdem eine Schwellentabelle; Vorschlag stackseitig, mit der Ownership-Frage gegen `kb/CONVENTIONS.md` benannt. - **Punkt 1:** Bündelort beim Hineinwachsen einer Bestandsdatei entschieden (Elternverzeichnis der Bestandsdatei). - **Punkt 6:** Trefferliste aus dem Baum vervollständigt — u. a. `dist_cmd.py:419` (`.gitkeep`-Seeding), die Ignore-Kanarie `incoming/documents/probe.pdf`, `tools/CONTRACT.md:74`, drei Testdateien. - Akzeptanzkriterien entsprechend erweitert (Fill-once beidseitig, Bündelort, `unknown`-Verweigerung, `required:`-Ausschluss). **Re-Label:** `kind/build` → `kind/decision`. Vier Entscheidungen (3a, 3b, 5a, Versionsteil-Bedingung 3) liegen beim Operator und blockieren den ersten Commit; danach zurück auf `kind/build`.
Author
Owner

Entscheidungen gefallen (Operator, 2026-09-08): alle vier wie empfohlen.

  • 3a: Übergabe per Meldung (raw accept verlangt beide Flags, schreibt bei --page direkt, druckt sonst die fertige new source-Zeile; new source verweigert ohne sie)
  • 3b: Fill-once statt Denylist (touch --set schreibt ein Capture-Feld nur, solange es fehlt)
  • 5a: Stackseitige Schwellentabelle, dokumentiert in kb/CONTRACT.md
  • Versionsteil: MINOR, weiterer Bump auf 4.8.0-beta.8

Body wird jetzt auf den entschiedenen Stand gebracht, Label zurück auf kind/build. Umsetzung beginnt in dieser Sitzung.

**Entscheidungen gefallen (Operator, 2026-09-08):** alle vier wie empfohlen. - 3a: Übergabe per Meldung (`raw accept` verlangt beide Flags, schreibt bei `--page` direkt, druckt sonst die fertige `new source`-Zeile; `new source` verweigert ohne sie) - 3b: Fill-once statt Denylist (`touch --set` schreibt ein Capture-Feld nur, solange es fehlt) - 5a: Stackseitige Schwellentabelle, dokumentiert in `kb/CONTRACT.md` - Versionsteil: MINOR, weiterer Bump auf `4.8.0-beta.8` Body wird jetzt auf den entschiedenen Stand gebracht, Label zurück auf `kind/build`. Umsetzung beginnt in dieser Sitzung.
torben added kind/build and removed kind/decision labels 2026-09-08 19:13:36 +00:00
Author
Owner

Changelog: Publish 1/3 gelaufen (Code + Verträge + Instruction), 4.8.0-beta.8. Body auf den erreichten Stand umgeschrieben: alle Akzeptanzkriterien außer dem Backfill (Publish 2/3) und der Belegzeile dazu (Publish 3/3) sind erledigt und mit den jeweiligen Testnamen belegt. Noch nicht committed/gepusht — Freigabe zum Publish steht noch aus.

**Changelog:** Publish 1/3 gelaufen (Code + Verträge + Instruction), `4.8.0-beta.8`. Body auf den erreichten Stand umgeschrieben: alle Akzeptanzkriterien außer dem Backfill (Publish 2/3) und der Belegzeile dazu (Publish 3/3) sind erledigt und mit den jeweiligen Testnamen belegt. Noch nicht committed/gepusht — Freigabe zum Publish steht noch aus.
Author
Owner

Changelog: Verifikation in den Body nachgetragen — Commits f4353cc (Stack) und d9af88f (README-Nachzug), CI-Run 152 grün inkl. dist export-Replay als frische Instanz. docs/-Veralterungsprüfung ergänzt (keine Seite veraltet, mit Begründung je Seite). Sonst unverändert; die zwei offenen Kriterien bleiben Publish 2/3 und 3/3.

**Changelog:** Verifikation in den Body nachgetragen — Commits `f4353cc` (Stack) und `d9af88f` (README-Nachzug), CI-Run 152 grün inkl. `dist export`-Replay als frische Instanz. `docs/`-Veralterungsprüfung ergänzt (keine Seite veraltet, mit Begründung je Seite). Sonst unverändert; die zwei offenen Kriterien bleiben Publish 2/3 und 3/3.
Author
Owner

Changelog: Body auf Endstand geschrieben und geschlossen. Neu gegenüber dem letzten Stand: Publish 2/3 (00220f8, Backfill) und 3/3 (46dfee0, Belegzeile + Workshop geschlossen) sind gelandet; die vier Entscheidungen stehen jetzt mit ihren verworfenen Alternativen im Body statt nur als Verweis; Backfill-Verteilung und Begründung je Kombination ergänzt. Korrigiert: 29 Source-Seiten, nicht 31 — die höhere Zahl war eine Fehlzählung (INDEX.md/COLLECTION.md mitgezählt). Ergebnis des Befunds nachgetragen: 67 von 152 Seiten über der Obergrenze, als Messung an #60 gehängt, das status/incoming bleibt.

**Changelog:** Body auf Endstand geschrieben und geschlossen. Neu gegenüber dem letzten Stand: Publish 2/3 (`00220f8`, Backfill) und 3/3 (`46dfee0`, Belegzeile + Workshop geschlossen) sind gelandet; die vier Entscheidungen stehen jetzt mit ihren verworfenen Alternativen im Body statt nur als Verweis; Backfill-Verteilung und Begründung je Kombination ergänzt. **Korrigiert:** 29 Source-Seiten, nicht 31 — die höhere Zahl war eine Fehlzählung (`INDEX.md`/`COLLECTION.md` mitgezählt). Ergebnis des Befunds nachgetragen: 67 von 152 Seiten über der Obergrenze, als Messung an #60 gehängt, das `status/incoming` bleibt.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#67