Das Archyl Harness: Coding-Agenten, die ihre Arbeit anmelden, bevor sie anfangen

Letzte Woche habe ich über drei Agenten, drei Pull Requests und ein inkohärentes System geschrieben. Der Post endete mit einer Übung: Nimm die letzte Woche, in der dein Team mehr als einen von einem Agenten geschriebenen Pull Request gemerged hat, lies sie nebeneinander, und frag, was dir in deinem jetzigen Setup gesagt hätte, dass sie sich uneinig waren.

Ich habe das an unserem eigenen Repository gemacht, und die Antwort war nichts. Nicht "dem Reviewer ist es irgendwann aufgefallen", nicht "die CI hat die Hälfte abgefangen". Nichts, denn keiner der Agenten hat je gesagt, was er gleich tun würde. Jeder hat das Repository gelesen, Code geschrieben und einen Pull Request geöffnet. Der erste Moment, in dem ein Mensch sehen konnte, dass zwei von ihnen am selben Service arbeiten, war das Review, und das ist der letzte Moment, und bis dahin waren beide damit fertig, sich sicher zu sein.

Also haben wir den fehlenden Schritt gebaut. Das Archyl Harness ist diese Woche live gegangen. Es ist kein weiterer Coding-Agent. Es sitzt über den Agenten, die du ohnehin schon laufen lässt, und bringt jeden einzelnen dazu, eine Arbeitseinheit anzumelden, gegen die dokumentierte Architektur, bevor er irgendetwas anfasst.

Eine Work Session von innen

Die Schleife besteht aus vier Calls, exponiert als MCP-Tools. Ein Agent plant, öffnet eine Session, arbeitet und schickt dabei Heartbeats, und schließt die Session mit dem, was tatsächlich passiert ist.

Hier ist der zweite dieser Calls, aus einer echten Session am Archyl-Projekt selbst, gekürzt:

▶ start_work_session(
    task: "rank recalled memories by freshness so stale facts stop winning",
    agentName: "claude-code/vincent")

# Harness Session

- **Session ID**: `24643fa6…`
- **Gate**: warn
  - 1 target element(s) are being worked on by other active sessions — coordinate before changing them
- **Leased elements** (you are the announced worker on these):
  - component `Harness Service`
  - container `MCP Server`
- **Conflicts** (someone else is already working here):
  - MCP Server — held by claude-code/memory-ui: render the memory graph with element clusters

**Protocol**: call `heartbeat_work_session` at least every 30 minutes while working,
and `finish_work_session` with a summary (and decisions worth recording) when done.

## Most relevant elements

- **Harness Service** (component) — `backend/internal/service/harness`
  Work sessions, leases, preflight gate, element memory.

## Related decisions (respect these)

- ADR-5: Agents propose, humans merge [accepted]

## What previous sessions did here

- **MCP Server** [PITFALL] (claude-code/vincent, 1 day ago): every new ID argument
  name must be added to idArgumentResolvers in authz.go, or the cross-org check
  silently skips it.

Vier Dinge sind in diesem einen Call passiert, und keines davon kann eine Rules-Datei.

Die Aufgabe wurde gegen das C4-Modell aufgelöst, also hat der Agent die Scheibe Architektur bekommen, auf die es ankommt, statt der ganzen. Advisory Leases wurden auf die Elemente genommen, die er gleich ändern wird, und genau so erfährt der nächste Agent von diesem hier. Das Preflight Gate hat ein Verdict zurückgegeben. Und das Briefing hat die Entscheidungen mitgebracht, die die Arbeit einschränken, plus das, was der letzte Agent, der hier stand, auf die harte Tour gelernt hat.

Diese letzte Zeile ist Memory, und das verdient einen eigenen Post statt eines Absatzes in diesem. Die Kurzfassung: Sessions hinterlassen Notizen, Konventionen und Fallstricke an Architekturelementen, und die nächste Session bekommt sie automatisch zurück.

Das Gate hat drei Verdicts, und deny ist das seltene

Das Preflight Gate ist bewusst klein. Es beantwortet eine Frage, bevor die Arbeit beginnt, mit einem Verdict, mit dem der Agent etwas anfangen kann.

allow heißt: Keine andere Session hält ein Lease auf deinen Zielelementen, und kein Guardrail auf Error-Level trifft auf die Aufgabe zu. Weitermachen.

warn ist das häufige, und es kommt mit Gründen. Eine andere Session arbeitet schon an einem Element, das du gleich änderst, oder eine Conformance Rule mit der Severity error deckt diese Aufgabe ab. Der genaue String im ersten Fall ist der, den du oben gesehen hast: N target element(s) are being worked on by other active sessions — coordinate before changing them. Der Agent macht weiter, aber er muss jeden gelisteten Grund adressieren, und die Gründe nennen Namen.

deny passiert nur, wenn eine Session danach fragt. Übergib exclusive: true, und ein Lease-Konflikt stoppt die Session, statt sie zu warnen. Das ist das Flag für Arbeit, die mit niemandem in ein Rennen geraten darf: eine Schema-Migration, eine Contract-Änderung, ein Rename, das jeden Aufrufer berührt. Die Session öffnet nie, und dem Agenten wird gesagt, er soll sich beim User melden, statt drumherum zu routen.

