Stand: abgeschlossen (2026-10-03). Ausgearbeitet aus einem status/incoming-Stub (Wortlaut im ersten Kommentar); die vier Designfragen hat der Betreiber am selben Tag entschieden. #111 (leerer Ordner bleibt nach dem Ingest stehen) ist hierin aufgegangen. Gebaut als 8.0.0-beta.27 (Commit 59c06e5), verifiziert durch CI-Run 509 (verify + pwsh). Der Abschluss-Check hat zwei veraltete Sätze gefunden und nachgezogen: 8.0.0-beta.28 (Commit 100ace8), verifiziert durch CI-Run 511.
Was fehlte
Kein Standardverhalten ohne Argument.wiki-ingest kannte nur den benannten Fall (Datei, Ordner, URL); ein bloßes „ingest“ war nirgends definiert. Gewünscht war: Ohne Angabe wählt die Sitzung selbst genau einen Eintrag aus incoming/ und ingestet ihn, ältere zuerst, damit Neueres auf Älterem aufbaut oder es korrigiert.
Ein Ordner kam nicht sauber nach raw/.raw accept nahm nur Dateien, höchstens eine Ebene unter incoming/. Es bündelte sie flach unter dem Stem der ersten Datei, verlor also den Ordnernamen, und ließ den geleerten Ordner stehen (ehemals #111). Ein Ordner mit Unterordnern war gar nicht übernehmbar. ingest-large-tree.md setzt aber voraus, dass der Baum schon unter raw/ liegt (work new --input lehnt alles außerhalb ab).
Die Rückwärtskompatibilität für Typ-Ordner hatte keinen Zweck mehr. Seit der Datums-Shard-Umstellung wird der Quelltyp aus dem Inhalt abgeleitet (source_type: auf der Source-Seite), und raw/ ist nach Datum sortiert. Ein Unterordner in incoming/ wurde nur noch „toleriert und ignoriert“. Diese Toleranz ist gestrichen: Ein Unterordner von incoming/ ist eine Quelle.
Entscheidungen
E1 - Reihenfolge: mtime, älteste zuerst (Betreiber, 2026-10-03). Bei Gleichstand entscheidet der Name (Bytefolge des Pfads). Für ein Bündel oder einen Ordner zählt die jüngste mtime aller enthaltenen Dateien, rekursiv: Eine Einheit ist so neu wie ihr neuester Teil. Die Grenze steht in den Ausgabe-Notes und im Contract: Bei cp -p/rsync -a/entpackten Archiven ist die mtime die letzte Änderung des Dokuments, bei Downloads und raw fetch nur der Ablagezeitpunkt. Verworfen wurden das Inhaltsdatum (verlangt das Lesen jedes Kandidaten, nicht mechanisch) und der Name allein (sagt nichts über das Alter).
E2 - Ein Ordner ist eine Ingest-Einheit; die Stufe entscheiden die bestehenden Schwellen (Betreiber, 2026-10-03). Ob Standard-Ingest oder ingest-large-tree, entscheidet wie bisher dessen § When to run (Volumen/Breite). Es gibt keinen Automatismus „Ordner = Tree-Ingest“: Drei Notizen verdienen keinen Workshop.
E3 - #111 und #112 sind ein Paket (Betreiber, 2026-10-03). Die Ordner-Übernahme wurde hier gebaut, nicht getrennt.
E4 - Die Toleranz für Unterordner wird gestrichen (Betreiber, 2026-10-03; geprüft: Der Typ kommt aus dem Inhalt, die Ordner tragen keine Information mehr). Dateiargumente von raw accept und raw fetch --html müssen direkt in incoming/ liegen. Ein Unterordner wird nur als Ganzes übernommen. Für die vier alten Namen (articles, assets, documents, notes) gibt es keine Sonderbehandlung: Sie sind gewöhnliche Ordner, und leer sind sie keine Kandidaten. Nicht betroffen sind die alten Typverzeichnisse unter raw/ (raw/articles/ usw.): raw/ ist immutabel, --replaces schreibt dorthin zurück, und _occupied_stems unterscheidet sie strukturell.
E5 - Kandidatenbildung in incoming/ (aus dem Baum abgeleitet):
Nur Top-Level-Einträge zählen.
Dotfiles (.gitkeep usw.) und leere Verzeichnisse sind keine Kandidaten.
Top-Level-Dateien mit gleichem Stem bilden einen Kandidaten (bundle). Das raw fetch-Paar und PDF + konvertiertes Markdown sind laut raw/CONTRACT.mdeine Quelle in einemraw accept-Aufruf.
Ein Top-Level-Ordner ist ein Kandidat (folder) mit allen Dateien darunter, rekursiv.
Uploads in mcp-upload/ sind keine Kandidaten. mcp-upload/ liegt neben incoming/, nicht darin, und eine Datei landet erst nach dem Upload Review Gate als gewöhnliche Datei in incoming/.
Was gebaut wurde
Alles in tools/chemenu/commands/raw_cmd.py. Die Vorab-Prüfungen (_check_directly_in_incoming, _check_files, _plan_file_moves, _plan_folder) werfen _Refused, statt sofort fail() aufzurufen. raw accept macht daraus Exit 1, raw pending liest den Grund heraus. Die Prüflogik existiert also nur einmal.
A. raw accept incoming/<ordner> - einen Ordner als eine Quelle übernehmen
Ein Verzeichnisargument ist nur allein zulässig: keine weiteren Argumente, kein --page, kein --replaces. Jede Kombination gibt Exit 1 und bewegt nichts.
Ziel ist raw/<YYYY>/<MM>/<ordner>/…, die relative Struktur bleibt erhalten. Der Ordnername ist der Bündelname und unterliegt der Eindeutigkeitsregel (_occupied_stems). Die Dateien darin belegen keinen Namen, mehrere README.md in einem Baum sind also kein Problem. Kollidiert der Ordnername, nennt die Meldung nur das Umbenennen in incoming/, denn ein --replaces für Ordner gibt es nicht.
--fidelity/--authority sind Pflicht, ein Paar für den ganzen Ordner.
Alle Prüfungen laufen, bevor sich etwas bewegt. Der Ordner liegt direkt in incoming/ und ist nicht leer. Im ganzen Baum gibt es keinen versteckten Eintrag, keinen Symlink und, als Ergänzung zum Design, keine Spezialdatei (FIFO o. Ä.); jeder solche Eintrag wird genannt. Jedes Ziel liegt im Pfadbudget, und keines existiert schon.
Invariante: Nach Erfolg existiert incoming/<ordner> nicht mehr, und jede Datei liegt byte-identisch am selben relativen Pfad. Aufgeräumt wird mit rmdir je Verzeichnis, nie rekursiv löschend, und rmdir verweigert ein nicht leeres Verzeichnis. Taucht während des Laufs doch etwas auf, bleibt das Verzeichnis stehen, und es kommt eine WARN-Zeile.
Nicht atomar: eine Bewegung pro Datei, so steht es im cli_contract-Datensatz. Ein halb übernommener Ordner wird nicht fortgesetzt.
--dry-run listet alle Bewegungen und das zu entfernende Verzeichnis.
Die Ausgabe enthält die new source --set raw_files=…-Zeile mit dem fidelity/authority-Paar. Als Ergänzung zum Design steht dort zusätzlich die work new --input raw/<YYYY>/<MM>/<ordner>-Zeile für einen Baum über den Large-Tree-Schwellen.
B. Dateiargumente nur noch direkt in incoming/ (E4)
Eine Datei in einem Unterordner gibt Exit 1. Die Meldung nennt beide Wege, raw accept incoming/<ordner> und das Hochziehen nach incoming/. Das gilt für raw accept (auch mit --replaces) und für raw fetch --html.
Modul-Docstring und Kommentare sind umgeschrieben.
C. wikitool raw pending - die Warteschlange lesen
Listet die Kandidaten (E5) in der Reihenfolge E1. Je Kandidat stehen da Pfad(e), Art (file/bundle/folder), Dateianzahl, mtime (ISO, lokale Zeit mit Offset) und ob er übernehmbar ist, sonst mit Grund. Die Standardwahl ist mit * markiert und wird in einer eigenen Zeile genannt, zusammen mit der Zahl der danach wartenden Einträge.
„Übernehmbar“ heißt: Die Vorab-Prüfungen von raw accept laufen durch, Fidelity/Authority ausgenommen.
--json liefert kind, paths, files, mtime, acceptable, reason und default.
effect read, idempotent, budget counted, kein Netz, Exit 0 auch bei leerem Eingang. Gelesen werden nur Verzeichnislisten und lstat, nie ein Inhalt. In cli_contract.GROUPS steht das Kommando unter „Raw material and uploads“.
D. Instruktionen und Doku
instructions/wiki-ingest/SKILL.md: description und Trigger kennen „ingest“ ohne Argument, und ein Lauf ist eine Quelle. Schritt 1 behandelt den Fall ohne Argument (raw pending aufrufen, die Standardwahl ansagen, keine Rückfrage, bei nichts Übernehmbarem Ende mit den Gründen) und den Fall Ordner (E2). In Schritt 5 steht die Ordnerübernahme an der Stelle der Toleranz-Sätze. Schritt 12 nennt am Ende die Zahl der wartenden Einträge. Kommandoliste und Beispiele sind ergänzt.
instructions/ingest-large-tree.md Schritt 2 nennt raw accept incoming/<folder> vor work new --input raw/<YYYY>/<MM>/<folder>.
raw/CONTRACT.md § Getting a file in beschreibt: Dateien direkt in incoming/, der Ordner als Quelle mit seinen Prüfungen, warum die Toleranz gestrichen wurde, und die Warteschlange (Kandidaten, Reihenfolge, mtime-Grenze, Standardwahl).
tools/CONTRACT.md ist aus den Datensätzen neu erzeugt.
README.md: die Baumzeile, „Adding Knowledge“ (ein Ordner pro Quelle, „Ingest“ ohne Argument) und „Curate sources“. tools/README.md ist geprüft, dort war nichts zu ändern.
CHANGES.md über version bump, mit Changeset-Prosa.
Nachgezogen im Abschluss-Check (8.0.0-beta.28): Der Fehlerdatensatz von raw fetch --html sagt jetzt „not directly in incoming/“ und nennt das Hochziehen. In kb/CONTRACT.md nennt der Absatz zum Pfadbudget für einen Ordner den kürzeren Ordner- oder Dateinamen als Abhilfe. Ebenfalls geprüft und weiterhin korrekt: docs/pipeline-rationale.md (Vertrauensgrenze vor incoming/), instructions/ingest-queue.md, types/source.guidance.md und die übrigen Abschnitte von raw/CONTRACT.md.
Tests
In tools/chemenu/tests/test_raw_cmd.py sind die vier Toleranz-Tests ersetzt: Eine Datei im Unterordner wird abgelehnt (Tiefe 1 und 2), --replaces aus einem Unterordner wird abgelehnt, und --replaces in ein Alt-Typverzeichnis funktioniert weiter. Neu sind 12 Testfunktionen zum Ordner (16 Fälle mit Parametrisierung) und 7 zu raw pending. In test_raw_fetch.py kam ein Test für --html im Unterordner dazu. Die Ignore-Kanarie incoming/documents/probe.pdf ist unverändert.
Version
MAJOR im laufenden Kandidaten: 8.0.0-beta.27 mit Impact high, dazu die Nachzieh-Korrektur 8.0.0-beta.28 mit Impact low. version bump hat --breaking auf dem schon eskalierten Kandidaten angenommen, und der Bruch steht als eigener Punkt im Breaking-Change-Block.
Was bricht:raw accept und raw fetch --html lehnen eine Datei in einem Unterordner von incoming/ ab. Ein Unterordner von incoming/ ist eine Quelle.
Was eine Instanz tun muss: Ablage-Skripte legen direkt in incoming/ ab. Dateien, die nach dem Update noch in incoming/<typ>/ warten, werden hochgezogen oder, wenn sie zusammengehören, als Ordner übernommen. Das geht erst mit der neuen Version; die Design-Fassung hatte „vor dem Update“ geschrieben.
Migration: keine. Die bestehende --no-migration-Zeile des Kandidaten gilt weiter.
Akzeptanzkriterien
raw accept mit Ordner
incoming/baum/{a.md, sub/b.md, sub/deep/README.md} → nach Erfolg liegen alle drei byte-identisch unter raw/<YYYY>/<MM>/baum/ am selben relativen Pfad, und incoming/baum existiert nicht mehr.
Zwei gleichnamige Dateien in verschiedenen Unterordnern (x/README.md, y/README.md) werden beide übernommen.
Ein versteckter Eintrag oder ein Symlink irgendwo im Ordner gibt Exit 1, der Eintrag wird genannt, und incoming/ und raw/ sind danach unverändert (Dateiliste plus Inhalte verglichen).
Ein leerer Ordner, ein Ordner zusammen mit weiteren Argumenten, mit --page oder mit --replaces gibt jeweils Exit 1, nichts bewegt.
Ein Ordnername, der unter raw/ schon belegt ist, gibt Exit 1 mit dem Umbenennungsweg, nichts bewegt.
Ein Ziel über dem Pfadbudget gibt Exit 1 vor der ersten Bewegung, nichts bewegt.
--dry-run listet alle Bewegungen, danach sind incoming/ und raw/ unverändert.
sources coverage meldet die Dateien des Ordners danach als ungedeckt (noch keine Source-Seite), keinen kaputten Verweis. Geprüft über uncovered_raw_files/broken_raw_refs, auf denen sources coverage aufsetzt.
Toleranz gestrichen
raw accept incoming/documents/a.pdf gibt Exit 1, die Meldung nennt Ordnerübernahme und Hochziehen, die Datei bleibt liegen. Dasselbe für --replaces und raw fetch --html mit einer Datei im Unterordner.
raw accept incoming/a.pdf (Top-Level) funktioniert unverändert, ebenso Bündel aus mehreren Top-Level-Dateien.
raw pending
Leerer Eingang (nur .gitkeep, leere Unterordner): Exit 0, kein Kandidat.
incoming/post.html + incoming/post.md → einbundle-Kandidat mit beiden Pfaden.
Ein Ordner mit n Dateien (rekursiv) → ein folder-Kandidat mit n; seine Dateien erscheinen nicht einzeln.
Reihenfolge mit per os.utime gesetzten mtimes: älteste zuerst; für Bündel und Ordner zählt die jüngste enthaltene mtime; Gleichstand nach Name.
Ein Kandidat, den raw accept ablehnen würde (versteckter Eintrag, belegter Name, Pfadbudget), ist mit Grund als nicht übernehmbar markiert, und die Standardwahl ist der erste übernehmbare.
incoming/, raw/, kb/ sind nach dem Aufruf byte-identisch, mtimes unverändert.
--json liefert dieselben Kandidaten in derselben Reihenfolge.
Doku und Gates
wiki-ingest beschreibt den Fall ohne Argument (Standardwahl ansagen, einer pro Lauf, Rest am Ende nennen) und die Ordnerübernahme. ingest-large-tree.md nennt raw accept incoming/<ordner> vor work new.
raw/CONTRACT.md sagt nirgends mehr, ein Unterordner werde toleriert oder ignoriert, und beschreibt Kandidatenbildung, Reihenfolge und die mtime-Grenze.
docs verify, instructions verify, pytest lokal grün (2119 passed, 3 skipped, auch auf leerer Maschine); CI auf dem publizierten Commit 59c06e5 grün (Run 509, verify + pwsh), ebenso auf der Nachzieh-Korrektur 100ace8 (Run 511).
CHANGES: Bump --major im laufenden 8.0.0-Kandidaten (8.0.0-beta.27) mit dem Bruch im Breaking-Change-Block.
**Stand: abgeschlossen** (2026-10-03). Ausgearbeitet aus einem `status/incoming`-Stub (Wortlaut im ersten Kommentar); die vier Designfragen hat der Betreiber am selben Tag entschieden. **#111** (leerer Ordner bleibt nach dem Ingest stehen) ist hierin aufgegangen. Gebaut als **`8.0.0-beta.27`** (Commit `59c06e5`), **verifiziert durch CI-Run [509](https://gitea.nehmer.net/torben/chemenu/actions/runs/509)** (verify + pwsh). Der Abschluss-Check hat zwei veraltete Sätze gefunden und nachgezogen: **`8.0.0-beta.28`** (Commit `100ace8`), **verifiziert durch CI-Run [511](https://gitea.nehmer.net/torben/chemenu/actions/runs/511)**.
## Was fehlte
1. **Kein Standardverhalten ohne Argument.** `wiki-ingest` kannte nur den benannten Fall (Datei, Ordner, URL); ein bloßes „ingest“ war nirgends definiert. Gewünscht war: **Ohne Angabe wählt die Sitzung selbst genau einen Eintrag aus `incoming/` und ingestet ihn**, ältere zuerst, damit Neueres auf Älterem aufbaut oder es korrigiert.
2. **Ein Ordner kam nicht sauber nach `raw/`.** `raw accept` nahm nur Dateien, höchstens eine Ebene unter `incoming/`. Es bündelte sie flach unter dem Stem der *ersten Datei*, verlor also den Ordnernamen, und ließ den geleerten Ordner stehen (ehemals #111). Ein Ordner mit Unterordnern war gar nicht übernehmbar. `ingest-large-tree.md` setzt aber voraus, dass der Baum schon unter `raw/` liegt (`work new --input` lehnt alles außerhalb ab).
3. **Die Rückwärtskompatibilität für Typ-Ordner hatte keinen Zweck mehr.** Seit der Datums-Shard-Umstellung wird der Quelltyp aus dem Inhalt abgeleitet (`source_type:` auf der Source-Seite), und `raw/` ist nach Datum sortiert. Ein Unterordner in `incoming/` wurde nur noch „toleriert und ignoriert“. Diese Toleranz ist gestrichen: **Ein Unterordner von `incoming/` ist eine Quelle.**
## Entscheidungen
**E1 - Reihenfolge: mtime, älteste zuerst** (Betreiber, 2026-10-03). Bei Gleichstand entscheidet der Name (Bytefolge des Pfads). Für ein Bündel oder einen Ordner zählt die **jüngste** mtime aller enthaltenen Dateien, rekursiv: Eine Einheit ist so neu wie ihr neuester Teil. Die Grenze steht in den Ausgabe-Notes und im Contract: Bei `cp -p`/`rsync -a`/entpackten Archiven ist die mtime die letzte Änderung des Dokuments, bei Downloads und `raw fetch` nur der Ablagezeitpunkt. Verworfen wurden das Inhaltsdatum (verlangt das Lesen jedes Kandidaten, nicht mechanisch) und der Name allein (sagt nichts über das Alter).
**E2 - Ein Ordner ist eine Ingest-Einheit; die Stufe entscheiden die bestehenden Schwellen** (Betreiber, 2026-10-03). Ob Standard-Ingest oder `ingest-large-tree`, entscheidet wie bisher dessen § When to run (Volumen/Breite). Es gibt keinen Automatismus „Ordner = Tree-Ingest“: Drei Notizen verdienen keinen Workshop.
**E3 - #111 und #112 sind ein Paket** (Betreiber, 2026-10-03). Die Ordner-Übernahme wurde hier gebaut, nicht getrennt.
**E4 - Die Toleranz für Unterordner wird gestrichen** (Betreiber, 2026-10-03; geprüft: Der Typ kommt aus dem Inhalt, die Ordner tragen keine Information mehr). Dateiargumente von `raw accept` und `raw fetch --html` müssen **direkt** in `incoming/` liegen. Ein Unterordner wird nur als Ganzes übernommen. Für die vier alten Namen (`articles`, `assets`, `documents`, `notes`) gibt es **keine** Sonderbehandlung: Sie sind gewöhnliche Ordner, und leer sind sie keine Kandidaten. **Nicht betroffen** sind die alten Typverzeichnisse unter `raw/` (`raw/articles/` usw.): `raw/` ist immutabel, `--replaces` schreibt dorthin zurück, und `_occupied_stems` unterscheidet sie strukturell.
**E5 - Kandidatenbildung in `incoming/`** (aus dem Baum abgeleitet):
1. Nur Top-Level-Einträge zählen.
2. Dotfiles (`.gitkeep` usw.) und leere Verzeichnisse sind keine Kandidaten.
3. Top-Level-Dateien mit gleichem Stem bilden **einen** Kandidaten (`bundle`). Das `raw fetch`-Paar und PDF + konvertiertes Markdown sind laut `raw/CONTRACT.md` *eine* Quelle in *einem* `raw accept`-Aufruf.
4. Ein Top-Level-Ordner ist ein Kandidat (`folder`) mit allen Dateien darunter, rekursiv.
5. Uploads in `mcp-upload/` sind keine Kandidaten. `mcp-upload/` liegt neben `incoming/`, nicht darin, und eine Datei landet erst nach dem Upload Review Gate als gewöhnliche Datei in `incoming/`.
## Was gebaut wurde
Alles in `tools/chemenu/commands/raw_cmd.py`. Die Vorab-Prüfungen (`_check_directly_in_incoming`, `_check_files`, `_plan_file_moves`, `_plan_folder`) werfen `_Refused`, statt sofort `fail()` aufzurufen. `raw accept` macht daraus Exit 1, `raw pending` liest den Grund heraus. Die Prüflogik existiert also nur einmal.
### A. `raw accept incoming/<ordner>` - einen Ordner als eine Quelle übernehmen
- Ein Verzeichnisargument ist nur **allein** zulässig: keine weiteren Argumente, kein `--page`, kein `--replaces`. Jede Kombination gibt Exit 1 und bewegt nichts.
- Ziel ist `raw/<YYYY>/<MM>/<ordner>/…`, die **relative Struktur bleibt erhalten**. Der **Ordnername ist der Bündelname** und unterliegt der Eindeutigkeitsregel (`_occupied_stems`). Die Dateien darin belegen keinen Namen, mehrere `README.md` in einem Baum sind also kein Problem. Kollidiert der Ordnername, nennt die Meldung nur das Umbenennen in `incoming/`, denn ein `--replaces` für Ordner gibt es nicht.
- `--fidelity`/`--authority` sind Pflicht, ein Paar für den ganzen Ordner.
- **Alle Prüfungen laufen, bevor sich etwas bewegt.** Der Ordner liegt direkt in `incoming/` und ist nicht leer. Im ganzen Baum gibt es keinen versteckten Eintrag, keinen Symlink und, als Ergänzung zum Design, keine Spezialdatei (FIFO o. Ä.); jeder solche Eintrag wird genannt. Jedes Ziel liegt im Pfadbudget, und keines existiert schon.
- **Invariante:** Nach Erfolg existiert `incoming/<ordner>` nicht mehr, und jede Datei liegt byte-identisch am selben relativen Pfad. Aufgeräumt wird mit `rmdir` je Verzeichnis, nie rekursiv löschend, und `rmdir` verweigert ein nicht leeres Verzeichnis. Taucht während des Laufs doch etwas auf, bleibt das Verzeichnis stehen, und es kommt eine WARN-Zeile.
- Nicht atomar: eine Bewegung pro Datei, so steht es im `cli_contract`-Datensatz. Ein halb übernommener Ordner wird nicht fortgesetzt.
- `--dry-run` listet alle Bewegungen und das zu entfernende Verzeichnis.
- Die Ausgabe enthält die `new source --set raw_files=…`-Zeile mit dem `fidelity`/`authority`-Paar. Als Ergänzung zum Design steht dort zusätzlich die `work new --input raw/<YYYY>/<MM>/<ordner>`-Zeile für einen Baum über den Large-Tree-Schwellen.
### B. Dateiargumente nur noch direkt in `incoming/` (E4)
- Eine Datei in einem Unterordner gibt Exit 1. Die Meldung nennt beide Wege, `raw accept incoming/<ordner>` und das Hochziehen nach `incoming/`. Das gilt für `raw accept` (auch mit `--replaces`) und für `raw fetch --html`.
- Modul-Docstring und Kommentare sind umgeschrieben.
### C. `wikitool raw pending` - die Warteschlange lesen
- Listet die Kandidaten (E5) in der Reihenfolge E1. Je Kandidat stehen da Pfad(e), Art (`file`/`bundle`/`folder`), Dateianzahl, mtime (ISO, lokale Zeit mit Offset) und ob er übernehmbar ist, sonst mit Grund. Die Standardwahl ist mit `*` markiert und wird in einer eigenen Zeile genannt, zusammen mit der Zahl der danach wartenden Einträge.
- „Übernehmbar“ heißt: Die Vorab-Prüfungen von `raw accept` laufen durch, Fidelity/Authority ausgenommen.
- `--json` liefert `kind`, `paths`, `files`, `mtime`, `acceptable`, `reason` und `default`.
- `effect read`, idempotent, `budget counted`, kein Netz, Exit 0 auch bei leerem Eingang. Gelesen werden nur Verzeichnislisten und `lstat`, nie ein Inhalt. In `cli_contract.GROUPS` steht das Kommando unter „Raw material and uploads“.
### D. Instruktionen und Doku
- `instructions/wiki-ingest/SKILL.md`: `description` und Trigger kennen „ingest“ ohne Argument, und ein Lauf ist eine Quelle. Schritt 1 behandelt den Fall ohne Argument (`raw pending` aufrufen, die Standardwahl ansagen, keine Rückfrage, bei nichts Übernehmbarem Ende mit den Gründen) und den Fall Ordner (E2). In Schritt 5 steht die Ordnerübernahme an der Stelle der Toleranz-Sätze. Schritt 12 nennt am Ende die Zahl der wartenden Einträge. Kommandoliste und Beispiele sind ergänzt.
- `instructions/ingest-large-tree.md` Schritt 2 nennt `raw accept incoming/<folder>` vor `work new --input raw/<YYYY>/<MM>/<folder>`.
- `raw/CONTRACT.md` § Getting a file in beschreibt: Dateien direkt in `incoming/`, der Ordner als Quelle mit seinen Prüfungen, warum die Toleranz gestrichen wurde, und die Warteschlange (Kandidaten, Reihenfolge, mtime-Grenze, Standardwahl).
- `tools/CONTRACT.md` ist aus den Datensätzen neu erzeugt.
- `README.md`: die Baumzeile, „Adding Knowledge“ (ein Ordner pro Quelle, „Ingest“ ohne Argument) und „Curate sources“. `tools/README.md` ist geprüft, dort war nichts zu ändern.
- `CHANGES.md` über `version bump`, mit Changeset-Prosa.
- **Nachgezogen im Abschluss-Check** (`8.0.0-beta.28`): Der Fehlerdatensatz von `raw fetch --html` sagt jetzt „not directly in `incoming/`“ und nennt das Hochziehen. In `kb/CONTRACT.md` nennt der Absatz zum Pfadbudget für einen Ordner den kürzeren Ordner- oder Dateinamen als Abhilfe. Ebenfalls geprüft und weiterhin korrekt: `docs/pipeline-rationale.md` (Vertrauensgrenze vor `incoming/`), `instructions/ingest-queue.md`, `types/source.guidance.md` und die übrigen Abschnitte von `raw/CONTRACT.md`.
### Tests
In `tools/chemenu/tests/test_raw_cmd.py` sind die vier Toleranz-Tests ersetzt: Eine Datei im Unterordner wird abgelehnt (Tiefe 1 und 2), `--replaces` aus einem Unterordner wird abgelehnt, und `--replaces` in ein Alt-Typverzeichnis funktioniert weiter. Neu sind 12 Testfunktionen zum Ordner (16 Fälle mit Parametrisierung) und 7 zu `raw pending`. In `test_raw_fetch.py` kam ein Test für `--html` im Unterordner dazu. Die Ignore-Kanarie `incoming/documents/probe.pdf` ist unverändert.
## Version
**MAJOR** im laufenden Kandidaten: `8.0.0-beta.27` mit Impact `high`, dazu die Nachzieh-Korrektur `8.0.0-beta.28` mit Impact `low`. `version bump` hat `--breaking` auf dem schon eskalierten Kandidaten angenommen, und der Bruch steht als eigener Punkt im Breaking-Change-Block.
- **Was bricht:** `raw accept` und `raw fetch --html` lehnen eine Datei in einem Unterordner von `incoming/` ab. Ein Unterordner von `incoming/` ist eine Quelle.
- **Was eine Instanz tun muss:** Ablage-Skripte legen direkt in `incoming/` ab. Dateien, die nach dem Update noch in `incoming/<typ>/` warten, werden hochgezogen oder, wenn sie zusammengehören, als Ordner übernommen. Das geht erst mit der neuen Version; die Design-Fassung hatte „vor dem Update“ geschrieben.
- **Migration:** keine. Die bestehende `--no-migration`-Zeile des Kandidaten gilt weiter.
## Akzeptanzkriterien
**`raw accept` mit Ordner**
- [x] `incoming/baum/{a.md, sub/b.md, sub/deep/README.md}` → nach Erfolg liegen alle drei byte-identisch unter `raw/<YYYY>/<MM>/baum/` am selben relativen Pfad, und `incoming/baum` existiert nicht mehr.
- [x] Zwei gleichnamige Dateien in verschiedenen Unterordnern (`x/README.md`, `y/README.md`) werden beide übernommen.
- [x] Ein versteckter Eintrag oder ein Symlink irgendwo im Ordner gibt Exit 1, der Eintrag wird genannt, und `incoming/` und `raw/` sind danach unverändert (Dateiliste plus Inhalte verglichen).
- [x] Ein leerer Ordner, ein Ordner zusammen mit weiteren Argumenten, mit `--page` oder mit `--replaces` gibt jeweils Exit 1, nichts bewegt.
- [x] Ein Ordnername, der unter `raw/` schon belegt ist, gibt Exit 1 mit dem Umbenennungsweg, nichts bewegt.
- [x] Ein Ziel über dem Pfadbudget gibt Exit 1 vor der ersten Bewegung, nichts bewegt.
- [x] `--dry-run` listet alle Bewegungen, danach sind `incoming/` und `raw/` unverändert.
- [x] `sources coverage` meldet die Dateien des Ordners danach als ungedeckt (noch keine Source-Seite), keinen kaputten Verweis. Geprüft über `uncovered_raw_files`/`broken_raw_refs`, auf denen `sources coverage` aufsetzt.
**Toleranz gestrichen**
- [x] `raw accept incoming/documents/a.pdf` gibt Exit 1, die Meldung nennt Ordnerübernahme und Hochziehen, die Datei bleibt liegen. Dasselbe für `--replaces` und `raw fetch --html` mit einer Datei im Unterordner.
- [x] `raw accept incoming/a.pdf` (Top-Level) funktioniert unverändert, ebenso Bündel aus mehreren Top-Level-Dateien.
**`raw pending`**
- [x] Leerer Eingang (nur `.gitkeep`, leere Unterordner): Exit 0, kein Kandidat.
- [x] `incoming/post.html` + `incoming/post.md` → **ein** `bundle`-Kandidat mit beiden Pfaden.
- [x] Ein Ordner mit n Dateien (rekursiv) → ein `folder`-Kandidat mit n; seine Dateien erscheinen nicht einzeln.
- [x] Reihenfolge mit per `os.utime` gesetzten mtimes: älteste zuerst; für Bündel und Ordner zählt die jüngste enthaltene mtime; Gleichstand nach Name.
- [x] Ein Kandidat, den `raw accept` ablehnen würde (versteckter Eintrag, belegter Name, Pfadbudget), ist mit Grund als nicht übernehmbar markiert, und die Standardwahl ist der erste übernehmbare.
- [x] `incoming/`, `raw/`, `kb/` sind nach dem Aufruf byte-identisch, mtimes unverändert.
- [x] `--json` liefert dieselben Kandidaten in derselben Reihenfolge.
**Doku und Gates**
- [x] `wiki-ingest` beschreibt den Fall ohne Argument (Standardwahl ansagen, einer pro Lauf, Rest am Ende nennen) und die Ordnerübernahme. `ingest-large-tree.md` nennt `raw accept incoming/<ordner>` vor `work new`.
- [x] `raw/CONTRACT.md` sagt nirgends mehr, ein Unterordner werde toleriert oder ignoriert, und beschreibt Kandidatenbildung, Reihenfolge und die mtime-Grenze.
- [x] `docs verify`, `instructions verify`, `pytest` lokal grün (2119 passed, 3 skipped, auch auf leerer Maschine); CI auf dem publizierten Commit `59c06e5` grün (Run 509, verify + pwsh), ebenso auf der Nachzieh-Korrektur `100ace8` (Run 511).
- [x] CHANGES: Bump `--major` im laufenden 8.0.0-Kandidaten (`8.0.0-beta.27`) mit dem Bruch im Breaking-Change-Block.
Ausarbeitung des Stubs. Der ursprüngliche Text, wörtlich:
ohne weitere angabe selbst ein verfügbarer incoming eintrag aussuchen. dabei nur top level in betracht ziehen, ist es ein ordner, den gesamten unterordner als tree ingest bearbeiten, ist es ein file, es individuell in betracht ziehen.
Kriterium: älteres zuerst??? so dass neueres auf älterem wissen aufbaut bzw. es eher korrigieren kann.
Changelog: Body neu geschrieben - gegen den Baum geprüft (raw accept lehnt Tiefe >1 ab, raw fetch legt ein Dateipaar ab, Alt-Typverzeichnisse in incoming/), Mechanismus wikitool raw pending vorgeschlagen, vier offene Fragen benannt. Labels gesetzt, status/incoming entfernt. Bezug zu #111 vermerkt.
**Ausarbeitung des Stubs.** Der ursprüngliche Text, wörtlich:
> ohne weitere angabe selbst ein verfügbarer incoming eintrag aussuchen. dabei nur top level in betracht ziehen, ist es ein ordner, den gesamten unterordner als tree ingest bearbeiten, ist es ein file, es individuell in betracht ziehen.
>
> Kriterium: älteres zuerst??? so dass neueres auf älterem wissen aufbaut bzw. es eher korrigieren kann.
**Changelog:** Body neu geschrieben - gegen den Baum geprüft (`raw accept` lehnt Tiefe >1 ab, `raw fetch` legt ein Dateipaar ab, Alt-Typverzeichnisse in `incoming/`), Mechanismus `wikitool raw pending` vorgeschlagen, vier offene Fragen benannt. Labels gesetzt, `status/incoming` entfernt. Bezug zu #111 vermerkt.
torben
changed title from standardverhalten für wiki ingest to wiki-ingest ohne Argument: nächsten Eintrag aus incoming/ selbst wählen (`raw pending`)2026-10-03 06:17:27 +00:00
torben
changed title from wiki-ingest ohne Argument: nächsten Eintrag aus incoming/ selbst wählen (`raw pending`) to incoming/ als Warteschlange: wiki-ingest ohne Argument wählt selbst (`raw pending`), `raw accept` übernimmt einen ganzen Ordner2026-10-03 06:24:52 +00:00
Changelog: Die vier offenen Fragen sind vom Betreiber entschieden und stehen jetzt als E1-E4 im Body. #111 ist hier aufgegangen (Ordnerübernahme mit raw accept incoming/<ordner>, Struktur bleibt erhalten, der geleerte Ordner verschwindet), und die Toleranz für Unterordner in incoming/ wird gestrichen. Dadurch neu: Abschnitte A-D, die zu ersetzenden Tests und ein Versionsteil MAJOR im laufenden 8.0.0-Kandidaten statt MINOR. Die Markierung „nicht übernehmbar wegen Tiefe“ entfällt. Labels: kind/decision → kind/build (alles entschieden), size/M → size/L (Paket um #111 erweitert, mit einem Bruch).
**Changelog:** Die vier offenen Fragen sind vom Betreiber entschieden und stehen jetzt als E1-E4 im Body. #111 ist hier aufgegangen (Ordnerübernahme mit `raw accept incoming/<ordner>`, Struktur bleibt erhalten, der geleerte Ordner verschwindet), und die Toleranz für Unterordner in `incoming/` wird gestrichen. Dadurch neu: Abschnitte A-D, die zu ersetzenden Tests und ein Versionsteil **MAJOR** im laufenden 8.0.0-Kandidaten statt MINOR. Die Markierung „nicht übernehmbar wegen Tiefe“ entfällt. Labels: `kind/decision` → `kind/build` (alles entschieden), `size/M` → `size/L` (Paket um #111 erweitert, mit einem Bruch).
Changelog: Gebaut und publiziert als 8.0.0-beta.27 (Commit 59c06e5), verifiziert durch CI-Run 509; alle Akzeptanzkriterien sind abgehakt. Der Body steht jetzt im Perfekt („Was gebaut wurde“). Neu darin: die gemeinsame Prüflogik über _Refused (raw accept und raw pending nutzen dieselben Checks) und zwei Ergänzungen über den Design-Body hinaus, nämlich Spezialdateien im Ordner werden mit abgelehnt, und die Erfolgsmeldung nennt auch die work new --input-Zeile. Korrigiert: Unter „Was eine Instanz tun muss“ hieß es, Unterordner seien „vor dem Update“ zu bereinigen. Die Ordnerübernahme gibt es aber erst mit der neuen Version, deshalb heißt es jetzt „nach dem Update“, so wie auch in CHANGES.md. Der nicht blockierende Vorbehalt zu --breaking ist entfallen, weil version bump den Punkt angenommen hat.
**Changelog:** Gebaut und publiziert als `8.0.0-beta.27` (Commit `59c06e5`), verifiziert durch CI-Run 509; alle Akzeptanzkriterien sind abgehakt. Der Body steht jetzt im Perfekt („Was gebaut wurde“). Neu darin: die gemeinsame Prüflogik über `_Refused` (`raw accept` und `raw pending` nutzen dieselben Checks) und zwei Ergänzungen über den Design-Body hinaus, nämlich Spezialdateien im Ordner werden mit abgelehnt, und die Erfolgsmeldung nennt auch die `work new --input`-Zeile. Korrigiert: Unter „Was eine Instanz tun muss“ hieß es, Unterordner seien „vor dem Update“ zu bereinigen. Die Ordnerübernahme gibt es aber erst mit der neuen Version, deshalb heißt es jetzt „nach dem Update“, so wie auch in `CHANGES.md`. Der nicht blockierende Vorbehalt zu `--breaking` ist entfallen, weil `version bump` den Punkt angenommen hat.
Changelog: Der Body ist in den Endstand gebracht und steht als „abgeschlossen“. Der Abschluss-Check hat zwei veraltete Sätze gefunden, die der Pull-through vor dem Publish übersehen hatte. Das waren der Fehlerdatensatz von raw fetch --html („not under incoming/“) und in kb/CONTRACT.md die Abhilfe beim Pfadbudget, die nur die Datei nannte, nicht den Ordner. Beide sind nachgezogen als 8.0.0-beta.28 (Commit 100ace8), CI-Run 511 grün, Release-Workflow 512 grün. Ebenfalls geprüft und weiterhin korrekt: docs/pipeline-rationale.md, instructions/ingest-queue.md, types/source.guidance.md und die übrigen Abschnitte von raw/CONTRACT.md. Keine Installationsanleitung berührt.
Übergabe
Phase
Modell
Effort
Eigene Session?
Kontext übergelaufen oder kompaktiert?
1 Design (stack-dev)
unbekannt (Kommentare 06:16 und 06:25 nennen es nicht)
unbekannt
ja (vor /clear)
unbekannt
2 Build (stack-build)
Opus 5.5
niedrig (nicht high)
ja, nach /clear
nein
3 Abschluss (stack-close)
Opus 5.5
niedrig (nicht high), entgegen der Empfehlung im selben Lauf wie der Build
nein, gleiche Session wie Phase 2
nein
size/L. Anmerkung zur Bewertung: Der niedrige Effort hat sich im Abschluss gezeigt. Die beiden Funde aus dem Abschluss-Check sind genau die Konsistenz über mehrere Dateien, die der Build-Pull-through übersehen hatte.
**Changelog:** Der Body ist in den Endstand gebracht und steht als „abgeschlossen“. Der Abschluss-Check hat zwei veraltete Sätze gefunden, die der Pull-through vor dem Publish übersehen hatte. Das waren der Fehlerdatensatz von `raw fetch --html` („not under `incoming/`“) und in `kb/CONTRACT.md` die Abhilfe beim Pfadbudget, die nur die Datei nannte, nicht den Ordner. Beide sind nachgezogen als `8.0.0-beta.28` (Commit `100ace8`), CI-Run 511 grün, Release-Workflow 512 grün. Ebenfalls geprüft und weiterhin korrekt: `docs/pipeline-rationale.md`, `instructions/ingest-queue.md`, `types/source.guidance.md` und die übrigen Abschnitte von `raw/CONTRACT.md`. Keine Installationsanleitung berührt.
**Übergabe**
| Phase | Modell | Effort | Eigene Session? | Kontext übergelaufen oder kompaktiert? |
|---|---|---|---|---|
| 1 Design (`stack-dev`) | unbekannt (Kommentare 06:16 und 06:25 nennen es nicht) | unbekannt | ja (vor `/clear`) | unbekannt |
| 2 Build (`stack-build`) | Opus 5.5 | niedrig (nicht high) | ja, nach `/clear` | nein |
| 3 Abschluss (`stack-close`) | Opus 5.5 | niedrig (nicht high), entgegen der Empfehlung im selben Lauf wie der Build | nein, gleiche Session wie Phase 2 | nein |
`size/L`. Anmerkung zur Bewertung: Der niedrige Effort hat sich im Abschluss gezeigt. Die beiden Funde aus dem Abschluss-Check sind genau die Konsistenz über mehrere Dateien, die der Build-Pull-through übersehen hatte.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Stand: abgeschlossen (2026-10-03). Ausgearbeitet aus einem
status/incoming-Stub (Wortlaut im ersten Kommentar); die vier Designfragen hat der Betreiber am selben Tag entschieden. #111 (leerer Ordner bleibt nach dem Ingest stehen) ist hierin aufgegangen. Gebaut als8.0.0-beta.27(Commit59c06e5), verifiziert durch CI-Run 509 (verify + pwsh). Der Abschluss-Check hat zwei veraltete Sätze gefunden und nachgezogen:8.0.0-beta.28(Commit100ace8), verifiziert durch CI-Run 511.Was fehlte
wiki-ingestkannte nur den benannten Fall (Datei, Ordner, URL); ein bloßes „ingest“ war nirgends definiert. Gewünscht war: Ohne Angabe wählt die Sitzung selbst genau einen Eintrag ausincoming/und ingestet ihn, ältere zuerst, damit Neueres auf Älterem aufbaut oder es korrigiert.raw/.raw acceptnahm nur Dateien, höchstens eine Ebene unterincoming/. Es bündelte sie flach unter dem Stem der ersten Datei, verlor also den Ordnernamen, und ließ den geleerten Ordner stehen (ehemals #111). Ein Ordner mit Unterordnern war gar nicht übernehmbar.ingest-large-tree.mdsetzt aber voraus, dass der Baum schon unterraw/liegt (work new --inputlehnt alles außerhalb ab).source_type:auf der Source-Seite), undraw/ist nach Datum sortiert. Ein Unterordner inincoming/wurde nur noch „toleriert und ignoriert“. Diese Toleranz ist gestrichen: Ein Unterordner vonincoming/ist eine Quelle.Entscheidungen
E1 - Reihenfolge: mtime, älteste zuerst (Betreiber, 2026-10-03). Bei Gleichstand entscheidet der Name (Bytefolge des Pfads). Für ein Bündel oder einen Ordner zählt die jüngste mtime aller enthaltenen Dateien, rekursiv: Eine Einheit ist so neu wie ihr neuester Teil. Die Grenze steht in den Ausgabe-Notes und im Contract: Bei
cp -p/rsync -a/entpackten Archiven ist die mtime die letzte Änderung des Dokuments, bei Downloads undraw fetchnur der Ablagezeitpunkt. Verworfen wurden das Inhaltsdatum (verlangt das Lesen jedes Kandidaten, nicht mechanisch) und der Name allein (sagt nichts über das Alter).E2 - Ein Ordner ist eine Ingest-Einheit; die Stufe entscheiden die bestehenden Schwellen (Betreiber, 2026-10-03). Ob Standard-Ingest oder
ingest-large-tree, entscheidet wie bisher dessen § When to run (Volumen/Breite). Es gibt keinen Automatismus „Ordner = Tree-Ingest“: Drei Notizen verdienen keinen Workshop.E3 - #111 und #112 sind ein Paket (Betreiber, 2026-10-03). Die Ordner-Übernahme wurde hier gebaut, nicht getrennt.
E4 - Die Toleranz für Unterordner wird gestrichen (Betreiber, 2026-10-03; geprüft: Der Typ kommt aus dem Inhalt, die Ordner tragen keine Information mehr). Dateiargumente von
raw acceptundraw fetch --htmlmüssen direkt inincoming/liegen. Ein Unterordner wird nur als Ganzes übernommen. Für die vier alten Namen (articles,assets,documents,notes) gibt es keine Sonderbehandlung: Sie sind gewöhnliche Ordner, und leer sind sie keine Kandidaten. Nicht betroffen sind die alten Typverzeichnisse unterraw/(raw/articles/usw.):raw/ist immutabel,--replacesschreibt dorthin zurück, und_occupied_stemsunterscheidet sie strukturell.E5 - Kandidatenbildung in
incoming/(aus dem Baum abgeleitet):.gitkeepusw.) und leere Verzeichnisse sind keine Kandidaten.bundle). Dasraw fetch-Paar und PDF + konvertiertes Markdown sind lautraw/CONTRACT.mdeine Quelle in einemraw accept-Aufruf.folder) mit allen Dateien darunter, rekursiv.mcp-upload/sind keine Kandidaten.mcp-upload/liegt nebenincoming/, nicht darin, und eine Datei landet erst nach dem Upload Review Gate als gewöhnliche Datei inincoming/.Was gebaut wurde
Alles in
tools/chemenu/commands/raw_cmd.py. Die Vorab-Prüfungen (_check_directly_in_incoming,_check_files,_plan_file_moves,_plan_folder) werfen_Refused, statt sofortfail()aufzurufen.raw acceptmacht daraus Exit 1,raw pendingliest den Grund heraus. Die Prüflogik existiert also nur einmal.A.
raw accept incoming/<ordner>- einen Ordner als eine Quelle übernehmen--page, kein--replaces. Jede Kombination gibt Exit 1 und bewegt nichts.raw/<YYYY>/<MM>/<ordner>/…, die relative Struktur bleibt erhalten. Der Ordnername ist der Bündelname und unterliegt der Eindeutigkeitsregel (_occupied_stems). Die Dateien darin belegen keinen Namen, mehrereREADME.mdin einem Baum sind also kein Problem. Kollidiert der Ordnername, nennt die Meldung nur das Umbenennen inincoming/, denn ein--replacesfür Ordner gibt es nicht.--fidelity/--authoritysind Pflicht, ein Paar für den ganzen Ordner.incoming/und ist nicht leer. Im ganzen Baum gibt es keinen versteckten Eintrag, keinen Symlink und, als Ergänzung zum Design, keine Spezialdatei (FIFO o. Ä.); jeder solche Eintrag wird genannt. Jedes Ziel liegt im Pfadbudget, und keines existiert schon.incoming/<ordner>nicht mehr, und jede Datei liegt byte-identisch am selben relativen Pfad. Aufgeräumt wird mitrmdirje Verzeichnis, nie rekursiv löschend, undrmdirverweigert ein nicht leeres Verzeichnis. Taucht während des Laufs doch etwas auf, bleibt das Verzeichnis stehen, und es kommt eine WARN-Zeile.cli_contract-Datensatz. Ein halb übernommener Ordner wird nicht fortgesetzt.--dry-runlistet alle Bewegungen und das zu entfernende Verzeichnis.new source --set raw_files=…-Zeile mit demfidelity/authority-Paar. Als Ergänzung zum Design steht dort zusätzlich diework new --input raw/<YYYY>/<MM>/<ordner>-Zeile für einen Baum über den Large-Tree-Schwellen.B. Dateiargumente nur noch direkt in
incoming/(E4)raw accept incoming/<ordner>und das Hochziehen nachincoming/. Das gilt fürraw accept(auch mit--replaces) und fürraw fetch --html.C.
wikitool raw pending- die Warteschlange lesenfile/bundle/folder), Dateianzahl, mtime (ISO, lokale Zeit mit Offset) und ob er übernehmbar ist, sonst mit Grund. Die Standardwahl ist mit*markiert und wird in einer eigenen Zeile genannt, zusammen mit der Zahl der danach wartenden Einträge.raw acceptlaufen durch, Fidelity/Authority ausgenommen.--jsonliefertkind,paths,files,mtime,acceptable,reasonunddefault.effect read, idempotent,budget counted, kein Netz, Exit 0 auch bei leerem Eingang. Gelesen werden nur Verzeichnislisten undlstat, nie ein Inhalt. Incli_contract.GROUPSsteht das Kommando unter „Raw material and uploads“.D. Instruktionen und Doku
instructions/wiki-ingest/SKILL.md:descriptionund Trigger kennen „ingest“ ohne Argument, und ein Lauf ist eine Quelle. Schritt 1 behandelt den Fall ohne Argument (raw pendingaufrufen, die Standardwahl ansagen, keine Rückfrage, bei nichts Übernehmbarem Ende mit den Gründen) und den Fall Ordner (E2). In Schritt 5 steht die Ordnerübernahme an der Stelle der Toleranz-Sätze. Schritt 12 nennt am Ende die Zahl der wartenden Einträge. Kommandoliste und Beispiele sind ergänzt.instructions/ingest-large-tree.mdSchritt 2 nenntraw accept incoming/<folder>vorwork new --input raw/<YYYY>/<MM>/<folder>.raw/CONTRACT.md§ Getting a file in beschreibt: Dateien direkt inincoming/, der Ordner als Quelle mit seinen Prüfungen, warum die Toleranz gestrichen wurde, und die Warteschlange (Kandidaten, Reihenfolge, mtime-Grenze, Standardwahl).tools/CONTRACT.mdist aus den Datensätzen neu erzeugt.README.md: die Baumzeile, „Adding Knowledge“ (ein Ordner pro Quelle, „Ingest“ ohne Argument) und „Curate sources“.tools/README.mdist geprüft, dort war nichts zu ändern.CHANGES.mdüberversion bump, mit Changeset-Prosa.8.0.0-beta.28): Der Fehlerdatensatz vonraw fetch --htmlsagt jetzt „not directly inincoming/“ und nennt das Hochziehen. Inkb/CONTRACT.mdnennt der Absatz zum Pfadbudget für einen Ordner den kürzeren Ordner- oder Dateinamen als Abhilfe. Ebenfalls geprüft und weiterhin korrekt:docs/pipeline-rationale.md(Vertrauensgrenze vorincoming/),instructions/ingest-queue.md,types/source.guidance.mdund die übrigen Abschnitte vonraw/CONTRACT.md.Tests
In
tools/chemenu/tests/test_raw_cmd.pysind die vier Toleranz-Tests ersetzt: Eine Datei im Unterordner wird abgelehnt (Tiefe 1 und 2),--replacesaus einem Unterordner wird abgelehnt, und--replacesin ein Alt-Typverzeichnis funktioniert weiter. Neu sind 12 Testfunktionen zum Ordner (16 Fälle mit Parametrisierung) und 7 zuraw pending. Intest_raw_fetch.pykam ein Test für--htmlim Unterordner dazu. Die Ignore-Kanarieincoming/documents/probe.pdfist unverändert.Version
MAJOR im laufenden Kandidaten:
8.0.0-beta.27mit Impacthigh, dazu die Nachzieh-Korrektur8.0.0-beta.28mit Impactlow.version bumphat--breakingauf dem schon eskalierten Kandidaten angenommen, und der Bruch steht als eigener Punkt im Breaking-Change-Block.raw acceptundraw fetch --htmllehnen eine Datei in einem Unterordner vonincoming/ab. Ein Unterordner vonincoming/ist eine Quelle.incoming/ab. Dateien, die nach dem Update noch inincoming/<typ>/warten, werden hochgezogen oder, wenn sie zusammengehören, als Ordner übernommen. Das geht erst mit der neuen Version; die Design-Fassung hatte „vor dem Update“ geschrieben.--no-migration-Zeile des Kandidaten gilt weiter.Akzeptanzkriterien
raw acceptmit Ordnerincoming/baum/{a.md, sub/b.md, sub/deep/README.md}→ nach Erfolg liegen alle drei byte-identisch unterraw/<YYYY>/<MM>/baum/am selben relativen Pfad, undincoming/baumexistiert nicht mehr.x/README.md,y/README.md) werden beide übernommen.incoming/undraw/sind danach unverändert (Dateiliste plus Inhalte verglichen).--pageoder mit--replacesgibt jeweils Exit 1, nichts bewegt.raw/schon belegt ist, gibt Exit 1 mit dem Umbenennungsweg, nichts bewegt.--dry-runlistet alle Bewegungen, danach sindincoming/undraw/unverändert.sources coveragemeldet die Dateien des Ordners danach als ungedeckt (noch keine Source-Seite), keinen kaputten Verweis. Geprüft überuncovered_raw_files/broken_raw_refs, auf denensources coverageaufsetzt.Toleranz gestrichen
raw accept incoming/documents/a.pdfgibt Exit 1, die Meldung nennt Ordnerübernahme und Hochziehen, die Datei bleibt liegen. Dasselbe für--replacesundraw fetch --htmlmit einer Datei im Unterordner.raw accept incoming/a.pdf(Top-Level) funktioniert unverändert, ebenso Bündel aus mehreren Top-Level-Dateien.raw pending.gitkeep, leere Unterordner): Exit 0, kein Kandidat.incoming/post.html+incoming/post.md→ einbundle-Kandidat mit beiden Pfaden.folder-Kandidat mit n; seine Dateien erscheinen nicht einzeln.os.utimegesetzten mtimes: älteste zuerst; für Bündel und Ordner zählt die jüngste enthaltene mtime; Gleichstand nach Name.raw acceptablehnen würde (versteckter Eintrag, belegter Name, Pfadbudget), ist mit Grund als nicht übernehmbar markiert, und die Standardwahl ist der erste übernehmbare.incoming/,raw/,kb/sind nach dem Aufruf byte-identisch, mtimes unverändert.--jsonliefert dieselben Kandidaten in derselben Reihenfolge.Doku und Gates
wiki-ingestbeschreibt den Fall ohne Argument (Standardwahl ansagen, einer pro Lauf, Rest am Ende nennen) und die Ordnerübernahme.ingest-large-tree.mdnenntraw accept incoming/<ordner>vorwork new.raw/CONTRACT.mdsagt nirgends mehr, ein Unterordner werde toleriert oder ignoriert, und beschreibt Kandidatenbildung, Reihenfolge und die mtime-Grenze.docs verify,instructions verify,pytestlokal grün (2119 passed, 3 skipped, auch auf leerer Maschine); CI auf dem publizierten Commit59c06e5grün (Run 509, verify + pwsh), ebenso auf der Nachzieh-Korrektur100ace8(Run 511).--majorim laufenden 8.0.0-Kandidaten (8.0.0-beta.27) mit dem Bruch im Breaking-Change-Block.Ausarbeitung des Stubs. Der ursprüngliche Text, wörtlich:
Changelog: Body neu geschrieben - gegen den Baum geprüft (
raw acceptlehnt Tiefe >1 ab,raw fetchlegt ein Dateipaar ab, Alt-Typverzeichnisse inincoming/), Mechanismuswikitool raw pendingvorgeschlagen, vier offene Fragen benannt. Labels gesetzt,status/incomingentfernt. Bezug zu #111 vermerkt.standardverhalten für wiki ingestto wiki-ingest ohne Argument: nächsten Eintrag aus incoming/ selbst wählen (`raw pending`)wiki-ingest ohne Argument: nächsten Eintrag aus incoming/ selbst wählen (`raw pending`)to incoming/ als Warteschlange: wiki-ingest ohne Argument wählt selbst (`raw pending`), `raw accept` übernimmt einen ganzen OrdnerChangelog: Die vier offenen Fragen sind vom Betreiber entschieden und stehen jetzt als E1-E4 im Body. #111 ist hier aufgegangen (Ordnerübernahme mit
raw accept incoming/<ordner>, Struktur bleibt erhalten, der geleerte Ordner verschwindet), und die Toleranz für Unterordner inincoming/wird gestrichen. Dadurch neu: Abschnitte A-D, die zu ersetzenden Tests und ein Versionsteil MAJOR im laufenden 8.0.0-Kandidaten statt MINOR. Die Markierung „nicht übernehmbar wegen Tiefe“ entfällt. Labels:kind/decision→kind/build(alles entschieden),size/M→size/L(Paket um #111 erweitert, mit einem Bruch).Changelog: Gebaut und publiziert als
8.0.0-beta.27(Commit59c06e5), verifiziert durch CI-Run 509; alle Akzeptanzkriterien sind abgehakt. Der Body steht jetzt im Perfekt („Was gebaut wurde“). Neu darin: die gemeinsame Prüflogik über_Refused(raw acceptundraw pendingnutzen dieselben Checks) und zwei Ergänzungen über den Design-Body hinaus, nämlich Spezialdateien im Ordner werden mit abgelehnt, und die Erfolgsmeldung nennt auch diework new --input-Zeile. Korrigiert: Unter „Was eine Instanz tun muss“ hieß es, Unterordner seien „vor dem Update“ zu bereinigen. Die Ordnerübernahme gibt es aber erst mit der neuen Version, deshalb heißt es jetzt „nach dem Update“, so wie auch inCHANGES.md. Der nicht blockierende Vorbehalt zu--breakingist entfallen, weilversion bumpden Punkt angenommen hat.Changelog: Der Body ist in den Endstand gebracht und steht als „abgeschlossen“. Der Abschluss-Check hat zwei veraltete Sätze gefunden, die der Pull-through vor dem Publish übersehen hatte. Das waren der Fehlerdatensatz von
raw fetch --html(„not underincoming/“) und inkb/CONTRACT.mddie Abhilfe beim Pfadbudget, die nur die Datei nannte, nicht den Ordner. Beide sind nachgezogen als8.0.0-beta.28(Commit100ace8), CI-Run 511 grün, Release-Workflow 512 grün. Ebenfalls geprüft und weiterhin korrekt:docs/pipeline-rationale.md,instructions/ingest-queue.md,types/source.guidance.mdund die übrigen Abschnitte vonraw/CONTRACT.md. Keine Installationsanleitung berührt.Übergabe
stack-dev)/clear)stack-build)/clearstack-close)size/L. Anmerkung zur Bewertung: Der niedrige Effort hat sich im Abschluss gezeigt. Die beiden Funde aus dem Abschluss-Check sind genau die Konsistenz über mehrere Dateien, die der Build-Pull-through übersehen hatte.