Harness Engineering
De Oorsprong
De term is afkomstig uit een artikel van Birgitta Boeckeler op martinfowler.com, geschreven vanuit de context van ThoughtWorks en teams die echte software leveren met AI-codeassistenten. Boeckeler merkte iets op dat veel teams onafhankelijk van elkaar hadden vastgesteld: AI-assistenten produceren plausibel ogende code, maar zonder beperkingen treden ze af naar een lagere kwaliteit (drift). Ze vergeten conventies, herhalen fouten en eroderen langzaam de interne consistentie van een codebase. De code blijft compileren en slaagt voor de tests; de degradatie verloopt stil.
Het inzicht van Boeckeler was dat dit probleem al een opgeloste analogue heeft in software engineering: de test harness. Tests zorgen er niet voor dat code per definitie correct is, maar ze detecteren wanneer code stopt met correct te zijn. Een test harness is geen beperking op welke code je schrijft, maar een mechanisme dat continu controleert of wat je hebt geschreven aan een standaard voldoet. De harness vertrouwt de programmeur niet; hij verifieert.
Dezelfde logica is van toepassing op AI-ondersteunde ontwikkeling, met één cruciaal verschil. Test harnesses controleren functionele correctheid: doet het programma wat het zou moeten doen? Een harness voor AI-codering moet echter iets breder controleren: belichaamt de codebase nog steeds de architecturale beslissingen, naamgevingsconventies, beveiligingsbeperkingen en structurele regels die het team is overeengekomen? Functionele tests zijn noodzakelijk, maar onvoldoende hiervoor. Er is een ander type harness nodig.
Dat is wat harness engineering biedt.
De Drie Componenten
Boeckeler beschrijft drie categorieën van aandacht waar een harness op moet inspelen.
Context Engineering
Een AI-codeassistent kan alleen werken binnen wat hij weet. Als hij niet weet dat je project een specifieke logging-bibliotheek gebruikt, zal hij zijn eigen aanpak verzinnen. Als hij niet weet dat je nooit mutable global state gebruikt, zal hij dit doen wanneer het handig is. Als hij niet weet dat alle database-schrijfacties via een specifieke abstractielaag moeten lopen, zal hij die laag omzeilen.
Context engineering is de discipline om ervoor te zorgen dat de AI weet wat hij moet weten. In de praktijk betekent dit het bijhouden van een document — in de conventies van deze plugin HARNESS.md — waarin de stack, de architecturale beslissingen, de naamgevingsconventies, de beperkingen en de rationale achter elk van deze zaken worden vastgelegd. Dit document is geen README voor mensen; het is een kennisbank voor de AI. Het moet accuraat en specifiek zijn en actueel worden gehouden.
Het onderscheid is belangrijk: een README legt uit wat het project doet. Een contextdocument vertelt een AI-agent wat hij wel en niet moet doen, en waarom. Dit zijn verschillende documenten met verschillende doelgroepen en verschillende update-ritmes.
Architecturale Beperkingen
Het kennen van de regels en het handhaven van de regels zijn aparte problemen. Je kunt elke beperking in HARNESS.md schrijven, maar de AI zal ze nog steeds schenden, omdat de AI een probabilistisch systeem is dat optimaliseert voor plausibiliteit, en geen regel-volgende machine. Context engineering vermindert schendingen, maar elimineert ze niet.
Architecturale beperkingen zijn de mechanismen die schendingen opvangen. Boeckeler noemt de handhavingspunten "verificatieslots" — gedefinieerde momenten in de ontwikkelworkflow waar een check wordt uitgevoerd en deze ofwel slaagt of de voortgang blokkeert. De belangrijkste ontwerpbeslissing voor elk verificatieslot is of er gebruik wordt gemaakt van een deterministisch hulpmiddel of een agent-gebaseerde review.
- Een deterministisch hulpmiddel is een linter, een script, een regex-check of een file-structure-assertie — alles wat een pass/fail-resultaat produceert zonder oordeel. Deze hebben de voorkeur wanneer de beperking precies kan worden uitgedrukt. Ze zijn snel, goedkoop en volledig betrouwbaar binnen hun specificatie.
- Een agent-gebaseerde review is een taalmodel dat code bekijkt tegenover een beschrijving van de beperking en een oordeel velt. Dit is noodzakelijk wanneer de beperking betrekking heeft op intentie, semantiek of patronen die moeilijk als een mechanische regel uit te drukken zijn. Agents zijn duurder en minder deterministisch, maar ze kunnen zaken opvangen die geen enkel script kan opvangen.
Beide soorten verificatieslots horen in een harness. Het doel is om beperkingen op termijn te migreren van agent-gebaseerd naar deterministisch, naarmate het begrip van de beperking voldoende verscherpt om deze precies te kunnen specificeren. Dit is het principe van progressieve harding, dat hieronder wordt beschreven.
Garbage Collection
Een codebase is een levend systeem. Zelfs met goede context engineering en strikte architecturale beperkingen hoopt entropie zich op. Dead code groeit. TODO-commentaren blijven maandenlang staan. Dependencies worden verouderd. Abstracties die in een bepaalde fase van het project logisch waren, worden in een latere fase obstakels. Conventies die vroeg zijn vastgesteld, worden stilletjes verlaten wanneer ze onhandig worden.
Garbage collection (GC) is het periodieke proces om deze entropie te bestrijden. In tegenstelling tot de andere twee componenten, die opereren op het moment van codegeneratie of review, opereert GC volgens een schema. Het wordt niet getriggerd door een specifieke code-gebeurtenis, maar draait omdat er tijd is verstreken.
In een harness engineering-framework zijn GC-regels expliciete verklaringen van hoe "schoon" eruitziet, gekoppeld aan geplande agents of scripts die controleren of de codebase nog steeds aan die standaarden voldoet. De output is niet een lijst met fouten om een PR te blokkeren, maar een rapport dat de aandacht vestigt op accumulerende problemen voordat ze ernstig worden.
De Levende Harness
De belangrijkste eigenschap van een goed onderhouden harness is dat deze niet statisch is. Een harness die eenmaal is geschreven en nooit is bijgewerkt, reflecteert het begrip van het team op één specifiek moment. De codebase blijft echter evolueren. Er ontstaan nieuwe patronen, oude beperkingen worden irrelevant en er verschijnen nieuwe categorieën AI-gegenereerde fouten die de oorspronkelijke auteurs niet hadden voorzien.
HARNESS.md is ontworpen als een zelfrefererend document. Het beschrijft niet alleen welke beperkingen van kracht zijn, maar houdt ook de status van elke beperking bij: of deze momenteel ongeverifieerd is, onder agent-review staat of deterministisch wordt afgedwongen. Het document verklaart wat waar zou moeten zijn. Agents, hooks en CI-checks verifiëren of dit daadwerkelijk waar is. De harness auditor — een geplande agent in deze plugin — leest de resultaten van die checks en werkt de statusvermeldingen in HARNESS.md bij om de realiteit te reflecteren.
Dit creëert een feedbackloop. Het document is zowel een specificatie als een gezondheidsverslag. Het lezen van HARNESS.md vertelt je op elk gewenst moment niet alleen waar het team heeft afgesproken dat de codebase aan moet voldoen, maar ook hoe goed die afspraken daadwerkelijk worden nageleefd.
De zelfrefererende eigenschap is wat een levende harness onderscheidt van een document dat veroudert en wordt genegeerd. Omdat de harness zelf een doelwit is van handhaving — de harness-audit agent controleert of HARNESS.md de huidige staat van verificatie accuraat reflecteert — wordt het verwaarlozen van de harness zichtbaar in plaats van onzichtbaar. De dagelijkse toegang tot deze zelfcontrole is /harness-sync, die de detectielogica van de audit uitvoert en een geünificeerde drift-tabel presenteert; gebruikers zien de discrepantie tussen de gedeclareerde harness en de realiteit zonder dat ze zich hoeven te herinneren een aparte diagnose aan te roepen.
Progressieve Harding
Niet alle beperkingen zijn gelijk, en niet alle beperkingen zijn vanaf het begin klaar om deterministisch te worden afgedwongen. Progressieve harding is de promotieladder die beschrijft hoe beperkingen rijpen.
De ladder is één as. Bereik — of een beperking vereist is op elke PR of alleen "voltooi-indien-aanwezig" — is een tweede as, maar dit wordt niet vastgelegd in het Enforcement-veld.
- Unverified (Ongeverifieerd): Dit is de begintoestand. Je hebt een beperking gedeclareerd in
HARNESS.md. Je gelooft dat het belangrijk is, maar je hebt nog geen mechanisme om het te controleren. Deze status is geen falen, maar een eerlijke administratie. Een ongeverifieerde beperking is een toezegging om handhaving te bouwen, geen claim dat handhaving al bestaat. - Agent: Dit is de tweede staat. Je hebt een agent-prompt geschreven die de beperking controleert als onderdeel van de PR-review of een geplande inspectie. De beperking wordt afgedwongen, maar door een taalmodel dat een oordeel velt, niet door een deterministische regel. Agent-handhaving vangt de meeste schendingen de meeste tijd op. Het is niet perfect betrouwbaar en vereist menselijke review van de output van de agent.
- Deterministic (Deterministisch): Dit is de eindtoestand. Je hebt de beperking nauwkeurig genoeg uitgedrukt om deze te coderen als een script, een linter-regel of een structurele check. Het draait in de CI. Het slaagt, of het blokkeert de merge. Er is geen oordeel bij betrokken, en er is geen mogelijkheid dat de check wordt verward of misleid.
De richting van beweging is altijd richting deterministisch. Wanneer een agent herhaaldelijk dezelfde klasse van schendingen opvangt, is die herhaling een signaal: het patroon is nu voldoende begrepen om te automatiseren. Schrijf het script, retireer de agent-check voor die specifieke beperking en verplaats de vermelding in HARNESS.md naar de deterministische status.
Progressieve harding is belangrijk omdat het twee faalmodi voorkomt. De eerste faalmodus is proberen alles vanaf het begin deterministisch af te dwingen, wat onmogelijk is voor nieuwe of semantisch complexe beperkingen. De tweede faalmodus is het accepteren van agent-gebaseerde handhaving als een permanente staat, wat duur en onbetrouwbaar is. De ladder biedt een pad tussen beide.
Hoe deze Plugin het Implementeert
Deze plugin structureert de verificatieslots in drie handhavingsloops, die opereren op verschillende tijdschalen en met verschillende toleranties voor fout-positieven.
- De inner loop (binnenste loop) is adviserend en draait tijdens het bewerken. Wanneer je een bestand opslaat of een coderingssessie afrondt, draaien lichtgewicht checks die potentiële problemen presenteren als suggesties in plaats van blokkades. De inner loop is geoptimaliseerd voor lage wrijving en mag de flow niet onderbreken. Het doel is om problemen vroegtijdig zichtbaar te maken, niet om het werk te stoppen.
- De middle loop (middelste loop) is strikt en draait tijdens de PR. Wanneer je een pull request opent, draait een volledige suite van agent-gebaseerde en deterministische checks. Deze loop heeft de autoriteit om een merge te blokkeren. Het is het belangrijkste handhavingspunt voor architecturale beperkingen. Fouten hier moeten worden opgelost voordat de code wordt geland.
- De outer loop (buitenste loop) is onderzoekend en draait volgens een schema. Garbage collection-regels, fitness-functies en harness-audits draaien periodiek — dagelijks, wekelijks, of in whatever cadence logisch is voor de regel. De outer loop produceert rapporten in plaats van blokkades. De bevindingen hiervan voeden de harness als potentiële nieuwe beperkingen of updates aan bestaande beperkingen.
De drie loops corresponderen ruwweg met de drie componenten: de inner loop dient context engineering (de AI op het moment geïnformeerd houden), de middle loop dient architecturale beperkingen (overeengekomen standaarden afdwingen bij integratie), en de outer loop dient garbage collection (langzame entropie detecteren tussen integratie-events).
Agents in deze plugin opereren met begrensd vertrouwen. Geen enkele agent heeft unilaterale autoriteit om productiecode te wijzigen of wijzigingen te mergen. Agents reviewen, suggereren, rapporteren en vlaggen. Mensen beslissen. Dit is een bewuste ontwerpkeuze: de harness versterkt het menselijk oordeel; hij vervangt het niet.
De Zelfverbeterende Dimensie
Het oorspronkelijke framework van Boeckeler beschrijft een harness als iets dat een team bouwt en onderhoudt. Deze plugin voegt daar een laag aan toe: de harness kan leren van zijn eigen werking.
Na elke coderingssessie legt het /reflect-commando vast wat goed ging, wat faalde, welke conventies werden geschonden en welke nieuwe patronen ontstonden. Deze reflecties hopen zich op in een leerlog (learnings log). De harness-agents lezen uit dit logboek bij het nemen van beslissingen, zodat patronen van fouten uit het verleden de huidige review informeren.
Regressiedetectie werkt in dezelfde richting. Wanneer de harness-audit agent draait, controleert hij niet alleen of de huidige beperkingen worden nageleefd. Hij kijkt naar de geschiedenis van beperkingsschendingen om patronen te identificeren: worden dezelfde beperkingen herhaaldelijk geschonden? Zo ja, dan is dat een signaal dat de beperking een sterker handhavingsmechanisme nodig heeft, of dat het contextdocument de rationale niet duidelijk genoeg uitlegt, of dat de beperking zelf onjuist is en heroverwogen moet worden.
Dit sluit een loop die het oorspronkelijke framework open laat. Een statische harness wordt alleen beter wanneer mensen fouten opmerken en deze handmatig bijwerken. Een zelfverbeterende harness behandelt zijn eigen operationele geschiedenis als inputdata en genereert voorstellen voor zijn eigen verbetering. Mensen beslissen nog steeds welke voorstellen worden geaccepteerd, maar het werk van patroonherkenning — het lezen van het schendingslogboek en opmerken dat dezelfde fout blijft terugkeren — wordt gedelegeerd aan de agents.
De auto-harness toevoegingen in deze plugin breiden dit verder uit: het harness-init proces leest bestaande code om beperkingen af te leiden die al aanwezig zijn in de codebase maar nog niet zijn gedeclareerd. In plaats van het team te vereisen alles vanaf nul te specificeren, bootstrapt de agent een kandidaat HARNESS.md op basis van geobserveerde patronen en vraagt de ontwikkelaar om elke vermelding te bevestigen, te weigeren of te verfijnen. De mens blijft de autoriteit, maar de initiële kosten voor het bouwen van de harness worden aanzienlijk verlaagd.
harness-init ondersteunt ook incrementele adoptie. Teams kiezen welke functies ze configureren — context engineering, beperkingen, garbage collection, CI en observability — en kunnen het commando later opnieuw uitvoeren om meer toe te voegen. Bestaande configuraties blijven behouden tussen runs. Dit betekent dat een team kan beginnen met alleen context en beperkingen, de waarde kan bewijzen, en garbage collection en CI-handhaving kan toevoegen wanneer ze daar klaar voor zijn. De harness groeit mee met de volwassenheid van het team in plaats van direct volledige toewijding te eisen.
Verder Lezen
De conceptuele basis voor deze plugin rust op het artikel van Birgitta Boeckeler op martinfowler.com. Dat artikel is de primaire referentie voor het drie-componentenmodel en het kader van de verificatieslots. De Diataxis-structuur put ook uit Agent Harness Engineering van Addy Osmani, die het onderscheid tussen model-plus-harness en de "every line earned"-discipline aanscherpt. Het Diataxis-framework (diataxis.fr) informeert de documentstructuur. Het model van de drie handhavingsloops, de ladder van progressieve harding en de zelfverbeterende dimensie zoals hier beschreven, zijn extensies die zijn ontwikkeld in de context van deze plugin.
Voor het document zelf — wat HARNESS.md is, hoe het wordt bediend en hoe het zich verhoudt tot AGENTS.md / CI / hooks — zie HARNESS.md, the Document.
Zie de andere pagina's in deze sectie voor een diepere behandeling van elke component.
Groetjes,