Hier präzise zu sein zählt mehr, als das Gate clever klingen zu lassen. deny ist keine Policy-Engine. Es liest nicht deinen Plan und lehnt ihn aus Prinzip ab. Es weigert sich, zwei Agenten dasselbe Element beanspruchen zu lassen, wenn du gesagt hast, dass dieses Element exklusiv ist, und alles andere ist eine Warnung, für die der Agent geradestehen muss.

Der Guard überwacht die Writes

Die Session deckt die Absicht ab. Der Guard deckt ab, was tatsächlich geschrieben wird.

Er ist ein PreToolUse-Hook für Claude Code, installiert mit dem Plugin. Bevor der Agent eine Datei schreibt oder editiert, rekonstruiert der Hook die Datei so, wie sie nach dem Edit aussehen würde, schickt sie an die Conformance Rules deines Projekts und liest das Verdict. Ein kritischer Verstoß blockiert den Write und gibt den Grund an den Agenten zurück:

Archyl Guard: this change violates the project's architecture rules for
backend/internal/adapter/http/handlers/report.go:
- [critical] No direct database access from HTTP handlers — move the query
  behind a service

Adjust the change to respect these rules, or ask the user whether to override them.

Der Agent liest das, repariert das Layering und macht weiter. Kein Mensch wurde unterbrochen, und der Verstoß hat nie einen Branch erreicht.

Zwei Design-Entscheidungen sollte man klar aussprechen. ARCHYL_GUARD_BLOCK steuert die Schwelle: critical per Default, high um mehr zu blockieren, off um nur zu warnen. Und der Hook ist überall fail-open. Kein API-Key, kein Netz, kein installiertes jq, eine langsame Antwort: Der Edit läuft unangetastet durch. Ein Governance-Tool, das jemandem die Editier-Session zerschießen kann, ist in einer Woche wieder deinstalliert, also kann es das nicht.

Die Schleife schließen

finish_work_session nimmt ein ehrliches Ergebnis entgegen: eine Zusammenfassung, die Entscheidungen, die es wert sind, festgehalten zu werden, die Follow-ups, die liegen geblieben sind. Die Leases werden freigegeben, die Zusammenfassung wird an die Elemente geheftet, die die Session gehalten hat, und wenn die Arbeit die Architektur verändert hat, öffnet createChangeRequest: true einen Architecture Change Request als Draft.

Das ist der Teil, der das Modell davon abhält, still abzudriften. Ein Agent, der einen Service umbaut, editiert nicht heimlich das C4-Modell. Er reicht einen Vorschlag ein, ein Mensch liest, wie die Dokumentation nachziehen sollte, und der Merge läuft durch die Versionsprüfung, über die wir letzte Woche geschrieben haben. Agenten schlagen vor. Menschen mergen. Wir haben nicht vor, diese Grenze zu entfernen.

Über allem zeigt die Fleet console im Agent Hub jede Session in der Organisation live: wer arbeitet, woran, welche Elemente er hält, hinter welchem Gate, wie frisch sein letzter Heartbeat ist. Elemente unter einem aktiven Lease zeigen außerdem einen Working-Indikator direkt im C4-Diagramm, und das ist die Ansicht, in der "hier drin ist schon jemand" tatsächlich nützlich ist.

Wir haben es unter sich selbst gebaut

Das Harness wurde von Agenten gebaut, die unter dem Harness gearbeitet haben, an einem Archyl-Projekt, das Archyl dokumentiert.

Das war keine Demo. Es war der einzige Weg herauszufinden, ob die Schleife den Kontakt mit echter Arbeit übersteht, und es hat das Produkt mehrfach verändert. Sessions sind echt auf warn gelaufen, an echten Konflikten, weil zwei Agenten tatsächlich denselben Container in derselben Stunde editiert haben. Der Fallstrick im Transkript oben ist eine Memory, die eine Session geschrieben hat, nachdem sie einen Nachmittag daran verloren hatte, und eine spätere Session hat sie in ihrem Briefing zurückbekommen, bevor sie dieselbe Datei angefasst hat. Drei Architecture Change Requests sind aus diesen Sessions entstanden, jeder davon ein Mensch, der reviewt, wie das Modell mit dem nachziehen soll, was ein Agent gerade getan hat.

Es hat auch kleinere Korrekturen produziert, die nur Dogfooding an die Oberfläche bringt. Das Gate-Badge in der Console hat früher für allow einen neutralen Chip gerendert, bis jemand angemerkt hat, dass ein Badge, das in jeder Zeile "nichts ist falsch" anzeigt, Rauschen ist. Es rendert jetzt gar nichts mehr, wenn das Verdict allow ohne Gründe ist, und die Begründung dahinter wurde als Konvention am Projekt gespeichert, damit der nächste Agent, der diese Component anfasst, sie nicht hilfsbereit wieder einbaut.

Die Installation ist ein Befehl

Aus dem Root deines Repositories:

