Denkmaschinen · Teil 7 · Serien-Finale · 27. Juli 2026

Von "wir bräuchten mal..." zum auditierbaren Release: die Pipeline am Stück

Teil 7 (Finale) einer Artikelserie über zwei eigene Agenten-Projekte: wintermute (produktiver persönlicher KI-Agent) und agenticframework (produktiv eingesetztes Meta-Framework für autonome Entwicklungs-Pipelines).

Alle Teile zusammensetzen

Sechs Teile lang habe ich einzelne Aspekte herausgegriffen: Sicherheitsgrenzen, Halluzinations-Abwehr, Kostenmodell, Autonomie-Grenzen. Zum Abschluss die Frage, für die agenticframework eigentlich gebaut ist: Was passiert zwischen dem Satz "wir bräuchten mal eine Möglichkeit, X zu tun" und einem Release, dessen Zustandekommen man drei Wochen später noch lückenlos nachvollziehen kann?

Die Antwort ist eine Pipeline aus sechs Phasen, jede mit einem verantwortlichen Agenten: Discovery (Ada) → Architektur (Daedalus) → Zerlegung (Tess) → Orchestrierung und Coding (Seldon + Case) → Review und Security (Argus + Molly) → Validierung und Integration (Turing + Forge). Das Interessante ist aber nicht die Liste — es ist das, was zwischen den Phasen passiert.

Das Bindegewebe: typisierte Übergaben

Jede Phase hat genau ein Eingabe- und ein Ausgabedokument, und alle teilen denselben Umschlag:

kind:                 string   - discriminator for routing (e.g. "intent_handover")
schema_version:       string   - contract version used for validation/migration
pipeline_stage:       string   - e.g. "phase1->phase2", "phase2->phase3"
hitl_approved:        bool     - must be true before the next phase starts
generated_at:         ISO-8601 UTC timestamp
source_agent_id:      string
source_agent_version: string
trace_id:             string   - correlates artifacts to a PipelineRunManifest

Dieser Umschlag ist die halbe Architektur. kind und pipeline_stage machen jede Übergabe eindeutig adressierbar, schema_version erlaubt Migration, hitl_approved erzwingt die Freigabe-Disziplin aus Teil 6, und trace_id verbindet jedes Artefakt mit seinem Pipeline-Lauf. Agenten sind dadurch vollständig entkoppelt: Daedalus weiß nichts über Adas Innenleben — er kennt nur den IntentHandover-Vertrag. Man kann jeden Agenten austauschen, solange der Vertrag hält (und dass er hält, prüft die Schema-Validierung aus Teil 3 an jeder Grenze).

Phase 1: Aus Vagheit wird ein Vertrag

Am Anfang steht das unschärfste Artefakt der Softwareentwicklung: menschliche Absicht. Ada zerlegt sie in strukturierte Datensätze — Ziele, Fakten, Konflikte — und bewertet jede Analyse mit einem Ambiguity-Score. Unklares erzeugt gezielte Rückfragen, Widersprüche landen beim Menschen zur VETO/RESOLVE-Entscheidung (die Resolver-Rolle aus Teil 6). Das Ergebnis ist bewusst schmal:

class IntentHandover(HandoverEnvelope):
    kind: Literal["intent_handover"] = "intent_handover"
    pipeline_stage: Literal["phase1->phase2"] = "phase1->phase2"
    source_agent_id: Literal["ada"] = "ada"
    hitl_approved: bool
    goals: list[str]
    scoped_facts: list[str]
    open_conflicts: list[str]

Ein Detail mit Tiefgang: scoped_facts enthält nur die Fakten, die der Mensch explizit für den Scope ausgewählt hat — die vollständige Liste bleibt für Audit-Zwecke erhalten. Scope-Entscheidungen sind damit dokumentierte Entscheidungen, kein Nebeneffekt dessen, was der Agent zufällig für relevant hielt. Daedalus macht daraus anschließend das Architektur-Paket: Domain-Modell, ADR-Referenzen, Modul-Briefs und eine Zerlegungsstrategie für die nächste Phase.

Phase 3: Ein Graph, der sich gegen Zyklen wehrt

Tess zerlegt die Architektur in atomare Issues (die Sizing-Budgets kennen Sie aus Teil 4) plus einen Abhängigkeitsgraphen. Und dieser Graph validiert sich selbst — Zyklenfreiheit ist keine Konvention, sondern Teil des Pydantic-Schemas:

@model_validator(mode="after")
def dependency_graph_is_acyclic(self) -> DecomposerHandover:
    issue_ids = {issue.issue_id for issue in self.atomic_issues}
    # ... keys must match issue ids, no unknown dependencies ...
    visiting: set[str] = set()
    visited: set[str] = set()

    def visit(node: str) -> None:
        if node in visiting:
            raise ValueError("dependency graph must be acyclic")
        # ... DFS ...

Ein Zerlegungsplan mit Zirkelbezug ("A braucht B, B braucht A") kann die Phasengrenze physisch nicht passieren — er ist kein gültiges Dokument. Das ist dasselbe Prinzip wie überall in dieser Serie: Eigenschaften, auf die man sich verlassen will, werden nicht erhofft, sondern am Typ erzwungen.

Phase 4: Warum es atomare Diffs sein müssen — die 22-KB-Geschichte

Dass Case, der Coding-Agent, ausschließlich Unified Diffs produziert und niemals ganze Dateien überschreibt, hat eine konkrete Vorgeschichte in wintermute: Beim Self-Modification-Experiment (Teil 6) ließ das damals verwendete Modell bei Dateien ab etwa 22 KB stillschweigend den content-Parameter aus dem Tool-Call fallen. Kein Fehler, keine Warnung — der Schlüssel fehlte einfach. Ein disziplinierter Plan, ein korrekter Prompt, und trotzdem landete nichts Committbares. Diese Erfahrung steht heute wörtlich als Constraint im Routing-File von agenticframework:

