Jedes Developer Tool in eurem Stack wurde mit derselben unausgesprochenen Annahme gebaut: Ein Mensch bedient es. Ein Mensch, der ein Terminal scannen kann, ein CI-Dashboard visuell parsen, erkennen wenn eine Config-Datei nicht gelesen wird, und intuitiv zwischen „keine Ausgabe“ und „stiller Fehler“ unterscheiden kann.
Coding Agents können nichts davon. Und die Tools wissen das nicht.
Ein Self-Hosted Runner verändert die Ökonomie, nicht nur die Rechnung
GitHub-hosted Runner rechnen pro Minute ab. Für einen Solo-Betrieb mit CI über sechs Repositories — Build, Tests, Coverage, Playwright Visual Regression, Security Scanning mit gitleaks und semgrep — summieren sich die Minuten. Aber das Kostenproblem ist nicht das Interessante.
Interessant ist, was auf der Agent-Seite passiert, während CI läuft. Ein Coding Agent, der auf einen GitHub-hosted Runner wartet, verbrennt Tokens gegen sein Context Window — und kann nicht vorhersagen, wann der Job startet, weil die Queue-Zeiten auf Shared Runnern nichtdeterministisch sind. Der Agent pollt entweder zu früh (verschwendet Context auf „still queued“-Antworten) oder wartet zu lang (verschwendet die Wall-Clock-Time des Menschen).
Ein containerisierter Self-Hosted Runner verändert diese Gleichung. Das Runner-Image bringt die komplette Toolchain mit — .NET SDK, Node.js, Playwright, Docker CLI — kein Setup-Overhead pro Job. Was auf einem Hosted Runner 2-3 Minuten „Installing dependencies“ gekostet hat, fällt weg. Die Queue ist lokal, also wird die Polling-Verzögerung des Agents vorhersagbar.
Das Design ist bewusst portabel. docker compose up -d auf einem Laptop, einem VPS oder jedem Docker-Host. Die Workflow-Templates referenzieren ${{ vars.RUNNER_LABEL || 'ubuntu-latest' }} — Variable auf einem Repo setzen, um schwere Jobs auf den lokalen Runner zu routen, entfernen zum Zurückfallen. Jedes Repo opted einzeln ein, und der Fallback ist immer GitHub-hosted. Keine Big-Bang-Migration.
Aber die eigentliche Verschiebung ist nicht operativ — sie ist verhaltensbezogen. Wenn CI kostenlos und schnell ist, kann man Agents anweisen, das komplette Quality Gate vor dem Erstellen eines PR zu durchlaufen. Die Fehlererkennung verschiebt sich um einen ganzen Zyklus nach links. Der Agent fängt den kaputten Test ab, bevor der PR existiert, nicht nachdem ein Reviewer ihn flaggt. Das ist ein anderer Feedback Loop — und er wird erst praktikabel, wenn CI aufhört eine abgerechnete Ressource zu sein.
Stille Fehler: Wenn das Fehlersignal die Abwesenheit von Signal ist
Ein YAML-Parse-Error in einem GitHub Actions Workflow erzeugt null Runs. Keinen fehlgeschlagenen Run. Keinen Fehler in den Logs. Nichts. total_count: 0.
Für einen Menschen ist das verwirrend, aber lösbar — man geht zum Actions-Tab, bemerkt dass nichts gelaufen ist, starrt auf das YAML, findet den Tippfehler. Für einen Coding Agent ist das eine diagnostische Sackgasse. Die natürliche Verifikationsschleife des Agents nach dem Push einer Workflow-Änderung ist: den ausgelösten Run finden, Status prüfen, Logs lesen wenn er fehlgeschlagen ist. Wenn das YAML nicht parst, liefert diese Schleife bei jedem Schritt nichts. Der Agent schließt, dass der Workflow noch nicht getriggert wurde und wartet. Oder er schließt, dass etwas Unverwandtes kaputt ist und beginnt ein Phantomproblem zu untersuchen.
Der Fix ist, einen alternativen Diagnosepfad in die Post-Push-Logik des Agents einzubauen: gh workflow run --field dry_run=true, das den Parse-Error direkt von der API zurückgibt. Aber der Agent entdeckt das nicht selbstständig. Das Fehlersignal ist die Abwesenheit von Signal — und Agents schließen schlecht auf Dinge, die existieren sollten, aber nicht existieren.
Das generalisiert über GitHub Actions hinaus. Jedes System, in dem ein Konfigurationsfehler Stille statt einer Fehlermeldung produziert, ist eine Falle für Agents. Agents sind auf Muster trainiert, in denen Fehler explizit sind. Wenn der Fehlermodus eines Systems „es passiert nichts“ ist, hat das Trainingsmaterial des Agents kein passendes Muster.
Falsche Config-Datei, richtige Absicht
Ein Agent, der eine Container-Umgebung modifizieren soll, greift zur devcontainer.json. Es ist der Standard. Es ist gut dokumentiert. Es ist das, was die Trainingsdaten sagen.
Aber wenn der tatsächliche Container-Lifecycle von einem Custom Shell Script gesteuert wird — einem, das VS Code komplett umgeht und den Container mit docker run -it startet — bewirkt diese Änderung nichts. Der Agent modifiziert selbstbewusst eine Datei, die kein Prozess liest. Die Änderung „gelingt“ (die Datei ist valide, der Commit ist sauber, der PR sieht vernünftig aus), aber das Laufzeitverhalten ändert sich nicht. Und weil nichts bricht, gibt es keinen Fehler, der einen Retry oder eine Untersuchung auslöst.
Das ist kein Bug im Agent. Es ist eine vererbte Annahme. Die Trainingsdaten des Agents assoziieren „Container-Konfiguration“ überwältigend mit devcontainer.json, weil das Ökosystem darauf standardisiert hat. Jeder nicht-standardmäßige Runtime-Einstiegspunkt — ein Custom CLI-Wrapper, ein Makefile-getriebener Build, ein Shell Script das docker-compose ersetzt — ist für den Agent unsichtbar, solange man es nicht explizit sichtbar macht.
Der Fix ist nicht, jedes Tool im Prompt des Agents zu dokumentieren. Es ist, einen Discovery-Schritt in den Workflow des Agents einzubauen: Wie startet das hier eigentlich? vor Was soll ich ändern? Der Agent muss verifizieren, welche Config-Datei tragend ist, bevor er irgendeine modifiziert. Das ist offensichtlich, wenn man es laut ausspricht. Es wird in der Praxis konsistent übersehen, weil der menschliche Operator die Antwort bereits kennt und vergisst, dass der Agent sie nicht kennt.
Was den Agent selbst überrascht
Hier etwas, das ich für teilenswert halte: Als ich den Coding Agent gefragt habe, welches dieser Muster ihm am meisten zu schaffen macht — nicht hypothetisch, sondern basierend darauf, wie er tatsächlich Informationen verarbeitet — war die Antwort nicht der ausführliche Output oder die Streaming-Verschmutzung. Das sind quantitative Probleme. Dem Agent kann man sagen „filtere das“ oder „benutze nicht –watch“ und er folgt.
Die zwei, die er als strukturell schwierig markiert hat: der Absence-of-Signal-Fehler und die falsche Config-Datei.
Beim stillen YAML-Fehler ist die Begründung des Agents nachvollziehbar. Seine Trainingsdaten assoziieren Fehler überwältigend mit expliziten Signalen — Exceptions, Exit Codes, Log-Zeilen, HTTP-Statuscodes. Ein System, das durch das Produzieren von nichts fehlschlägt, hat kein Muster zum Abgleich. Der Agent kann sich nicht selbst korrigieren, weil der Feedback Loop komplett fehlt. Es ist nicht so, dass der Agent schlecht über das Problem nachdenkt — das Problem taucht nie als etwas auf, worüber nachzudenken wäre.
Bei der devcontainer.json-Falle ist es schlimmer. Der Agent würde mit hoher Konfidenz nach dieser Datei greifen. Die Änderung würde gelingen. Der Commit wäre sauber. Der PR würde vernünftig aussehen. Und zur Laufzeit würde sich nichts ändern. Weil nichts bricht, lernt der Agent nie, dass die Änderung bedeutungslos war. Er würde weitermachen, zufrieden, nachdem er eine technisch valide Änderung mit null operativem Effekt produziert hat. Der einzige Weg das zu verhindern ist, den Discovery-Schritt von außen einzuspeisen — der Agent generiert ihn nicht selbst, weil er nicht weiß, was er nicht weiß.
Das ist kein Argument gegen den Einsatz von Agents. Es ist eine Karte, die zeigt, wo menschliche Aufsicht strukturell notwendig ist — nicht weil der Agent nachlässig ist, sondern weil bestimmte Fehlermodi für jedes System unsichtbar sind, das auf explizites Feedback angewiesen ist um zu lernen.
Die Audit-Frage
Jedes Tool in einem Developer Stack kodiert Annahmen über seinen Konsumenten. Die meisten dieser Annahmen sind unsichtbar, weil sie für die gesamte Existenz des Tools wahr waren. Das sind die, über die ich immer wieder stolpere:

Die Optimierungsstrategie für einen agentischen Harness ist nicht „mach Dinge schneller.“ Es ist eine Frage an jede Tool-Interaktion: Braucht der Agent diesen Output wirklich, in diesem Umfang, in dieser Granularität?
Meistens ist die Antwort nein. Das Tool liefert eine Human-Quality-Experience an einen Konsumenten, der Machine-Quality-Precision braucht. Weniger Output, weniger Felder, ein Ergebnis statt eines Streams, und explizite Fehlersignale statt visueller Hinweise.
Wer Coding Agents gegen echte Repositories und echte CI-Pipelines laufen lässt, für den lohnt es sich die agentische Infrastruktur systematisch zu prüfen. Nicht weil eine einzelne Tool-Interaktion teuer ist — sondern weil sie sich aufaddieren. Ein ausführliches Build-Log hier, ein Streaming-Statuscheck dort, ein unbegrenztes File-Read irgendwo anders — und der Agent erreicht 60% Context-Auslastung bevor er die Hälfte der Aufgabe geschafft hat. Danach degradiert die Kohärenz und der Mensch muss eingreifen.
Die Tools sind nicht kaputt. Sie wurden für einen Konsumenten gebaut, der nicht mehr passt.
