# ADR-0010: Auftragskatalog als geräteweise Zuweisung bestehender Merkmale **Status:** Beschlossen **Datum:** 03.08.2026 ## Kontext Nach der Kernschleife des Provisioning Agent (Check-in, Ansible-Pull, siehe `13-live-provisioning-boot.md` und `06-backend-api.md`) sollte als nächster Ausbauschritt ein „Auftragskatalog" entstehen: eine Sammlung einzeln zuweisbarer Aufgaben, die ein Gerät auch nach der Erstinstallation zusätzlich zu seiner Bereitstellungsvorlage bekommen kann, gruppiert in Kategorien. Zwei Anforderungen an diesen Katalog waren zu Beginn der Diskussion offen: 1. Ein Auftrag muss nach der Zuweisung auch wieder **abwählbar** sein, und das Abwählen muss real etwas zurückbauen, nicht nur zukünftige Anwendung verhindern. 2. Pro Gerät muss **transparent nachvollziehbar** sein, was wann wie durchgeführt wurde. Die naheliegende erste Frage war, ob dafür ein neues, eigenständiges „Auftrag"-Modell nötig ist, oder ob sich das bestehende Merkmal/Blueprint-Modell (ADR-0002, `12-feature-blueprint-model.md`) wiederverwenden lässt. Ein Auftrag im hier gemeinten Sinn ist fachlich nicht von einem Merkmal zu unterscheiden: eine einzelne, distributionsunabhängig benannte Eigenschaft, die pro Backend als Ansible-Rolle umgesetzt und über den bestehenden Ansible-Pull-Mechanismus angewendet wird. Der einzige Unterschied ist der Zuweisungsweg: ein Merkmal wird bisher ausschließlich über die Workspace-Zugehörigkeit einer Bereitstellungsvorlage zugewiesen (zum Zeitpunkt der Installation, für die Lebensdauer des Geräts fix). Ein Auftrag soll zusätzlich direkt einem einzelnen, bereits laufenden Gerät zugewiesen und wieder entzogen werden können. ## Entscheidung Ein Auftrag ist technisch ein Merkmal. Es wird kein separates Auftrag/Auftrag-Blueprint-Modell parallel zu Merkmal/Blueprint eingeführt. Merkmale, die für die geräteweise Ad-hoc-Zuweisung freigegeben sind, werden über ein neues Attribut `im_auftragskatalog` markiert und optional einer `Kategorie` zugeordnet (neues, eigenständiges Kernobjekt, siehe `09-data-model-v1.md`). Die Ad-hoc-Zuweisung eines Merkmals zu einem einzelnen Gerät ist eine neue, von der Workspace-Zugehörigkeit (`workspace_merkmale`) unabhängige Beziehung (`device_merkmale`), mit einem Aktiv-Flag statt einer reinen Zeile-existiert-oder-nicht-Semantik. Das Deselektieren eines Auftrags setzt dieses Flag auf inaktiv, statt die Zeile zu löschen. Für jedes Gerät wird beim Check-in der vollständige Soll-Zustand aller katalogfähigen Merkmale (nicht nur die neu hinzugekommenen) an den Agenten übermittelt, je Merkmal mit explizitem Zustand `present` oder `absent`. Das ist rein aus dem aktuellen Auswahlstand ableitbar und erfordert keine serverseitige Historie. Damit ein Deselektieren real etwas zurückbaut, muss die zugehörige Ansible-Rolle einen `absent`-Zweig besitzen; das ist eine Erweiterung der Rollenkonvention aus `12-feature-blueprint-model.md`, keine Änderung an diesem Dokument selbst. Für die Nachvollziehbarkeit pro Gerät wird ein einziges, generisches, ausschließlich anhängendes Ereignisprotokoll (`device_merkmal_events`) eingeführt, statt mehrerer spezialisierter Log-Tabellen. Ein `event_type`-Feld unterscheidet sowohl Auswahländerungen (`selected`, `deselected`) als auch vom Agenten gemeldete Ausführungsergebnisse (`applied`, `apply_failed`, `removed`, `remove_failed`). Damit der Agent Ausführungsergebnisse überhaupt melden kann, braucht die Check-in-API einen neuen, additiven Report-Kanal; dessen genaue Form wird nicht in diesem ADR, sondern bei der Umsetzung in `08-provisioning-api.md` spezifiziert. Workspace-komponierte Merkmale (nicht im Auftragskatalog) bleiben von dieser Änderung unberührt: sie werden weiterhin ausschließlich additiv über `--tags` angewendet, ohne `absent`-Zustand. Die Frage, ob sich eine Workspace-Zusammensetzung nachträglich für ein bereits provisioniertes Gerät ändern und zurückbauen lassen soll, ist ein separates, hier bewusst nicht adressiertes Problem. ## Konsequenzen Neue Merkmale, die in den Auftragskatalog aufgenommen werden sollen, brauchen zusätzlich zum bestehenden Blueprint pro Backend eine `absent`-Umsetzung in der jeweiligen Ansible-Rolle. Merkmale, die ausschließlich über Workspaces zugewiesen werden, sind davon nicht betroffen. Der Check-in-Response wird um einen expliziten `state`-Wert je Katalogeintrag erweitert; das ist rückwärtskompatibel additiv, kein Bruch der bestehenden, bereits gegen die QEMU-Testumgebung verifizierten Check-in-Antwort. Ein neuer Report-Endpoint wird nötig, damit Ausführungsergebnisse serverseitig sichtbar werden. Bis dieser existiert, bleibt die einzige Ausführungsevidenz lokal auf dem Gerät (`/run/tuxflotte/agent/applied/`), wie bereits heute. Das Datenmodell bleibt für künftige Auftragsarten erweiterbar, ohne neue Tabellen: neue Ereignisarten sind neue `event_type`-Werte, keine Schema-Änderung. Sollten künftig Aufträge nötig werden, die sich nicht als idempotenter Zielzustand beschreiben lassen (echte einmalige Aktionen ohne Present/Absent-Semantik), ist das ein eigenständiges, hier nicht getroffenes Entwurfsproblem. Details zum Datenmodell: `09-data-model-v1.md`. Details zum Merkmal/Blueprint-Grundmodell: `12-feature-blueprint-model.md`, ADR-0002.