constraints:
  - "Atomic diffs only, never whole-file writes. See section 1.5 Wintermute lessons for rationale."
  - "Output must stay within ~500 tokens per model call; larger changes must be chunked."
  - "Client-side schema validation before tool invocation and after model output."

Und die Skepsis reicht bis in die Tests: Ein eigener Testfall stellt sicher, dass das CodeHandover seine files_changed-Liste aus dem geparsten Diff bezieht — nicht aus den Metadaten, die der Modell-Provider behauptet. Selbst wenn das Modell falsche Dateinamen meldet, zählt, was im Diff tatsächlich steht. Vertrauen ist gut, Parsen ist besser.

Phase 5 und 6: Gates und das Ende der Reise

Die parallelen Qualitäts-Gates (Argus/Molly, inklusive des nicht überstimmbaren Security-Vetos) haben ihren eigenen Artikel in Teil 2. Danach übernimmt Phase 6: Turing führt die Integrationstests aus und protokolliert Kommandos, Ergebnisse und ein Go/No-Go-Verdict im ValidationHandover; Forge übernimmt die Integration und liefert das IntegrationResult mit Zusammenfassung und Referenzen auf alle integrierten Artefakte. Erst hier wird aus einer Kette validierter Dokumente ein Release.

Der Audit-Trail: Jeder Lauf erzählt seine Geschichte selbst

Was diese Pipeline von einem Skript mit sechs Schritten unterscheidet, ist die Buchführung. Jeder Lauf hat ein Manifest, das festhält: den Eingabe-Handover, die aktuelle Phase, Agent-Versionen, Modell-Auswahlen, alle Artefakt-Referenzen, alle Gate-Entscheidungen, alle menschlichen Entscheidungen, Kostenschätzungen und strukturierte Fehler. Parallel dazu läuft ein append-only Event-Log (NDJSON) mit Phasenübergängen, Agent-Starts, Retries und Eskalationen. Beides liegt — zusammen mit jedem Handover-Dokument — im "Transient Repository", einem Git-gestützten Ablagesystem:

runs/<run-id>/manifest.json          ← PipelineRunManifest
runs/<run-id>/events.ndjson          ← RunEventLog (append-only)
runs/<run-id>/artifacts/<phase>/...  ← jedes Handover-Dokument, versioniert

Jeder Schreibvorgang ist ein Commit; jeder Zustand der Pipeline ist reproduzierbar und zurückspulbar; alle Dokumente sind Markdown und JSON, für Menschen lesbar. Die Frage "warum hat das System vor drei Wochen diese Entscheidung getroffen?" beantwortet sich per Checkout — nicht per Meeting-Archäologie.

Der ehrliche Schluss: Für wen sich das lohnt — und für wen nicht

Nach sieben Teilen bin ich Ihnen ein letztes Stück Ehrlichkeit schuldig. Diese Maschinerie — typisierte Verträge, dreifach geprüfte Ticket-Budgets, Manifeste, Event-Logs — ist für ein Wochenend-Feature absurdes Overengineering. Ihr Wert entsteht dort, wo drei Dinge zusammenkommen: Volumen (Teil 4: die Unit Economics greifen ab Dutzenden Läufen), Nachweispflicht (der Audit-Trail ist für Compliance-Kontexte gebaut, nicht für Hobby-Projekte) und Arbeitsteilung über Rollen hinweg (die Verträge lohnen sich, wenn nicht eine Person alles im Kopf hat). Und: Die Pipeline ist nur so gut wie ihre erste Phase. Ein sauber durchvalidierter, lückenlos auditierter Lauf auf Basis einer schlecht geklärten Anforderung produziert das falsche Feature — mit exzellenter Dokumentation. Deshalb beginnt die Pipeline mit Ada und einem Ambiguity-Score, und deshalb begann diese Serie mit der Frage nach dem Warum, nicht mit der Technik.

Serien-Fazit

Sieben Teile, zwei Repositories, ein roter Faden: Behauptungen werden geprüft, Entscheidungen werden begründet, Grenzen werden technisch durchgesetzt, und Scheitern wird dokumentiert. Nichts davon ist an KI-Agenten gebunden — es ist Software-Engineering, angewendet auf eine Technologie, die zum Abkürzen verführt wie keine zweite. Wenn Sie aus der Serie einen einzigen Satz mitnehmen: Der Unterschied zwischen einem Agenten-Demo und einem Agenten-System liegt nicht im Modell, sondern in allem drumherum.

Danke fürs Mitlesen. Die beiden Lessons-Logs wachsen weiter — und wenn sich genug Neues angesammelt hat, gibt es einen Nachschlag.


Quellen: agenticframework/FRAMEWORK.md (Phasenmodell, Handover-Envelope Zeilen 454–488, Manifest/Event-Log Zeilen 162–174, Transient Repository Zeilen 678–757), apps/intent-compiler/INTENT_COMPILER.md (Ada-Discovery-Mechanik), apps/intent-compiler/backend/src/api/models/state.py (IntentHandover Zeilen 164–193), orchestrator/src/agentic_orchestrator/phases/results.py (ArchitectHandover, DecomposerHandover inkl. Zyklen-Validator, ValidationHandover, IntegrationResult), orchestrator/src/agentic_orchestrator/kernel/models.py (PipelineRunManifest, RunEventLog), model_routing.yml (Atomic-Diff-Constraints), apps/intent-compiler/backend/tests/test_case_diff_validation.py (Parser-Metadaten statt Provider-Behauptung); wintermute/LESSONS.md (Lesson #25: die 22-KB-Geschichte).