Wie prüft man ein WebAssembly-Plugin für KI-Agenten?
Die CI des covey-Katalogs baut ein Wasm-Plugin aus Quellstand und Go-Version nach und nimmt es nur an, wenn die Bytes zum Digest im Eintrag passen.
Ein Plugin für einen KI-Agenten aus einem fremden Repository verlangt vor der Installation eine Prüfung. Bei einem JSON-Manifest bleibt diese Prüfung überschaubar. Der Pull Request zeigt die ganze Datei mit jeder Aktion samt Methode und Pfad, und eine spätere Änderung erscheint als Diff von wenigen Zeilen.
Bei einem WebAssembly-Modul fehlt diese Abkürzung. Im Katalogeintrag stehen nur eine Adresse und ein Digest über kompilierten Code. Der verlinkte Quelltext liegt daneben, ohne dass etwas die beiden Dinge miteinander verbindet.
Ein Manifest liest man im Diff, ein Modul muss man nachbauen
Der covey-Katalog verteilt neben Manifesten und MCP-Konfigurationen auch Module mit kind: "wasm". Das sind gewöhnliche Go-Programme, die mit GOOS=wasip1 GOARCH=wasm übersetzt wurden. Ein solches Modul ist das Plugin vulndb, das Lock-Dateien gegen OSV.dev abgleicht und bis covey 0.5.0 fest im Binary steckte. Seine Version 1.0.0 liegt als vulndb.wasm im Release v0.7.0 des Repositorys covey-plugin-pack.
Die Spec stellt beide Fälle nebeneinander. Ein Manifest lässt sich im Pull Request prüfen, weil der Diff das Verhalten zeigt. Ein Binary wird für die Prüfung neu gebaut.
Der Katalogeintrag nennt Quellstand, Go-Version und Digest
Für Einträge mit kind: "wasm" verlangt das Schema des Index-Repositorys covey-plugins in jeder Version einen Block build. Pflichtfelder darin sind repo, ref und go, optional kommt dir für das Unterverzeichnis hinzu. Beim Plugin vulndb stehen dort das Repository covey-plugin-pack, der Commit c6da03f0, die Go-Version 1.26.6 und das Verzeichnis wasm/vulndb. Daneben steht der sha256 des Moduls, der mit 85a9a640 beginnt.
Die Anleitung für Autoren verlangt für die Adresse des Artefakts einen Tag oder einen Commit, und das Schema beschreibt den Quellstand in ref ebenso als Tag oder Commit. Eine Adresse auf einen Zweig besteht die Prüfung einmal und driftet danach von ihrem Digest weg. Deshalb erkennt das Skript build_catalog.py bei einigen Adressformen von GitHub, GitLab und Gitea Artefaktadressen, die auf Zweige wie main, master oder trunk zeigen, und weist sie mit einer Fehlermeldung ab.
Die CI des Katalogs baut das Modul nach und vergleicht die Bytes
Der Workflow rebuild.yml läuft bei jedem Pull Request und jedem Push auf main des Index-Repositorys. Für jede Version mit build-Block klont er das genannte Repository und wechselt auf den genannten Stand. Danach lädt er genau die genannte Go-Version von go.dev, da ein anderer Compiler andere Bytes erzeugt.
Gebaut wird im Verzeichnis aus dir mit -trimpath. Den sha256 des Ergebnisses vergleicht der Job mit dem Digest aus dem Eintrag und scheitert bei einer Abweichung mit beiden Werten in der Fehlermeldung. Für vulndb übersetzt die CI also den Commit c6da03f0 mit Go 1.26.6. Sie besteht nur, wenn dabei wieder das Modul mit dem Digest 85a9a640 herauskommt.
Das funktioniert, weil Go seine wasm-Ausgabe unter diesen Bedingungen bytegleich erzeugt. Spec und Workflow nennen das auf verschiedenen Maschinen und Pfaden nachgeprüft. Ohne -trimpath landet der Build-Pfad im Binary, und zwei Builds desselben Quelltexts unterscheiden sich.
Die Vorlage covey-plugin-template setzt das Flag deshalb im Makefile. Ihr make build gibt Digest und Go-Version für den Katalogeintrag aus. In ihrer eigenen CI baut sie bei jedem Push ein zweites Mal in einem anderen Verzeichnis und vergleicht beide Ergebnisse. Ein Reviewer im Index liest damit den Quelltext und prüft, ob der Code tut, was die Beschreibung verspricht.
Die Instanz baut nichts nach, sie prüft gegen den Eintrag und legt neue Module deaktiviert an
Die covey-Instanz selbst überlässt den Nachbau dem Katalog. Beim Installieren aus dem Katalog lädt internal/marketplace das Artefakt von der Adresse im Eintrag und berechnet den sha256. Bei einer Abweichung bricht die Installation ab und nennt den erwarteten und den gefundenen Wert.
Dazu kommt die Mindestversion. Verlangt ein Eintrag mit covey_min_version eine neuere Version als die bekannte Version der Instanz, lehnt covey die Installation ebenfalls ab. Bei vulndb liegt diese Grenze bei 0.6.0. Ein neu installiertes Modul landet mit Quelle, Version und Digest in der Datenbank und bleibt deaktiviert, bis jemand in der Organisation es einschaltet.
Der Nachbau verlagert das Vertrauen auf den Merge in den Index
Dass der Digest zum Quelltext passt, weiß eine Instanz allein aus der CI des Index. Der Katalog arbeitet ohne Signaturen, und die Spec nennt den geprüften Pull Request als Anker des Vertrauens. Wer einen eigenen Katalog aus einer anderen Quelle ausliefert, bekommt den Nachbau nur mit einer eigenen Pipeline.
Dazu kommt ein Preis im Betrieb. Der Workflow baut bei jedem Lauf sämtliche Wasm-Versionen des Katalogs neu. Ist ein Quell-Repository nicht mehr erreichbar, scheitert damit jeder weitere Pull Request am Index, bis der Eintrag angepasst oder entfernt ist. Eine zurückgezogene Version verhindert laut Anleitung nur neue Installationen, und Instanzen mit dieser Version behalten sie.
Für ein Plugin wie vulndb verschiebt sich die Frage nach dem Vertrauen damit von einem kompilierten Binary auf zwei lesbare Dinge mit Geschichte: einen Commit im Quell-Repository und einen Merge im Index.