curl -fsSL https://raw.githubusercontent.com/archyl-com/agent-skills/main/templates/setup.sh | bash

Es fragt nach deinem Projekt und einem API-Key und schreibt dann drei Dinge: eine .mcp.json, die auf Archyls MCP Server mit ?profile=coding zeigt, eine committbare .archyl.json, die das Repository an das Projekt bindet (der Key bleibt in deiner Environment), und die Harness-Schleife, angehängt an CLAUDE.md und AGENTS.md:

# Architecture — Archyl Harness

This project's architecture is documented in Archyl. Work under the harness loop:

1. For any non-trivial task, call `plan_work` first — it returns an implementation
   plan grounded in the documented architecture.
2. BEFORE changing code, call `start_work_session` (task + your agent name).
   Read the briefing: gate verdict, leased elements, conflicts, decisions, guardrails.
...

Dann /plugin marketplace add archyl-com/agent-skills und /plugin install archyl-developer@archyl-marketplace in Claude Code, was den archyl-harness-Skill und den Guard-Hook mitbringt. Plugin-Version 0.7.0 ist live.

?profile=coding ist das kleine Detail, das den Rest funktionieren lässt. Archyls MCP Server exponiert 189 Tools, was die richtige Zahl ist, um eine Architektur zu verwalten, und die falsche, um sie einem Agenten vorzusetzen, der gerade Rate Limiting einbauen will. Das Coding-Profil bewirbt 16: Orientierung, task-bezogenen Kontext, die vier Session-Tools, Memory sowie die Conformance- und Diff-Checks. Nichts, was das Modell direkt editiert, denn dieser Weg geht über Change Requests. In unseren eigenen Tests exploriert ein Agent, dem man den vollen Katalog gibt, den Katalog. Ein Agent, dem man sechzehn Tools gibt, folgt der Schleife.

Was es nicht tut

Leases sind advisory. Nichts sperrt. Ein Lease sagt dem zweiten Agenten, dass der erste da drin ist, in seinem Briefing, in der Console und im Diagramm. Es hält ihn nicht auf. Das ist vorerst Absicht, denn ein harter Lock auf einem Modell deiner Architektur ist ein sehr wirksamer Weg, dein Team lahmzulegen, wenn ein Agent mitten in der Session stirbt, aber du solltest Leases deinem Team gegenüber nicht als gegenseitigen Ausschluss beschreiben.

Ein Agent, der nie eine Session öffnet, ist unsichtbar. Jede Garantie hier fängt damit an, dass der Agent start_work_session aufruft. Nichts im Protokoll erzwingt diesen Call. Der Skill und das CLAUDE.md-Snippet machen ihn zum Default-Verhalten; ein entschlossener Agent, oder einer, der ohne den Harness-Skill verbunden ist, schreibt einfach Code so, wie er es immer getan hat. Der Guard-Hook ist der eine Teil, der ohne Kooperation feuert, und nur in Claude Code.

deny ist nur so gut wie das, was du geschrieben hast. Das Gate liest deine Conformance Rules und deine Leases. Ein leeres Regelset und ein einzelner Agent produzieren für immer allow, was technisch korrekt und vollkommen nichtssagend ist.

Pläne sind fundiert, nicht richtig. plan_work ist ein KI-Plan, gebaut aus deinem C4-Modell, deinen ADRs und Guardrails, mit einem deterministischen Fallback, der die geordnete Ground Truth zurückgibt, wenn kein KI-Provider konfiguriert ist oder das Modell etwas Unbrauchbares liefert. Er respektiert die dokumentierte Architektur. Er weiß nicht, ob die dokumentierte Architektur eine gute Idee ist.

Ein Change Request braucht einen bekannten Autor. Sessions, die mit einem Credential gestartet wurden, das an keinen User gebunden ist, können keinen öffnen, und finish_work_session sagt das in seiner Antwort, statt zu scheitern. Wenn der Key deines CI-Bots org-scoped ist, landen seine Ergebnisse als Memory, aber nicht als Vorschlag.

Wo anfangen

Wenn du schon Agenten gegen ein dokumentiertes Archyl-Projekt laufen lässt, dauert der Setup-Befehl oben etwa fünf Minuten, und die erste Session wird dir etwas sagen. Beobachte die Fleet console an einem Nachmittag, an dem zwei Agenten laufen. Der interessante Moment ist das erste warn, denn es benennt eine Kollision, die früher bis zum Review unsichtbar war.

Wenn du noch keine dokumentierte Architektur hast, ist genau das die eigentliche Voraussetzung, und es ist dieselbe wie immer: Das Harness arbitriert mithilfe des Modells, also arbitriert ein leeres Modell nichts.


Das Harness ist Teil von archyl: Work Sessions, das Preflight Gate, die Fleet console und Memory. Das Plugin, die Skills und der Guard-Hook sowie die GitHub Actions sind Open Source. Das vollständige Setup steht im Harness-Guide. Weiterlesen: viele Agenten, eine Architektur, warum deine Agenten eine Rules-Datei haben und kein Modell und der MCP Server dahinter.