# Gitea-Ingest — Tickets und Kommentare in die Ablage Umsetzung von [spine/core#13](https://git.42i.org/spine/core/issues/13). Code: `image/km/ingest_gitea.py`. Stand: Prototyp, läuft am Baum, noch nicht als Dienst. ## Was er tut Er liest Issues, Pull Requests und deren Kommentare aus einer Gitea-Instanz und legt **je Vorgang eine Markdown-Datei** in der km-Ablage ab: ``` //vorgaenge///.md ``` Die Datei ist das, was km über den Vorgang weiß — lesbar ohne den Dienst, in SilverBullet blätterbar, für die Suche indexierbar. Sie besteht aus: | Teil | Inhalt | |---|---| | Frontmatter | Forge, Namespace, Klassifikation, Repo, Nummer, Art (issue/pull), Titel, Zustand, Autor, Beteiligte, Labels, Milestone, Zuweisung, erstellt/aktualisiert/geschlossen, URL, **Verweise** | | Stand-Block | der `tldr`-Block aus dem Ticketkopf, wenn vorhanden, vor dem Body | | Body | der Ticket-Text | | Kommentare | alle, in Reihenfolge, mit Autor und Zeit; „(bearbeitet)" wenn nachträglich geändert | **Verweise** sind das, was über eine Volltextsuche hinausgeht: jedes `owner/repo#N`, jedes nackte `#N` (im eigenen Repo) und jede Ticket-URL in Body oder Kommentaren wird zu einem Eintrag `verweise:` im Frontmatter — also zu einer Kante, nicht einer Zeichenkette. Aufzählungen wie `42i/intern#193 / #198` werden dem qualifizierten Repo zugeordnet, nicht dem eigenen. ## Wie er läuft ```bash # Erstbefüllung oder Abgleich einzelner Repos AGENT_PERSONA=elton image/km/ingest_gitea.py --ablage /srv/km/ablage \ --repo spine/core --repo 42i/intern --repo live/live # alle Repos einer Organisation image/km/ingest_gitea.py --ablage /srv/km/ablage --org spine --org hive # zweite Forge, eigener Namespace KM_GITEA_URL=https://git.home KM_NAMESPACE=familie KM_CLASSIFICATION=home \ image/km/ingest_gitea.py --ablage /srv/km/ablage --org ahmann ``` - **Inkrementell.** Je Repo merkt er sich in einer Standdatei (`/../km-ingest-state.json`, außerhalb der Ablage) den Zeitpunkt des letzten vollständigen Durchlaufs und fragt Gitea nur nach seither geänderten Vorgängen (`since`, Gitea filtert nach `updated`). Ein geänderter Vorgang wird **komplett neu geschrieben** — ein umgeschriebener Body ist eine Änderung des Stands, kein Anhang. - **Idempotent.** Dieselbe Eingabe ergibt dieselbe Datei; unveränderte Dateien werden nicht angefasst. Damit ist `--full` zugleich der Abgleich aus spine/core#17: wiederholbar, mit belegbarem „zuletzt geprüft um". - **Abbruch ohne Lücke.** Der Stand wird erst nach vollständigem Durchlauf eines Repos gesetzt. Bricht ein Lauf ab, holt der nächste dieselben Vorgänge noch einmal — wiederholen ist billig, Lücken sind es nicht. - **Zugang** kommt aus OpenBao (`secret get git username|password`), wie beim Gitea-Helfer der Agenten. Nichts davon erscheint in Ausgabe, Kommandozeile oder Datei. Der Ingest **schreibt nichts nach Gitea** (die Festlegung aus #13: Vorgänge bleiben in der Forge, km liest). ## Gemessen am 2026-09-04 | Repo | Vorgänge | Dauer | Anmerkung | |---|---|---|---| | spine/core | 20 | 6 s | Erstbefüllung | | spine/core | 0 gesehen | 0,3 s | inkrementell, nichts geändert | | 42i/intern | 1165 | ~3 min | Erstbefüllung, noch ein API-Aufruf je Vorgang für die Kommentare | | live/live | 2175 | ~2 min | Erstbefüllung mit repo-weitem Kommentar-Endpunkt (ein Aufruf je 50 Kommentare) | | elf Repos (live, intern, spine/*, hive/*) | 2241 | 94 s | ein Lauf | Die erste Fassung holte die Kommentare je Vorgang und blieb bei live/live nach 371 Vorgängen an einer offenen Verbindung hängen. Seitdem gilt: bei der Erstbefüllung kommen die Kommentare **repo-weit** (`/issues/comments`, älteste zuerst), inkrementell je geändertem Vorgang. Dazu ein Verbindungs-Timeout und Fortschritt je 100 Vorgänge auf stderr. ## Was noch fehlt (Reihenfolge) 1. **Bus-Anschluss.** Heute ist der Ingest ein Aufruf; er soll von `wake.km` geweckt werden (spine/core#12: Gitea-Webhook → HTTP→Bus-Adapter → Bus → km) und dann den inkrementellen Lauf machen. Der periodische Abgleich bleibt daneben Pflicht. 2. ~~Suche über die Ablage.~~ Gebaut: SQLite mit FTS5 und sqlite-vec, siehe [index-suche.md](index-suche.md). 3. **Verknüpfung mit Doku und Memory.** Die `verweise:` sind erst Kanten zwischen Vorgängen. Kanten zu Doku-Seiten (ein Ticket, das eine Seite betrifft) und die Konsistenzprüfung gegen abgelegte Festlegungen kommen mit der prüfenden Schreibfunktion. 4. **Commit und Push** der Ablage nach dem Lauf, wie `wissens_mcp/repo.py` (Serialisierung, Rebase bei abgelehntem Push). Beim Prototyp am Baum läuft das noch von Hand. ## Offen aus #13, hier vorgeschlagen - **Historientiefe:** Erstbefüllung vollständig, weil sie ohnehin nur einmal anfällt und drei Minuten je tausend Vorgänge kostet. Ein Stichtag spart nichts Nennenswertes. - **Zwei Forges:** getrennt über `--namespace` und `--classification`; `git.home` → `familie`/`home`, `git.42i.org` → `42i`/`lan`. Mit einem km je Instanz (hive/core#61) liegt die Familien-Forge ohnehin in einem anderen Dienst.