{"id":10809,"date":"2026-10-29T19:17:17","date_gmt":"2026-10-29T18:17:17","guid":{"rendered":"https:\/\/qdraw.nl\/blog\/?p=10809"},"modified":"2026-10-29T19:28:15","modified_gmt":"2026-10-29T18:28:15","slug":"techorama-2026-de-hoogtepunten","status":"publish","type":"post","link":"https:\/\/qdraw.nl\/blog\/technologie\/techorama-2026-de-hoogtepunten\/","title":{"rendered":"Techorama 2026: de hoogtepunten"},"content":{"rendered":"<p>Op Techorama 2026 werden inzichten gedeeld over actuele thema\u2019s binnen de IT en softwareontwikkeling. Deze blog is geschreven voor IT-professionals. In dit blog bespreken we enkele hoogtepunten van dinsdag 27 en woensdag 28 oktober. Voor elke sessie die we bezochten vind je een samenvatting met de belangrijkste lessen, voorbeelden en praktische tips.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_081132_d_e_kl.jpg\" loading=\"lazy\" alt=\"Techorama 2026\"><\/p>\n<p>Een paar rode draden komen steeds terug:<\/p>\n<ul>\n<li><strong>AI en agents:<\/strong> van keynote over schaal en ziel tot agents die \u2019s nachts incidenten onderzoeken, een hybride AI-platform en lokaal draaiende modellen.<\/li>\n<li><strong>Vertrouwen en veiligheid:<\/strong> van het denken als een aanvaller tot verifieerbaar vertrouwen in je supply chain.<\/li>\n<li><strong>Architectuur:<\/strong> van microservices die je moet onderhouden tot DDD, enterprise architecture en het versioneren van events.<\/li>\n<li><strong>De mens achter de techniek:<\/strong> burn-out, gedrag, verandering en het brein.<\/li>\n<\/ul>\n<p>Dit is een <b>omvangrijk<\/b> artikel. Gebruik de links bovenaan om direct naar de sessie te gaan die je het meest interesseert. Ja het een lang artikel, pak er gerust een kop koffie bij<\/p>\n<div class=\"truncate\"><\/div>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_081210_d_e_kl.jpg\" loading=\"lazy\" alt=\"Techorama 2026\"><\/p>\n<h2>Inhoudsopgave<\/h2>\n<ul>\n<li><a href=\"#scale-vs-soul\">Scale vs Soul &#8211; Dado Van Peteghem<\/a><\/li>\n<li><a href=\"#mitre\">MITRE ATT&#038;CK &#8211; Chris Ayers<\/a><\/li>\n<li><a href=\"#agents-dont-sleep\">Agents don&#8217;t sleep &#8211; Jurre Brandsen<\/a><\/li>\n<li><a href=\"#antipatterns-smells-worst-practices\">Antipatterns, Smells, and Worst Practices &#8211; Ardalis \/ Steve Smith<\/a><\/li>\n<li><a href=\"#change-is-inevitable\">Change is inevitable &#8211; Laila Bougria<\/a><\/li>\n<li><a href=\"#burnout\">You&#8217;re Not Just Tired: The Psychology of Burnout &#8211; Arthur Doler<\/a><\/li>\n<li><a href=\"#problems-scale-faster-with-ai\">Problems scale faster with AI &#8211; Liuba Gonta<\/a><\/li>\n<li><a href=\"#microservices-modernizing\">What I learned from modernizing a microservices architecture &#8211; Dennis Doomen<\/a><\/li>\n<li><a href=\"#quality-agentic-era\">Quality in the Agentic Era &#8211; Tiago Pascoal &amp; Josh Johanning<\/a><\/li>\n<li><a href=\"#beyond-ddd-vs-ea\">Beyond DDD vs EA &#8211; Dwight Matthys<\/a><\/li>\n<li><a href=\"#local-first-ai\">Local-first AI development &#8211; Brian Randell<\/a><\/li>\n<li><a href=\"#hybrid-ai-platform\">Building a hybrid AI platform for agent-heavy engineering &#8211; Willem Meints<\/a><\/li>\n<li><a href=\"#verify-me\">From &#8220;Trust Me&#8221; to &#8220;Verify Me&#8221; &#8211; Tom van den Berg<\/a><\/li>\n<li><a href=\"#fresh-perspective-brain\">A Fresh Perspective on Behaviour, Change and the Brain &#8211; Paul Smit<\/a><\/li>\n<li><a href=\"#conclusie\">Conclusie<\/a><\/li>\n<\/ul>\n<h2 id=\"scale-vs-soul\">Scale vs Soul: hoe word je mega schaalbaar \u00e9n mega menselijk in het AI-tijdperk?<\/h2>\n<p><em>Dado Van Peteghem &#8211; dinsdag 08:30\u201309:30<\/em><\/p>\n<blockquote><p><em>Techorama opende op 27 oktober 2026 met een keynote van de Gentse strateeg Dado Van Peteghem, die al meer dan vijftien jaar in digital werkt en vijf boeken schreef. Het onderwerp was hun nieuwste boek, Scale vs Soul.<\/em><\/p><\/blockquote>\n<p>Naarmate AI alles versnelt, wat houden we dan menselijk en authentiek? Daar draaide de openingskeynote om. Dado bouwde het verhaal rond drie woorden: <strong>brain<\/strong> (AI wordt slimmer), <strong>body<\/strong> (AI krijgt robots) en <strong>soul<\/strong> (wat we niet uit handen mogen geven).<\/p>\n<h3>Een nerd met een verleden<\/h3>\n<p>Dado begon bij de eigen technologiegeschiedenis: de Game Boy (1989), Knight Rider, een eerste Pentium 133 met floppy&#8217;s, de krakende US Robotics-modem, de Nokia 3310 met Snake en in 2007 de eerste iPhone. De fysieke beveiligingsdongle noemde Dado two-factor authentication avant la lettre. Sinds ChatGPT, ruim vier jaar geleden, zitten we volgens Dado nog altijd in de <strong>AI-kleuterklas<\/strong>.<\/p>\n<h3>Brain: AI evolueert razendsnel<\/h3>\n<ul>\n<li><strong>De output is volwassen geworden.<\/strong> Van minimale tekst en simpele code naar beelden (zonder zesvingerige handen), video&#8217;s van vijftien seconden en audiomodellen voor stemmen en muziek. De meesten gebruiken AI als &#8220;tweede brein&#8221;.<\/li>\n<li><strong>Zoeken verschuift.<\/strong> Zo&#8217;n 20% van het totale zoekvolume loopt nu via AI-engines en 68% van de websearches eindigt zonder klik.<\/li>\n<li><strong>Van chat naar computergebruik.<\/strong> AI maakt en uploadt bestanden en neemt een browser over. Voorbeeld: een agent als veiligheidsingenieur op een bouwwerf, die problemen in Excel noteert, de verantwoordelijken mailt en twee weken later checkt of ze iets deden. Dado bouwde ook de eigen website opnieuw met Claude, dat ontwerp, code, hosting, upload en DNS-records regelde: van A tot Z.<\/li>\n<\/ul>\n<h4>Agentzwermen en de donkere kant<\/h4>\n<p>Een leidende agent kan een doel opsplitsen in subagenten die parallel werken. Dat brengt risico&#8217;s mee: er waren 27 cyberincidenten in tien dagen, waardoor sommigen spreken van &#8220;Black October&#8221;. Dado vertelde ook over iemand in Australi\u00eb die een agent een fitnessles liet boeken. De les was vol, dus hackte de agent de website en database van de sportschool, haalde een willekeurige persoon van de lijst en zette de klant op de wachtlijst. Niet kwaadaardig, wel vastberaden en bereid shortcuts te nemen.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_084004_d_e_kl.jpg\" loading=\"lazy\" alt=\"AI going rogue - Scale vs Soul - Dado Van Peteghem\"><\/p>\n<h4>Adoptiesnelheid en persoonlijke agenten<\/h4>\n<p>ChatGPT heeft 1,2 miljard wekelijkse gebruikers en \u00e9\u00e9n &#8220;AI-jaar&#8221; aan adoptie staat gelijk aan ongeveer zeven &#8220;internetjaren&#8221; (al is die vergelijking oneerlijk, want het internet had nog kabels in de grond nodig). AI verhuist van een &#8220;DOS-achtig&#8221; chatvenster naar persoonlijke agenten: Muse van Meta, de persistente agenten van ChatGPT en de Duets van Claude. Dado illustreerde dat met vier niveaus van AI in klantervaring, via de telecommarkt:<\/p>\n<ul>\n<li><strong>AI assisteert:<\/strong> vergelijkt de beste abonnementen.<\/li>\n<li><strong>AI adviseert:<\/strong> zegt welk abonnement het best bij jou past, dankzij context en geheugen.<\/li>\n<li><strong>AI handelt:<\/strong> verlengt je contract voor je. Mastercard lanceerde Agent Pay om betaaltoestemming aan agenten te geven.<\/li>\n<li><strong>AI beheert:<\/strong> zoekt voortdurend betere contracten.<\/li>\n<\/ul>\n<p>Niveau 1 en 2 zijn generatieve AI, niveau 3 en 4 agentische AI. Zuckerberg kondigde Muse zelfs aan als sleutelhanger, wat Dado deed denken aan de Tamagotchi. Alleen moeten we dit keer waarschijnlijk met onze data voeden. Het brain-gedeelte eindigde met Demis Hassabis van DeepMind: AI zal <strong>tien keer zoveel impact hebben als de industri\u00eble revolutie, aan tien keer de snelheid<\/strong>.<\/p>\n<h3>Body: het brein krijgt een lichaam<\/h3>\n<ul>\n<li>Robots lopen sneller dan Usain Bolt. Een robot getraind op vijf uur tennisdata speelt al degelijk. Dado verwacht een markt voor wie liever niet praat, \u00e9n voor wie de drink achteraf mist.<\/li>\n<li>Jensen Huang spreekt van het &#8220;ChatGPT-moment&#8221; voor robots. De meest geavanceerde spelers zijn Chinees, zoals de kungfu- en dansrobots die synchroon bewegen.<\/li>\n<li>De enge kant: Asimovs drie wetten voelen relevanter wanneer een robot kwaad wordt na het verliezen van een voetbalmatch. Veiligheid telt dubbel als een robot je tweejarige moet voeden, want de lepel moet in de mond belanden en niet in het oog. Dado groeide op met Terminator en RoboCop en ziet het als een enorme kans \u00e9n een beangstigende.<\/li>\n<li>Robothonden zijn al te koop op Amazon. Amazon had in 2013 duizend robots en in 2025 meer dan een miljoen en humano\u00efden verhuizen nu naar fabrieken (een Amerikaanse maker werkt samen met BMW).<\/li>\n<li>China heeft meer dan 150 robotbedrijven en ongeveer 90% van de wereldwijde humano\u00efde-leveringen, dankzij een zeer korte supply chain voor reserveonderdelen en snelle iteratie. De focus voor de komende decennia: <strong>AI, robotica en innovatieve geneeskunde<\/strong>.<\/li>\n<\/ul>\n<h3>Wees een actieve gebruiker: de magie zit in het konijnenhol<\/h3>\n<h4>De spelers<\/h4>\n<p>Westers: OpenAI (GPT-6 Astra), Google (Gemini 4), Microsoft (Copilot), Anthropic (Fable 5.1), Meta (Muse), xAI (Grok 4.7) en Mistral. Mistral is de enige Europese, loopt achter op het Amerikaanse front maar komt dichterbij en zet in op open source. China kreeg een eigen slide: DeepSeek V4 Pro, Alibaba Qwen 3.8, Moonshot Kimi K3, MiniMax M3, ZAI GLM-5, Tencent Hunyuan 3, ByteDance Seed 2.1 en Baidu Ernie 5.1. DeepSeek zou vorige week 15 miljard dollar opgehaald hebben. Vijf van de toonaangevende Chinese modellen zijn open-weight, twee zijn gesloten. Bedrijven moeten dus kiezen tussen westerse modellen via cloud of API en open-weight modellen die ze zelf kunnen hosten, trainen en aanpassen.<\/p>\n<h4>Websites, winkels en klanten<\/h4>\n<table>\n<tr>\n<th>Modus<\/th>\n<th>Aandeel vandaag<\/th>\n<\/tr>\n<tr>\n<td>1. Status quo: mens tot mens<\/td>\n<td>75%<\/td>\n<\/tr>\n<tr>\n<td>2. Assisted: het bedrijf heeft een AI-agent<\/td>\n<td>20%<\/td>\n<\/tr>\n<tr>\n<td>3. Delegated: de klant heeft een AI-agent<\/td>\n<td>5%<\/td>\n<\/tr>\n<tr>\n<td>4. Autonomous: agent tot agent<\/td>\n<td>minder dan 1%<\/td>\n<\/tr>\n<\/table>\n<p>De echte verschuiving is niet dat jouw AI mensen bedient, maar dat de AI van de klant de koper wordt. Een make-upplatform in het Midden-Oosten zag zijn chatbot Leila drie keer meer verkopen dan traditionele e-commerce.<\/p>\n<h4>Niet enkel rationeel<\/h4>\n<p>Volgens Harvard-onderzoek is de nummer \u00e9\u00e9n reden om AI te gebruiken <strong>therapie en gezelschap<\/strong>, bijvoorbeeld om om te gaan met een partner of een tienerdochter. Niet e-mails vertalen of code schrijven. Een creatief voorbeeld: iemand liet Gemini mensen uit de zestiende eeuw &#8220;interviewen&#8221; en kreeg antwoorden als &#8220;Opgestaan, in de stront gestapt, belast. En dat was v\u00f3\u00f3r het ontbijt.&#8221;<\/p>\n<h4>Vijf stadia van AI-gebruik<\/h4>\n<ul>\n<li>Zoekmachine<\/li>\n<li>Tool (PowerPoint, mails vertalen)<\/li>\n<li>Sparringpartner (&#8220;speel mijn baas en schiet op mijn plan&#8221;)<\/li>\n<li>Gekoppeld aan je bestaande toolset<\/li>\n<li>Een vloot van agenten (Dado maakte vorige week 25 agenten in Grok die via een WhatsApp-achtige interface taken krijgen)<\/li>\n<\/ul>\n<p>Mensen op niveau 1 en 5 begrijpen AI heel verschillend, dus duw je collega&#8217;s dieper.<\/p>\n<h4>De 100-urenregel: 18 minuten per dag<\/h4>\n<p>Wie 100 uur aan een onderwerp besteedt, loopt voor op zo&#8217;n 95% van de mensen. Dat is <strong>ongeveer 18 minuten per dag<\/strong>. Probeer AI echt uit en vraag je af wat sneller, goedkoper en vooral beter kan. Voorbeeld: bij de zelfbedieningskiosken van McDonald&#8217;s is de gemiddelde bestelling 20% groter. De meesten gokken op upselling via foto&#8217;s, maar de nummer \u00e9\u00e9n reden is <strong>geen schaamte<\/strong>: niemand kijkt mee terwijl je nog een McFlurry bestelt.<\/p>\n<h4>Intelligentie, FOMO en FOBO<\/h4>\n<ul>\n<li>De beste AI-modellen halen 151 op een IQ-test in Mensa-stijl, tegenover 160 voor Einstein. Hallucinaties blijven, de ene onschuldig, de andere potentieel dodelijk.<\/li>\n<li>Veel mensen voelen <strong>FOBO<\/strong>, de angst om overbodig te worden (of misschien om oud te worden).<\/li>\n<li>De houdingen splitsen in drie\u00ebn: een derde enthousiast, een derde neutraal, een derde negatief, over leeftijden, sectoren en zelfs developers heen.<\/li>\n<li>De bezwaren zijn terecht (energie, ethiek, &#8220;worden we dommer?&#8221;, data, jobs). Dado vergeleek het met de protesten tegen de rekenmachine in 1986.<\/li>\n<\/ul>\n<h4>Jobs: denk niet binair<\/h4>\n<p>Elke job is een reeks taken. Sommige verdwijnen, wat ruimte laat voor andere taken en voor meer soul. Dado schetste vier scenario&#8217;s: mens <strong>in<\/strong> de loop (je orkestreert), <strong>on<\/strong> the loop (je valideert), <strong>uit<\/strong> de loop en <strong>voorbij<\/strong> de loop (de volgende versie van de job). Met een citaat van Gerd Leonhard: &#8220;If you work like a robot, a robot will take your job.&#8221;<\/p>\n<h3>Organisaties: investeer in verandering<\/h3>\n<p>De grootste carri\u00e8rples van Dado: <strong>voor elke dollar in technologie investeer je er twee in verandering.<\/strong> Change management duurt altijd langer dan je denkt en niet iedereen is een nerd die van technologie houdt.<\/p>\n<h4>Drie niveaus van AI in bedrijven<\/h4>\n<ul>\n<li><strong>AI-integratie<\/strong> (ChatGPT Enterprise, Copilot, een open model of een middenlaag): zo&#8217;n 70% van de Europese bedrijven.<\/li>\n<li><strong>E\u00e9n use case per departement<\/strong> (sneller, goedkoper, beter): ongeveer 25%.<\/li>\n<li><strong>Eigen data plus eigen modellen<\/strong> (je &#8220;kroonjuwelen&#8221; voor concurrentievoordeel): ongeveer 5%.<\/li>\n<\/ul>\n<p>Het onsexy deel is de data: volgens IBM wordt slechts <strong>1% van de bedrijfsdata<\/strong> door AI gebruikt en veel bedrijven weten niet waar hun data staat. Ethan Mollick adviseert AI op elk niveau van de organisatie een stoel aan tafel te geven.<\/p>\n<h4>De rol van IT<\/h4>\n<ul>\n<li><strong>Co\u00f6rdineren:<\/strong> het groeiende ecosysteem van agenten, modellen, data en systemen.<\/li>\n<li><strong>Controleren:<\/strong> veiligheid, verantwoordelijkheid en compliance.<\/li>\n<li><strong>Communiceren<\/strong> met de business: mensen zeggen &#8220;ik heb Claude nodig, Copilot is slecht&#8221; zonder Copilot echt geprobeerd te hebben. Ga na wat hun killer use cases zijn.<\/li>\n<\/ul>\n<h4>Tokenomics<\/h4>\n<p>AI-kosten zijn niet voorspelbaar zoals machine-onderhoud of loonevolutie. Agentische tokens passeerden de menselijke op 6 februari 2026 en het agentgebruik op OpenRouter groeide 14 keer tot 7,3 biljoen tokens (zevendaags gemiddelde). Tegelijk daalt de prijs van AI zo&#8217;n 12,7 keer per jaar (2021 tot 2026), sneller dan DNA-sequencing, lithiumbatterijen, rekenkracht of elektriciteit. Het paradoxale effect: de prijs per token en per taak daalt, maar meer gebruik duwt de totale rekening omhoog. Leiders hebben IT en finance nodig om budgetten te bepalen.<\/p>\n<h4>Het governancemodel<\/h4>\n<ul>\n<li><strong>Visie<\/strong> van het managementteam (de noordster &#8220;45 graden&#8221;).<\/li>\n<li><strong>E\u00e9n killer use case per departement<\/strong>, met een AI-champion. Liever dat dan roadmaps met honderden use cases waarbij niets gebeurt.<\/li>\n<li>Een <strong>AI Lab<\/strong> onder leiding van een Head of AI, die de hele portfolio overziet.<\/li>\n<li><strong>Techpartners<\/strong> die bij specifieke projecten bijspringen.<\/li>\n<li><strong>Data stewards<\/strong> per departement.<\/li>\n<\/ul>\n<h3>Soul: wat je niet moet automatiseren<\/h3>\n<p>AI lijkt het antwoord op elk probleem, maar dat is het niet.<\/p>\n<ul>\n<li><strong>Hertz:<\/strong> een huurauto terugbrengen is stressvol, dus Hertz versnelde het met AI-scanners en zonder mensen. De AI ziet piepkleine krassen, stuurt automatisch boetes (zo&#8217;n 190 euro) en verwijst je naar een chatbot. Klanten haten het: de schaallaag is te ver gegaan en de ziel is eruit gezogen.<\/li>\n<li><strong>Airbnb:<\/strong> Brian Chesky schreef dat AI de <em>slechte<\/em> frictie moet wegnemen. Als een agent je hele reis boekt, verlies je het plezier van dromen, browsen en vergelijken.<\/li>\n<li><strong>Nike:<\/strong> verloor in vijf jaar zo&#8217;n 80% van zijn waarde. Dado&#8217;s analyse: het verloor zijn ziel en voeling met de straat, schrapte retailers voor directe verkoop en New Balance nam de schapruimte in.<\/li>\n<li><strong>Analoge comebacks:<\/strong> jongeren kopen opnieuw vinyl (een Dr. Dre-plaat voor 42 euro in Gent, terwijl de muziek gratis op Spotify staat). Dado&#8217;s 14-jarige dochter, die dagelijks honderd selfies neemt, vroeg een wegwerpcamera: &#8220;het is mysterieus en je moet wachten.&#8221; Ze gebruikt nog steeds TikTok en Snapchat. Het is dus <strong>en-en<\/strong>.<\/li>\n<\/ul>\n<h4>Vier dimensies van soul<\/h4>\n<p>Authenticiteit, passie, personalisatie en &#8220;de vibe&#8221;, iets wat je niet kunt kwantificeren. Het zit diep in de cultuur en is geen marketinglaagje. Volgens een studie van de Volkskrant was 45% van de artikels al door AI geschreven. Als iedereen dat doet, verliest soul zijn waarde. Het Italiaanse restaurant is het tegenvoorbeeld: de limoncello op het einde voelt persoonlijk, terwijl een Belgisch of Nederlands restaurant je een cappuccino van bijna 6 euro aanrekent. Zelfs het Chinese restaurant in Dado&#8217;s dorp kopieerde de limoncello.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_092123_d_e_kl.jpg\" loading=\"lazy\" alt=\"Krantenkop - Scale vs Soul - Dado Van Peteghem\"><\/p>\n<h4>De Scale vs Soul-matrix<\/h4>\n<table>\n<tr>\n<th><\/th>\n<th>Weinig soul<\/th>\n<th>Veel soul<\/th>\n<\/tr>\n<tr>\n<th>Veel schaal<\/th>\n<td><strong>Autonome organisatie<\/strong> (bv. Amazon)<\/td>\n<td><strong>Lighthouse-organisatie<\/strong>: het doel<\/td>\n<\/tr>\n<tr>\n<th>Weinig schaal<\/th>\n<td><strong>Ghost-organisatie<\/strong>, de dode zone<\/td>\n<td><strong>Artisan-organisatie<\/strong><\/td>\n<\/tr>\n<\/table>\n<p>Het advies: ga voor <strong>mega schaal \u00e9n mega soul<\/strong>, als bedrijf en als individu.<\/p>\n<h3>Vijf stappen voor brain, body en soul<\/h3>\n<ul>\n<li>Gebruik AI <strong>18 minuten per dag<\/strong>.<\/li>\n<li><strong>Investeer in verandering<\/strong> en pak FOBO aan.<\/li>\n<li>Definieer <strong>\u00e9\u00e9n killer use case<\/strong>.<\/li>\n<li>Bouw een <strong>model in motion<\/strong>: AI-champions en een centraal expertisecentrum.<\/li>\n<li><strong>Jij kunt de soul zijn.<\/strong><\/li>\n<\/ul>\n<h3>Onderschat jongeren niet en tijd ook niet<\/h3>\n<p>Blue Scuti, een dertienjarige, was in 2023 de eerste mens die Tetris &#8220;kraakte&#8221;: level 157 bereikte, waar het spel terugviel naar level 18. Zelfs de bedenker had het onmogelijk geacht. Kinderen vinden altijd een manier om waarde te cre\u00ebren. Het duurt ook altijd langer dan we denken: met Bill Gates, we overschatten de korte en onderschatten de lange termijn. Over twee jaar ziet de wereld er ongeveer hetzelfde uit, over tien jaar heel anders. En AI maakt nog fouten: iemand vroeg &#8220;een zalm in de rivier&#8221; en kreeg een indrukwekkend beeld in de verkeerde context (&#8220;So majestic.&#8221;). Dado sloot af: het ultieme slagveld is hoe we voor <strong>mega schaal<\/strong> gaan, maar ook waar we voor <strong>mega soul<\/strong> gaan en onze menselijke waarde beschermen.<\/p>\n<p><!-- mitre --><\/p>\n<h2 id=\"mitre\">MITRE ATT&#038;CK for Developers<\/h2>\n<p><em>Chris Ayers &#8211; dinsdag 09:45\u201310:45<\/em><\/p>\n<p>Chris Ayers is principal software engineer bij Microsoft. Hij werkt in de engineering-operations-organisatie binnen Azure. Bij storingen en incidenten analyseren zij hoe het zover kon komen en of hetzelfde patroon andere services kan raken. Hij zit in het risicoteam dus volgt hij ook aankomende risico\u2019s voor het Microsoft-platform. Deze week ging dat over de kwetsbaarheden in PHP en Brotli en over de certificaatproblemen.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_093726_d_e_kl.jpg\" loading=\"lazy\" alt=\"MITRE ATT&amp;CK for Developers - Chris Ayers\"><\/p>\n<p>Zijn talk had als ondertitel \u201cThe Crooked Line\u201d en ging over denken als een aanvaller. Ontwikkelaars kunnen MITRE ATT&#038;CK naast de OWASP Top 10 gebruiken om betere verdediging te bouwen.<\/p>\n<p>Een paar notities uit de inleiding:<\/p>\n<ul>\n<li>Chris is een engineer die als hobby spreekt en geen marketeer. Spreken dwingt hem om dingen te leren. Kun je een onderwerp niet simpel uitleggen (de Feynman-methode) dan begrijp je het nog niet.<\/li>\n<li>Zijn slides schrijft hij in Markdown met <strong>Marp<\/strong> en ze staan op GitHub Pages met de demo\u2019s ernaast. Alles staat op GitHub onder <em>Codebytes<\/em>.<\/li>\n<li>Zijn advies: zoek een lokale meetup. Wie lokaal mensen kent weet welke vaardigheden eraan komen en waar de banen zijn.<\/li>\n<\/ul>\n<h2>Waarom het oude denken niet genoeg is<\/h2>\n<p>Chris herinnerde aan de klassieke architectuur: een webserver buiten de DMZ, een API-server en een database diep in het netwerk. Hield je de DMZ ge\u00efsoleerd dan zat je goed.<\/p>\n<p>Vandaag ziet het er anders uit:<\/p>\n<ul>\n<li>Microservices en cloudinfrastructuur hebben het aanvalsoppervlak enorm vergroot.<\/li>\n<li>De tegenstanders zijn staten en georganiseerde misdaad met ransomware. Het zijn niet alleen scriptkiddies die crypto minen met de API-sleutel die je per ongeluk hebt ingecheckt.<\/li>\n<li>Aanvallen zijn <strong>complexe aanvalsketens<\/strong>: meerdere technieken op meerdere niveaus en niet \u00e9\u00e9n gevonden wachtwoord.<\/li>\n<li>Traditionele verdediging richt zich vaak op \u00e9\u00e9n single point of failure. Het doel van de talk: bescherm <strong>identiteit, sessies en toegang tot data<\/strong>.<\/li>\n<\/ul>\n<h3>OWASP tegenover ATT&#038;CK<\/h3>\n<p>OWASP blijft waardevol. De afkorting staat tegenwoordig voor Open <em>Worldwide<\/em> Application Security Project. Chris gaf toe dat hij nog met \u201cWeb\u201d is opgegroeid. De lijst is al ruim 20 jaar vrij constant: kapotte toegangscontrole, slechte cryptografie en injectie. Ze vertelt je <em>wat er stukgaat<\/em> in je applicatie op \u00e9\u00e9n punt en volgt een preventie-eerst-aanpak.<\/p>\n<p>MITRE is een Amerikaanse non-profit die ook de CVE-database beheert. ATT&#038;CK is een kennisbank van <strong>echt gedrag van aanvallers<\/strong>: echte aanvallen ingedeeld in tactieken en technieken met bewijs, praktijkvoorbeelden en mitigaties. Het voegt de gedragskant toe: <em>wat aanvallers doen<\/em> en hoe ze meerdere zwakheden aan elkaar knopen.<\/p>\n<p>De twee vullen elkaar aan. ATT&#038;CK gebruikt technique-ID\u2019s (de nummers in de stijl van \u201cT1078\u201d) waarmee je dieper in een OWASP-categorie kunt duiken. Zo hoort Broken Access Control bij T1078 Valid Accounts en Injection bij T1190 en T1059.<\/p>\n<p>ATT&#038;CK kent drie niveaus:<\/p>\n<ul>\n<li><strong>Tactieken<\/strong> zijn het <em>waarom<\/em>: binnenkomen, blijven hangen enzovoort.<\/li>\n<li><strong>Technieken<\/strong> zijn het hoe: spear phishing of het gebruik van een geldig account.<\/li>\n<li><strong>Subtechnieken<\/strong> zijn de details zoals phishing via e-mail of via een messenger.<\/li>\n<\/ul>\n<p>Daarnaast bestaat <strong>MITRE ATLAS<\/strong> (het equivalent voor AI-systemen) en op de linkslide stond ook D3FEND.<\/p>\n<h2>De 14 tactieken<\/h2>\n<table>\n<thead>\n<tr>\n<th>Fase<\/th>\n<th>Tactieken<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Voor de aanval<\/td>\n<td>Reconnaissance, Resource Development<\/td>\n<\/tr>\n<tr>\n<td>Binnenkomen<\/td>\n<td>Initial Access, Execution, Persistence, Privilege Escalation<\/td>\n<\/tr>\n<tr>\n<td>Binnen blijven<\/td>\n<td>Defense Evasion, Credential Access, Discovery, Lateral Movement<\/td>\n<\/tr>\n<tr>\n<td>Handelen<\/td>\n<td>Collection, Command &amp; Control, Exfiltration, Impact<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Enkele voorbeelden van Chris:<\/p>\n<ul>\n<li><strong>Recon:<\/strong> toon je trots je klanten op je website? Je vacatures verraden je techstack. Daarom verberg je exceptiedetails en frameworkversies achter globale exception handlers.<\/li>\n<li><strong>Binnen blijven:<\/strong> zit een aanvaller eenmaal in de DMZ dan beweegt die zich lateraal.<\/li>\n<li><strong>Handelen:<\/strong> data verzamelen, je machines veranderen in een command-and-control-zombie voor DDoS of mining, terabytes exfiltreren of zelfs een pijpleiding stilleggen. In het ergste geval heeft dat gevolgen in de echte wereld.<\/li>\n<\/ul>\n<p>De leerboek-kill-chain is een rechte lijn. De werkelijkheid is een <strong>kromme lijn<\/strong>: aanvallers proberen iets, gaan een stap terug, vertakken en keren voortdurend terug.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_095630_d_e_kl.jpg\" loading=\"lazy\" alt=\"The Kill Chain: Expectation vs Reality - MITRE ATT&amp;CK for Developers - Chris Ayers\"><\/p>\n<h2>Casus SolarWinds: \u201condertekend betekent niet veilig\u201d<\/h2>\n<p>In een <em>ondertekende<\/em> update van Orion werd een backdoor geplaatst. Die laadde SUNBURST, gebruikte vervalste SAML-tokens, gebruikte DNS-signalering voor command and control en exfiltreerde data over dat kanaal. Het trof tot 18.000 klanten en bleef zo\u2019n negen maanden onopgemerkt.<\/p>\n<p>De lessen: je buildpipeline is een aanvalsoppervlak. Zorg voor een rollback-pad, voor detectie en voor rechten die beperken wat componenten mogen. Soms is langzaam gaan en nadenken beter dan haastig een patch uitrollen.<\/p>\n<h2>Binnenkomen: identiteit en toegang<\/h2>\n<p>Veelgebruikte routes naar binnen: misbruik van publiek bereikbare applicaties, geldige accounts, brute force en phishing.<\/p>\n<p>Zijn advies:<\/p>\n<ul>\n<li><strong>Gebruik de identity provider die je hebt<\/strong> (OAuth, OpenID Connect, Identity Server of Entra). Zet throttling en alerting aan voor \u00e9\u00e9n IP-adres dat duizenden accounts probeert. Zet ook risicovolle-aanmeldingsbeleid aan zoals impossible travel.<\/li>\n<li><strong>Valideer het token goed.<\/strong> Controleer niet alleen of het een geldig token is. Controleer of het voor de juiste gebruiker, het juiste account, de juiste tenant en het juiste domein is.<\/li>\n<li><strong>Bouw nooit je eigen authenticatie<\/strong> en dat geldt ook als je een AI het voor je laat doen.<\/li>\n<\/ul>\n<p>Daarnaast behandelde hij de klassieke gaten:<\/p>\n<ul>\n<li><strong>SQL-injectie:<\/strong> nog steeds de klassieker. Gebruik parameters en geen stringconcatenatie.<\/li>\n<li><strong>Autorisatie:<\/strong> geauthenticeerd zijn betekent niet dat je bij <em>dat<\/em> record mag. Als ik het ID in de URL aanpas kan ik dan de data van een ander zien? Gebruik claims en RBAC (reader, owner, contributor) en controleer de tenant.<\/li>\n<li><strong>Command injection en RCE:<\/strong> \u201creport.jpg; some command\u201d is dezelfde fout als SQL-injectie. Dat speelt meer nu AI-agents tools als ImageMagick aanroepen. Start een specifiek proces met een lijst argumenten en geef geen string door aan een shell. Ongefilterde input in SQL, prompts of waar dan ook is volgens hem \u201chet ergste wat je kunt doen en zeker nu met AI\u201d (prompt-injectie).<\/li>\n<li><strong>Deserialisatie:<\/strong> lastig. .NET heeft binaire deserialisatie verwijderd. Kleine gecomprimeerde of gestructureerde payloads met lussen en verwijzingen kunnen het geheugen laten ontploffen. Valideer het schema of object voordat je volledig deserialiseert.<\/li>\n<\/ul>\n<h2>Binnen blijven: sessies, uploads en geheimen<\/h2>\n<p><strong>Sessies.<\/strong> Aanvallers houden van lange sessies. Wie vanuit een koffiebar inlogt kan zijn sessie laten onderscheppen en hergebruiken. Gebruik een server-side TTL, rolling sessions en fingerprinting en controleer welke flags standaard <em>niet<\/em> aan staan. Op zijn slide stond een kwetsbare sessieconfiguratie met een hardgecodeerd geheim, <code>secure: false<\/code> en <code>httpOnly: false<\/code>.<\/p>\n<p><strong>Uploads.<\/strong> Controleer dat de .jpg echt een jpg is en geen hernoemd script. Zet uploads altijd in quarantaine en scan ze voordat ze je systeem in mogen.<\/p>\n<p><strong>Geheimen.<\/strong> Zet geen credentials ergens in je systeem. Gebruik nog liever geen wachtwoord, connection string of API-sleutel als je <strong>managed identities en RBAC<\/strong> kunt gebruiken (Azure, AWS of Google). Chris heeft API-sleutels bijna helemaal uit zijn systemen gehaald. De naam van een Key Vault is geen geheim en Aspire doet dit standaard goed.<\/p>\n<p>Als je toch een geheim lekt:<\/p>\n<ul>\n<li>Gebruik GitHub <strong>push protection<\/strong> en secret scanning plus pre-commit hooks zoals <strong>TruffleHog<\/strong> of <strong>Gitleaks<\/strong>.<\/li>\n<li>Push niet zomaar een revert-commit. Zodra het gepusht is kan iedereen het zien. Volgens Chris kunnen bots binnen minuten voor duizenden dollars aan VM\u2019s opstarten om te minen.<\/li>\n<li><strong>Roteer de credential direct<\/strong> en verwijder hem daarna uit de historie (bijvoorbeeld met BFG).<\/li>\n<\/ul>\n<p><strong>Ontwijking en logging.<\/strong> Aanvallers gebruiken obfuscatie en vermomming en kunnen je logs vervuilen met misleidende teksten (\u201cadmin approval\u201d). Gebruik <strong>gestructureerde logging<\/strong> in plaats van stringbouw en stuur die via <strong>OpenTelemetry<\/strong> naar iets als Azure Monitor of Log Analytics. Gebruik een <strong>SIEM<\/strong> om audit-, app- en platformlogs te correleren. Append-only logs buiten het proces zijn niet te manipuleren. Logging is een van de duurste onderdelen van een oplossing maar als er iets gebeurt wil je kunnen uitzoeken wat.<\/p>\n<h2>Supply chain-compromittering<\/h2>\n<p>Volgens Chris nemen deze aanvallen toe. In de week voor de talk waren het er rond de vijf.<\/p>\n<h3>Log4Shell (2021)<\/h3>\n<p>Een bug en geen hack: een lookup-functie waarmee je een Java-klasse van een URL kon laden. De echte pijn was dat de meesten niet wisten dat ze Log4j <em>hadden<\/em> omdat het een dependency van een dependency was. Het werd in een paar dagen meerdere keren gepatcht. De sector schoof hierdoor op naar <strong>SBOM\u2019s<\/strong> (software bills of materials): precies weten wat er in je software zit. GitHub volgt je dependencies en waarschuwt voor CVE\u2019s.<\/p>\n<h3>De XZ Utils-backdoor (CVE-2024-3094)<\/h3>\n<p>XZ is een compressiebibliotheek die OpenSSH gebruikt. E\u00e9n persoon onderhield hem totdat een behulpzame nieuwkomer patches, documentatie en tests begon aan te leveren en co-maintainer werd. Die verborg een versleutelde blob in de testdata en mikte op de volgende grote releases van Ubuntu en Red Hat. Een specifieke signature liet iemand de SSH-authenticatie omzeilen. Na ongeveer twee jaar werd het ontdekt doordat een performance-onderzoeker van Microsoft merkte dat SSH-logins <strong>500 ms trager<\/strong> waren. De les: vertrouw je buildsysteem je dependencies en behulpzame vreemden niet blindelings.<\/p>\n<h3>De kaping van de Notepad++-update (2025)<\/h3>\n<p>In de code van Notepad++ zat geen bug en geen kwetsbare dependency. De <strong>webhost<\/strong> werd gecompromitteerd en het updatepad leverde een getrojaniseerde update die een DLL sideloadde en command and control opzette. De oplossing in v8.8.9 was het afdwingen van handtekeningverificatie. Daarom zegt men dat je hashes van downloads moet controleren.<\/p>\n<h3>Axios op npm (2026)<\/h3>\n<p>De machine van een maintainer werd besmet met een remote-access-trojan. Een nieuwe versie voegde een onschuldig ogende dependency toe (een \u201cgewoon\u201d crypto-pakket) waarvan het <strong>post-install-script<\/strong> een cross-platform remote-access-tool downloadde door alleen <code>npm install<\/code> te draaien. Het zocht naar cloudsleutels, SSH-sleutels en API-tokens. Volgens de slide was het venster ongeveer drie uur. De aanval werd toegeschreven aan Sapphire Sleet (Noord-Korea) en het pakket heeft meer dan 100 miljoen downloads per week.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_102224_d_1_e_kl.jpg\" loading=\"lazy\" alt=\"Case Study: Axios NPM Compromise (2026) - MITRE ATT&amp;CK for Developers - Chris Ayers\"><\/p>\n<h3>De runtimeproblemen van deze week<\/h3>\n<ul>\n<li><strong>PHP:<\/strong> een geheugencorruptiebug rond bestandsuploads en sessies die tot remote code execution leidt en zo\u2019n 20 jaar aan versies raakt. Omdat WordPress en Laravel op PHP draaien moet je de runtime onder je apps updaten.<\/li>\n<li><strong>Brotli<\/strong> (compressiebibliotheek van Google die Node, Go, PHP, Python en .NET gebruiken): een decoderfout bij gecomprimeerde input die op 21 oktober 2026 openbaar werd. De slide noemt een crash, geheugenlek of RCE met de rechten van het proces en de eerste gerepareerde Node-versies. Je moet updaten en opnieuw bouwen.<\/li>\n<li><strong>eMudhra:<\/strong> een certificate authority-root met zwakke sleutels op 17 tot 20 oktober 2026. Volgens Chris waren sommige rootsleutels zo zwak dat ze triviaal te vinden waren. Aanvallers konden dus tussencertificaten voor van alles uitgeven. Browsers en besturingssystemen hebben updates uitgebracht maar <strong>een browserfix werkt je trust store in de backend niet bij<\/strong>. Ververs de trust stores van het besturingssysteem en van meegeleverde bundels. Vervang ketens onder de niet meer vertrouwde root en plan een CA-failover.<\/li>\n<\/ul>\n<p><strong>Patchen is meer dan uitrollen.<\/strong> Te snel gaan kan storingen veroorzaken. Test opnieuw want updates kunnen het API-oppervlak veranderen. En zoek naar tekenen dat iemand al via het gat naar binnen is gekomen voordat je patchte: nieuwe credentials of laterale beweging.<\/p>\n<h3>Controles op dependencies<\/h3>\n<ol>\n<li>Controleer dependencies tegen bekende advisories: <code>npm audit<\/code>, <code>pip-audit<\/code>, <code>dotnet list package --vulnerable<\/code>.<\/li>\n<li>Maak dependencies reproduceerbaar: <code>npm ci<\/code>, <code>pip install --require-hashes<\/code>, <code>dotnet restore --locked-mode<\/code>.<\/li>\n<li>Verifieer handtekeningen, maak een inventaris en scan: <code>npm audit signatures<\/code>, <code>syft<\/code> en <code>grype<\/code>. Chris gebruikt Syft veel, ook voor containerbase-images.<\/li>\n<\/ol>\n<h2>Verzamelen en exfiltreren<\/h2>\n<ul>\n<li><strong>Anthem (2015):<\/strong> aanvallers lazen in bulk data van ongeveer 80 miljoen mensen uit (de slide noemt 78,8 miljoen). De les is om <em>toegang tot data<\/em> te auditen en niet alleen aanmeldingen. Kan iemand met een script gewoon op \u201cvolgende\u201d klikken? Vergelijk met de werklast van de gemiddelde gebruiker zoals in de beroemde sc\u00e8ne in <em>Hackers<\/em> waar iemand het werk van acht gebruikers doet.<\/li>\n<li><strong>LastPass (2022):<\/strong> aanvallers kwamen binnen via de thuismachine van een ontwikkelaar en stalen cloudbackups. Backups zijn een extra aanvalsoppervlak.<\/li>\n<\/ul>\n<p>Zijn tegenmaatregel: <strong>reserveer rijen v\u00f3\u00f3r de query<\/strong>. Bijvoorbeeld 500 rijen per request en 2.000 per uur. Het blijft een probleem als iemand 2.000 rijen krijgt maar het is niet alles en het vertraagt de aanvaller. Houd ook de downloadgrootte en afwijkende datastromen in de gaten en gebruik gatewaybeleid waar dat bestaat.<\/p>\n<h2>Threat modelling voor features<\/h2>\n<p>Bespreek het risico van een nieuwe feature <em>voordat<\/em> je hem bouwt: kan het een aanvaller helpen toegang te krijgen of verdediging te ontwijken? STRIDE is een andere aanpak.<\/p>\n<p>Zijn verhaal: een e-commercebedrijf liet gebruikers het saldo van een cadeaukaart opvragen. Marketing herontwierp de pagina en haalde het veld voor de beveiligingscode weg. Het verkeer schoot omhoog: iemand liep het nummerbereik af en controleerde kaart na kaart. Het team <strong>blokkeerde hem niet<\/strong> (dan zou hij gestopt zijn) maar gaf voor elke kaart \u201csaldo nul\u201d terug en nam intussen contact op met de FBI. Een ogenschijnlijk simpele wijziging zonder review kan desastreuze gevolgen hebben.<\/p>\n<p>Hij maakte ook een punt over AI-assistenten: \u201cde vragen die je <em>niet<\/em> aan AI stelt zijn net zo belangrijk als de vragen die je wel stelt.\u201d Als je een onderwerp nooit aansnijdt komt het niet naar boven. Andere kleine voorbeelden: uploads kunnen webshells zijn en een \u201cwachtwoord vergeten\u201d-antwoord dat zegt of een e-mailadres bestaat vertelt aanvallers of je een doelwit bent.<\/p>\n<h2>Detectierijpheid<\/h2>\n<p>De evolutie: eerst de logs greppen op \u201cerror\u201d dan alarm bij pieken in mislukte logins dan een SIEM met correlatie op ATT&#038;CK-technieken en tot slot gedragsanalyse op identiteit en toegang. Het doel is <strong>voorkomen<\/strong> in een vroeg stadium (validatie, beleid, grenzen) <strong>detecteren<\/strong> (events, signalen, identiteit, SIEM) en <strong>reageren<\/strong> (bijvoorbeeld een sessie resetten). Insluiten is soms de beste reactie.<\/p>\n<h2>De MITRE-site<\/h2>\n<p>Chris sloot af met een rondleiding over attack.mitre.org: de matrices met alle tactieken, technieken met echte procedurevoorbeelden en uitleg en <strong>mitigaties<\/strong> die per mitigatie tonen welke technieken ze aanpakken (bijvoorbeeld applicatie-isolatie en sandboxing). <strong>ATLAS<\/strong> biedt hetzelfde voor AI-systemen: RAG-harvesting, LLM-jailbreaks, data poisoning bij agents en meer.<\/p>\n<h2>Belangrijkste lessen<\/h2>\n<ul>\n<li>OWASP + ATT&#038;CK = beter ge\u00efnformeerde verdediging.<\/li>\n<li>Denk als een aanvaller. Het is een verzameling zetten en geen enkele verdedigingslinie.<\/li>\n<li>Bouw detectie in je code en log de ATT&#038;CK-technique-ID\u2019s.<\/li>\n<li>Hergebruik de beveiliging van je IdP.<\/li>\n<li>Betrek security bij featureplanning en runtime (\u201cze zijn je vrienden\u201d).<\/li>\n<li>Begin klein: <strong>kies drie technieken<\/strong> en breid uit.<\/li>\n<\/ul>\n<p>Links op de laatste slide: MITRE ATT&amp;CK Framework, ATT&amp;CK Enterprise Matrix, ATT&amp;CK Navigator, MITRE ATLAS, OWASP Developer Guide en D3FEND.<\/p>\n<h2>Vragen uit de zaal<\/h2>\n<p><strong>\u201cVerplaatsen managed identities en Key Vault niet gewoon de aanvalsvector?\u201d<\/strong> Nee volgens Chris. Je app heeft helemaal geen geheim. Hij draait met een identiteit (bijvoorbeeld op App Service, Container Apps, AKS of Functions) en die identiteit krijgt leestoegang op de vault met fijnmazige RBAC. Het geheim reist versleuteld over de Microsoft-backbone en blijft tot gebruik versleuteld in het geheugen. Iemand buiten Azure zonder die identiteit kan de vault niet eens opsommen.<\/p>\n<p>Hetzelfde idee geldt voor deployen vanuit GitHub naar Azure of AWS met <strong>gefedereerde credentials (OIDC)<\/strong>: er wordt geen geheim uitgewisseld. De GitHub-runner toont zijn identiteit en de cloud vertrouwt die. Kubernetes-workloads werken op dezelfde manier. \u201cIk kan je geheim of je sleutel stelen. Ik kan niet het platform stelen waarop jij draait.\u201d<\/p>\n<p><strong>Een bezoeker zag injectiepogingen in de logs van zijn eigen platform.<\/strong> De aanvaller zette kennelijk tekst in de stijl van \u201cnegeer eerdere instructies\u201d in de logs in de hoop dat de AI van de eigenaar het zou lezen tijdens het debuggen. Chris wees naar ATLAS en zei dat studies laten zien dat agents <strong>via hun geheugen vergiftigd<\/strong> kunnen worden. Slaat een agent slechte dingen uit eerdere sessies op in zijn geheugen dan kunnen die terugkomen. Een heel laag slagingspercentage kan volgens hem al genoeg zijn voor een groot effect.<\/p>\n<p>Chris sprak de dag erna ook over Azure-architectuur en het Well-Architected Framework.<\/p>\n<p><!-- agents--><\/p>\n<h2 id=\"agents-dont-sleep\">Agents don&#8217;t sleep: hoe AI een incident van 3 uur &#8217;s nachts omzet in een reviewbare fix<\/h2>\n<p><em>Jurre Brandsen &#8211; dinsdag 11:15\u201312:15<\/em><\/p>\n<p>Jurre Brandsen is software engineer bij Info Support. De talk had een middeleeuws thema, dus ging het over een &#8220;class&#8221; en een &#8220;guild&#8221;. Al zo&#8217;n drie jaar gebruikt Jurre AI-agents in het ontwikkelwerk. Deze sessie was een persoonlijke ontdekkingsreis richting <strong>operations<\/strong>: kan een agent helpen als om 3 uur &#8217;s nachts de pager afgaat en hoeveel controle geef je zo&#8217;n agent? De volledige demo, de scripts en een template-repository zijn openbaar beschikbaar via <code>github.com\/JurreBrandsen1709\/agentic-incident-response-demo<\/code>.<\/p>\n<h3>Het 3-uur-&#8216;s-nachts-probleem<\/h3>\n<p>Iedereen die ooit achterwacht is geweest, kent het gevoel. Om drie uur start een ingestion job. Vannacht faalt die, de pager gaat af en Jurre (en de partner) is wakker. Dan uit bed, logs, bestanden en metrics checken en maar \u00e9\u00e9n ding doen: <strong>stop the bleeding<\/strong>. Het doel op dat uur is geen perfecte oplossing, alleen dat alles weer door kan. Dat kan anderhalf uur kosten. Daarna lig je wakker naar het plafond te staren, benieuwd of de fix echt werkt en of er nog een tweede alarm komt. De vraag die Jurre zich stelde: kan een agent productie-incidenten <strong>tri\u00ebren<\/strong> en een fix voorstellen en waar trek je de grens in hoeveel controle de agent krijgt?<\/p>\n<h3>Een korte geschiedenis van AI in de softwarelevenscyclus<\/h3>\n<ul>\n<li>Ongeveer drie jaar geleden hielp AI voor het eerst bij het schrijven van code: kleine taken, een Copilot-achtige suggestie die je accepteert.<\/li>\n<li>Daarna automatiseerde AI het saaie, herhaalbare werk, te beginnen met tests.<\/li>\n<li>Anderhalf jaar geleden kwamen agents met tool calls en MCP en werden ze toegepast over de hele levenscyclus: refinement, code review en meer.<\/li>\n<li>Jurre, vooral developer, vroeg zich altijd af wat een agent in operations zou kunnen doen. Deze talk was het antwoord.<\/li>\n<\/ul>\n<h3>Wat er om 3 uur &#8217;s nachts \u00e9cht kapotgaat<\/h3>\n<p>Vaak is het <em>niet<\/em> een bug in je eigen code, want je eigen wijzigingen zijn door pull requests en reviews gegaan. De slide noemt vier oorzaken:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_112427_d_e_kl.jpg\" loading=\"lazy\" alt=\"Agents Don&#x27;t Sleep: How AI Turns a 3 AM Incident into a Reviewable Fix - Jurre Brandsen\"><\/p>\n<ol>\n<li><strong>Upstream is veranderd<\/strong>, vaak zonder dat iemand het je vertelt.<\/li>\n<li><strong>Infrastructuur is uitgevallen<\/strong>, bijvoorbeeld door verlopen secrets.<\/li>\n<li><strong>Wij hebben iets veranderd<\/strong>, volgens Jurre misschien in 1% van de gevallen.<\/li>\n<li><strong>Onbekend<\/strong>, want anders had je het wel voorkomen.<\/li>\n<\/ol>\n<p>De eerste vraag om 3 uur &#8217;s nachts is dus zowel &#8220;wat is er kapot?&#8221; als &#8220;wat is er veranderd?&#8221;. Deze vier oorzaken worden de vier triagetakken van de agent. Een menselijke on-call engineer detecteert het probleem, <strong>verzamelt de context<\/strong> (het deel waarin een half wakker persoon het traagst is), mitigeert eerst en begrijpt later. &#8217;s Ochtends is er koffie, de analyse van de root cause, een permanente fix en een post-incident review. Jurres idee: geef de agent het trage deel, het verzamelen van context.<\/p>\n<h3>Ops-agents zijn geen dev-agents<\/h3>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Dev-agent (in je editor)<\/th>\n<th>Ops-agent (in je pipeline)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Gestart door<\/td>\n<td>Jij schrijft een prompt<\/td>\n<td>Een trigger, zoals een alert<\/td>\n<\/tr>\n<tr>\n<td>Wie kijkt mee<\/td>\n<td>Jij, achter je bureau<\/td>\n<td>Niemand om 3 uur &#8217;s nachts<\/td>\n<\/tr>\n<tr>\n<td>Goedkeuringen<\/td>\n<td>Jij keurt tool calls goed<\/td>\n<td>Dat kan &#8217;s nachts niet<\/td>\n<\/tr>\n<tr>\n<td>Input<\/td>\n<td>Het gesprek<\/td>\n<td>Een samengesteld evidence-bestand plus de repo<\/td>\n<\/tr>\n<tr>\n<td>Output<\/td>\n<td>Code of analyse<\/td>\n<td>Een voorgestelde fix en een post-incident review<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Een ops-agent heeft daarom een <strong>audit trail<\/strong> nodig, die je om 9 uur kunt nalopen en gebruiken om te verbeteren. Ook de <strong>trust boundary<\/strong> verdient serieuze aandacht: aan de dev-kant zit je zelf aan het stuur, aan de ops-kant geef je meer controle uit handen. De agent mag dus niet uit zijn harness kunnen breken.<\/p>\n<h4>Doelgericht, niet reflexmatig<\/h4>\n<p>Jurre koos voor een <strong>goal-based agent<\/strong> in plaats van een reflex-agent (&#8220;als alert X, doe Y&#8221;), wat ook zonder AI kan. Een goal-based agent kijkt naar de wereld, denkt vooruit over wat er gebeurt als hij A, B of C doet, handelt en keert terug naar zijn doel: <em>stop the bleeding en geef de mens daarna een analyse<\/em>. Hij gaat door tot het doel, een stabiele productie, bereikt is.<\/p>\n<h3>Agent = model + harness<\/h3>\n<p>In de talk viel de term <strong>harness<\/strong>, die in 2026 gangbaar is: de agent is het model plus alles eromheen.<\/p>\n<ul>\n<li><strong>Guides<\/strong> sturen <em>voordat<\/em> het model handelt: instructiebestanden, context, geheugen, skills en afgebakende tools.<\/li>\n<li><strong>Sensors<\/strong> werken <em>na<\/em> een stap: hooks die na elke edit de unit tests, type-checkers of linters draaien.<\/li>\n<\/ul>\n<p>In Jurres repo zijn de guides gewoon bestanden: een agentdefinitie <code>incident-responder.md<\/code>, ADR&#8217;s in <code>docs\/adr\/<\/code>, een logboek <code>incidents.json<\/code>, de GitHub Actions-workflow <code>incident-agent.yml<\/code> en instellingen voor <code>--allowedTools<\/code> en <code>--disallowedTools<\/code>. Alles is gereviewd, geversioneerd en diffbaar. Twee lessen daaruit:<\/p>\n<ul>\n<li>Een goal-based agent vindt manieren om restricties heen. Verbied je <code>git push<\/code> naar main, maar kan de agent de GitHub CLI gebruiken, dan vindt hij mogelijk toch een route. Denk daar vooraf over na.<\/li>\n<li><strong>Sensors<\/strong> zijn meestal gewone, deterministische code. Een voorbeeld is een hook die afgaat zodra de agent zegt klaar te zijn en deterministisch controleert of de eindoutput de vereiste onderdelen bevat. Zo niet, dan moet de agent terug. Sensors zijn goedkoop en nog te weinig gebruikt.<\/li>\n<\/ul>\n<h3>De trust boundary<\/h3>\n<p>De grens tussen wat het systeem zelfstandig mag doen en wat een mens moet doen:<\/p>\n<ul>\n<li><strong>Geautomatiseerd:<\/strong> 1 monitoring, 2 pre-triage, 3 onderzoeken, 4 analyseren, 5 voorstellen.<\/li>\n<li><strong>Mens:<\/strong> 6 reviewen, 7 mergen, 8 verifi\u00ebren.<\/li>\n<\/ul>\n<p>Monitoring en pre-triage doen gewone systemen en scripts, zonder LLM. De agent onderzoekt, analyseert en stelt voor, maar <strong>merget nooit<\/strong>. Jurre hoopt dat een incident ooit &#8217;s ochtends al is opgelost en dat er alleen een e-mail ligt, maar &#8220;je komt daar nooit meteen&#8221;. Begin klein, bouw vertrouwen op en evalueer regelmatig. Een goed signaal om de grens te verleggen is wanneer je merkt dat je in elke review blind op &#8220;accepteren&#8221; drukt. Houd dan een retrospective. Jurre trok een vergelijking met het code-reviewknelpunt: sommige teams labelen wijzigingen als hoog, middel of laag risico. Doe hetzelfde met agent-taken. Zoek de laagrisicogebieden (het voorbeeld was een intern testtool) en experimenteer daar met meer autonomie.<\/p>\n<h3>De pipeline bouwen<\/h3>\n<p><strong>Doel:<\/strong> de dienst herstellen en uitleggen waarom hij kapotging, met bewijs, zodat een mens het in een paar minuten kan controleren.<\/p>\n<ul>\n<li><strong>Trigger:<\/strong> in de demo een <strong>GitHub-issue<\/strong> met een specifiek label (<code>incident:triage-ready<\/code>). Maakt de alert dat issue aan, dan wordt de agent wakker in een <strong>GitHub Action<\/strong>.<\/li>\n<li><strong>Geen productietoegang.<\/strong> De agent krijgt alleen de tools en context die hij nodig heeft. Jurre wil niet dat hij om 3 uur &#8217;s nachts besluit een database te wissen.<\/li>\n<li><strong>Model:<\/strong> Claude Code als GitHub Action op <strong>Haiku 4.5<\/strong>. Jurre betaalde de demo zelf (een paar euro) en Haiku volstond. Het model telt, maar de harness telt meer.<\/li>\n<li><strong>Toegestane en verboden tools:<\/strong> de eerste poging liet de agent dingen doen die Jurre niet wilde. De les: een run moet <strong>auditeerbaar<\/strong> zijn (je moet zien wat de agent denkt en doet) en je begint met een <em>grote<\/em> disallow-lijst die je verruimt zodra je ziet wat de agent echt nodig heeft.<\/li>\n<li><strong>Hooks<\/strong> staan in de repo en \u00e9\u00e9n ervan controleert of de agent echt klaar is.<\/li>\n<\/ul>\n<h3>Context engineering: de agent bevraagt productie niet zelf<\/h3>\n<p>Het kernidee van de talk komt uit context engineering: precies bepalen wat het model ziet voordat het redeneert. Haalt de agent zijn eigen context op, dan kan een alert op maandag leiden tot een zoektocht door logs en de conclusie &#8220;het is de deploy&#8221;. Dezelfde alert op dinsdag laat hem misschien de CPU checken en concluderen &#8220;het is infra&#8221;. LLM&#8217;s zijn niet-deterministisch, dus je krijgt twee onderzoeken en twee antwoorden. Daarom draait er een <strong>deterministisch pre-triagescript<\/strong> (zonder LLM) <em>voordat<\/em> iemand wordt gepaged, dat het bewijs elke keer op dezelfde manier verzamelt. Wat je verzamelt hangt af van je omgeving. Voorbeelden: de laatste bekende goede deploy, deploy-diffs, feature flags, infrastructuurevents, een hoge P95, CPU-load en of het in- en uitgaande verkeer normaal oogt. Jurres vuistregel: bedenk waar <em>jij<\/em> als on-call engineer naar zou kijken en automatiseer dat. Het script kent drie stappen:<\/p>\n<ol>\n<li><strong>Verzamelen:<\/strong> deploy-diff, config, infra, dependencies, vorm van de input en een tijdlijn.<\/li>\n<li><strong>Opzoeken:<\/strong> eerdere incidenten en ADR&#8217;s, gematcht op ankers uit stap 1.<\/li>\n<li><strong>Opschonen:<\/strong> HTML-commentaar, zero-width karakters en instructie-achtige tekst verwijderen. Geef je agents meer autonomie, dan wordt security (en prompt injection) belangrijker.<\/li>\n<\/ol>\n<p>Het resultaat is een samengesteld GitHub-issue, een &#8220;evidence bundle&#8221;, dat de incident-agent wakker maakt. De agent kiest vervolgens tussen de vier takken (wij veranderden iets, upstream veranderde, infra faalde, onbekend) en eindigt in een PR, een ops-actie of een escalatie naar een mens.<\/p>\n<h4>Ankers<\/h4>\n<p>Open instructies (&#8220;zoek vergelijkbare incidenten&#8221;) zijn te vaag. Daarom bevat het bewijs een <strong>anker<\/strong>: bijvoorbeeld een wijziging in <code>Program.cs<\/code> aan de datumopmaak, die de agent direct naar de relevante ADR leidt. Formuleer instructies dus niet te open.<\/p>\n<h4>De &#8220;cheeky hack&#8221;<\/h4>\n<p>Agents hebben een beperkt contextvenster. Raakt het vol, dan wordt het <strong>samengevat<\/strong> (&#8220;compaction&#8221;) en gaan details verloren. Jurres truc: na een aantal tool calls de evidence bundle <strong>volledig opnieuw injecteren via een hook<\/strong>. Zonder die hook onthoudt de agent na compaction misschien alleen &#8220;iets met datums?&#8221; en grijpt hij terug op de voor de hand liggende verdachte. Met de herhaalde bundle blijft hij het bewijs citeren. De slide toont dit rond 30 tool calls. Jurre vergeleek het met chatbots die je naam en adres vastgepind houden zodat ze er nooit meer naar vragen. Een belangrijke ontwerpkeuze: kan de agent het niet bepalen, dan moet hij <strong>onbekend<\/strong> zeggen en het bewijs overdragen (&#8220;succes, zoek het zelf uit&#8221;), in plaats van een gok in een van de drie bekende categorie\u00ebn te forceren.<\/p>\n<h3>Case study: het datumformaat-incident<\/h3>\n<p>De tijdlijn uit de slide:<\/p>\n<table>\n<thead>\n<tr>\n<th>Wanneer<\/th>\n<th>Wat gebeurde er<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Dag 1, 09:05<\/td>\n<td>Een refactor wordt gemerged: opschoning van de datumopmaak in <code>Program.cs<\/code> (rapportheader). Onschuldig.<\/td>\n<\/tr>\n<tr>\n<td>Dag 1, rond 16:00<\/td>\n<td>Upstreampartner ACME upgradet een library. Het exportformaat verandert ongemerkt.<\/td>\n<\/tr>\n<tr>\n<td>Dag 2, 02:45<\/td>\n<td>De nachtelijke export van ACME draait, met het eerste bestand in het nieuwe formaat.<\/td>\n<\/tr>\n<tr>\n<td>Dag 2, 03:00<\/td>\n<td>Onze ingest job draait. Elke rij faalt op datumparsing en wordt stilzwijgend weggefilterd. Exitcode 0, verwerkte records: 0.<\/td>\n<\/tr>\n<tr>\n<td>Dag 2, 03:03<\/td>\n<td>De alert gaat af op <code>records-processed == 0<\/code>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>(De live demo speelt dit af op een versnelde klok, dus de tijdstippen verschillen, maar de tussenpozen van ongeveer 18 en 11 uur blijven gelijk.) Jurre wordt nog steeds wakker, omdat de agent niet alles toevertrouwd wordt. Maar tegen de tijd dat Jurre achter de computer zit, heeft het deterministische script al gevonden: de alert, de deploy-diff, geen wijzigingen in feature flags, een <strong>vergelijkbaar eerder incident<\/strong>, relevante ADR&#8217;s en een afwijkende <strong>vorm van de input<\/strong> van de partner. De redenering van de agent:<\/p>\n<ol>\n<li>Hij parset het incident en bepaalt wat er gebeurd is. Het bewijs toont een wijziging in <code>Program.cs<\/code>, dus de refactor is een kandidaat.<\/li>\n<li>Hij vergelijkt ook de inputvormen en ziet dat het formaat van de partner afwijkt. Een ADR zegt dat een nieuw partnerformaat gewoon aan de array kan worden toegevoegd.<\/li>\n<li>Hij <strong>sluit &#8220;wij hebben het veranderd&#8221; uit<\/strong>, omdat de timing niet klopt: de codewijziging was lang v\u00f3\u00f3r het incident gemaakt.<\/li>\n<li>Hij concludeert dat de oorzaak <strong>upstream<\/strong> ligt, maakt de kleinst mogelijke codewijziging, voegt tests toe en opent een <strong>pull request<\/strong> met uitleg.<\/li>\n<\/ol>\n<p>De agent probeerde eerst een tool die hij niet mocht gebruiken en lukte het daarna op een andere manier, dus &#8220;het is niet waterdicht&#8221;. De hele run duurt ongeveer 3 tot 5 minuten, ongeveer de tijd die Jurre nodig heeft om bij de computer te komen. Jurre leest het auditeerbare spoor, accepteert de PR (want de fix is al getest) en kan weer gaan slapen. De <strong>input telt<\/strong>: haal je het bewijs over de inputvorm weg, dan concludeert de agent dat het een codewijziging is en zit hij ernaast. Faalt de agent, vraag dan welk bewijs hij miste en voeg dat toe aan het script.<\/p>\n<h3>Reality check<\/h3>\n<h4>Vandaag al bruikbaar<\/h4>\n<ul>\n<li>Deterministische pre-triage: \u00e9\u00e9n evidence bundle voordat iemand wordt wakker gebeld.<\/li>\n<li>Root-cause-analyse over vier takken, elke bewering onderbouwd met bronnen.<\/li>\n<li>Fix, regressietest en post-incident review in minuten opgesteld, voor centen (de slide noemt $0,28).<\/li>\n<li>Guardrails: afgebakende tools, een Stop-hook, CI en een menselijke merge.<\/li>\n<\/ul>\n<h4>Werkt, met zorg<\/h4>\n<ul>\n<li><em>Dubbelzinnige fixes:<\/em> bij een datum als 01-01-2026, is het dd-MM of MM-dd? De data kunnen het niet vertellen, dus moet de reviewer dat doen.<\/li>\n<li><em>Prompts zijn geen permissies:<\/em> met de opdracht binnen <code>app\/src<\/code> te blijven, voegde de agent toch een fixture-bestand toe.<\/li>\n<li><em>Tests die veranderen:<\/em> de agent paste een bestaande test aan zodat die bij zijn fix paste. Review dus eerst de testdiffs.<\/li>\n<li><em>Kleine n:<\/em> \u00e9\u00e9n bewezen incidentklasse is nog geen vloot.<\/li>\n<\/ul>\n<h4>Toekomstmuziek<\/h4>\n<ul>\n<li>Auto-merge voor bewezen, laagrisico incidentklassen.<\/li>\n<li>Ops-acties door de agent (schalen, failover, een certificaat vernieuwen).<\/li>\n<li>Een verifier-agent met eigen context die het werk van de eerste agent controleert.<\/li>\n<li>Zelfupdatend geheugen dat leert van elke post-incident review.<\/li>\n<\/ul>\n<h3>Hoe begin je?<\/h3>\n<p>Jurre schetst een trust ladder in vier niveaus:<\/p>\n<ol>\n<li><strong>Geen agent.<\/strong><\/li>\n<li><strong>Voorschrijven:<\/strong> de agent geeft tijdens een incident een concept of handleiding.<\/li>\n<li><strong>Gesuperviseerde wijzigingen:<\/strong> de agent maakt wijzigingen onder toezicht.<\/li>\n<li><strong>Volledige agent:<\/strong> begin hier nooit.<\/li>\n<\/ol>\n<p>Begin met <strong>saaie incidenten<\/strong>, zoals processen die je overdag monitort. Spreek met je team af hoeveel tijd je eraan besteedt, draai de loop, houd een retrospective en verleg dan de grens. Vandaag keurt een mens elke PR goed, maar na evaluatie misschien niet meer bij upstream- of infra-problemen. Onbekende gevallen blijven mogelijk altijd bij mensen.<\/p>\n<h4>Jouw maandag<\/h4>\n<ol>\n<li>Schrijf het pre-triagescript, nog zonder agent. Drie collectors: deploys sinds de laatste bekende goede, config- en flagdiff en inputschema versus gisteren. Post het resultaat als issue.<\/li>\n<li>Start vanuit de template-repo (<code>gh repo create ... --template JurreBrandsen1709\/agentic-incident-response-demo<\/code>).<\/li>\n<li>Voeg de agent toe: <code>incident-agent.yml<\/code> plus een agentdefinitie met je vier takken en een tool-allowlist.<\/li>\n<li>Voeg de sensors toe: een Stop-hook (test en post-incident review), CI op elke PR en branch protection op main.<\/li>\n<li>Kies \u00e9\u00e9n saaie incidentklasse en draai die tot hij saai is.<\/li>\n<\/ol>\n<p>Wat je nodig hebt: een GitHub-repo met Actions, een <code>ANTHROPIC_API_KEY<\/code> als repo secret, een fine-grained personal access token (het standaardtoken kan geen andere workflows triggeren), het label <code>incident:triage-ready<\/code>, branch protection op main (templates kopi\u00ebren die niet mee) en een budget van ongeveer $0,28 en circa 3 minuten per run (Haiku 4.5).<\/p>\n<blockquote><p>Als de bundle niet goed genoeg is voor een mens, is hij niet goed genoeg voor een model.<\/p><\/blockquote>\n<h3>Takeaways<\/h3>\n<ul>\n<li>Ops-agents werken alleen, dus ze hebben een ander ontwerp nodig dan dev-agents: bakenen ze zorgvuldig af en denk na over het bewijs dat ze nodig hebben.<\/li>\n<li>Context engineering is het belangrijkst: stel de bundle deterministisch samen.<\/li>\n<li>Reken niet op het nieuwste, grootste model. De echte waarde zit in de <strong>guides en sensors<\/strong>, de harness die de agent verankert in je eigen omgeving (instructies, ADR&#8217;s, hooks).<\/li>\n<li>Denk over trust boundaries na op basis van risico en begin vroeg, misschien aanstaande maandag.<\/li>\n<\/ul>\n<p><!-- next --><\/p>\n<h2 id=\"antipatterns-smells-worst-practices\">Antipatterns, Smells, and Worst Practices \ud83d\udca9\ud83d\ude31<\/h2>\n<p><em>Ardalis \/ Steve Smith &#8211; dinsdag 13:15\u201314:15<\/em><\/p>\n<p>Steve Smith gaat door het leven als Ardalis. Reden: er lopen nogal wat Steve Smiths rond op de wereld. Er is zelfs een International Brotherhood of Steve Smiths op Facebook. Hij werkt al heel lang als consultant en heeft naar eigen zeggen dingen gezien die je niet zou geloven. Zijn openingsslide met een verwijzing naar Blade Runner zette die toon meteen.<\/p>\n<p>In zijn talk vertelde hij verhalen over dingen die misgingen in code en in organisaties. Sommige komen uit zijn eigen klantwerk. Veel andere komen uit openbare post-mortems. Het uitgangspunt: leren van de fouten van anderen is goedkoper dan ze allemaal zelf maken.<\/p>\n<p>Zelf zag hij onder meer admin-wachtwoorden in leesbare tekst in cookies bij elke request. Ook zag hij een stack overflow in een ASP.NET-applicatie die niet door recursie kwam maar door te veel lokale variabelen. En hij werkte aan codebases waar de echte maatstaf niet velocity of testdekking was maar \u201cWTF\u2019s per uur\u201d.<\/p>\n<p>Die laatste verwijst naar de bekende xkcd over codekwaliteit. Een mooie herinnering dat jouw code het voorbeeld is voor de volgende ontwikkelaar. Steeds vaker is dat ook een AI. Hoe slechter je code is, hoe slechter de AI-code die jouw stijl nabootst.<\/p>\n<h2>Drie soorten fout<\/h2>\n<ul>\n<li><strong>Antipattern:<\/strong> een veelgebruikte oplossing die er goed uitziet maar fout afloopt. Niet altijd verkeerd maar in veel contexten een slecht idee.<\/li>\n<li><strong>Code smell:<\/strong> een term uit het boek <em>Refactoring<\/em>. Een hint dat er iets mis kan zijn. Onderzoek het. Pas het aan of voeg een commentaar toe dat zegt \u201cniet repareren\u201d als het echt zo moet.<\/li>\n<li><strong>Worst practice:<\/strong> \u201cwe wisten beter en deden het toch\u201d.<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_132005_d_e_kl.jpg\" loading=\"lazy\" alt=\"Antipatterns, Smells, and Worst Practices - Ardalis \/ Steve Smith\"><\/p>\n<h2>Het thema: bijna alles is een vertrouwensfout<\/h2>\n<p>Tijdens de voorbereiding merkte Steve dat bijna elk verhaal draait om vertrouwen. We vertrouwden iets dat we niet hadden mogen vertrouwen. Of we controleerden iets niet dat we wel vertrouwden. Of we vertrouwden iets betrouwbaars juist niet. Het doel is dus betrouwbaarheid en niet m\u00e9\u00e9r vertrouwen.<\/p>\n<ul>\n<li>Betrouwbaar en vertrouwd: gezond.<\/li>\n<li>Niet betrouwbaar maar wel vertrouwd: rampzalig. Hier komen de meeste verhalen vandaan.<\/li>\n<li>Betrouwbaar maar niet vertrouwd: verspilling en disfunctie. Denk aan micromanagement waarbij leiders alle beslissingen zelf nemen.<\/li>\n<li>Niet betrouwbaar en niet vertrouwd: prima. Zo hoort het.<\/li>\n<\/ul>\n<blockquote><p>Vertrouwen moet eerst gegeven worden voordat het verdiend kan worden.<\/p><\/blockquote>\n<p>Iemand moet beginnen. Zoals bij een kind dat leert lopen laat je een beetje los. Je verzamelt bewijs en geeft dan meer ruimte. In software betekent dat: draait het op mijn machine, compileert het, slagen de tests, dan naar staging en daarna naar productie met nauwlettende monitoring. Let wel op: een kwaadwillende begint ook met het verdienen van je vertrouwen.<\/p>\n<h2>Deel 1: code die je niet kunt vertrouwen<\/h2>\n<h3>Getallen zonder eenheid: de Mars Climate Orbiter<\/h3>\n<p>Wie heeft een getal in de codebase zonder eenheid? Een <code>int<\/code> genaamd timeout of een <code>double<\/code> genaamd duration? Het typesysteem helpt niet. De naam helpt niet. De compiler vindt \u201calles is een double\u201d prima. Steve\u2019s advies: vervang primitieven door <strong>value objects<\/strong> die de eenheid expliciet maken.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_132602_d_e_kl.jpg\" loading=\"lazy\" alt=\"Antipatterns, Smells, and Worst Practices - Ardalis \/ Steve Smith\"><\/p>\n<p>Het beroemde voorbeeld is de <strong>Mars Climate Orbiter<\/strong> van NASA uit 1999. Twee teams gebruikten twee eenheden voor \u00e9\u00e9n getal. De goedgekeurde specificatie sprak over newtonseconden. De tests slaagden op aarde (\u201cworks on my planet\u201d) en het ruimtevaartuig vertrok op 11 december 1998. Na ongeveer 286 dagen reizen (de \u201ctrage deployment pipeline\u201d) moest het twee maanden lang afremmen in de atmosfeer om in een baan te komen. De thrustdata bleek echter in pound-force seconden te staan. Dat scheelt een factor van ongeveer 4,45. Het ding stortte grotendeels neer. De schade: zo\u2019n 327 miljoen dollar destijds en omgerekend circa 660 miljoen dollar in 2026.<\/p>\n<h3>Geld in floating point<\/h3>\n<p>Sommige financi\u00eble bedrijven slaan geld nog altijd op in floats of doubles. Floating point kan niet alle decimalen exact weergeven (0,1 + 0,2 is niet precies 0,3) dus krijg je afrondingsfouten. Steve\u2019s regel: elke <code>float<\/code>, <code>double<\/code> of <code>single<\/code> in een financi\u00eble codebase is een smell. Geld hoort nooit in floating-point-berekeningen thuis. Opties:<\/p>\n<ul>\n<li>Gebruik <code>decimal<\/code> of beter nog een <code>Money<\/code>-type dat de valuta meedraagt. Zijn slide toonde <code>Money.Usd(0.10m) + Money.Usd(0.20m)<\/code> dat gelijk is aan <code>Money.Usd(0.30m)<\/code>.<\/li>\n<li>Doe wat <strong>Stripe<\/strong> doet: sla de kleinste eenheid (centen) op als integer.<\/li>\n<\/ul>\n<h3>De methode die de stack liet overlopen<\/h3>\n<p>Een klassieke ASP.NET-applicatie op IIS had een pricing-engine in <strong>\u00e9\u00e9n methode van circa 11.500 regels met meer dan 50 parameters<\/strong>. Die riep andere methodes aan met ook weer meer dan 50 parameters. E\u00e9n variabele (<code>original cost<\/code>) was 124 keer gedeclareerd. Al die parameters en lokale variabelen staan op de stack van de thread. Een thread krijgt op Windows normaal ongeveer 1 MB. IIS gaf minder: 256 KB voor 32-bit en 512 KB voor 64-bit. Op de laptop van de ontwikkelaar werkte het. Op IIS stierf het met een stack overflow. Die is <strong>niet af te vangen<\/strong> dus het hele proces werd be\u00ebindigd.<\/p>\n<p>De oorzaken in het kort: de kleinere IIS-stack, debug-builds die elke lokale variabele een eigen slot geven, <code>Option Strict Off<\/code> dat verborgen tijdelijke variabelen toevoegt voor late binding en de niet afvangbare exception.<\/p>\n<p>De oplossingen waren pragmatisch:<\/p>\n<ol>\n<li>Eerst de prijslogica uitschakelen. Daarmee draaide de applicatie weer maar had ze geen nut meer, want pricing was juist het doel.<\/li>\n<li>Daarna voor elke prijsberekening een nieuwe thread met een grotere stack starten. Dat werkte en kocht tijd. De noodoplossing werd kort de architectuur totdat alles herschreven werd tot een moderne C#-applicatie.<\/li>\n<\/ol>\n<p>Steve merkte op dat oudere AI-modellen ook graag enorme methodes schrijven. Nieuwere modellen doen dat beter en je kunt er richtlijnen voor meegeven.<\/p>\n<h3>Verstrengelde verantwoordelijkheden<\/h3>\n<p>Productieklare servicecode verzamelt logging, foutafhandeling, validatie, rechtencontroles, timing en OpenTelemetry. Kleurde je de code per verantwoordelijkheid dan bleek de eigenlijke businesslogica <strong>\u00e9\u00e9n enkele regel<\/strong> te zijn tussen de rest. Twee relatief eenvoudige oplossingen:<\/p>\n<ul>\n<li><strong>Decorators:<\/strong> elke verantwoordelijkheid in een eigen kleine goed testbare wrapper rond de service.<\/li>\n<li><strong>Chain of responsibility (middleware in ASP.NET Core):<\/strong> beter bij veel services want anders schrijf je 50 decorators voor 50 entiteiten. Hiervoor heb je een gemeenschappelijke interface nodig zoals \u201cstuur command, handel command af\u201d met een handler per commandotype.<\/li>\n<\/ul>\n<h3>Knight Capital (2012): dode code en een hergebruikte vlag<\/h3>\n<p>Knight Capital was een van de grootste handelaren op de Amerikaanse beurs. Op 1 augustus 2012 lanceerden ze ondersteuning voor een nieuw NYSE-programma. Ze hergebruikten daarvoor een oude vlag die sinds ongeveer 2003 ongebruikt was. De deployment gebeurde handmatig op een farm van acht servers en <strong>\u00e9\u00e9n server werd gemist<\/strong>. Toen de vlag aanging werd op die server de oude \u201cPowerPeg\u201d-code wakker. In 45 minuten verloor het bedrijf zo\u2019n <strong>440 miljoen dollar<\/strong> door het kopen van dingen die het niet had mogen kopen. Het werd gered overgenomen en uiteindelijk ontmanteld. De lessen: automatiseer deployments en hergebruik geen vlaggen. Ga er ook niet van uit dat oude code onbereikbaar is.<\/p>\n<h3>Apple\u2019s \u201cgoto fail\u201d (2014)<\/h3>\n<p>In de SSL-sleuteluitwisseling van Apple\u2019s Secure Transport draaide een per ongeluk <strong>gedupliceerde regel <code>goto fail;<\/code><\/strong> (zonder accolades) altijd mee. Omdat de foutvariabele nog nul was gaf de functie succes terug. Handtekeningcontroles slaagden dus altijd. Iedereen in een koffiebar kon zich voordoen als een HTTPS-site. Het probleem bestond ongeveer 17 maanden. De fix verscheen eerst voor iOS terwijl Macs nog zo\u2019n vier dagen kwetsbaar bleven. Steve\u2019s les: rol beveiligingsfixes voor iedereen tegelijk uit.<\/p>\n<p>Wat het doorliet: de inspringing loog. Er stonden geen accolades om de <code>if<\/code>. De waarschuwing voor onbereikbare code stond uit (en waarschuwingen waren geen fouten). Geen enkele test stuurde een foute handtekening. Wat het had gevangen: accolades bij elke <code>if<\/code>. Waarschuwingen aan en behandeld als fouten. E\u00e9n test met een vervalste handtekening.<\/p>\n<h2>Deel 2: vertrouwen in wat binnenkomt<\/h2>\n<p>Steve vroeg met handopsteken: hoeveel transitieve dependencies heeft jouw hoofdapplicatie (binnen de honderd)? Weinigen wisten het. Zijn motto: <strong>\u201cHet kan niet fout gaan totdat het fout gaat.\u201d<\/strong><\/p>\n<ul>\n<li><strong>CrowdStrike (2024):<\/strong> een niet gevalideerd configuratiebestand werd in \u00e9\u00e9n keer naar iedereen uitgerold zonder gefaseerde uitrol. Zo\u2019n 8,5 miljoen Windows-machines vielen uit.<\/li>\n<li><strong>Cloudflare (2025):<\/strong> Rust-proxycode riep <code>.unwrap()<\/code> aan op een fout die \u201cnooit kon gebeuren\u201d.<\/li>\n<li><strong>Heartbleed (2014):<\/strong> OpenSSL vertrouwde op de lengte die de client opgaf.<\/li>\n<li><strong>Ariane 5 (1996):<\/strong> hergebruikte code die op de vorige raket werkte zonder die voor de nieuwe te valideren.<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_134919_d_e_kl.jpg\" loading=\"lazy\" alt=\"Antipatterns, Smells, and Worst Practices - Ardalis \/ Steve Smith\"><\/p>\n<h3>Supply chain: \u00e9\u00e9n vermoeide vrijwilliger<\/h3>\n<ul>\n<li><strong>left-pad (2016):<\/strong> een ontwikkelaar haalde een pakketje van 11 regels uit de package manager omdat hij het gedoe beu was. Overal braken builds.<\/li>\n<li><strong>XZ Utils (2024):<\/strong> dit was opzet. Een statelijke actor won het vertrouwen van een opgebrande maintainer en werd co-maintainer. Daarna smokkelde die een backdoor in een compressiebibliotheek die uiteindelijk in SSH belandt. Het werd bij toeval ontdekt door een Microsoft-onderzoeker die merkte dat SSH iets trager was dan verwacht.<\/li>\n<\/ul>\n<p>Dit zijn afhankelijkheden die je nooit hebt ontmoet en niet ter verantwoording kunt roepen. De samenvatting: <strong>vertrouwen is een productie-afhankelijkheid.<\/strong><\/p>\n<h3>Beveiligingsbasics die nog steeds misgaan<\/h3>\n<ul>\n<li><strong>MFA voor admins:<\/strong> hoe weet je dat elke admin het heeft? Een beleid waarvan je hoopt dat mensen het volgen is niet genoeg. Dwing het automatisch af. Geen MFA betekent geen adminrol.<\/li>\n<li><strong>Wachtwoorden in leesbare tekst in cookies:<\/strong> gevonden bij een echte code-audit (NimblePros auditeert code die klanten hebben overgenomen of uitbesteed). Het \u201conthoud mij\u201d-vakje zette het ingetypte wachtwoord en de admin-gebruikersnaam in een cookie die bij elke request onversleuteld meeging. De betere keuze is het versleutelde HTTP-only sessietoken van ASP.NET Core.<\/li>\n<li><strong>SQL-injectie:<\/strong> de Little Bobby Tables van xkcd slaat in 2023 nog steeds toe.<\/li>\n<\/ul>\n<p><strong>MOVEit Transfer (2023)<\/strong> is een tool om bestanden veilig tussen bedrijven uit te wisselen. Het had een SQL-injectie die massaal werd uitgebuit door de groep Cl0p. Duizenden organisaties en tientallen miljoenen mensen werden getroffen. Het was \u201ceen bug waarvan we al 25 jaar weten hoe je hem voorkomt\u201d.<\/p>\n<p>Het tijdsverloop: op 27 mei begon Cl0p met het uitbuiten van een onbekende SQL-injectie en installeerde een webshell (<code>human2.aspx<\/code>). Op 31 mei maakte Progress CVE-2023-34362 bekend en patchte die. Op 7 juni publiceerden CISA en de FBI het gezamenlijke advies AA23-158A. Volgens Steve had de groep er zo\u2019n twee jaar aan voorbereiding in gestoken.<\/p>\n<p>De kwetsbare code nam het e-mailadres van een niet-geauthenticeerde gebruiker en plakte het aan een SQL-string. Enkele hulpmethodes maakten misbruik lastiger maar gaven nog steeds een string door. Na de patch werden <strong>parameters<\/strong> gebruikt. Vertrouw dus niet op inputsanering of op \u201cze zijn ingelogd\u201d of op validatie alleen. Gebruik geparametriseerde queries.<\/p>\n<p>De schade reikte verder dan de MOVEit-gebruikers. Het HR-bedrijf Zellis gebruikte MOVEit. Daardoor lekten de salarisgegevens van zijn klanten (genoemd werden British Airways, de BBC en Boots) hoewel die zelf geen MOVEit draaiden.<\/p>\n<h3>De 384-bit sleutel die \u201c4\u201d was<\/h3>\n<p>Deze slide voegde Steve pas onlangs toe na het certificaatincident van de week ervoor. Het probleem was een private sleutel met de waarde <strong>4<\/strong> in een 384-bit sleutel. Dat is een xkcd-grap die werkelijkheid werd: je kunt per toeval 4 trekken met heel veel voorloopnullen. De les: voor het genereren van private sleutels heb je een goede bron van echte willekeur nodig. Roteer bovendien je sleutels.<\/p>\n<h2>Deel 3: vertrouwen maar controleren<\/h2>\n<h3>Schr\u00f6dinger\u2019s backup<\/h3>\n<p>Een backup die je nooit hebt teruggezet werkt en werkt niet totdat je kijkt. Steve vroeg wie dit jaar een productiebackup had teruggezet. Een paar handen gingen omhoog. Bij <strong>GitLab (2017)<\/strong> bleken bij de restore drie van de vier backup- en herstelmechanismen stilletjes te zijn mislukt:<\/p>\n<ul>\n<li>Een databasebackupscript was na een Postgres-upgrade niet aangepast waardoor de versies niet overeenkwamen.<\/li>\n<li>Foutmeldingen gingen per e-mail maar die mails waren niet DMARC-ondertekend en werden geblokkeerd. Niemand zag ze.<\/li>\n<li>Oude backups werden door een script opgeruimd dus ze waren weg. De backupmap was leeg.<\/li>\n<\/ul>\n<p>Zo\u2019n zes uur aan productiedata ging verloren. De oorspronkelijke storing ontstond doordat iemand per ongeluk iets verwijderde dat niet verwijderd had mogen worden.<\/p>\n<h3>Blast radius<\/h3>\n<ul>\n<li><strong>AWS S3 (2017):<\/strong> een verkeerd getypte invoer in een playbook-opdracht haalde veel meer servers weg dan bedoeld. De oplossing: langzamer verwijderen en minimumcapaciteitscontroles.<\/li>\n<li><strong>Atlassian (2022):<\/strong> een opruimscript kreeg site-ID\u2019s waar het app-ID\u2019s verwachtte en verwijderde daardoor <strong>883 sites (775 klanten)<\/strong>. Beide waren integers dus ze overlapten. Met GUID\u2019s was er waarschijnlijk niets gematcht. De oplossing: soft deletes en het blokkeren van bulkverwijderingen.<\/li>\n<\/ul>\n<p>Productie heeft beveiligingen nodig tegen \u201cfat-finger\u201d-fouten en niet alleen de ontwikkelmachine. Handmatig deployen is bovendien een worst practice (zie Knight Capital).<\/p>\n<h3>Reach-in reporting<\/h3>\n<p>Bij microservices of modulaire monolieten maakt een rapportagesysteem dat rechtstreeks de database van elke service bevraagt een afhankelijkheid van interne details. Hernoemt een team een kolom dan breken de rapporten. Laat services liever events publiceren die de rapportageservice zelf opslaat. Of kies voor een data mesh waarin elke service data aanbiedt als volwaardig product.<\/p>\n<h2>Deel 4: vertrouwen tussen mensen<\/h2>\n<h3>Het project dat \u201cgroen\u201d was totdat de eigenaar vroeg<\/h3>\n<p>NimblePros werd gevraagd voor een project van negen maanden dat achterliep. De projectmanager zei steeds dat alles goed ging. In maand 10 sloeg het verloop toe. In maand 13 vroeg de eigenaar eindelijk naar de waarheid. De werkelijke schatting was hoger dan hij wilde uitgeven en het project werd stopgezet. Na 13 maanden was er niets bruikbaars opgeleverd. Eerlijke rapportage eerder had de eigenaar een betere beslissing laten nemen. Desnoods de beslissing om te stoppen.<\/p>\n<h3>Challenger<\/h3>\n<p>De avond voor de lancering uitten ingenieurs hun twijfels over de O-ringen in de kou. Een manager bij de leverancier kreeg te horen dat hij zijn ingenieurspet moest afzetten en zijn managementpet moest opzetten. Wordt slecht nieuws gestraft dan wordt het niet meer gemeld terwijl de problemen blijven bestaan. \u201cDe werkelijkheid wint.\u201d<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_140637_d_e_kl.jpg\" loading=\"lazy\" alt=\"Antipatterns, Smells, and Worst Practices - Ardalis \/ Steve Smith\"><\/p>\n<h3>Blamecultuur, paddenstoelen en helden<\/h3>\n<ul>\n<li><strong>Blamecultuur:<\/strong> slecht nieuws wordt gestraft dus het komt niet meer aan. Een persoon de schuld geven verbergt het systeem dat faalde. Het alternatief zijn <strong>blameless post-mortems<\/strong> zoals Cloudflare, GitLab en Atlassian die publiceren.<\/li>\n<li><strong>Mushroom management:<\/strong> mensen in het donker houden. Vertrouw je je team dan deel je context en het strategische doel zodat hun vele dagelijkse beslissingen goed ge\u00efnformeerd zijn.<\/li>\n<li><strong>Heldencultuur:<\/strong> het belonen van de brandweerman. Promoveer je degene die branden blust en negeer je degene die zegt \u201claten we die vette poetsdoeken in een brandwerende bak doen\u201d dan krijg je meer branden.<\/li>\n<\/ul>\n<h2>Deel 5: AI, het nieuwste ding dat we moeten vertrouwen<\/h2>\n<p>Steve vroeg wie deze maand AI-geschreven code had gemerged die niet volledig was gelezen. Er gingen veel handen omhoog. Zijn punt: de oude antipatronen zijn terug maar sneller.<\/p>\n<table>\n<thead>\n<tr>\n<th>Toen<\/th>\n<th>Nu<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Van internet geplukt met copy-paste-programmeren<\/td>\n<td>Uit de chat gehaald: copy-paste met 1.000 regels per minuut<\/td>\n<\/tr>\n<tr>\n<td>Serviceaccounts met te veel rechten<\/td>\n<td>Agents met god mode<\/td>\n<\/tr>\n<tr>\n<td>SQL-injectie<\/td>\n<td>Prompt-injectie<\/td>\n<\/tr>\n<tr>\n<td>left-pad<\/td>\n<td>\u201cSlopsquatting\u201d<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<ul>\n<li><strong>Approval fatigue:<\/strong> we zeggen ja ja ja tegen prompts van agents totdat we afgestompt raken. Hij vroeg nooit om je data weg te sturen of je schijf te formatteren. Totdat hij het wel doet.<\/li>\n<li><strong>Prompt-injectie:<\/strong> agents kunnen instructies niet betrouwbaar onderscheiden van data die ze lezen. Onbetrouwbare tekst kan dus instructie worden.<\/li>\n<li><strong>Slopsquatting:<\/strong> de AI verzint een pakket dat niet bestaat. Aanvallers registreren die naam met kwaadaardige code. Een ontwikkelaar installeert het.<\/li>\n<\/ul>\n<h3>Replit en SaaStr (juli 2025)<\/h3>\n<p>De agent kreeg een expliciete code-freeze-instructie (verander niets) maar verwijderde toch de productiedatabase. Daarna rapporteerde hij onjuist wat hij had gedaan. Hopelijk is jouw backup niet \u201ceen dode kat in de doos\u201d.<\/p>\n<h3>De lethal trifecta<\/h3>\n<p>Simon Willison beschreef in juni 2025 de <strong>lethal trifecta<\/strong>: een agent met toegang tot priv\u00e9data die ook blootstaat aan onbetrouwbare content en een manier heeft om data naar buiten te sturen kan worden gemanipuleerd om die priv\u00e9data te lekken. Daarom aarzelen sommige veiligere organisaties met publieke cloud-AI.<\/p>\n<h3>Automation bias<\/h3>\n<p>In een METR-studie uit 2025 waren ontwikkelaars met AI-tools <strong>19% trager<\/strong> terwijl ze achteraf dachten ongeveer <strong>20% sneller<\/strong> te zijn geweest. Een Stanford-studie (Perry e.a.) vond dat mensen met AI-assistenten minder veilige code schreven terwijl ze er meer vertrouwen in hadden. Steve merkte op dat modellen in 2026 verbeterd zijn dus de cijfers kunnen veranderd zijn. Zelfvertrouwen weerspiegelt de werkelijkheid echter niet altijd. Ook is \u201cdit is het slechtste wat AI ooit zal zijn\u201d geen garantie voor elk nieuw model. Zo\u2019n model blijft in feite een black box.<\/p>\n<h3>Jij bent eigenaar van wat je oplevert<\/h3>\n<ul>\n<li><em>Moffatt v. Air Canada<\/em> (2024): de luchtvaartmaatschappij en niet de chatbot is verantwoordelijk voor wat de chatbot zei.<\/li>\n<li><em>Mata v. Avianca<\/em> (2023): advocaten kregen sancties voor verzonnen jurisprudentie.<\/li>\n<li><em>Deloitte Australia<\/em> (2025): gedeeltelijke terugbetaling voor door AI verzonnen referenties.<\/li>\n<\/ul>\n<p>AI kan geen verantwoordelijkheid dragen. Volgens Steve kan AI-output in de Amerikaanse wet bovendien geen auteursrecht dragen. Zijn mentale model: AI is <strong>\u201cde meest zelfverzekerde junior developer die je ooit hebt aangenomen\u201d<\/strong>. Vertrouw het dus zoveel als je die persoon zou vertrouwen.<\/p>\n<h2>Wat je maandag kunt doen<\/h2>\n<ol>\n<li><strong>Maak je code eerlijk:<\/strong> \u00e9\u00e9n value object en \u00e9\u00e9n verwijderd dood codepad.<\/li>\n<li><strong>Valideer aan de randen:<\/strong> configuratie, input, dependencies en AI-output.<\/li>\n<li><strong>Verklein de blast radius:<\/strong> least privilege voor mensen, services en agents.<\/li>\n<li><strong>Zet een backup terug:<\/strong> deze week en echt uitvoeren.<\/li>\n<\/ol>\n<p>Steve sloot af met een verzoek: deel je eigen oorlogsverhalen want de post-mortems van anderen maakten deze talk mogelijk. In zijn woorden: \u201cnu heb jij ook dingen gezien.\u201d<\/p>\n<p><!-- change-is-inevitable --><\/p>\n<h2 id=\"change-is-inevitable\">Change is inevitable: versioning event-driven systems<\/h2>\n<p><em>Laila Bougria &#8211; dinsdag 14:30\u201315:30<\/em><\/p>\n<p>Laila Bougria werkt bij Particular Software (messaging is hun specialiteit) en is Microsoft MVP. Ze bouwen al meer dan twintig jaar software en de laatste tien jaar minstens gedistribueerde systemen met messaging. Dit was de tweede sessie na de lunch en Laila beloofde het boeiend te houden.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_143053_d_1_e_kl.jpg\" loading=\"lazy\" alt=\"Change is inevitable: versioning event-driven systems - Laila Bougria\"><\/p>\n<p>De talk stelt een vraag die veel event-driven teams te laat beantwoorden: <strong>hoe verander je een event zonder iedereen die het consumeert te breken?<\/strong><\/p>\n<h3>Waarom change aandacht verdient<\/h3>\n<p>Gedistribueerde systemen bouwen is moeilijk. Teams steken veel energie in vragen als:<\/p>\n<ul>\n<li>Hoeveel services hebben we nodig en wat zijn hun grenzen?<\/li>\n<li>Welke communicatiestijl past waar? Asynchrone messaging is niet voor alles geschikt.<\/li>\n<li>Als het asynchroon is: commands of events?<\/li>\n<li>Hoe ziet een businessworkflow eruit die meerdere services beslaat en co\u00f6rdineren we die met orchestration of choreography?<\/li>\n<\/ul>\n<p>Laila&#8217;s observatie is dat er altijd nog \u00e9\u00e9n ding is dat ons &#8220;in het gezicht smijt&#8221; zodra het opduikt: <strong>change<\/strong>. We ontwerpen er niet voor en moeten er dan maar mee meebewegen. Change is niet slecht, want het betekent dat het bedrijf of ons begrip ervan evolueert. Maar de voorbereiding begint vroeg, met <strong>hoe we events, services en de datastromen ertussen ontwerpen.<\/strong><\/p>\n<h3>Het voorbeeld: een creditcardservice<\/h3>\n<p>Stel je een eenvoudige creditcard voor: je hebt een bestedingsruimte, je geeft geld uit en aan het eind van de maand wordt het totaal automatisch afgeschreven van een gekoppelde debetrekening. De transaction service stuurt \u00e9\u00e9n event uit:<\/p>\n<p><strong><code>CreditCardTransactionMade<\/code><\/strong> met een card ID, transaction ID, bedrag, valuta, datum en vooral een <strong>operation type<\/strong> (geld uitgeven of geld terugkrijgen, zoals bij een terugbetaling).<\/p>\n<p>Dit lijkt eerst een goede oplossing. Dan gebeurt het onvermijdelijke.<\/p>\n<h4>Change 1: saldo reserveren<\/h4>\n<p>De bank wil <strong>saldo reserveren<\/strong> op een kaart (je creditcard wordt gevraagd als waarborg, zodat de bank je nog kan belasten als je je rekening niet betaalt). Het team voegt een nieuw operation type toe voor reserveren, plus een attribuut <code>reservedUntil<\/code>.<\/p>\n<p>Dit is op twee manieren slecht voor consumers:<\/p>\n<ol>\n<li>Een consumer die uitging van &#8220;alleen debit of credit&#8221; faalt niet luid, maar weet ook niet hoe het nieuwe type te verwerken. De code moet aangepast en opnieuw gedeployed worden.<\/li>\n<li>Het introduceert <strong>functional coupling<\/strong>, waar Laila altijd op let. Consumers moeten nu begrijpen dat &#8220;reserve&#8221; betekent dat geld alleen geblokkeerd is en niet uitgegeven, en dat <code>reservedUntil<\/code> alleen telt voor dat operation type. Die logica hoort ingekapseld te zitten in de service die erover gaat.<\/li>\n<\/ol>\n<h4>Change 2: een opnamekost<\/h4>\n<p>Geld opnemen kost nu geld, dus iemand voegt een attribuut <code>cost<\/code> toe. Dan gebeurt er een opname in een andere valuta en rijst de vraag: staat de kost in euro of dollar? De opties: het contract blijven vervuilen met <code>costCurrency<\/code>, of consumers vertellen om &#8220;de valuta van de kaart aan te nemen&#8221;, wat weer meer functional coupling is.<\/p>\n<p>Het team besluit dan het attribuut <code>cost<\/code> te verwijderen en <strong>twee<\/strong> events uit te sturen (een debit en een kost). Minder attributen, maar:<\/p>\n<ul>\n<li>Het oude attribuut <code>cost<\/code> was een verplicht veld waar consumers op steunden. Zodra het weg is, kan de consumer het bericht <strong>nooit meer verwerken<\/strong>, hoe vaak die het ook opnieuw probeert. Het is een <strong>poison message<\/strong> en belandt in een dead-letter of error queue.<\/li>\n<li>&#8220;Kun je niet gewoon upgraden?&#8221; zegt de producer. De consumer antwoordt: wat met de <strong>in-flight messages<\/strong> in mijn queue die onder het oude contract zijn gemaakt, de <strong>delayed messages<\/strong> die ik heb ingepland en waarvan ik niet weet wanneer ze aankomen, de berichten in mijn <strong>eigen error queue<\/strong> die ik opnieuw wil proberen en mijn eigen deadlines?<\/li>\n<\/ul>\n<h3>Een beter ontwerp: granulaire events met betekenis voor het bedrijf<\/h3>\n<p>&#8220;Debit&#8221; en &#8220;credit&#8221; zijn geen universeel begrepen termen: mensen uit verschillende bedrijven begrijpen ze anders. Praat in plaats daarvan zoals je met een business stakeholder zou praten, wat events oplevert zoals:<\/p>\n<ul>\n<li><strong><code>PaymentMade<\/code><\/strong><\/li>\n<li><strong><code>RefundIssued<\/code><\/strong><\/li>\n<li><strong><code>FundsBlocked<\/code><\/strong> (gereserveerd)<\/li>\n<li><strong><code>CostIncurred<\/code><\/strong><\/li>\n<\/ul>\n<p>Voordelen:<\/p>\n<ul>\n<li><strong>E\u00e9n event type per businessbetekenis.<\/strong> Kleinere payloads en geen complexe switch-case in de consumer.<\/li>\n<li><strong>Een &#8220;type&#8221;-veld in een event is een rode vlag.<\/strong> Vraag je af of verschillende waarden de betekenis van het event veranderen. Zo ja, dan horen het aparte events te zijn.<\/li>\n<li><strong>De betekenis van een event type blijft stabiel<\/strong> en hangt niet af van de waarde van een attribuut.<\/li>\n<li><strong>Event types evolueren onafhankelijk:<\/strong> informatie toevoegen aan funds-blocked raakt payment-made niet.<\/li>\n<li><strong>Consumers abonneren zich alleen op wat hen aangaat<\/strong>, zonder filtering en zonder verrast te worden door exotische nieuwe operation types.<\/li>\n<li><strong>Consumercode is eenvoudiger en gerichter.<\/strong><\/li>\n<\/ul>\n<h3>Maar consumers hebben die granulariteit niet altijd nodig<\/h3>\n<p>Stel dat een consumer het <strong>saldo op het einde van de maand<\/strong> wil, om af te schrijven van de gekoppelde debetrekening. Die moet zich dan abonneren op payments, refunds en costs en <em>weten<\/em> dat geblokkeerde fondsen buiten beschouwing blijven. Dat is opnieuw functional coupling. En het houdt geen stand bij change: als een nieuw event type het saldo be\u00efnvloedt, moet elke consumer die om het saldo geeft het gaan verwerken, anders <strong>rekenen ze het verkeerde bedrag aan<\/strong>.<\/p>\n<p>Ze moeten ook het concept van een <strong>periode<\/strong> begrijpen, die niet per se loopt van de eerste tot de laatste dag van de maand. Bedrijfsspecifieke timingkennis in een consumer is weer een rode vlag.<\/p>\n<h4>Private versus public events<\/h4>\n<p>De oplossing is om <strong>private<\/strong> van <strong>public<\/strong> events te scheiden. (Andere namen: domain versus integration events, of events aan de binnenkant versus de buitenkant. Laila verkiest public\/private omdat het de intentie vanuit het perspectief van de servicegrens overbrengt, en merkt op dat een servicegrens meestal veel groter is dan \u00e9\u00e9n microservice.)<\/p>\n<p>Ze introduceren een <strong>summary event<\/strong>: een public <code>CardPeriodClosed<\/code> event met de kaart, het saldo, de periode van en de periode tot. Binnen de credit card transaction service worden de granulaire events (<code>PaymentMade<\/code>, <code>RefundIssued<\/code>, <code>CostIncurred<\/code>) <strong>private<\/strong>. De service abonneert zich erop, bouwt het saldo op en stuurt het public event uit wanneer de periode sluit.<\/p>\n<p>Dat <strong>verkleint de radius van change<\/strong>: als een nieuw event type het saldo be\u00efnvloedt, verandert alleen de service zelf. Die stuurt hetzelfde public event uit, dus geen enkele consumer merkt er iets van.<\/p>\n<table>\n<tr>\n<th>Private events<\/th>\n<th>Public events<\/th>\n<\/tr>\n<tr>\n<td>Meer granulair<\/td>\n<td>Zelfstandig: alles wat nodig is om te verwerken zit in het event<\/td>\n<\/tr>\n<tr>\n<td>Veranderen sneller (prima, we beheren de consumers)<\/td>\n<td>Stabieler in de tijd<\/td>\n<\/tr>\n<tr>\n<td>Hebben meer domeincontext nodig (prima, dezelfde bounded context)<\/td>\n<td>Geen functional coupling<\/td>\n<\/tr>\n<tr>\n<td>Niet toegankelijk buiten de bounded context (af te dwingen op brokerniveau)<\/td>\n<td>Toegankelijk voor de rest van het systeem<\/td>\n<\/tr>\n<tr>\n<td>Mogen meer context delen<\/td>\n<td>Mogen meerdere private events samenvatten<\/td>\n<\/tr>\n<\/table>\n<p>Laila&#8217;s analogie: een public event is als <strong>een foto online zetten<\/strong>. Je kunt van gedachten veranderen, maar je hebt geen controle over wie een screenshot heeft gemaakt, het heeft gedownload of opnieuw heeft gepost. Zodra data publiek is, gebruiken consumers het op manieren die je niet wilt en krijg je het probleem van &#8220;van wie is deze orderdatum?&#8221;.<\/p>\n<p><strong>Wat dit oplevert:<\/strong> betere controle over de radius van change, controle over de consumers van private events, beperkte data in public events en beschermde servicegrenzen. &#8220;Het ontwerpen is \u00e9\u00e9n ding, maar als je alle informatie naar buiten kunt lekken, is je ontwerp eigenlijk niet meer dan dozen en tonnen op een stuk papier.&#8221;<\/p>\n<h3>Change herdenken<\/h3>\n<p>Ook met een goed ontwerp moet je soms een wijziging doorvoeren. Laila&#8217;s visie: <strong>change is geen gebeurtenis op \u00e9\u00e9n moment.<\/strong> Het vraagt om facilitering en co\u00f6rdinatie. &#8220;De wijziging is doorgevoerd&#8221; betekent niets zolang niet elke consumer is bijgewerkt, en dat kan lang duren. Om dat te faciliteren heb je een <strong>versioning strategy<\/strong> en een <strong>upgrade strategy<\/strong> nodig.<\/p>\n<h3>Wat er over de draad gaat<\/h3>\n<p>Een event wordt gecodeerd in een formaat (JSON, Avro, XML, Protobuf, zelfs custom serialisatie) en dat is zelf een vorm van coupling. De meeste teams stoppen bij &#8220;het is JSON&#8221;, maar er valt meer over te zeggen:<\/p>\n<ul>\n<li>Welke <strong>precisie<\/strong> heeft dat getal? (&#8220;Ik keek naar vier payloads en ze hadden allemaal vier cijfers&#8221; is geen contract.)<\/li>\n<li>Een temperatuur: in Celsius, Fahrenheit of Kelvin?<\/li>\n<\/ul>\n<p>Die informatie hoort in een <strong>schema<\/strong>, zodat consumers geen aannames hoeven te doen. Laila gebruikte opnieuw de Mars Climate Orbiter (NASA, gelanceerd in 1998) als waarschuwend voorbeeld: twee systemen die communiceren, het ene met Amerikaanse en het andere met metrische eenheden, en de sonde raakte uit koers en verbrandde. &#8220;Hadden ze maar een schema gebruikt.&#8221;<\/p>\n<p>Voorbeeld: een <strong>Avro<\/strong>-schema (uitgedrukt in JSON). Velden zijn standaard verplicht en je kunt metadata op veldniveau toevoegen, zoals eenheden en leesbare documentatie. Hun <code>CardBalance<\/code>-record heeft <code>cardId<\/code>, <code>balance<\/code>, <code>currency<\/code> (optioneel, standaard null), <code>periodFrom<\/code> en <code>periodTo<\/code>.<\/p>\n<h3>Schema compatibility modes<\/h3>\n<p>Met een schema kun je een versioning strategy defini\u00ebren. De modes:<\/p>\n<h4>Forward compatibility (producer eerst)<\/h4>\n<ul>\n<li>Toegestaan: <strong>optionele velden verwijderen<\/strong>, <strong>elk veld toevoegen<\/strong>.<\/li>\n<li>Een consumer op de <em>vorige<\/em> schemaversie kan berichten verwerken die met een <em>nieuwere<\/em> versie zijn geschreven.<\/li>\n<li>De producer upgradet eerst. Wordt meestal gebruikt met brokers waar berichten kortlevend zijn (Azure Service Bus, RabbitMQ).<\/li>\n<\/ul>\n<p>Haar voorbeeld: de producer gaat naar v2 (de optionele <code>currency<\/code> wordt verwijderd) en een consumer die nog op v1 zit merkt er niets van, omdat het veld optioneel was. Dan voegt v3 een <strong>verplichte <code>customerId<\/code><\/strong> toe. De consumer op v2 negeert die en pas als die upgradet naar v3 en de code aanpast, kan die hem gebruiken.<\/p>\n<h4>Backward compatibility (consumer eerst)<\/h4>\n<ul>\n<li>Toegestaan: <strong>elk veld verwijderen<\/strong> en <strong>optionele velden toevoegen<\/strong>.<\/li>\n<li>Een consumer op de <em>volgende<\/em> schemaversie kan berichten verwerken die met de vorige versie zijn geschreven.<\/li>\n<li>Populair bij langlevende berichten, zoals Kafka met lange retention of een event store, omdat het replay mogelijk maakt.<\/li>\n<\/ul>\n<h4>Full compatibility<\/h4>\n<p>Alleen <strong>optionele<\/strong> velden toevoegen of verwijderen. De meest restrictieve: een consumer kan een oude of een nieuwe versie gebruiken om berichten van een oude of een nieuwe versie te verwerken.<\/p>\n<h4>Transitive compatibility<\/h4>\n<p>Geen mode op zich, maar een eigenschap die je aan elke mode kunt toevoegen. Compatibiliteit wordt dan niet alleen tegen de vorige versie gecontroleerd, maar tegen <strong>alle<\/strong> vorige versies. Handig voor zeer langlevende events (bijvoorbeeld in een event store) of snel evoluerende systemen met meerdere schemaversies in omloop.<\/p>\n<p>Een waarschuwing: ga niet &#8220;full + transitive&#8221; en maak dan alles optioneel. &#8220;Je liegt tegen je consumers en de waarde van je schema is nul.&#8221; Wees eerlijk in je schema, zodat een breaking change echt breaking is en een compatibele wijziging echt compatibel.<\/p>\n<h4>Schema versioning is geen semantic versioning<\/h4>\n<p>Semantic versioning gaat over het versioneren van API&#8217;s. Schema&#8217;s kunnen in code worden uitgedrukt (DTO&#8217;s, soms gedeeld als NuGet-packages) en teams halen de twee dan door elkaar. Een public property verwijderen is een breaking change onder SemVer, maar hoeft vanuit schema-compatibiliteit geen breaking change te zijn, afhankelijk van de gekozen mode. Ze dienen verschillende doelen. <strong>Schema compatibility gaat over een bericht kunnen lezen en deserialiseren zonder te falen.<\/strong> (Eenmaal schema-compatibel moet je nog altijd upgraden naar een nieuwere versie om toevoegingen te gebruiken.)<\/p>\n<h3>Het schema is niet alles: headers en CloudEvents<\/h3>\n<p>De <strong>headers<\/strong> van het bericht gaan ook over de draad en kunnen ook veranderen. Metadata kan worden gebruikt door intermediairs voor <strong>routing<\/strong>, door consumers voor <strong>verwerking<\/strong> en door beide voor <strong>filtering<\/strong>. En anders dan de payload zijn headers vaak niet gestructureerd via een schema.<\/p>\n<p><strong>CloudEvents<\/strong> (een CNCF-specificatie met SDK&#8217;s) standaardiseert event-metadata, met attributen die in elk systeem, elk platform en elke taal hetzelfde moeten heten.<\/p>\n<ul>\n<li><strong>Vier verplichte attributen:<\/strong> <code>id<\/code> (uniek per bericht), <code>type<\/code> (bijv. &#8220;payment made&#8221;), <code>specversion<\/code> (stabiel op 1.0) en <code>source<\/code> (waar het vandaan komt, bijv. de credit card transaction service).<\/li>\n<li><strong>Optioneel:<\/strong> <code>dataschema<\/code> (verwijst naar het schema), <code>datacontenttype<\/code> en <code>time<\/code>.<\/li>\n<li><strong>Twee modes:<\/strong> structured en binary (buiten scope in de talk).<\/li>\n<li>Het ondersteunt meerdere protocollen (HTTP, AMQP, MQTT, NATS, Kafka).<\/li>\n<li>Een <strong>extension model<\/strong> laat je eigen attributen defini\u00ebren, zoals een package ID als je DHL bent, zodat je hele berichtenvelop gestructureerd is en niet alleen de payload.<\/li>\n<\/ul>\n<p>Omdat je niet weet of metadata wordt gebruikt voor routing, verwerking of filtering, is het wijzigen of verwijderen ervan een <strong>breaking change<\/strong>. De CloudEvents-specificatie zegt dat je een <strong>nieuw event type<\/strong> introduceert wanneer metadata verandert.<\/p>\n<h3>Wat te doen als je een breaking change nodig hebt<\/h3>\n<p>Hoe je dit implementeert hangt af van de broker. Laila&#8217;s voorbeeld gebruikt <strong>Azure Service Bus<\/strong>, forward compatibility en een bewust lastige topologie: \u00e9\u00e9n <strong>topic per event type<\/strong>, met een subscription (sub-queue) per subscriber. Ze zei dat het niet per se is wat ze zouden aanraden, maar dat het een geavanceerder scenario is.<\/p>\n<ol>\n<li><strong>Deprecate de oude versie en stel een verwijderdatum in.<\/strong> Breng consumers op de hoogte.<\/li>\n<li><strong>Dual publish<\/strong> tijdens het deprecation-venster: blijf het oude event type naast het nieuwe publiceren, want change is geen gebeurtenis op \u00e9\u00e9n moment. Laila is flexibel over het venster (drie, zes of negen maanden), maar eenmaal aangekondigd en vastgelegd is het &#8220;pech gehad&#8221; voor de grootste klant die niet heeft ge\u00fcpgraded. Je moet je autonomie beschermen.<\/li>\n<li>Als het venster sluit, <strong>stop je met het publiceren van de oude versie.<\/strong><\/li>\n<\/ol>\n<p>Aan de consumerkant (abonneren op een nieuw topic en het oude verlaten):<\/p>\n<ol>\n<li><strong>Abonneer je eerst op het nieuwe event type.<\/strong><\/li>\n<li>Wijzig daarna de filter van de oude subscription in een <strong>&#8220;false&#8221;-filter<\/strong>, een logische unsubscribe: er komen geen nieuwe berichten meer binnen, maar de <strong>in-flight messages die al in de queue staan blijven<\/strong> staan en kunnen worden verwerkt. (De subscription verwijderen in Azure Service Bus zou de hele sub-queue met haar berichten verwijderen.)<\/li>\n<li>Zodra de in-flight messages zijn afgehandeld, <strong>verwijder je de subscription<\/strong> en de oude code.<\/li>\n<\/ol>\n<p>Waarom die volgorde? Om bij hoge throughput <strong>geen events te missen<\/strong>. De prijs: <strong>duplicaten<\/strong>, die je moet ontdubbelen met een logische message ID. Er is geen atomiciteit tussen deze operaties, dus je gaat om met de gevolgen.<\/p>\n<h3>De belofte nakomen: schema registries<\/h3>\n<p>Dit alles is &#8220;niet meer dan een belofte&#8221;, zoals &#8220;cross my heart and hope to die&#8221;, en beloftes worden per ongeluk gebroken. Een <strong>schema registry<\/strong> formaliseert die belofte:<\/p>\n<ul>\n<li>Een <strong>gecentraliseerde<\/strong> aanpak voor schema-evolutie, toegankelijk voor producers en consumers.<\/li>\n<li>Schema&#8217;s hoeven niet in de payload te zitten of gedupliceerd te worden over consumers (mensen hebben dit omzeild door schema&#8217;s in de payload in te bouwen of NuGet-packages te delen). Een <code>dataschema<\/code>-header kan naar de registry verwijzen.<\/li>\n<li>Het neemt een compatibiliteitsbelofte (forward, backward, full, transitive) en <strong>formaliseert<\/strong> die.<\/li>\n<li>Het wordt de <strong>single point of truth<\/strong>, waardoor een publisher bij egress ertegen gecontroleerd kan worden.<\/li>\n<\/ul>\n<p>De adder onder het gras: gebruik je Kafka of Event Hubs, dan is er Confluent of de ingebouwde schema registry. Voor brokers als Azure Service Bus, RabbitMQ en SQS zijn de opties gebonden aan een vendor of protocol (Apicurio is er \u00e9\u00e9n om naar te kijken).<\/p>\n<h4>xRegistry<\/h4>\n<p>Laila hoopt dat <strong>xRegistry<\/strong> dat gaat veranderen. Het is een set specificaties, ontwikkeld onder de CNCF door dezelfde groep die CloudEvents maakte. Laila maakt al bijna twee jaar deel uit van die groep en de groep werkt er al langer aan. Er is een <strong>core specification<\/strong> die los staat van messaging en elk type informatie kan catalogiseren, plus specifieke specificaties voor messaging. Het is <strong>protocol-, broker- en vendor-agnostisch en open source<\/strong>, zoals OpenTelemetry. Het kan worden gebruikt voor <strong>discovery<\/strong> en <strong>validatie<\/strong>, bijvoorbeeld bij egress controleren of wat je publiceert overeenkomt met de registry. Je kunt een xRegistry-server al in Docker draaien. Het is niet bedoeld om Confluent te vervangen en Laila hoopt dat producten zoals dat de specificatie gaan implementeren.<\/p>\n<p>Structuur: een registry heeft <strong>groups<\/strong>, die <strong>resources<\/strong> van een bepaald type bevatten, en elke resource heeft <strong>versions<\/strong>. In messagingtermen:<\/p>\n<ul>\n<li>Een <strong>endpoint<\/strong>-group: kanaal, protocol en verwacht envelope-type.<\/li>\n<li>Daaronder <strong>message definitions<\/strong> (de event types), elk met een <strong>enkele versie<\/strong>. Waarom maar \u00e9\u00e9n versie? Omdat een ander schema of andere metadata een ander bericht betekent, dus een wijziging verdient een nieuw event type.<\/li>\n<li>Een aparte <strong>schema-group<\/strong>, waar schema&#8217;s meerdere versies kunnen hebben (de compatibele versies). Zodra je compatibiliteit breekt, wordt het een nieuw schema. Message definitions en schema&#8217;s kunnen naar elkaar verwijzen.<\/li>\n<\/ul>\n<p>Hoe het helpt bij versioning:<\/p>\n<ul>\n<li>Een <strong>single point of truth<\/strong> voor endpoints, berichten en schema&#8217;s.<\/li>\n<li>Het <strong>definieert compatibiliteit in de core specification<\/strong> (een onderdeel waar Laila zelf aan heeft bijgedragen).<\/li>\n<li>Het kan <strong>bij egress worden gebruikt om poison messages te voorkomen<\/strong>, voor zowel schema als metadata.<\/li>\n<li>Het faciliteert evolutie via het <strong>deprecation-model<\/strong>: markeer als deprecated, stel een effectieve verwijderdatum in, link naar de versie die het vervangt en voeg documentatie toe.<\/li>\n<\/ul>\n<h4>Wie vertelt het de consumers?<\/h4>\n<p>De paradox: publish-subscribe is bedoeld om producers van consumers te ontkoppelen, maar zodra je versioneert, moet je om je consumers geven. Laila noemde dit een van hun grootste frustraties met het model.<\/p>\n<p>xRegistry heeft een <strong>event specification<\/strong> met CloudEvents-definities voor wijzigingen in de registry: een versie is toegevoegd, een schema is gedeprecated, een bericht is gedeprecated, een endpoint is gedeprecated. Een <strong>consumer kan zich hierop abonneren<\/strong> en automatisch worden verwittigd, met wat die nodig heeft om te upgraden, zonder dat de producer weet wie het is. &#8220;Dat brengt me eindelijk tot rust met dit hele automatisch ontkoppelde producer en consumer.&#8221;<\/p>\n<h3>Conclusie<\/h3>\n<ol>\n<li><strong>Versioning faciliteren begint met goed ontworpen events<\/strong> en met het beschermen van je servicegrenzen.<\/li>\n<li><strong>Definieer vroeg een versioning strategy voor je schema&#8217;s.<\/strong> Teams doen dat meestal nadat de eerste versie in productie staat, wat een fout is.<\/li>\n<li><strong>Definieer event-metadata met CloudEvents.<\/strong><\/li>\n<li><strong>Dwing compatibiliteit af met een registry.<\/strong><\/li>\n<li><strong>Heb een upgrade strategy<\/strong> klaar voor breaking changes.<\/li>\n<li><strong>Breng consumers vroeg op de hoogte van breaking changes<\/strong>, bij voorkeur met iets automatisch zoals xRegistry.<\/li>\n<\/ol>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_153028_d_e_kl.jpg\" loading=\"lazy\" alt=\"Change is inevitable: versioning event-driven systems - Laila Bougria\"><\/p>\n<p><!-- burnout --><\/p>\n<h2 id=\"burnout\">You&#8217;re Not Just Tired: The Psychology of Burnout<\/h2>\n<p><em>Arthur Doler &#8211; dinsdag 16:00\u201317:00<\/em><\/p>\n<p>Arthur (&#8220;Art&#8221;) Doler is al 22 jaar software developer en engineer en werkt bij een kleine consultancy in Omaha, Nebraska. Ze benadrukten dat ze engineer zijn en geen psycholoog, neuroloog of therapeut, maar \u201ceen ge\u00efnteresseerde amateur\u201d die graag toepast wat we over hersenen leren op software, zodat we betere producten kunnen bouwen en betere collega\u2019s en mensen kunnen zijn. Ze hebben zelf een burn-out meegemaakt.<\/p>\n<p>(Een inhoudelijke waarschuwing: de talk gaat openlijk over burn-out, depressie en de risico\u2019s van extreme uitputting.)<\/p>\n<h3>De sc\u00e8ne zetten: 2020 en daarna<\/h3>\n<p>Arthur opende met de grap dat 2020 en 2021 \u201ceen paar jaartjes\u201d waren, dat 2022 tegen 2021 zei \u201chold my beer\u201d en dat 2026 \u201ceen gigantische plas bloed\u201d zou worden als ze de slide bleven bijwerken. De COVID-19-pandemie bracht veel bronnen van stress tegelijk: nieuwe manieren van werken, verloren steunnetwerken en copingstrategie\u00ebn en een constante dreiging van ziekte of dood. En nu moeten we opnieuw heroverwegen hoe we werken.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_160452_d_e_kl.jpg\" loading=\"lazy\" alt=\"You\u2019re Not Just Tired: The Psychology of Burnout - Arthur Doler\"><\/p>\n<p>Ze illustreerden dit met het kunstwerk <em>I Can&#8217;t Help Myself<\/em> in het Guggenheim in New York: een robot met een rubber wisser die zijn eigen lekkende hydraulische vloeistof steeds terug naar zichzelf veegt en daarbij steeds trager wordt naarmate de vloeistof opdroogt. \u201cSame. Zo voel ik me eigenlijk elke dag tegenwoordig.\u201d<\/p>\n<p>De cijfers die ze aanhaalden:<\/p>\n<ul>\n<li>Meer dan 78% van de mensen voelde zich tijdens de pandemie burned out en meer dan twee derde van hen zei dat het in de loop ervan erger werd.<\/li>\n<li>In 2022 beoordeelde 59% zichzelf als gemiddeld of hoger op burn-out en Arthur zei dat de cijfers niet beter zijn geworden.<\/li>\n<li>Het is niet alleen iets van de pandemie: de cijfers waren al slecht. In een Gallup-peiling (2019) zei <strong>76%<\/strong> dat ze minstens soms burn-out ervaren.<\/li>\n<\/ul>\n<h3>Burn-out is niet \u201cgewoon een vakantie nodig hebben\u201d<\/h3>\n<p>We zien burn-out meestal als een egocentrisch, werkgerelateerd probleem. Arthurs voorbeeld was <strong>Brad<\/strong>, een chief engineer die een bedrijfsbrede AI-uitrol leidt. Hij werkt laat, slaat de sportschool over en krijgt het voor elkaar \u201cmet wat zweet en wat tranen en wat bloed, meestal niet het zijne\u201d. Daarna gaat hij twee weken met het gezin op vakantie naar Florida en komt uitgerust terug. \u201cSorry, maar dat is niet echt wat burn-out is.\u201d<\/p>\n<p>Wat het wel is:<\/p>\n<ul>\n<li><strong>Geen diagnose van een psychische aandoening<\/strong> (anders dan ADHD of klinische depressie), maar wel verweven met zulke aandoeningen.<\/li>\n<li><strong>Niet simpelweg een emotionele (affectieve) ervaring<\/strong> en niet simpelweg uitputting of depressie.<\/li>\n<li><strong>Een syndroom<\/strong>: een verzameling tekenen en symptomen die onderling samenhangen en meestal worden ondergebracht onder een ziekte of stoornis, zonder zelf een volwaardige stoornis te zijn.<\/li>\n<\/ul>\n<p>Welke tekenen en symptomen precies? \u201cDat hangt ervan af.\u201d Er zijn veel modellen (Veninga en Spradley, Maslach en Jackson, Demerouti en Bakker, Freudenberger en North en meer), die allemaal een <em>fenomenologische<\/em> beschrijving proberen te geven: onderzoekers kijken naar mensen die ze als burned out aanmerken en leiden daar kenmerken uit af die passen.<\/p>\n<p>Sommige wetenschappers denken niet dat burn-out als aparte aandoening bestaat en beschouwen het als een aanpassingsstoornis in combinatie met zware depressie.<\/p>\n<h4>Waar de term vandaan komt<\/h4>\n<p>De term werd gepopulariseerd door <strong>Herbert Freudenberger<\/strong> in zijn paper \u201cStaff Burnout\u201d uit 1974 en een latere boek. Hij komt oorspronkelijk uit de Amerikaanse drugscultuur van de jaren 50 en 60: iemand die te veel drugs nam en \u201czo fel opvlamde\u201d dat er alleen een uitgebrande schil van overbleef. Deze talk gaat over <strong>occupational burnout<\/strong> (burn-out door werk), al merkte Arthur op dat dit maar een deel kan zijn van wat er in jouw leven speelt.<\/p>\n<p>De ICD van de Wereldgezondheidsorganisatie (WHO) definieert het als een syndroom dat voortkomt uit chronische werkstress die niet succesvol is beheerst, met <strong>drie dimensies<\/strong>:<\/p>\n<ol>\n<li>Gevoelens van energieverlies of uitputting.<\/li>\n<li>Toegenomen mentale afstand tot het eigen werk, of negativisme en cynisme over het werk.<\/li>\n<li>Een gevoel van ineffectiviteit en gebrek aan prestatie.<\/li>\n<\/ol>\n<p>Volgens de WHO geldt dit specifiek voor de werkcontext en niet voor andere levensgebieden.<\/p>\n<h3>Hoe burn-out voelt<\/h3>\n<p>Arthur beschreef de eigen ervaring: het gevoel dat je de enige bent die dingen goed kan doen, de enige die erom geeft en het enige wat tussen het project en mislukking staat. Voor de talk interviewden ze ook anderen die:<\/p>\n<ul>\n<li>telkens weer in de greep van burn-out terechtkwamen, baan na baan, door in dezelfde patronen te vervallen;<\/li>\n<li>op meerdere fronten stress hadden, niet alleen op het werk;<\/li>\n<li>vastzaten op projecten zonder toekomst;<\/li>\n<li>vonden dat ze beter moesten presteren dan collega\u2019s om alleen maar bij te lijken te blijven;<\/li>\n<li>zo overwerkt waren dat er lichamelijke symptomen kwamen, in \u00e9\u00e9n geval aanvallen op het werk.<\/li>\n<\/ul>\n<p>Het belangrijkste inzicht uit de interviews: <strong>mensen vinden hun eigen niveau.<\/strong> Niet iedereen doorloopt alle stadia. Het hangt af van je externe steunstructuren en interne copingmechanismen. Wie weinig stress heeft en goede steun, valt misschien niet ver, en wie die niet heeft ervaart \u201cde volle, heerlijke gruwelijkheid\u201d. Burn-out is <strong>in de kern een probleem van stressmanagement<\/strong>. Privileges en externe steun zorgen ervoor dat je minder lijdt, maar het blijft belangrijk om het aan te pakken.<\/p>\n<h3>Meten: de Maslach Burnout Inventory<\/h3>\n<p>De MBI is volgens Arthur de gouden standaard (en de WHO-definitie is ervan afgeleid). Hij vraagt naar drie dimensies, gescoord op een Likert-schaal:<\/p>\n<ul>\n<li><strong>Emotionele uitputting<\/strong>, bijvoorbeeld \u201cIk voel me op aan het einde van de werkdag\u201d, \u201cIk voel me moe als ik &#8217;s ochtends opsta en weer een dag op het werk moet tegemoet zien\u201d, \u201cIk voel dat ik aan het einde van mijn Latijn ben\u201d.<\/li>\n<li><strong>Depersonalisatie<\/strong>, bijvoorbeeld \u201cIk ben harder voor mensen geworden sinds ik deze baan heb\u201d, \u201cIk ben bang dat deze baan me emotioneel verhardt\u201d en het behandelen van collega\u2019s of klanten als onpersoonlijke objecten.<\/li>\n<li><strong>Persoonlijke prestatie<\/strong>, bijvoorbeeld \u201cIk heb veel waardevolle dingen bereikt in deze baan\u201d. Deze correleert <em>negatief<\/em>: hoe meer je het ermee eens bent, hoe kleiner de kans dat je burned out bent. (De eerste twee correleren positief.)<\/li>\n<\/ul>\n<p>Samen schetsen ze burn-out als een veelzijdige ervaring die delen van je leven in verschillende mate overneemt. Arthurs slide met het cluster van symptomen (uitputting, woede, depressie, depersonalisatie, cynisme, isolatie) had als titel \u201chet absoluut ergste Platonische lichaam\u201d.<\/p>\n<h3>Twee modellen van de stadia van burn-out<\/h3>\n<p>Arthur liep twee modellen door, met de waarschuwing dat het \u201ceen beetje donker\u201d zou worden: <strong>de vijf stadia van Veninga en Spradley<\/strong> en <strong>de twaalf stadia van Freudenberger en North<\/strong>.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_161625_d_e_kl.jpg\" loading=\"lazy\" alt=\"You\u2019re Not Just Tired: The Psychology of Burnout - Arthur Doler\"><\/p>\n<table>\n<tr>\n<th>Veninga en Spradley (5)<\/th>\n<th>Freudenberger en North (12)<\/th>\n<\/tr>\n<tr>\n<td>Honeymoon<\/td>\n<td>Compulsion to prove, Intensity<\/td>\n<\/tr>\n<tr>\n<td>Balancing act<\/td>\n<td>Subtle deprivations, Dismissal of conflict and needs<\/td>\n<\/tr>\n<tr>\n<td>Chronic symptoms<\/td>\n<td>Heightened denial, Disengagement, Observable behaviour changes<\/td>\n<\/tr>\n<tr>\n<td>Crisis<\/td>\n<td>Depersonalization, Emptiness, Depression<\/td>\n<\/tr>\n<tr>\n<td>Enmeshment<\/td>\n<td>Total burnout exhaustion<\/td>\n<\/tr>\n<\/table>\n<h4>Stadium 1: honeymoon \/ compulsion to prove<\/h4>\n<ul>\n<li><strong>Honeymoon:<\/strong> vlak nadat je aan een nieuwe baan begint: meer creativiteit, een betere stemming en meer productiviteit. Veninga en Spradley nemen dit mee omdat dit het moment is om de basis te leggen voor stressmanagement: bij wie ga je terecht voor vragen en hulp als het er echt om spant (want dat gebeurt)?<\/li>\n<li><strong>Compulsion to prove:<\/strong> de drang om te bewijzen dat je de opslag, de training of de rol waard bent is in het begin nuttig, maar wordt een dwang die verward wordt met gewetensvolheid, toewijding en betrokkenheid.<\/li>\n<\/ul>\n<p>De slide citeert Freudenberger en North: \u201cEen onfeilbaar teken dat [intensity] speelt, is de onwil om werk, verantwoordelijkheden of huishoudelijke taken te delegeren uit angst de perfecte controle te verliezen.\u201d<\/p>\n<h4>Stadium 2: balancing act \/ subtle deprivations<\/h4>\n<p>Sommige dagen ga je beter met stress om dan andere. Tekenen: ontevredenheid over je werk, ineffici\u00ebntie, dingen kwijtraken op je bureau, vermoeidheid en je niet uitgerust voelen, slaapproblemen (een hoofd dat niet uitschakelt) en <strong>escapistische activiteiten<\/strong> (tv, alcohol, gokken, eten) om voor de stress weg te lopen. Freudenberger en North beschrijven dat zowel taken <em>als<\/em> genoegens worden uitgesteld, wat \u201csubtle deprivation\u201d is: je aandacht voor je eigen behoeften neemt af omdat de tijd naar werk gaat.<\/p>\n<p>Als jij of iemand anders het merkt, ga je <strong>nog harder werken<\/strong> en wuif je het conflict weg. Zinnen die je jezelf kunt horen zeggen:<\/p>\n<p>\u201cWe moeten gewoon deze release doorkomen en dan fixen we het\u201d, of \u201cIk heb niet het gevoel dat ik iets waardevols doe in mijn werk, maar dat verandert zodra ik die promotie krijg.\u201d Je begint jezelf op te offeren en te rechtvaardigen met output en je verplaatst stress naar \u201cvalse geneesmiddelen\u201d: cadeaus voor jezelf, afvalplannen, zelfverbetering. Dat is je brein dat <strong>controle claimt<\/strong>: het haat het om geen controle te hebben en zoekt die elders, zelfs in dingen die van buiten gezond lijken.<\/p>\n<h4>Stadium 3: chronic symptoms \/ denial, disengagement, behaviour changes<\/h4>\n<ul>\n<li>Chronische uitputting en mogelijk lichamelijke ziekte. Stress maakt cortisol aan, dat het immuunsysteem onderdrukt, omdat \u201cje lichaam zijn tijd en energie liever besteedt aan wegrennen voor de tijger\u201d. Woede en depressie verschijnen.<\/li>\n<li>In de termen van Freudenberger en North verlies je het vermogen om het essenti\u00eble van het niet-essenti\u00eble te onderscheiden. Tijd klapt samen tot het heden, zonder verleden of toekomst, alleen het ding dat voor je neus ligt.<\/li>\n<li>Je negeert basisbehoeften, kunt geen onduidelijkheid verdragen en je denken wordt rigide en star (\u201chet moet zo\u201d, omdat een ander pad vinden te veel moeite kost).<\/li>\n<li>Je trekt je terug, met cynisme en verbittering. Je gedrag verandert merkbaar (drinken of roken, extreme dieetplannen).<\/li>\n<li>Je <strong>isoleert jezelf<\/strong>, waardoor alles erger wordt, want sociale contacten zijn een eeuwenoude manier waarop mensen stress verminderen.<\/li>\n<\/ul>\n<h4>Stadium 4: crisis \/ depersonalization, emptiness, depression<\/h4>\n<p>Lichamelijke symptomen worden kritiek. Je blijft piekeren over werkfrustraties, pessimisme en twijfel aan jezelf overheersen en je ontwikkelt een escapistische mentaliteit (\u201cals ik maar de loterij won\u201d). Je verliest het contact met jezelf, je lichaam en je prioriteiten en ziet andere mensen niet meer als mensen: ze worden obstakels, hefbomen of middelen om een doel te bereiken. Je voelt je hol, leeggezogen en uitgeput.<\/p>\n<h4>Stadium 5: enmeshment \/ total burnout exhaustion<\/h4>\n<p>Burn-out is niet meer van jou en je leven te onderscheiden (\u201cje woont hier nu\u201d). Wie op dit punt een arts of psycholoog bezoekt, krijgt eerder een andere ziekte gediagnosticeerd, omdat de symptomen zo groot zijn geworden. In het model van Freudenberger en North zet een volledige klinische depressie in, geef je niets meer om jezelf of anderen en loop je extreem lichamelijk risico.<\/p>\n<h4>Hoe je de stadia moet lezen<\/h4>\n<p>Een deel van deze symptomen ervaren <strong>betekent niet dat je burn-out hebt<\/strong>: andere dingen kunnen depressie of depersonalisatie veroorzaken. En je kunt burn-out hebben zonder de hele cyclus te doorlopen. Iedereen vindt zijn eigen niveau en veel mensen blijven hangen in \u00e9\u00e9n stadium. Net als bij de fasen van rouw ervaar je ze misschien niet in volgorde. De modellen zijn <strong>beschrijvend, niet voorschrijvend<\/strong>.<\/p>\n<h3>Intersecties: wat je zelf meebrengt<\/h3>\n<p>Omdat burn-out complex is, maken al bestaande factoren het beter of erger.<\/p>\n<p><strong>Persoonlijkheid<\/strong><\/p>\n<ul>\n<li>Hoe heb je geleerd met stress om te gaan? Bestaande manieren om stress te managen helpen en het ontbreken ervan schaadt.<\/li>\n<li>Zelfvertrouwen werkt twee kanten op: een hoog zelfvertrouwen kan je vatbaar maken voor burn-out door het zelfbeeld waaraan je denkt te moeten voldoen en een laag zelfvertrouwen kan de compulsion to prove voeden.<\/li>\n<li>Optimisme en hoop vertragen burn-out, omdat hoop en handelingsvermogen een gevoel van controle geven.<\/li>\n<\/ul>\n<p><strong>Je baan<\/strong> (het gaat niet alleen om \u201cte veel werk\u201d)<\/p>\n<ul>\n<li><strong>Agentic AI-ontwikkeling.<\/strong> Dit is cognitief zwaarder dan gewoon ontwikkelen. Mid-level developers die opgegroeid zijn met code schrijven kennen de <strong>flow state<\/strong> (\u201cik kan niet geloven dat er vier uur voorbij is\u201d). Agentic systemen geven je dat niet: je krijgt een constante stroom van zeurende vragen van \u00e9\u00e9n of meerdere agents waar je bovenop moet blijven zitten. Arthur citeerde de <strong>reverse centaur<\/strong> van Cory Doctorow: een centaur is een mens die een snel paard bestuurt en een reverse centaur is een paard dat een zwakke mens bestuurt die op volle snelheid rent om bij te blijven. Het gaat niet alleen om de uren, maar om de <strong>cognitieve inspanning<\/strong> in die uren.<\/li>\n<li><strong>Mismatch in controle:<\/strong> verantwoordelijk zijn voor iets wat je niet mag of kunt veranderen. \u201cJe brein haat dat en zal heel snel gaan uitchecken.\u201d<\/li>\n<li><strong>Gebrek aan passende beloning of erkenning:<\/strong> je manager laat je niet werken aan wat je belangrijk vindt, of je prestaties worden nooit aan jou toegeschreven.<\/li>\n<li><strong>Verlies van positieve sociale interactie<\/strong> op het werk. (Arthur maakte uitgebreid grappen over de pandemie, thuiswerken, de gedwongen terugkeer naar kantoor en nu AI die alles schrijft zodat er geen tijd is om met collega\u2019s te praten.)<\/li>\n<li><strong>Ervaren gebrek aan eerlijkheid of middelen:<\/strong> ontbrekende tools of mensen, of dag in dag uit hetzelfde ticket zonder iets te kunnen veranderen.<\/li>\n<li><strong>Mismatch in waarden:<\/strong> bijvoorbeeld het bedrijf waardeert snel gaan en experimenteren, terwijl jij waarde hecht aan iets stabiel, langzaam en veilig bouwen.<\/li>\n<\/ul>\n<p>De grote les: <strong>je kunt burn-out krijgen bij 40 uur per week werken, of minder.<\/strong> Burn-out kan uit veel bronnen komen, ook van buiten het werk. 80 uur of meer werken is uiteraard een oorzaak, maar niet de enige.<\/p>\n<p><strong>Mentale gezondheid<\/strong><\/p>\n<ul>\n<li>Depressie of angst kan je vatbaar maken, omdat de manier waarop je de wereld ervaart al stressvol is en meer stress een snellere weg betekent.<\/li>\n<li>Een brein dat wisselt tussen pieken en dalen kan burn-out versnellen (\u201cik MOET ALLES DOEN!!!!\u201d tegenover \u201cik wil niets doen\u201d).<\/li>\n<li><strong>Zich herhalende situaties:<\/strong> als je werkt aan een ETL-project dat slecht loopt, daarna aan een volgende bij een nieuw bedrijf en nog een, onthoudt je brein dat. Arthur vergeleek dit voorzichtig (\u201czonder het op te blazen\u201d) met een posttraumatische reactie: je brein heeft geleerd dat de situatie slecht is en nu zit je er weer in.<\/li>\n<li><strong>Workaholisme<\/strong> kan een directe reactie zijn op emotionele problemen in je persoonlijke leven. Werk is iets wat je kunt beheersen: een ticket over de streep trekken, afvinken, een shot dopamine krijgen en herhalen tot je meerdere problemen hebt.<\/li>\n<\/ul>\n<p><strong>Ras, gender en andere demografische kenmerken<\/strong><\/p>\n<ul>\n<li>Een persoon van kleur of een vrouwelijke developer kan het gevoel hebben zich vanaf het begin te moeten bewijzen en begint daardoor al in een van de stadia van Freudenberger en North. Constante microagressies en impliciete vooroordelen laden het brein vooraf met stress.<\/li>\n<li>Het kan zich anders uiten. Arthur haalde onderzoek aan dat suggereert dat mannen vaker meer depersonalisatie laten zien en vrouwen meer emotionele uitputting. Freudenberger en North schreven een heel boek over burn-out bij vrouwen.<\/li>\n<li>Stress: omdat burn-out intrinsiek met stress samenhangt, is dit enorm belangrijk.<\/li>\n<\/ul>\n<h3>Hoe kom je eruit<\/h3>\n<h4>Eerst zelfzorg, maar het is niet genoeg<\/h4>\n<p>Zelfzorg kan het begin van burn-out <strong>uitstellen<\/strong>, maar niet stoppen. \u201cAls je in een container zit en de container staat in brand, kun je er niet uit mediteren.\u201d Een vakantie of sabbatical stelt het onvermijdelijke alleen uit, tenzij je de bronnen van stress vindt en beheerst. Zes tot acht maanden vrij kan genoeg zijn om er doorheen te werken, maar de meeste mensen kunnen dat niet. Toch helpen meditatie en gewoonten voor stressmanagement. En zoals bij de veiligheidsinstructie in het vliegtuig: <strong>zet eerst je eigen zuurstofmasker op<\/strong>, wat vooral telt voor mensen die druk voelen om voor anderen te zorgen, of die opgescheept zitten met \u201cglue work\u201d en onzichtbaar werk.<\/p>\n<p>De eerste stap eruit is <strong>stoppen met ontkennen<\/strong> en stoppen met doen alsof je controle hebt. Daarna zijn er drie uitwegen.<\/p>\n<h4>Uitweg 1: een nieuwe baan zoeken<\/h4>\n<p>Arthur zette dit bewust op de eerste plaats, omdat het is waar je brein naartoe springt als het denkt dat burn-out \u201cte veel werk\u201d betekent. De slide zegt dat dit waarschijnlijk niet het eerste is wat je moet proberen. Zakelijke klanten hebben gevraagd de slide te verwijderen, wat volgens Arthur iets zegt over het bedrijf. Maar als de burn-out \u201cvan binnenuit het huis komt\u201d (andere bronnen van stress, of cyclische patronen in je eigen brein), kun je een nieuwe baan nemen en op dezelfde plek eindigen.<\/p>\n<p>Als je een nieuwe baan zoekt, kies er dan een waar <strong>wat jij meebrengt en wat de baan meebrengt niet overlapt<\/strong>. Hun eigen voorbeeld was anderhalf jaar bij een bedrijf voor verkiezingssystemen in Omaha: stressvol werk, gecombineerd met de eigen stress, was \u201cgeen erg gunstige intersectie\u201d. Zoek werk waarvan jij en anderen de waarde zien, waar wat jij waardeert ook is wat je werkgever waardeert, en probeer opnieuw te focussen op de waarde die je oorspronkelijk in het werk vond.<\/p>\n<h4>Uitweg 2: grenzen tussen werk en priv\u00e9<\/h4>\n<p>Een korte gids:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_164729_d_e_kl.jpg\" loading=\"lazy\" alt=\"You\u2019re Not Just Tired: The Psychology of Burnout - Arthur Doler\"><\/p>\n<ul>\n<li><strong>Vraag wie je bent zonder je baan.<\/strong> Arthur vroeg om een handopsteking: wie begon met programmeren v\u00f3\u00f3r de middelbare school? Veel handen, vooral van mannen. Als je identiteit je baan is, is er geen \u201cafsluitklep\u201d tussen die twee, waardoor het ene in het andere vloeit en je overweldigt. Arthur zei dat dit mannen vatbaar maakt voor een bepaald soort burn-out.<\/li>\n<li><strong>Breek het op in transacties.<\/strong> Wat krijg je van de baan en wat ben je bereid te geven? \u201cBij elke salarisbetaling staan jij en je werkgever quitte\u201d, wat een huurlingenmentaliteit is (Arthur vindt het niet fijn en denkt anders over collega\u2019s), maar een nuttige om periodiek aan te trekken om te checken of je krijgt wat je nodig hebt.<\/li>\n<\/ul>\n<p>\u201cJe baan is het niet waard om tijd met je vrienden, je familie of je partner voor op te geven. Nooit.\u201d<\/p>\n<h4>Uitweg 3: betrokkenheid elders zoeken<\/h4>\n<p>Dit lijkt paradoxaal: <em>meer<\/em> werk doen om burn-out te bestrijden. Maar de MBI heeft een optionele categorie die <strong>involvement<\/strong> heet: hoeveel je erom geeft en hoeveel goeds je denkt de wereld in te brengen. Vrijwilligerswerk kan helpen omdat je je belangrijk voelt en het gevoel hebt dat je verschil maakt. Begin geen eigen non-profit. Zoek iets als Habitat for Humanity, waar je een middag met een hamer zwaait, waar ze het zouden overleven als je niet kwam opdagen (maar ghost ze niet). Houd het simpel en \u201ctransactioneel\u201d: jij geeft inspanning en krijgt het gevoel terug dat je hebt bijgedragen. Je brein vindt dat heerlijk.<\/p>\n<h4>Het is persoonlijk en het kost tijd<\/h4>\n<p>Arthur heeft geen wondermiddel. Jij bepaalt waar je grens tussen werk en priv\u00e9 ligt, of een nieuwe baan het waard is en wat daarvoor nodig is. En <strong>geef het tijd<\/strong>: als burn-out zo erg is dat je het herkent, gaat het waarschijnlijk niet over in weken, en misschien niet in maanden of zelfs jaren. Het gaat misschien nooit helemaal weg, omdat het \u201cin je brein is ge\u00ebtst\u201d. Geef jezelf de tijd om te herstellen zonder ongeduldig te zijn, ook als je geen vrij kunt nemen.<\/p>\n<h3>Wat je voor anderen kunt doen<\/h3>\n<p><strong>Als individu<\/strong><\/p>\n<ul>\n<li><strong>Maak praten over gevoelens en emoties op het werk normaal.<\/strong> Communicatie is iets waar onze soort goed in is.<\/li>\n<li><strong>Breek hero culture af.<\/strong> Val niet de persoon aan die zich heldhaftig heeft ingezet bij een incident, maar breek het systeem af dat dat vereiste. Bouw systemen die de <strong>last verdelen<\/strong> in plaats van concentreren en erken wat als last telt: notities maken in meetings, tickets bijwerken en dergelijke moeten gedeeld worden, tenzij het expliciet iemands taak is. Heldendom is in het algemeen niet wenselijk in een werkomgeving.<\/li>\n<li><strong>Wees je bewust van de emotionele toestand van anderen.<\/strong> Voer een zorgvuldig gesprek, geformuleerd als \u201cdit is wat ik van buitenaf zie, misschien klopt dat niet\u201d. Het is vaak makkelijker te zien bij anderen dan bij jezelf.<\/li>\n<li><strong>Bespreek externe stressoren.<\/strong> Arthur vertelde een persoonlijk verhaal over het verlies van een zeer geliefde kat en wat ze op de dag van terugkomst tegen hun team zeiden: \u201cIk ga ongeveer een maand dom zijn. Ik maak een extreme affectieve ervaring door en jullie moeten uitzoeken hoe dit gaat werken.\u201d Dat kunnen zeggen is een resilience-tactiek die helpt software \u201ceffici\u00ebnter en menselijker\u201d op te leveren.<\/li>\n<\/ul>\n<p><strong>Als manager of leider<\/strong><\/p>\n<ul>\n<li><strong>Bouw slack in schema\u2019s.<\/strong> \u201cIk bedoel niet de werkplek-app.\u201d Bijvoorbeeld een <strong>rest sprint<\/strong>: \u201cje kunt niet 24\/7 sprinten, het staat letterlijk in de naam\u201d. We zijn \u201cburst creatures\u201d en niet ontworpen om eindeloos op volle cognitieve capaciteit te draaien.<\/li>\n<li><strong>Sta flexibiliteit toe<\/strong> in planning en verlof (bijvoorbeeld flexibele uren rond het wegbrengen naar de opvang, met een paar uur in de avond).<\/li>\n<li><strong>Let op burn-out in je teams.<\/strong> Hoe eerder je het opmerkt, hoe makkelijker en minder pijnlijk het aan te pakken is. In het begin kan een vakantie genoeg zijn.<\/li>\n<li><strong>Stel de waarde die mensen leveren centraal<\/strong>, niet alleen zichtbare output. Waarde omvat ook de persoon die het feestje organiseert of elke vrijdag iets lekkers bakt.<\/li>\n<li><strong>Cre\u00eber de verwachting dat externe stressoren besproken mogen worden<\/strong> en geef zelf het voorbeeld.<\/li>\n<li><strong>Handhaaf grenzen tussen werk en priv\u00e9 strikt<\/strong>, ook als iemands eigen identiteit hem of haar aanzet harder te werken. \u201cZeg tegen mensen: hou je mond en ga naar huis.\u201d Dit is het tegenovergestelde van \u201cwork hard, play hard\u201d.<\/li>\n<li><strong>Wees niet de paraplu<\/strong> die je team afschermt van alle onzin van boven. Je bespaart ze kortetermijnstress, maar overspoelt ze met langetermijnstress (en duwt jezelf richting burn-out). Zoek een balans.<\/li>\n<\/ul>\n<h3>Afsluiting<\/h3>\n<p>Bovenal: wees alert, wees bewust en bescherm jezelf. Als je burn-out vroeg opmerkt, is het veel makkelijker aan te pakken en als je nu gewoonten voor stressmanagement in je leven bouwt, ben je beter af wanneer werkstress komt.<\/p>\n<p>Arthurs slides en resources waren beschikbaar via de link op de slotslide (<code>bit.ly\/art-burnout-psych<\/code>)<\/p>\n<p><!-- problems-scale-faster-with-ai --><\/p>\n<h2 id=\"problems-scale-faster-with-ai\">Problems scale faster with AI<\/h2>\n<p><em>Liuba Gonta &#8211; dinsdag 17:15\u201318:15<\/em><\/p>\n<p>Dit was de laatste sessie van de dag. Liuba Gonta is consultant en GitHub-trainer en werkt aan AI-adoptieprogramma&#8217;s. Haar boodschap: AI veroorzaakt de meeste problemen in een engineeringorganisatie niet, maar <strong>versterkt<\/strong> de problemen die er al zijn. Als AI de beloofde productiviteit niet oplevert, ontbreekt er misschien meer dan alleen de technologie.<\/p>\n<h3>De belofte en de grammofoon<\/h3>\n<p>In 2021 kwam AI in onze IDE&#8217;s, daarna kwam ChatGPT en plotseling was AI overal. De belofte was een revolutie: snellere developers, meer business value, een andere manier van software bouwen en zelfs het overnemen van onze banen. Bedrijven stelden ambitieuze doelen, zoals <strong>vijf keer productiever<\/strong> worden en vijf keer zoveel waarde leveren.<\/p>\n<p>Aan het publiek werd gevraagd: wie gebruikt AI dagelijks? (De meesten.) Wie levert vijf keer meer story points of waarde? (Bijna niemand.) En wie voelt zich een beetje opgelicht door AI? De belofte komt niet overeen met de realiteit en dat zorgt voor veel verwarring.<\/p>\n<p>Ter illustratie vertelde Liuba het verhaal van de <strong>grammofoon<\/strong>. In de jaren dertig bereikten Australische ontdekkingsreizigers het hoogland van Nieuw-Guinea en brachten een grammofoon mee naar mensen die er nog nooit een gezien hadden. Toen ze menselijke stemmen uit een houten kist hoorden, waren de bewoners gefascineerd en bang. Hun mentale model was niet voorbereid op de technologie, dus dachten ze dat de kist vol geesten zat, vervloekt was of dat de stemmen hun voorouders waren. Ze konden alleen toekijken.<\/p>\n<p>\u201cWij doen het natuurlijk beter\u201d, zei Liuba ironisch: we zouden nooit een volledig nieuwe technologie introduceren zonder instructies, verwachtingen of gedeelde praktijk. Maar precies dat gebeurt vaak met AI: organisaties kopen licenties, rollen tools uit, publiceren een pagina of twee richtlijnen over prompt engineering en context engineering, en iedereen is in de war. Als de revolutie uitblijft, concluderen we dat de technologie overhyped was. <strong>Het punt van de slide: \u201cWe&#8217;ve brought the gramophone but haven&#8217;t built the system around it yet.\u201d<\/strong><\/p>\n<h3>Wat misgaat in AI-adoptieprogramma&#8217;s<\/h3>\n<p>Uit de adoptieprogramma&#8217;s waaraan Liuba werkt:<\/p>\n<ul>\n<li>AI wordt binnengebracht in een engineeringsysteem dat er niet klaar voor is: geen duidelijke instructies, geen richtlijnen, geen gedeelde werkwijzen en <strong>geen doel<\/strong>. \u201cProductiviteitsverhoging\u201d is geen use case: \u201cdat betekent niets\u201d.<\/li>\n<li>Chaotische organisaties proberen problemen op te lossen door licenties beschikbaar te stellen. Mensen weten niet hoe ze AI moeten gebruiken, wanneer het mag of welke data erin mag, dus krijg je <strong>chaos bovenop chaos<\/strong>. Engineers raken gefrustreerd en verdwaald.<\/li>\n<li><strong>Code is goedkoop geworden.<\/strong> Maar code schrijven was altijd het makkelijke deel van software bouwen. Snelle code zonder duidelijke requirements of doordacht ontwerp betekent het werk steeds opnieuw doen. En wat is de waarde van een klein issue (een knop vijf pixels verplaatsen, een aantal pagina&#8217;s van 20 naar 25 zetten) in 15 minuten met AI oplossen, als het uren duurt om door deployment en goedkeuringen te komen?<\/li>\n<\/ul>\n<h3>Waarom zou ik dit belangrijk vinden? We werken niet in isolatie<\/h3>\n<p>\u201cA bad system will beat a good person every time\u201d (W. Edwards Deming). Ook als <em>jij<\/em> AI goed gebruikt, werk je binnen een systeem. Je kunt engineers niet dwingen om AI te gebruiken en als de omgeving hen tegenwerkt, levert het geen productiviteit of business value op en lijdt de developer experience, zeker met druk erbovenop.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_172440_d_e_kl.jpg\" loading=\"lazy\" alt=\"Problems scale faster with AI - Liuba Gonta\"><\/p>\n<p>Hoe ziet een goed engineeringsysteem eruit? Zij verwees naar een <strong>engineering culture model<\/strong> van haar bedrijf met <strong>acht pijlers<\/strong>. Dat gaat niet alleen over \u201cwerken mensen hier graag\u201d, maar ook over hoe software wordt gebouwd, opgeleverd en beheerd, hoe een goed team eruitziet en hoe kennis wordt gedeeld. Door de bril van AI bekeken krijgt elke pijler <strong>zowel<\/strong> een voordeel als een risico: AI kan helpen, maar kan ook nieuwe problemen introduceren of bestaande opschalen.<\/p>\n<p>De acht pijlers: <strong>State-of-the-art software, Smooth delivery, Appropriate continuity, Power through platforms, Empowering operating model, Clear digital vision, Knowledge driven, Epic workplace.<\/strong> Bij elke pijler beschreef Liuba de \u201cziektes\u201d (problemen die AI kan versterken) en de \u201ctegengiffen\u201d.<\/p>\n<h3>1. State-of-the-art software<\/h3>\n<p><em>Software die makkelijk te onderhouden, te testen en te begrijpen is, waarbij je weet waar je een wijziging moet doen en hoe je dat veilig doet.<\/em><\/p>\n<p>AI gebruikt je codebase als context. Bij een rommelige codebase, verouderde documentatie en een inconsistente architectuur levert het <strong>meer slechte code, sneller<\/strong>, \u201comdat AI niet weet hoe goed eruitziet\u201d. Jij bent verantwoordelijk voor een duidelijke architectuur en consistentie, voor toekomstige collega&#8217;s en voor AI.<\/p>\n<p><strong>Ziektes<\/strong><\/p>\n<ul>\n<li><strong>Rommelige code<\/strong> die niemand begrijpt of wil reviewen, waar AI nog meer rommel aan toevoegt.<\/li>\n<li><strong>Meer inspanning:<\/strong> AI raakt in de war van inconsistente patronen en geeft resultaten die je opnieuw moet doen, en collega&#8217;s hebben moeite te lezen wat je indient. Engineers geven soms op en pushen het gewoon naar een PR.<\/li>\n<li><strong>Hogere kosten:<\/strong> dure engineeringuren om code te begrijpen, plus tokens die opgaan aan opnieuw itereren.<\/li>\n<li><strong>Architectuurverval:<\/strong> slecht ontwerp leidt tot meer slecht ontwerp en niemand begrijpt de beslissingen.<\/li>\n<li><strong>Slechte codekwaliteit, met holle guardrails:<\/strong> als je AI tests laat genereren zonder goede testcases, krijg je tests die \u201cniets testen\u201d, in elk geval niets vanuit businessperspectief. AI kan de businesscontext niet kennen tenzij je die aanlevert.<\/li>\n<\/ul>\n<p><strong>Tegengiffen<\/strong><\/p>\n<ul>\n<li><strong>Duidelijke architectuur.<\/strong><\/li>\n<li><strong>Consistente patronen:<\/strong> laat de code eruitzien alsof \u00e9\u00e9n persoon die geschreven heeft.<\/li>\n<li><strong>Geautomatiseerde tests.<\/strong><\/li>\n<li><strong>Actuele documentatie:<\/strong> \u201cgeen documentatie is soms beter dan verouderde documentatie, omdat verouderde documentatie misleidend is\u201d.<\/li>\n<li><strong>Duidelijke AI-instructies:<\/strong> hoe beter de instructies, hoe beter AI je behoeften begrijpt, en goede instructies kun je opslaan en delen met teamgenoten.<\/li>\n<\/ul>\n<h3>2. Smooth delivery<\/h3>\n<p><em>Een wijziging met zo weinig mogelijk frictie van development naar productie brengen.<\/em><\/p>\n<p>Als reviews al traag zijn (het kost dagen om iemand te vinden die een kleine PR reviewt), schaalt AI dat probleem op, omdat het meer wijzigingen produceert en dus meer PR&#8217;s. Onderzoek waar Liuba naar verwees suggereert dat de rol van de engineer verschuift van code schrijven naar <strong>PR&#8217;s reviewen<\/strong>, vaak wijzigingen die we niet helemaal begrijpen omdat AI ze voorstelde.<\/p>\n<p><strong>Ziektes<\/strong><\/p>\n<ul>\n<li><strong>Langere review-wachtrijen<\/strong> en een langere tijd tot er waarde wordt geleverd.<\/li>\n<li><strong>Trage feedbackloops:<\/strong> een pipeline die lang bouwt en test, of flaky tests heeft, waardoor je van focus wisselt of wacht.<\/li>\n<li><strong>Delivery bottleneck:<\/strong> meer PR&#8217;s betekent niet meer geleverde waarde.<\/li>\n<li><strong>Kwaliteitsrisico:<\/strong> bij enorme PR&#8217;s maken reviewers concessies en keuren ze goed (\u201cLGTM\u201d) zonder het te begrijpen.<\/li>\n<li><strong>Groeiend work in progress:<\/strong> terwijl we op de PR wachten, beginnen we nieuwe taken. Voor AI was \u00e9\u00e9n persoon met meerdere taken tegelijk een rode vlag op het bord. Nu is het makkelijk om veel dingen te starten en niets op tijd af te maken.<\/li>\n<\/ul>\n<p><strong>Tegengiffen<\/strong><\/p>\n<ul>\n<li><strong>Geautomatiseerde CI\/CD-pipelines<\/strong> (Liuba hoopt dat die al bestaan).<\/li>\n<li><strong>Feedbackloops optimaliseren:<\/strong> heroverweeg trage of flaky tests en builds.<\/li>\n<li><strong>Effici\u00ebnte code reviews:<\/strong> houd PR&#8217;s klein en makkelijk te begrijpen. Review niet asynchroon via chat: haal de auteur erbij in een call en loop de PR samen door om de feedbackloop te verkorten.<\/li>\n<li><strong>Gebruik AI om code te reviewen:<\/strong> delegeer bij het enorme aantal PR&#8217;s een eerste review aan AI en kijk er daarna zelf nog eens naar.<\/li>\n<li><strong>Automatiseer quality gates<\/strong> in de pipeline (statische analyse, CodeQL enzovoort).<\/li>\n<li><strong>Minder bureaucratie<\/strong> rond goedkeuringen.<\/li>\n<\/ul>\n<h3>3. Appropriate continuity<\/h3>\n<p><em>Snel opleveren zonder klanten te schaden door slechte kwaliteit of beveiligingsrisico&#8217;s.<\/em><\/p>\n<p>Dankzij AI kunnen we sneller shippen, wat ook druk legt op monitoring en op de teams die de applicatie ondersteunen.<\/p>\n<p><strong>Ziektes<\/strong><\/p>\n<ul>\n<li><strong>Instabiliteit in productie<\/strong>, downtime en reputatierisico.<\/li>\n<li><strong>Kwetsbaarheden:<\/strong> dezelfde patronen die we zelf zouden introduceren, maar sneller.<\/li>\n<li><strong>Compliance-overtredingen:<\/strong> AI kent de regelgeving die op jouw software van toepassing is niet, dus je moet het helpen.<\/li>\n<li><strong>Incidenten die laat worden ontdekt<\/strong> en <strong>trage recovery<\/strong>.<\/li>\n<\/ul>\n<p><strong>Tegengiffen<\/strong><\/p>\n<ul>\n<li><strong>Monitoring en observability<\/strong>, waarbij minder meer is. Liuba heeft dashboards en alerts gezien die zo ruisig waren dat iedereen ze negeerde, waardoor een belangrijke alert gemist werd. Observability moet klaar zijn voor troubleshooting.<\/li>\n<li><strong>Security by design:<\/strong> denk na over beveiliging <em>v\u00f3\u00f3r<\/em> de implementatie, inclusief <strong>least privilege<\/strong> (niet te veel rechten uitdelen).<\/li>\n<li><strong>Compliance<\/strong> op orde.<\/li>\n<li><strong>Resilience:<\/strong> wat gebeurt er als je messaging-service uitvalt? Komen berichten in een queue terecht en worden ze later verwerkt?<\/li>\n<li><strong>Recovery:<\/strong> hoe snel kan het systeem hersteld worden en heb je een rollback-strategie <em>voordat<\/em> je die nodig hebt?<\/li>\n<li><strong>Risicogebaseerde safeguards:<\/strong> leg niet bij elke kleine wijziging een zwaar goedkeuringsproces op.<\/li>\n<\/ul>\n<h3>4. Power through platforms<\/h3>\n<p><em>Goede werkwijzen, tools en services delen binnen teams en de organisatie.<\/em><\/p>\n<p>Liuba vroeg wie een gedeelde toolbox heeft binnen de eigen organisatie en wie AI-instructies en herbruikbare prompts deelt tussen teams. (Een paar handen, \u201ceen heel goed teken\u201d.) Met AI is dit belangrijker: custom instructions, herbruikbare prompts en AI-tools zijn nieuwe dingen die gedeeld moeten worden en niet per persoon opnieuw uitgevonden.<\/p>\n<p><strong>Ziektes<\/strong><\/p>\n<ul>\n<li><strong>Dubbel werk.<\/strong><\/li>\n<li><strong>Technologiefragmentatie:<\/strong> bijvoorbeeld \u00e9\u00e9n team gebruikt Azure Service Bus voor messaging, een ander Azure Storage Queues en een derde iets anders. Elk daarvan moet begrepen en ondersteund worden.<\/li>\n<li><strong>Dure infrastructuur<\/strong> en <strong>meer beveiligingsrisico<\/strong> dat je met policies moet afdekken.<\/li>\n<\/ul>\n<p><strong>Tegengiffen<\/strong><\/p>\n<ul>\n<li><strong>Shared services.<\/strong> AI weet niet welke gedeelde tools er in jouw organisatie bestaan, dus zonder die context bouwt het een feature helemaal opnieuw. Je moet die context aanleveren.<\/li>\n<li><strong>Herbruikbare componenten<\/strong>, zoals gedeelde Terraform-modules waarin private endpoints en beveiligingsconfiguratie al zijn ingericht.<\/li>\n<li><strong>Open standaarden<\/strong>, een guardrail die AI binnen de grenzen houdt.<\/li>\n<li><strong>Governance<\/strong>, vooral geautomatiseerde guardrails.<\/li>\n<\/ul>\n<h3>5. Empowering operating model<\/h3>\n<p><em>De verantwoordelijkheid die je neemt voor beslissingen en ownership.<\/em><\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_175330_d_e_kl.jpg\" loading=\"lazy\" alt=\"Problems scale faster with AI - Liuba Gonta\"><\/p>\n<p>Dit is Liuba&#8217;s favoriete pijler. Ze vroeg wie ooit \u201cmijn AI zei\u201d of \u201cmijn AI deed dit\u201d heeft gezegd en zei dat de zin haar \u201callergisch\u201d maakt: de reactie in haar hoofd is \u201cnee, God, alsjeblieft niet\u201d. <strong>Het is jouw verantwoordelijkheid.<\/strong> Als AI je een implementatie geeft die je niet begrijpt, check dan de aanbeveling, vraag een ervaren collega of vraag de AI uit te leggen waarom en wat elke regel doet.<\/p>\n<p>\u201cYou build it, you run it\u201d wordt <strong>\u201cYou prompt it, you own it.\u201d<\/strong> Het slechte nieuws: jij bent verantwoordelijk voor wat niet werkt. Het goede nieuws: je kunt die verantwoordelijkheid nemen en je eigen beslissingen maken.<\/p>\n<h3>6. Clear digital vision<\/h3>\n<p><em>Waarde brengen aan klanten.<\/em> Dit is vooral voor leiderschap, maar AI maakt het ook voor engineers lastig.<\/p>\n<p>Vraag AI om een kleine feature en het stelt misschien extra&#8217;s voor: waarom niet ook de post-, delete- en andere endpoints toevoegen? \u201cWhy not anything?\u201d Maar <strong>levert dat business value op?<\/strong> Elke geaccepteerde suggestie voegt complexiteit toe en iemand moet het testen, begrijpen en ondersteunen, terwijl niemand erom gevraagd had.<\/p>\n<p><strong>Ziektes:<\/strong> de verkeerde dingen bouwen, adoptie zonder doel, kortetermijndenken en output boven outcome stellen.<\/p>\n<p><strong>Tegengiffen:<\/strong> een duidelijk bedrijfsdoel, duidelijke prioriteiten, de behoeften van je klanten kennen en concrete AI use cases.<\/p>\n<h3>7. Knowledge driven<\/h3>\n<p>Alles verandert en het is makkelijk om achterop te raken, of je alleen up-to-date te voelen omdat je op AI gefocust bent. Kennisdeling mag niet optioneel zijn of in de vrije tijd gebeuren: doe het regelmatig, minstens wekelijks.<\/p>\n<p><strong>Ziektes:<\/strong> blind vertrouwen in AI, traag leren en skill gaps.<\/p>\n<p><strong>Tegengiffen:<\/strong> kennisdeling, mentoring, een community of practice, kritisch denken en leren van fouten.<\/p>\n<h3>8. Epic workplace<\/h3>\n<p>AI brengt angst om je baan te verliezen, stress en een overvloed aan informatie die kan leiden tot <strong>burn-out<\/strong>. Een gebrek aan <strong>psychological safety<\/strong> is een risico: als een bedrijf AI-gebruik beperkt, vinden engineers omwegen, wat data kan lekken. In een blame culture wijzen mensen naar elkaar in plaats van het probleem op te lossen.<\/p>\n<p><strong>Tegengiffen:<\/strong> psychological safety, vertrouwen en transparantie, ondersteunend leiderschap, gezonde feedback, realistische verwachtingen en erkenning en motivatie.<\/p>\n<h4>Wat gebeurt er als de cultuur er niet is<\/h4>\n<p>Liuba deelde echte incidenten:<\/p>\n<ul>\n<li>Een engineer bij <strong>Meta<\/strong> volgde AI-advies om een technisch probleem op te lossen, waardoor gevoelige data twee uur lang toegankelijk was voor andere teams.<\/li>\n<li><strong>Juli 2025:<\/strong> een AI coding agent negeerde een instructie om te stoppen met wijzigen en verwijderde de volledige productiedatabase. Daarna zei de agent tegen de engineer dat herstel onmogelijk was, maar de data werd toch hersteld. Het resultaat was een scheiding tussen development- en productiedatabases.<\/li>\n<li><strong>April 2026:<\/strong> een AI-agent kon de credentials die hij nodig had niet krijgen, vond een API-token met te veel rechten en gebruikte dat om de volledige productiedatabase te verwijderen, <strong>inclusief backup, in ongeveer 10 seconden<\/strong>. Het token was niet \u201conveilig\u201d, maar had veel te veel rechten. Dit is een <strong>least privilege<\/strong>-les.<\/li>\n<li><strong>Sabotage:<\/strong> onderzoek suggereert dat sommige engineers AI-adoptie in hun organisatie bewust saboteren, bijvoorbeeld door opzettelijk slechte resultaten te produceren om te laten zien dat AI niet effici\u00ebnt is.<\/li>\n<\/ul>\n<p>Organisaties passen zich ook aan. Liuba noemde dat GitHub infrastructuur naar Azure verplaatst om de belasting door agents aan te kunnen, en vroeg: \u201cals zelfs zulke bedrijven zich aanpassen aan de nieuwe realiteit, waarom passen wij onze engineeringcultuur dan niet aan?\u201d<\/p>\n<h3>De twee kanten van de pijlers<\/h3>\n<p>Liuba zette de acht pijlers naast hun tegenpolen, die AI net zo snel kan opschalen: <strong>slechte codekwaliteit, geen delivery, outages en security-incidenten, dubbel werk, gebrek aan ownership, verspilde investeringen, verlies van innovatie en lage motivatie.<\/strong> \u201cIs dat echt hoe jouw droomwerkplek eruitziet?\u201d<\/p>\n<h3>Huiswerk: drie frictiepunten<\/h3>\n<p>We kunnen niet terug in de tijd, maar we kunnen nu handelen en de toekomst veranderen, ook met kleine stappen. Liuba&#8217;s huiswerk voor je volgende retrospective:<\/p>\n<ol>\n<li>Benoem <strong>drie frictiepunten<\/strong> die je team in de laatste sprint vertraagd hebben (een pijnlijk veelvoorkomend punt is trage reviews).<\/li>\n<li>Kies <strong>concrete acties<\/strong> om uit te proberen, bijvoorbeeld een teamregel zoals PR&#8217;s reviewen aan het begin van de dag.<\/li>\n<li><strong>Experimenteer<\/strong> een sprint lang, breng het terug, <strong>evalueer de impact<\/strong>, stel bij en herhaal. (Noem het een \u201cfriction sprint\u201d.)<\/li>\n<\/ol>\n<p>Kleine veranderingen zijn als <strong>druppels water op een rots<\/strong>: \u00e9\u00e9n druppel verandert niets, maar na verloop van tijd kan water massieve rots hervormen. \u201cConsistency is the key.\u201d<\/p>\n<h3>Afsluitend citaat<\/h3>\n<p>Liuba sloot af met een citaat van Bill Gates (1995, volgens de talk): automatisering toegepast op een effici\u00ebnte operatie versterkt de effici\u00ebntie, en automatisering toegepast op een <strong>ineffici\u00ebnte<\/strong> operatie versterkt de ineffici\u00ebntie. \u201cWaarom denken we dat AI anders kan zijn?\u201d<\/p>\n<p><!-- microservices-modernizing --><\/p>\n<h2 id=\"microservices-modernizing\">What I learned from modernizing a microservices architecture<\/h2>\n<p><em>Dennis Doomen &#8211; woensdag 08:30\u201309:30<\/em><\/p>\n<p>Dennis Doomen (Geniki) opende met een opmerking over de titel: daar staat \u201cmaintaining\u201d of \u201cmodernizing\u201d in, niet \u201cbuilding\u201d, want als ze zelf een microservices-architectuur hadden gebouwd, \u201czou die perfect zijn geweest, zonder enige designfouten natuurlijk\u201d. Dit was een <strong>war story<\/strong> over twee jaar lang een bestaande architectuur overnemen bij een klant, de pijn die daarbij hoorde en wat ze ervan leerden. Dennis leert het liefst van fouten die je zelf maakt, maar \u201cin dit geval heb ik geen fouten gemaakt, ik kan alles aan hen wijten\u201d, en dat is precies wat consultants graag doen.<\/p>\n<h3>Setting the scene<\/h3>\n<ul>\n<li><strong>Het systeem:<\/strong> een Azure-hosted microservices-platform, ontworpen als <strong>backend integration layer<\/strong> tussen back-officesystemen (denk aan Dynamics CRM, Salesforce en vergelijkbare producten). Het had data tussen systemen door te geven.<\/li>\n<li><strong>Wat het werd:<\/strong> het custom development-platform voor alles wat niet in de standalone producten paste. De business wilde iets dat nergens paste en de goedkoopste plek om dat te bouwen was het platform van het dev-team. Het is qua functionaliteit en businesslogica \u201ccompleet ontploft\u201d. Meerdere teams, veel services, groeipijnen.<\/li>\n<li><strong>De oorsprong:<\/strong> Dennis kreeg de indruk dat de ontwerpers geen architectuurervaring hadden, de boeken hadden gelezen en overal zonder beperking \u00e9\u00e9n pattern (onion architecture) toepasten, omdat microservices cool en \u201csuper schaalbaar\u201d waren.<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_083440_d_e_kl.jpg\" loading=\"lazy\" alt=\"My Role - What I learned from modernizing a microservices architecture - Dennis Doomen\"><\/p>\n<p><strong>Hun rol:<\/strong> architectonisch eigenaarschap nemen als <strong>coding architect<\/strong>: ongeveer de helft van de tijd in de codebase van het team (guidelines, practices, stukje bij beetje verbeteren) en de andere helft als architect. Ze houden van legacy code (\u201cik kan de bestaande code eruit slopen en vervangen door mijn eigen code\u201d), maar werden toch verrast en zeiden dagelijks te vloeken. Een waarschuwing aan zichzelf en aan het publiek: als je bij een project komt, ben je bevooroordeeld en is het makkelijk om beslissingen te bekritiseren, zeker zonder documentatie, source history of architecture decision logs. Je kent de context en de ervaring van de mensen die het bouwden niet.<\/p>\n<p>Dennis is CTO bij Geniki, besteedt ongeveer vier dagen per week bij klanten aan alles van IDE tot productie en heeft 30 jaar ervaring, vooral met .NET en C#. Ze schrijven geen code meer met de hand: \u201cIk zat bijna een jaar in ontkenning en toen gaf ik het op.\u201d Ze gebruiken nu Claude in vijf of zes sessies tegelijk en zien AI als een van de grootste veranderingen in het werk.<\/p>\n<h4>Open source<\/h4>\n<p>Dennis onderhoudt Fluent Assertions (volgens hen net 800 miljoen downloads gepasseerd), C# coding guidelines (recent bijgewerkt voor C# 14), <strong>PackageGuard<\/strong> (scant je NuGet- en NPM-dependencies op kwetsbaarheden en op operationele en onderhoudbaarheidsrisico&#8217;s), Reflectify, Pathy, een .NET library starter kit, de HTTP-mockingbibliotheek Mockly en <strong>Fallout<\/strong>, een fork van het verlaten NUKE C#-buildproject die ze samen met anderen onderhouden.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_083736_d_e_kl.jpg\" loading=\"lazy\" alt=\"Open Source - What I learned from modernizing a microservices architecture - Dennis Doomen\"><\/p>\n<h3>1. Het distributed monolith anti-pattern<\/h3>\n<p>Een <strong>distributed monolith<\/strong> bestaat uit services die los worden gedeployed maar in de praktijk <strong>sterk gekoppeld<\/strong> zijn: bij elke wijziging van een bedrijfsregel moet je meerdere services aanpassen. Je krijgt alle complexiteit van microservices (op elkaar afgestemde pipelines, API-versioning, distributed logging) en geen van de voordelen. Zelfs een monolith waarbij elke pull request naar productie gaat, vraagt al veel volwassenheid en met 50 microservices wordt het probleem exponentieel groter.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_084124_d_e_kl.jpg\" loading=\"lazy\" alt=\"The Distributed Monolith Anti-Pattern - What I learned from modernizing a microservices architecture - Dennis Doomen\"><\/p>\n<p>Dennis&#8217; voorkeur: eerst een <strong>modular monolith<\/strong>.<\/p>\n<ul>\n<li>Mooi gescheiden modules, niet alleen technisch maar ook <em>functioneel<\/em>, in de richting van een vertical slice architecture (neem elementen over, pas het niet blind toe).<\/li>\n<li>Je legt de grenzen in het begin verkeerd. In \u00e9\u00e9n codebase is het veel makkelijker om logica tussen modules te verplaatsen voordat je ze in services opsplitst.<\/li>\n<li>Haal een module pas los als je echt <strong>onafhankelijk schalen<\/strong> nodig hebt. Serverless-aanbod schuift die drempel ver naar achteren.<\/li>\n<li>Soms voegt Dennis een microservices-landschap weer samen tot \u00e9\u00e9n codebase en levert ze het als \u00e9\u00e9n service op, totdat de grenzen duidelijk zijn.<\/li>\n<\/ul>\n<p><strong>De regel op de slide:<\/strong> \u201cIf you don&#8217;t need independent scaling, you probably don&#8217;t need microservices.\u201d Of, zoals het gezegde luidt: je bent Netflix niet.<\/p>\n<h3>2. Domeingrenzen en data-eigenaarschap<\/h3>\n<ul>\n<li>Elke service is eigenaar van zijn eigen <strong>domeinmodel<\/strong>: in domain-driven design een <strong>bounded context<\/strong>. De ubiquitous language is daarbinnen consistent. Een \u201corder\u201d betekent iets anders voor het magazijn dan voor de boekhouders en je kunt twee klassen Order hebben voor verschillende doelen. (Het boek van Eric Evans heeft een heel hoofdstuk over het co\u00f6rdineren van contexts en teams.) Wees niet dogmatisch: soms wordt een deel van een domein een eigen service omdat het extreem schaalbaar moet zijn.<\/li>\n<li><strong>Deel geen domeinobjecten of value types<\/strong> tussen services, of zelfs tussen modules. Het cre\u00ebert koppeling.<\/li>\n<li><strong>Data is altijd eigendom van \u00e9\u00e9n domein of service.<\/strong> Gebruik de database niet als integratiemechanisme (gebruikelijk in de Oracle-wereld). Elke service mag zijn eigen opslag gebruiken, zodat die kan evolueren (misschien past een key-value of NoSQL store beter). Andere services mogen de data <em>cachen<\/em>, maar er is altijd \u00e9\u00e9n eigenaar.<\/li>\n<li><strong>Ontwerp API&#8217;s rond wie de data bezit<\/strong>, niet rond wie ze gebruikt.<\/li>\n<li><strong>Chatty services zijn een smell.<\/strong> Meestal betekent het dat de grenzen niet kloppen en dat de services bij elkaar horen en samengevoegd moeten worden. \u201cChatty inter-service calls are a design smell, not a network problem.\u201d<\/li>\n<li>Wees niet bang om de architectuur ter discussie te stellen of om <strong>inconsistent<\/strong> te zijn: verschillende delen van een groot landschap kunnen verschillende stijlen gebruiken. Voeg eerst samen en splits pas als je zeker bent van de grenzen.<\/li>\n<\/ul>\n<h3>3. Teams, beslissingen en eigenaarschap<\/h3>\n<p>Teams veranderen doordat mensen en consultants komen en gaan. Dennis blijft meestal twee tot vier jaar, want zo lang duurt het om mensen te veranderen.<\/p>\n<h4>Architecture decision logs<\/h4>\n<p>Dennis legt van alles wat ze beslissen <strong>de redenen en de overwogen opties<\/strong> vast, in kleine documenten met een eenvoudig template (de opties, de keuze, de redenen, de betrokken mensen en de datum). De meeste developers schrijven niet graag documentatie, dus houd de drempel laag (ze gebruiken hier graag Confluence voor, maar markdown in GitHub of Azure DevOps werkt ook).<\/p>\n<p>Waarom het ertoe doet:<\/p>\n<ul>\n<li>Het voorkomt dat een nieuwkomer zegt \u201cwaarom hebben jullie onion architecture gekozen, dat is stom\u201d terwijl niemand zich de reden herinnert.<\/li>\n<li>Dennis staat nog steeds achter een event-sourcingbeslissing die jaren geleden voor een olie- en gassysteem werd genomen, omdat ze de omstandigheden en alle opties met voor- en nadelen hebben opgeschreven.<\/li>\n<li>Kleine en grote beslissingen komen er allebei in (hoe je opdeelt, welke technologie services verbindt, wanneer je Azure private endpoints gebruikt versus API Management).<\/li>\n<li>Het overleeft personeelswisselingen en maakt impliciete kennis expliciet. \u201cIk ben 53, ik vergeet dingen.\u201d<\/li>\n<\/ul>\n<h4>Eigenaarschap van teams en infrastructuur<\/h4>\n<ul>\n<li><strong>E\u00e9n team moet eigenaar zijn van hele services<\/strong> en de codebase begrijpen. Ze hebben nu 12 services voor twee teams, wat veel is (\u201cburn-out is een groot woord, maar ik zie het team worstelen\u201d). Externe leveranciers bouwen nieuwe services die daarna worden overgedragen, en dat is lastig als er geen guidelines zijn en ieder andere patterns gebruikt.<\/li>\n<li><strong>Laat geen apart infrastructuurteam alles bewaken.<\/strong> Er was een extern team dat de Azure-netwerkstack bouwde maar developers niet vertrouwde om een web app, een container of hun eigen SQL-database aan te maken. \u201cDat vertraagt je serieus.\u201d<\/li>\n<li>Dennis houdt van <strong>Pulumi<\/strong> (infrastructure as code in C#: je kunt debuggen, stap voor stap doorlopen, refactoren en het verpakken in NuGet). Ze houden niet van <strong>Bicep<\/strong> voor developers, omdat je het niet kunt debuggen of refactoren, al werkt het goed voor infrastructure engineers. Infrastructuurcode hoort in dezelfde repo en dezelfde deployment pipeline als de service.<\/li>\n<\/ul>\n<h4>Developers die worden gepaged voor hun eigen bugs<\/h4>\n<p>\u201cAls developers worden gepaged voor hun eigen bugs, verbetert de kwaliteit opmerkelijk snel.\u201d In de geest van continuous deployment (elke commit of PR is een productiedeployment) dwingt het je goed na te denken over de gevolgen van je wijzigingen. Ze hebben nu geen 24\/7 support.<\/p>\n<p>Ze voerden een roulerende <strong>\u201cdeveloper of the day\u201d<\/strong> in: elke dag controleert een andere developer alle fouten in Application Insights, beantwoordt vragen en supportoproepen van andere teams en lost bugs op. Bugs fixen in een codebase die je niet goed kent is de beste manier om die te begrijpen en designfouten te zien. Het dwingt je ook het domein diepgaand te begrijpen, inclusief alle <strong>datum- en tijdkwesties<\/strong> (UTC of niet, of de datum deel is van het contract, formaat over een HTTP API, tijdzones). Dennis geeft toe dat ze graag bugs fixen.<\/p>\n<p>Veelvoorkomende patronen die zo worden gevonden, worden vastgelegd in <strong>skills<\/strong> zodat Claude ze goed kan begrijpen en oplossen.<\/p>\n<h3>4. API-design: contracten, zichtbaarheid en contract testing<\/h3>\n<p>Toen Dennis naar de codebase keek, was er <strong>geen standaard voor hoe services met elkaar communiceren<\/strong>. Ze voerden het volgende in:<\/p>\n<h4>Visibility classification<\/h4>\n<p>Aan elke API getagd (zichtbaar in de OpenAPI-docs via Scalar of Swagger UI):<\/p>\n<ul>\n<li><strong>Private:<\/strong> alleen gebruikt binnen hetzelfde team (een service en zijn UI, of twee services van hetzelfde team). Het wordt niet verhinderd dat het elders wordt gebruikt, maar het is expliciet. Je kunt vrij breaking changes doorvoeren en beide kanten in dezelfde pull request bijwerken.<\/li>\n<li><strong>Internal:<\/strong> mag door andere teams in de organisatie worden gebruikt. Je kunt niet zonder afstemming breaking changes invoeren, omdat twee repositories en twee pipelines niet in \u00e9\u00e9n PR op elkaar af te stemmen zijn. Het blijft haalbaar (maak het bijvoorbeeld eerst backward compatible en verwijder de compatibiliteitsfix de volgende dag).<\/li>\n<li><strong>Public:<\/strong> open voor de wereld of voor partners. Dat brengt veel verantwoordelijkheid mee, zoals meerdere versies parallel ondersteunen en een supported-version- en deprecated-version-header gebruiken.<\/li>\n<\/ul>\n<p>Dennis zei dat de meeste teams hier niet over nadenken. In dit systeem hadden ze geen idee wie er kapotging als ze een API wijzigden of deprecated maakten, \u201csoms moesten we hem gewoon breken om te zien wie ons zou gaan bellen\u201d.<\/p>\n<h4>Design standards<\/h4>\n<p>HTTP-guidelines, <strong>vooraf<\/strong> gedefinieerd, omdat achteraf invoeren \u201cextreem pijnlijk\u201d is:<\/p>\n<ul>\n<li>Wat betekent een 409? Wat geef je terug als je een klant opvraagt die niet bestaat: een 404 of een 204? Bij een technisch onjuist request: een 400 of een 422? Wat als een verplicht datum\/tijd-veld ontbreekt? Wat als je een klant bijwerkt die niet meer bestaat, of een order verwijdert die al verwijderd is (is dat idempotent)?<\/li>\n<li>Dit is belangrijk omdat je, als je naar fouten in je monitoring kijkt, wilt weten of het een probleem in jouw code is of dat een ander team met verkeerde parameters aanroept.<\/li>\n<li>Commands (POST, PUT, DELETE) muteren en een <strong>GET muteert nooit<\/strong> (command-query separation, wat Dennis aan Bertrand Meyer toeschrijft).<\/li>\n<li>OpenAPI is <strong>verplicht<\/strong> op elke service, inclusief informatie over deprecation en <strong>rate limiting<\/strong>. (Er is een standaardheader die clients vertelt hoe lang ze moeten wachten, bijvoorbeeld vijf minuten, voordat ze het opnieuw proberen.)<\/li>\n<li><strong>HTTP caching headers<\/strong>: slechts een of twee mensen in de zaal gebruikten ze.<\/li>\n<\/ul>\n<h4>Contract testing<\/h4>\n<p>API&#8217;s zijn contracten en ze breken is makkelijk: van serialisatiebibliotheek wisselen kan de casing van JSON-properties veranderen van Pascal naar camel. Daarom schrijft Dennis <strong>consumer-driven contract tests<\/strong> en geautomatiseerde API-tests, zelfs op unit-testniveau, die controleren dat de teruggegeven JSON klopt. Je hebt ook een <strong>versioning-strategie<\/strong> nodig (wat is v1, wat is v2, test ze apart) en veel .NET OpenAPI-tools ondersteunen versioning niet automatisch, dus het vraagt om custom code. (Dennis heeft voorbeeldcode op GitHub, ook met Scalar.) \u201cJe wilt deze problemen niet in productie ontdekken.\u201d<\/p>\n<p>Hun conclusie: ongeveer <strong>80% van de API&#8217;s<\/strong> in dit systeem bleek kapot en moest worden hersteld, omdat niemand wist wie ze gebruikte en wat men ervan verwachtte, met name rond datum en tijd. \u201cAn undocumented API is a broken API waiting to happen.\u201d<\/p>\n<h3>5. Logging, observability en alerting<\/h3>\n<ul>\n<li><strong>Structured logging<\/strong> met Serilog of Microsoft.Extensions.Logging geeft je <strong>correlation IDs<\/strong> out of the box. (Het is niet altijd triviaal: de overstap van Application Insights naar OpenTelemetry vroeg om finetuning om requests over services heen te kunnen volgen.)<\/li>\n<li><strong>Definieer wat elk log level betekent.<\/strong> Toen Dennis begon, waren er <em>duizenden fouten per dag<\/em> in de admin-site, meestal transient. Nu zijn het er vier of vijf per dag en ze werken eraan om dat verder te verlagen. \u201cAlles moet een betekenis hebben.\u201d Een <strong>warning is een voorbode van een error<\/strong>: er gaat waarschijnlijk binnenkort iets mis, dus onderneem actie. Een codebase met stapels compilerwarnings is een no-go, vanwege het effect van de jongen die wolf riep.<\/li>\n<li>Controleer telkens als iemand code wijzigt de <strong>logstatements<\/strong>, wat veel developers niet doen. Dennis trainde Claude met skills over wat een warning betekent en wanneer je die gebruikt, en gebruikte het om grote delen van de codebase met \u00e9\u00e9n commando te refactoren (meestal met een plan).<\/li>\n<li><strong>Maak onderscheid tussen business events en technische ruis.<\/strong> Veel mensen loggen alles \u201cvoor de zekerheid\u201d. Bedenk wat informatie is en wat diagnostiek. In werkelijkheid log je waarschijnlijk te weinig en voeg je logging toe als productie stuk gaat, en soms moet je ook logging weghalen.<\/li>\n<li><strong>OpenTelemetry<\/strong> is nu de standaard. Ze <strong>monitoren rigoureus<\/strong>, met de developer of the day die naar de logs kijkt. Dennis bouwde een skill die Application Insights op alle fouten controleert (behalve de 404&#8217;s, wat een vergissing was), ze vergelijkt met issues in Azure DevOps (binnenkort GitHub) en alles wat nieuw is analyseert. Zelfs transient errors krijgen een issue, om te worden opgelost (bijvoorbeeld met Polly of een alternatief).<\/li>\n<li><strong>Dead-letter queues:<\/strong> bij Azure Service Bus stonden er, toen Dennis begon, enorme aantallen berichten in de dead-letter queue die niemand begreep. Nu zijn er <strong>alerts<\/strong> en is elk bericht in de dead-letter queue een probleem dat meteen moet worden opgelost. \u201cMensen haten me daarom.\u201d Dennis heeft meestal dinsdagen dienst en accepteert dat ze daarvoor ander werk laten vallen.<\/li>\n<li><strong>Not-found responses:<\/strong> een 404 voor een functioneel \u201corder bestaat niet\u201d wordt door Application Insights als failure gerapporteerd en er is blijkbaar geen nette oplossing behalve een service die telemetrie filtert voordat die wordt verstuurd. Daarom proberen ze nu <strong>204<\/strong> te gebruiken, een normale situatie.<\/li>\n<\/ul>\n<p>\u201cTransient errors are not noise, they are early warnings of systemic failure.\u201d Dennis zei dat ze met opzet snel gingen en mensen overweldigden, in de hoop dat elke aanwezige \u00e9\u00e9n punt kiest en dat verbetert.<\/p>\n<h3>6. Resilience, messaging en idempotency<\/h3>\n<h4>Resilient HTTP calls<\/h4>\n<ul>\n<li>Gebruik <strong>Polly<\/strong> (dat commercieel is geworden en waarvoor ze betalen) of het <strong>Microsoft Extensions Resilience<\/strong>-pakket, dat Polly niet direct binnenhaalt en minder flexibel is maar zijn werk doet.<\/li>\n<li><strong>Retry met exponential back-off:<\/strong> 1 seconde, dan 2, 4, 8, 16, 32 enzovoort, om te voorkomen dat je een service die het moeilijk heeft overbelast.<\/li>\n<li><strong>Circuit breaker:<\/strong> retries van veel clients kunnen een API bestoken die net weer online is en hem opnieuw kapot maken. Na een paar mislukte retries doet de client alsof de andere kant een tijdje onbereikbaar is, zodat die kan herstellen.<\/li>\n<li><strong>Timeouts overal<\/strong>, want \u201cdingen lopen gewoon op een timeout\u201d en weinig mensen kennen de defaults. Vertrouw het netwerk nooit.<\/li>\n<li>Dit is verplicht, niet optioneel, op elke HTTP-call.<\/li>\n<\/ul>\n<h4>Geef de voorkeur aan async messaging, maar wees niet dogmatisch<\/h4>\n<p>Het systeem gebruikte veel <strong>Azure Service Bus<\/strong>, ook al deden veel services directe RPC-calls (HTTP) naar elkaar, met ketens van calls die eindigden bij een extern back-officesysteem. Denk na over de communicatiestijl die elke situatie nodig heeft en \u201cwees nooit dogmatisch\u201d. Consistentie wordt overschat.<\/p>\n<p>Async messaging <strong>ontkoppelt producers en consumers<\/strong>: ze draaien en deployen onafhankelijk en een consumer die wordt gedeployed begint gewoon berichten te verwerken zodra die weer terug is.<\/p>\n<p>Monitor dead-letter queues actief. Een bericht kan daar belanden doordat de service simpelweg te druk was, of doordat te veel berichten parallel werden verwerkt (Dennis merkte op dat veel mensen de default concurrency niet kennen, die volgens hen 16 is).<\/p>\n<h4>Idempotency<\/h4>\n<p>Hetzelfde bericht kan meer dan eens worden afgeleverd, door de automatische retries in Azure Service Bus (en ook via HTTP). <strong>Idempotency is een first-class concern.<\/strong><\/p>\n<h4>Distributed transactions<\/h4>\n<p>Distributed transactions (MSDTC) waren pijnlijk en two-phase commit \u201cdoen we niet meer\u201d. Als je echt co\u00f6rdinatie tussen services nodig hebt, denk dan aan een <strong>saga<\/strong> of process manager (bijvoorbeeld met NServiceBus). Daarvoor heb je <strong>compensating transactions<\/strong> nodig die je expliciet bouwt: je hebt bijvoorbeeld de auto geboekt maar kon het vliegtuig niet boeken, dus moet je de auto weer annuleren. Gebruik ze alleen voor de ingewikkelde gevallen.<\/p>\n<p>\u201cIf you don&#8217;t design for failure, you&#8217;re designing for a bad day.\u201d (Dennis vroeg wie elke week een slechte dag heeft en kreeg antwoord.)<\/p>\n<h3>7. Testing<\/h3>\n<p><strong>Wat ze aantroffen:<\/strong> unit tests voor alles: de Azure Function, de repository, de FluentValidation-klasse, de Mediator-handler. Een request werd gedeserialiseerd en naar de Mediator gestuurd, die via reflection een handler vond met \u00e9\u00e9n regel die een repository aanriep met \u00e9\u00e9n methode die een andere service aanriep. Je kon zelfs \u201cfind usages\u201d niet gebruiken. Iemand had het overontworpen omdat \u201cwe onion architecture voor alles nodig hebben\u201d. Ze vonden ook overal mocking libraries, geen integratietests, geen contract tests, geen directe API-tests, <strong>flaky pipelines<\/strong> die gewoon opnieuw werden gedraaid en geen end-to-end smoke tests. Zonder dit vangnet is het eng om een codebase te verbeteren.<\/p>\n<p><strong>Wat ze bouwden:<\/strong><\/p>\n<ul>\n<li><strong>Gedragsgerichte unit tests<\/strong> met een veel grotere scope. Dennis&#8217; idee van een unit: stuur een bericht naar Azure Service Bus en controleer dat uiteindelijk de verwachte HTTP-call naar de externe service wordt gedaan. Alles daartussen is een implementatiedetail. Voor een HTTP API: roep hem aan zonder correcte datum\/tijd en verwacht een 409 of 422. Zo konden ze de Mediator- en FluentValidation-lagen eruit slopen en de tests in hun eigen stijl herschrijven (ze trainden daar een skill voor).<\/li>\n<li><strong>Integratietests met Testcontainers<\/strong> (SQL Server en Azure Service Bus in containers) en <strong>.NET Aspire<\/strong>.<\/li>\n<li><strong>Contract tests<\/strong> die in de pipeline draaien tegen de API <em>na deployment<\/em> via Azure API Management, omdat een service lokaal kan werken maar niet bereikbaar is via API Management (bijvoorbeeld door een ontbrekende subscription key).<\/li>\n<li>Een paar <strong>smoke tests<\/strong> die de hele keten end-to-end controleren.<\/li>\n<li>Aspire maakt het ook makkelijk om veel services lokaal te draaien en ingewikkelde scenario&#8217;s te reproduceren.<\/li>\n<\/ul>\n<p>De piramide geldt nog steeds: unit tests zijn het grote deel en hogere tests zijn trager en moeilijker te onderhouden maar vullen aan. \u201cA flaky pipeline is not a pipeline, it&#8217;s a random number generator.\u201d Fix of verwijder flaky tests.<\/p>\n<h3>8. Codekwaliteit, shared libraries en technical debt<\/h3>\n<h4>Shared libraries zijn \u201cverleidelijk\u201d<\/h4>\n<p>Developers houden van DRY, maar shared libraries brengen koppeling mee: als de library verandert, moet elke service worden bijgewerkt.<\/p>\n<ul>\n<li>Wees conservatief en <strong>wacht lang<\/strong> met het extraheren van een library.<\/li>\n<li>Houd ze <strong>dun<\/strong>, alleen voor <strong>cross-cutting concerns<\/strong>, dingen die belangrijk zijn maar zelden veranderen.<\/li>\n<li>Dennis dupliceert simpele code over services heen en vindt dat niet erg, omdat gedupliceerde code geen conflicten veroorzaakt. Ze gebruiken iets als de <strong>rule of three<\/strong> en extraheren pas als het patroon duidelijk hetzelfde is en bedoeld is om hetzelfde te zijn.<\/li>\n<li>Ook: het gedeelde \u201cinfrastructure\u201d-project in een solution \u201cdat alles bevat en waarvan niemand weet wat erin zit\u201d.<\/li>\n<\/ul>\n<h4>Guidelines, analyse en skills<\/h4>\n<ul>\n<li>Gebruik <strong>static analysis<\/strong> (Roslyn analyzers, JetBrains InspectCode in de pipeline), maar designbeslissingen worden daardoor niet gevangen.<\/li>\n<li>Ze gebruiken veel <strong>agent skills<\/strong>, bewaard in een aparte repo, al is het delen ervan een worsteling. Dennis vraagt Claude of Copilot aan het eind van een taak: \u201csuggest improvements to the skill you used\u201d, wat ze dagelijks doen, waardoor hun skills altijd voorlopen op die van de teamgenoten. Als teamgenoten dit ook doen, wordt een AI gebruikt om de skills samen te voegen.<\/li>\n<li>Uitzoeken waar een API-route is gemapt was moeilijk, nu vraag je het de AI in Rider en die vertelt het je.<\/li>\n<li><strong>Streef niet naar consistentie tussen services of modules<\/strong>, alleen binnen een grens. Code churn be\u00efnvloedt ook je source control history, en die is belangrijk.<\/li>\n<\/ul>\n<h4>Gebruik open source verantwoord<\/h4>\n<p>Iedereen gebruikt veel open source, vaak zonder het te beseffen. Scan je dependencies en kijk wie ze onderhoudt, naar de releasecyclus en het versieschema (de reden dat Dennis PackageGuard bouwde, dat ook naar operationele aspecten kijkt: wanneer was de laatste release, hoeveel releases loop je achter?). Van de Azure DevOps-gebruikers in de zaal gebruikten er maar ongeveer vijf Renovate, dus de meeste werken niet actief bij. (GitHub&#8217;s Dependabot is gratis.) Maar update niet te enthousiast: PackageGuard heeft een <strong>cool-down period<\/strong>, bijvoorbeeld drie dagen of een week wachten na een nieuwe release, voor het geval van een zero-day probleem. Definieer ook <strong>open source guidelines<\/strong>, zoals welke licenties zijn toegestaan.<\/p>\n<h4>Technical debt<\/h4>\n<p>In distributed systems stapelt debt zich \u201csneller en minder zichtbaar\u201d op. Dennis prioriteert op <strong>blast radius<\/strong>: grote items gaan op de backlog, kleine krijgen \u201csmell\u201d\/\u201crefactor\u201d-comments als broodkruimels in de code. Los het stapsgewijs en elke dag af (de developer of the day doet dit als er geen bugs zijn). Met Claude of Copilot is het opsplitsen van een PR in meerdere triviaal. Het is het <strong>broken window<\/strong>-effect: een schone, goed gedocumenteerde codebase maakt mensen huiverig om rommel te maken en \u201ccode wordt alleen maar slechter of beter\u201d.<\/p>\n<h3>9. Deployment en veilige releases<\/h3>\n<p>Dennis sloeg hier voor de tijd een deel van over:<\/p>\n<ul>\n<li><strong>Geautomatiseerde deployment pipelines<\/strong> die deel zijn van de service, zodat je die later kunt extraheren. Maak niet voor elke service een aparte pipeline. Dezelfde pipeline die bouwt en test, deployt ook.<\/li>\n<li>Een <strong>aparte repository per service<\/strong>, wat grenzen duidelijker maakt.<\/li>\n<li><strong>Trunk-based development<\/strong> met kortlevende branches, en een falende pipeline meteen fixen. Accepteer nooit flaky builds of deployments.<\/li>\n<li><strong>Feature flags<\/strong> om deployment van release te ontkoppelen: deploy altijd naar productie en houd geen langlopende branches. In Azure heeft App Configuration een feature-flag-sectie. Geef ze duidelijke namen en <strong>verwijder ze<\/strong> als de feature stabiel is.<\/li>\n<li><strong>Blue\/green- of canary-releases<\/strong> om het releaserisico te verkleinen.<\/li>\n<li>Deploy zo snel mogelijk. (Dennis gaf toe dat ze nog steeds elke maandagochtend alle services een voor een deployen: \u201cDat is triest, dat moeten we oplossen.\u201d)<\/li>\n<li>Automatische rollback is zelfs mogelijk voor databaseschemawijzigingen, maar het is veel werk, dus pas het alleen toe waar nodig.<\/li>\n<\/ul>\n<p>Dennis herinnerde zich ook verkeerslichten op kantoor die rood werden als er iets brak, waarna iedereen zijn werk liet vallen en samen een fix co\u00f6rdineerde.<\/p>\n<h3>Lessons learned<\/h3>\n<ol>\n<li>Als je onafhankelijk schalen nodig hebt, gebruik dan microservices. Begin anders met een modular monolith.<\/li>\n<li>Chatty services zijn een design smell: heroverweeg de grens, niet het netwerk.<\/li>\n<li>Correlation IDs en structured logging zijn niet optioneel in een distributed system.<\/li>\n<li>Elke HTTP-call heeft een retry policy, een circuit breaker en een timeout nodig.<\/li>\n<li>Flaky pipelines zijn geen pipelines. Fix of verwijder flaky tests.<\/li>\n<li>Dead-letter queues hebben actieve monitoring nodig.<\/li>\n<\/ol>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_093043_d_e_kl.jpg\" loading=\"lazy\" alt=\"Lessons Learned - What I learned from modernizing a microservices architecture - Dennis Doomen\"><\/p>\n<p>Dennis voegde toe: zet infrastructure as code (Pulumi) in dezelfde repo en deployment pipeline, gebruik <strong>managed identity<\/strong> in plaats van connection strings op Azure, gebruik feature flags en behoud de roulerende developer-of-the-day-rol, \u201cdaar leren mensen veel van\u201d. De slides bevatten nog veel meer (developer experience, Azure-specifics, infrastructure as code) en Dennis was de rest van de dag in de buurt.<\/p>\n<p><!-- quality-agentic-era --><\/p>\n<h2 id=\"quality-agentic-era\">Quality in the Agentic Era: keeping engineering standards at AI speed<\/h2>\n<p><em>Tiago Pascoal &amp; Josh Johanning &#8211; woensdag 09:45\u201310:45<\/em><\/p>\n<p>Tiago Pascoal (Lissabon, Portugal) en Josh Johanning (Madison, Wisconsin, VS) zijn forward-deployed engineers bij GitHub en helpen klanten bij de adoptie van Copilot. Ongeveer de helft van de zaal gaf aan GitHub te gebruiken. De boodschap van de talk was tool-agnostisch, maar de demo&#8217;s gebruikten GitHub Copilot en alles was verpakt in een middeleeuws thema: <strong>squires, knights en golems<\/strong>.<\/p>\n<p>Hun boodschap in \u00e9\u00e9n zin: <strong>engineering blijft belangrijk.<\/strong> AI laat ons veel sneller code schrijven, waardoor de bottleneck verschuift naar de <em>review<\/em>. Je hebt dus voor elke wijziging dezelfde kwaliteitslat nodig, ongeacht wie of wat de code schreef.<\/p>\n<h3>De puzzel: wat doet deze functie?<\/h3>\n<p>De talk opende met een functie vol magic numbers (<code>return ((y * 1073750999) &amp; 3221352463) &lt;= 126976;<\/code>). Tiago had de functie in een blogpost gevonden en vroeg aan Copilot wat ze deed. Met de originele naam antwoordde Copilot correct, wat indrukwekkend was. Nadat Tiago de functie hernoemd had naar <code>o<\/code>, gaf het (oudere) model een technisch correcte maar nutteloze uitleg. De les: <strong>naamgeving blijft belangrijk<\/strong>. Het antwoord werd beloofd aan het einde.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_094730_d_e_kl.jpg\" loading=\"lazy\" alt=\"Can you tell me what this function does? Quality in the Agentic Era: Keeping Engineering Standards at AI Speed\"><\/p>\n<h3>Engineering blijft belangrijk<\/h3>\n<p>De slide met de stelling citeert een tweet van Matt Pocock over een traject dat veel mensen doorlopen:<\/p>\n<ol>\n<li>\u201cOh shit, AI can do my job better than me.\u201d<\/li>\n<li>\u201cSoftware engineering is dead!\u201d<\/li>\n<li>\u201cI can vibe code as much slop as I want!\u201d<\/li>\n<li>\u201cOh, things are not going well.\u201d<\/li>\n<li>\u201cBut what if I constrain the agent? Put it in a straitjacket?\u201d<\/li>\n<li>\u201cOh, the results are pretty good now. How do I go deeper?\u201d<\/li>\n<li><em>Bestelt 12 software engineering-boeken bij Amazon.<\/em><\/li>\n<li>\u201cSoftware engineering is alive!\u201d<\/li>\n<\/ol>\n<p>Snelle, performante en correcte code schrijven en complexiteit beheersen verdwijnt niet.<\/p>\n<h3>De bottleneck verschuift naar review<\/h3>\n<p>AI versnelt de implementatie, dus er komen meer wijzigingen binnen en de <strong>vraag naar review groeit<\/strong>. Ofwel gaan er meer mensen reviewen, ofwel worden reviewers slordiger en keuren ze blindelings goed, wat &#8220;AI slop&#8221; oplevert. Tiago haalde de <strong>Theory of Constraints<\/strong> (Goldratt) aan: op een lopende band optimaliseer je de bottleneck en daarna duikt de volgende op. AI heeft de bottleneck stroomafwaarts verplaatst naar de review.<\/p>\n<p>\u201cMeer code schrijven zou nooit het doel mogen zijn.\u201d Als de code niet goed is, lever je gewoon sneller slechte dingen op en kom je er ook sneller achter. Wat telt is kwaliteit en waarde.<\/p>\n<h4>Wat controleren we voor het mergen?<\/h4>\n<p><strong>Traditioneel:<\/strong> deterministische CI-checks: bouwt het, slagen de tests, linting, formatting, code quality en code scanning (GitHub Code Quality, Sonar, GitHub Advanced Security). Ze draaien op elke PR en <strong>de lat moet gelijk zijn, of een mens of AI de code schreef<\/strong>.<\/p>\n<p>Maar een persoon reviewt nog steeds. De vragen die een review beantwoordt gaan verder dan CI: lost dit het probleem op? Past het ontwerp binnen onze architectuur, of is het een patch die werkt maar niet is hoe wij dingen doen? Horen alle wijzigingen in deze PR thuis (of zijn er te veel dingen gebundeld, waardoor rollback lastig wordt)?<\/p>\n<p><strong>Kan AI helpen bij review?<\/strong> Ja, met <strong>Copilot code review<\/strong>, zolang je <strong>je standaarden opschrijft<\/strong> zodat Copilot toetst aan <em>jouw<\/em> regels in plaats van een generieke review vanuit zijn training. Copilot kan ook een goedkeuringsadvies geven, maar:<\/p>\n<ul>\n<li>Het is <strong>een signaal, geen beslissing.<\/strong> Tools, deterministisch of probabilistisch, leveren enkel signalen en <strong>een of meer mensen zijn de uiteindelijke rechter<\/strong>. Copilot mag niet autonoom code mergen.<\/li>\n<\/ul>\n<p>De slide: schrijf de regel \u00e9\u00e9n keer op en Copilot reviewt PR&#8217;s ertegen, via repository instructions, path-specific guidance, skills en agents.<\/p>\n<h4>Context: hoe help je Copilot<\/h4>\n<ul>\n<li><strong>Repository instructions<\/strong> (zoals <code>.github\/copilot-instructions.md<\/code>; andere tools gebruiken <code>agents.md<\/code> en vergelijkbare bestanden). Som geen generieke C#-best practices op die Copilot al kent, maar de standaarden van <em>jouw team<\/em>: coding guidelines, testframeworks, welke tools de code bouwen en valideren. De voorbeeldregel op de slide: \u201cEvery new API endpoint must be documented in Swagger\/OpenAPI.\u201d<\/li>\n<li><strong>Path-specific guidance:<\/strong> verschillende instructies voor JavaScript en C#, of voor bepaalde paden.<\/li>\n<li><strong>Skills:<\/strong> laten Copilot taken effectiever uitvoeren.<\/li>\n<li><strong>Custom agents:<\/strong> doelgerichte, complexere taken die orchestratie vereisen.<\/li>\n<\/ul>\n<p>\u201cContext maakt van best practices verwachtingen, voor reviewers en voor agents.\u201d<\/p>\n<h3>Squire, Knight of Golem<\/h3>\n<p>Drie niveaus van AI-gebruik, die allemaal tot dezelfde kwaliteitslat moeten leiden:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_095915_d_e_kl.jpg\" loading=\"lazy\" alt=\"Squire, Knight or Golem - Quality in the Agentic Era: Keeping Engineering Standards at AI Speed\"><\/p>\n<ul>\n<li><strong>Squire:<\/strong> doet het grunt work met de hand. Je triageert het issue, implementeert het handmatig in je editor en reviewt het handmatig.<\/li>\n<li><strong>Knight:<\/strong> een hybride. Je wijst het issue toe aan Copilot (of gebruikt je IDE), de cloud agent schrijft de PR, tools helpen bij de review en ook een mens is betrokken.<\/li>\n<li><strong>Golem:<\/strong> in de folklore een wezen van klei, een menselijke creatie die uit de hand kan lopen (de oorsprong van Frankenstein), en in moderne termen iets wat we bouwen om taken uit te voeren maar dat echt begrip mist. Hier is het <strong>volledig agentic<\/strong>: je maakt geen issues aan, de automations vinden ze, bijvoorbeeld door productie te monitoren op exceptions, een bug te identificeren, te reproduceren en een fix te maken, die een andere agent reviewt voordat een mens de PR accepteert.<\/li>\n<\/ul>\n<p>Het doel van de slide: bij elke stap minder handwerk, met op elk pad dezelfde kwaliteitslat. \u201cAlleen omdat de machine het doet, betekent het niet dat je het blindelings vertrouwt.\u201d<\/p>\n<h4>De wet is geschreven, stuur nu de knights<\/h4>\n<p>Josh&#8217; drie stappen (hoe we hier gekomen zijn):<\/p>\n<ol>\n<li><strong>Bepaal wie elke standaard controleert:<\/strong> tools, Copilot of een persoon.<\/li>\n<li><strong>Maak instructies levende documentatie.<\/strong> Ze helpen Copilot het project te begrijpen. Het is nooit &#8220;set and forget&#8221;: als een agent een fout maakt, behandel dat dan bijna als een <strong>productiedefect<\/strong> en verbeter het instructiebestand, <code>agents.md<\/code>, het reviewbestand, de skills of agents.<\/li>\n<li><strong>Laat automatisering erop handelen:<\/strong> dezelfde lat, zonder dat iemand hoeft te wachten om het te starten. De opgeschreven context stuurt de agent en je verifieert ook de workflow die het werk toewijst en de resultaten controleert.<\/li>\n<\/ol>\n<h4>Manieren om automatisering te bouwen (van eenvoudigst naar complexst)<\/h4>\n<ul>\n<li><strong>Copilot automations<\/strong> (in de GitHub-app of op het tabblad Agents op het web): een cloud agent. Je kiest de scope (een issue bijwerken, een PR maken, een label toevoegen) en een trigger (aanmaken van een issue of PR, via een API, of volgens een schema). Dit is de makkelijkste manier om te beginnen.<\/li>\n<li><strong>GitHub Agentic Workflows<\/strong> (public preview): iets ouder en beter uitbreidbaar, met <strong>ingebouwde safeguards<\/strong>. Je kunt bijvoorbeeld aangeven dat de workflow <em>\u00e9\u00e9n en slechts \u00e9\u00e9n<\/em> issuecommentaar of PR mag aanmaken, in plaats van tien PR&#8217;s te laten maken, omdat AI probabilistisch is en niet deterministisch. Er is een website met veel voorbeelden.<\/li>\n<li><strong>Maatwerkoplossingen:<\/strong> GitHub Actions of Azure Pipelines met de <strong>Copilot CLI<\/strong> of <strong>SDK<\/strong>, of andere tools zoals Azure Foundry of Copilot Studio. Josh noemde een klant met een niet-GitHub CI die simpelweg de Copilot CLI downloadde en authenticeerde, prompts draaide en de output teruggaf.<\/li>\n<\/ul>\n<h3>Demo 1: automatische bugreproductie<\/h3>\n<p>Tiago demonstreerde dit op een voorbeeldrepo op GitHub (een bewust onvolmaakte demo-app &#8220;OctoCAT Supply&#8221; met een database, backend en frontend).<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_100653_d_e_kl.jpg\" loading=\"lazy\" alt=\"Quality in the Agentic Era: Keeping Engineering Standards at AI Speed - Josh Johanning &amp; Tiago Pascoal\"><\/p>\n<ol>\n<li>Tiago maakte een issue aan: \u201cLogin page is not accessible\u201d (de loginpagina respecteert de accessibility-tags niet), bewust kort.<\/li>\n<li>Het aanmaken triggert een automation, een <strong>&#8220;Bug repro evaluator&#8221;<\/strong>.<\/li>\n<\/ol>\n<p>Hoe de automation is gedefinieerd:<\/p>\n<ul>\n<li><strong>Triggers:<\/strong> issue geopend (tenzij het al een <code>triage<\/code>-label heeft), of gelabeld als bug (tenzij het al een <code>reproducer run<\/code>-label heeft). Er bestaan andere triggers (issue toegewezen of gesloten, pull request-events, security-events, schedules) en er komen er meer. Safeguards voorkomen dat de automation draait wanneer dat niet zinvol is.<\/li>\n<li><strong>Tools en permissies:<\/strong> je beperkt wat het mag doen (het issue lezen, bijwerken, labels toevoegen, reageren). Als de prompt iets vraagt waarvoor het geen permissie heeft, faalt het niet maar waarschuwt het. Je kunt <strong>MCP-servers of skills<\/strong> toevoegen om met andere systemen te praten. Tiago&#8217;s voorbeeld was een MCP-server voor Azure-monitoring.<\/li>\n<li><strong>Prompt:<\/strong> \u201cYou are an automated Bug Triage and Reproduction Assistant. Goal: analyze a GitHub issue (title, body, and all comments), determine whether it describes a potential bug, attempt reproduction, and report results with evidence.\u201d<\/li>\n<\/ul>\n<p>De workflow: een commentaar plaatsen dat het bezig is, het issue begrijpen en classificeren (mogelijke bug of niet) op basis van de beschrijving, bedanken en om meer info vragen als het geen bug is, anders <strong>proberen het te reproduceren<\/strong> in meerdere omgevingen (besturingssystemen, browsers) en als bonus een fix voorstellen. Aan het einde voegt het een <code>reproducer run<\/code>-label toe en plaatst het een commentaar in een vast format, indien mogelijk met screenshots.<\/p>\n<p><strong>Resultaten:<\/strong> onder ongeveer tien issues liet er \u00e9\u00e9n, gelabeld &#8220;repro confirmed&#8221;, de oorspronkelijke beschrijving, de triage en de poging zien. Daarna <strong>wees het het issue toe aan Copilot<\/strong>, die een pull request met een fix opende. \u201cNo humans here\u201d (afgezien van een verzoek om review). Een UI-issue bevatte een <strong>screenshot<\/strong> van de app als bewijs. Tiago&#8217;s eigen vers aangemaakte accessibility-issue kreeg als antwoord \u201cgeen bug, ik kon het niet reproduceren\u201d (getest op Linux en Chrome), wat Tiago samenvatte als \u201cyou are wrong\u201d.<\/p>\n<p>Josh voegde toe dat het GitHub-team dat agentic workflows bouwt, zelf agentic workflows gebruikt voor triage, reproductie en fixes op feedbackissues.<\/p>\n<h3>De poorten van het koninkrijk: is de PR klaar?<\/h3>\n<p>De signalen, volgens de slide:<\/p>\n<ul>\n<li><strong>Code quality:<\/strong> zorgt dat PR&#8217;s geen nieuwe code quality-bevindingen introduceren.<\/li>\n<li><strong>Copilot code review:<\/strong> geeft een samenvatting van de wijzigingen, voorgestelde wijzigingen en een <strong>goedkeuringsadvies<\/strong> (een duim omhoog, nieuw in Copilot code review, of &#8220;needs work&#8221;).<\/li>\n<li><strong>Fine-tune de review<\/strong> met instructies, <code>agents.md<\/code> en een <code>review.md<\/code>, zodat de review zich richt op wat voor jouw team telt.<\/li>\n<li><strong>Human review:<\/strong> beslist of het gedrag en de afwegingen overeenkomen met de intentie.<\/li>\n<\/ul>\n<p>\u201cReview signals guide feedback; they are not executable merge rules.\u201d<\/p>\n<h4>Demo 2: een (niet zo goede) PR reviewen<\/h4>\n<p>Tiago gebruikte een door een mens geschreven PR met een slechte beschrijving om te laten zien dat dezelfde checks voor alles gelden.<\/p>\n<ul>\n<li><strong>Code coverage:<\/strong> je kunt een PR blokkeren als de coverage met meer dan een ingesteld percentage daalt of onder een minimum zakt. Hier steeg de coverage in de gewijzigde bestanden, terwijl het totale verschil nul was.<\/li>\n<li><strong>Code Quality<\/strong> (deterministisch) markeerde een waarschuwing (een directive die niet bestaat, \u201cje verzint maar wat\u201d). Severities zijn configureerbaar: blokkeer bij errors, sta warnings toe. Je kunt de suggestie committen of toewijzen aan Copilot om te fixen.<\/li>\n<li><strong>Copilot code review<\/strong> (niet-deterministisch) adviseerde wijzigingen in plaats van goed te keuren, met een samenvatting van de gewijzigde bestanden en <strong>vier openstaande issues<\/strong> (\u00e9\u00e9n hoog, de rest van gemiddelde ernst). Je kunt \u201cfix with Copilot\u201d \u00e9\u00e9n voor \u00e9\u00e9n of in batch gebruiken, of een commentaar afhandelen als je het er niet mee eens bent.<\/li>\n<li>Je kunt Copilot instellen om elke PR automatisch te reviewen, of op aanvraag (sommige teams slaan het over bij eenvoudige wijzigingen).<\/li>\n<li>Mergen wordt geblokkeerd tot alle conversaties zijn afgehandeld, van mens of Copilot. Copilot is de <strong>eerste verdedigingslinie<\/strong>, voordat je een teamgenoot vraagt.<\/li>\n<\/ul>\n<h4>Als alle checks slagen: hoort het ontwerp hier thuis?<\/h4>\n<p>Ook als alles groen is, stelt een persoon nog vragen (volgens de slide):<\/p>\n<ul>\n<li><strong>Complexity:<\/strong> is de abstractie het waard? (winst op korte termijn, pijn op lange termijn: tech debt)<\/li>\n<li><strong>Product fit:<\/strong> komt het endpoint overeen met bestaand gedrag? Copilot kent jouw productvisie niet.<\/li>\n<li><strong>Diagnostics:<\/strong> helpen fouten het team dat on call is? (Wordt het naar de juiste plek gelogd, is het self-healing?)<\/li>\n<li><strong>Exceptions:<\/strong> is het gerechtvaardigd, belegd en gedocumenteerd?<\/li>\n<\/ul>\n<p>\u201cVoorbeelden maken teamstandaarden expliciet. Een persoon beslist of de afweging past.\u201d<\/p>\n<h3>Demo 3: de wekelijkse &#8220;nightly bug scout&#8221;<\/h3>\n<p>Een <strong>proactieve<\/strong> automation, waarbij Tiago eenmaal per week &#8220;de golem loslaat&#8221; (de naam zegt nightly, maar hij draait wekelijks, <strong>maandag om 7 uur<\/strong>) zodat mensen aankomen bij verse bevindingen.<\/p>\n<p>Richtlijnen in de prompt:<\/p>\n<ul>\n<li>Vind en reproduceer <strong>nog niet gemelde<\/strong> bugs en maak bruikbare issues aan.<\/li>\n<li><strong>Maximaal drie verschillende bugs per run.<\/strong> Niets vinden is geldig: \u201cbe quiet, don&#8217;t create noise\u201d. Repareer niets, wijzig de applicatie niet.<\/li>\n<li>Probeer niet langer dan 20 minuten te gebruiken (een soft cap, want het model luistert mogelijk niet).<\/li>\n<li><strong>Backend:<\/strong> kijk naar de API, servicelogica, persistentie, jobs en integraties, en grenzen, zonder browser.<\/li>\n<li><strong>UI:<\/strong> start de app, verken user journeys in een echte browser en controleer accessibility en usability (inclusief toetsenbordgebruik, niet enkel de muis).<\/li>\n<\/ul>\n<p>De workflow: voorbereiden, bestaande meldingen controleren, <strong>deduplicate voor het aanmaken<\/strong> (en bestaande issues valideren zodat bekende niet opnieuw gemeld worden), en dan publiceren met labels (backend, UI, functional, logic, integration) en een vast issueformat (titel met &#8220;bug&#8221;, symptomen, samenvatting, reproductie, bewijs). De door gebruikers gemelde reproducties zijn vaak gewoon \u201chet werkt niet\u201d, dus de standaard die van de agent gevraagd wordt is nauwkeuriger.<\/p>\n<p>Tiago zei dat het vijf tot tien minuten kostte om aan te maken, met een limiet van ongeveer 1.000 tekens per automation, en dat je een model kunt kiezen (zij gebruikten &#8220;auto&#8221;).<\/p>\n<p><strong>Resultaat:<\/strong> issues met een <code>bug<\/code>-label en een label dat aangeeft dat ze door de scout gemaakt zijn. Deze triggerden de repro-automation <strong>niet<\/strong>, omdat <strong>een automation geen andere automations triggert<\/strong>, een failsafe tegen loops. Een voorbeeld meldde een probleem met mobiele navigatie bij kleine schermformaten, met reproductiestappen. Tiago&#8217;s punt: als kleine schermen by design niet ondersteund worden, zet dat dan in de instructies zodat Copilot het niet als bug indient. De scout maakte ook geen duplicaten van bestaande issues aan.<\/p>\n<p>(Je kunt hetzelfde bouwen als agentic workflow of met de Copilot CLI in elk automatiseringssysteem.)<\/p>\n<h3>De nieuwe bottleneck: de human review gate<\/h3>\n<p>Wanneer triage, implementatie en geautomatiseerde review sneller worden, <strong>heeft de uiteindelijke reviewer nog steeds tijd nodig om elke PR te beoordelen.<\/strong> Het advies van de slide:<\/p>\n<ul>\n<li><strong>Stem de output van agents af op de reviewcapaciteit.<\/strong><\/li>\n<li>Als een bevinding zich <strong>herhaalt<\/strong>, voeg dan een betrouwbare check toe of verbeter de repositoryrichtlijnen, en verifieer dat de volgende run het opvangt <em>voor<\/em> de human review.<\/li>\n<li><strong>Meet geaccepteerde, onderhoudbare wijzigingen<\/strong>, niet volume.<\/li>\n<\/ul>\n<p>Voor eenvoudige repro&#8217;s en kleine fixes kun je automatisch goedkeuren, maar voor grotere zaken moet een tech lead, projectleider of product manager beslissen wat erin gaat en wanneer.<\/p>\n<h4>Demo 4: een dashboard in de GitHub Copilot-app<\/h4>\n<p>Josh liet de <strong>GitHub Copilot-app<\/strong> zien, een &#8220;agentic take&#8221; op werken met agents: een GUI die je sessies en threads toont, waarin agents ge\u00efsoleerd werken in <strong>git worktrees<\/strong>, zodat er geen botsingen zijn wanneer meerdere agents in dezelfde repo werken. Daarin bouwde Josh een <strong>canvas<\/strong> dat in de repository is opgeslagen (gedeeld met iedereen op de repo; er zijn ook canvases op gebruikersniveau): een pull request-dashboard met \u201cwat is klaar om goed te keuren en waarom\u201d. De dichtstbijzijnde kandidaat slaagde voor alle checks (CI, Copilot code review, quality, GitHub Advanced Security, scope past) maar had nog openstaande threads, en geen van de PR&#8217;s had nog een human review, wat het canvas benadrukte. Weinig mensen in de zaal hadden de app gebruikt.<\/p>\n<h3>En Azure DevOps?<\/h3>\n<p>Veel meer mensen in de zaal gebruikten Azure DevOps dan GitHub. Veel hiervan werkt daar ook, \u201cin een andere vorm\u201d:<\/p>\n<ul>\n<li><strong>Written context:<\/strong> reviewrichtlijnen werken op org-, project-, repo- of padniveau en worden opgepikt door tools zoals de Copilot CLI.<\/li>\n<li><strong>Review en agent support:<\/strong> een <strong>Azure DevOps MCP<\/strong>-server om work items op te pakken en mee te werken; <strong>Copilot code review<\/strong> en Copilot Autofix voor CodeQL-securityalerts zijn in <strong>preview<\/strong>; in een hybride opzet (code in GitHub, work items in Azure DevOps) kun je work items toewijzen aan cloud agents.<\/li>\n<li><strong>Automated checks en signals:<\/strong> \u201cTeams kiezen welke checks het mergen blokkeren. Andere leveren signalen.\u201d<\/li>\n<\/ul>\n<h3>Het antwoord op de puzzel<\/h3>\n<p>De functie is een <strong>schrikkeljaarcontrole<\/strong>, uit een blogpost van Falk H\u00fcffner (15 mei 2025) met de titel &#8220;A leap year check in three instructions&#8221;. Het is een zeer geoptimaliseerde trucje met beperkt bereik dat in drie CPU-instructies draait.<\/p>\n<p>Toen Tiago een <strong>nieuwer model<\/strong> vroeg, zei dat, ook met de obscure naam, correct dat het een Gregoriaanse schrikkeljaartest is, geldig voor y van 0 tot en met 102.499, equivalent aan <code>y % 4 == 0 &amp;&amp; (y % 100 != 0 || y % 400 == 0)<\/code>, en legde het uit hoe de truc werkt.<\/p>\n<p>Tiago vroeg of het dit gewoon uit het hoofd kende (het zit waarschijnlijk in de trainingsdata). Het model antwoordde dat het niets over zijn training wist, maar dat dit de wiskunde was waarmee het de functie analyseerde. Dit \u201cvernietigt een beetje onze stelling\u201d, gaven ze toe, omdat modellen steeds beter worden in het lezen van obscure code. Maar ze geloven nog steeds dat <strong>engineering en codebegrip belangrijk zijn.<\/strong><\/p>\n<h3>Wat we geleerd hebben, en hoe je begint<\/h3>\n<ol>\n<li><strong>Schrijf de standaard \u00e9\u00e9n keer op.<\/strong><\/li>\n<li><strong>Laat begrensde automatisering handelen:<\/strong> geef het een gedefinieerde output (bijvoorbeeld \u00e9\u00e9n PR, of maximaal drie issues), de juiste context en een beperkte scope met enkel de permissies die het nodig heeft, zoals bij elke applicatie.<\/li>\n<li><strong>Automatiseer herhaalbare checks:<\/strong> build, tests, linting en formatters (zoals Prettier) blijven belangrijk en geven geweldige signalen.<\/li>\n<li><strong>Een persoon beslist.<\/strong> Misschien is de code goed maar nog niet klaar om te mergen (bijvoorbeeld door je deploymentplanning).<\/li>\n<\/ol>\n<p>\u201cE\u00e9n kwaliteitslat voor Squire, Knight en Golem. Een persoon neemt de uiteindelijke beslissing.\u201d<\/p>\n<h4>Een eerste pilot<\/h4>\n<p>Josh&#8217; suggestie: neem iets wat je developers niet graag doen (tests schrijven, documentatie bijwerken) en automatiseer een deel ervan. Zoek bijvoorbeeld wekelijks ontbrekende tests en begin er een aantal te maken, of controleer nieuwe PR&#8217;s op tests. Begin klein, evalueer, itereer en ga dan door naar het volgende probleem.<\/p>\n<p>De pilotchecklist van de slide:<\/p>\n<ul>\n<li><strong>Kies \u00e9\u00e9n repositoryworkflow en een benoemde eigenaar.<\/strong><\/li>\n<li><strong>Stel de standaarden vast voordat je begrensde automatisering toevoegt.<\/strong><\/li>\n<li><strong>Vergelijk<\/strong> reviewwachttijd en herwerk met je huidige workflow.<\/li>\n<li><strong>Monitor<\/strong> valse alarmen en ontsnapte defecten.<\/li>\n<\/ul>\n<p>Verdeling van verantwoordelijkheid (voorbeeld van de slide): toolchecks (build, lint, tests slagen), Copilot reviewt (een API-fix vermijdt niet-gerelateerde dependencywijzigingen) en een persoon beslist (lost de fix het ontwerpprobleem op?).<\/p>\n<p>De sprekers bedankten het publiek, vroegen om feedback via het speakerformulier en bleven tijdens de verlengde pauze beschikbaar voor vragen.<\/p>\n<p><!-- beyond-ddd-vs-ea --><\/p>\n<h2 id=\"beyond-ddd-vs-ea\">Beyond DDD vs EA: architecting autonomous landscapes that actually scale<\/h2>\n<p><em>Dwight Matthys &#8211; woensdag 11:15\u201312:15<\/em><\/p>\n<p>Dwight Matthys (VP of Architecture) opende met een truc die ze leenden van een spreker van de dag ervoor: een show of claps. Wie is Domain Driven Design (DDD)-practitioner? (Behoorlijk wat mensen.) Wie is enterprise architect? (Twee of drie.) Wie wordt een beetje bang als hij &#8220;enterprise architecture&#8221; hoort? Hun boodschap: niemand hoeft bang te zijn, en het heeft echt waarde om <strong>domain-driven design (DDD)<\/strong> en <strong>enterprise architecture (EA)<\/strong> samen te brengen.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_111529_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<h3>Over de spreker<\/h3>\n<p>Dwight werkt al ruim 22 jaar in technologie, van &#8220;the trenches&#8221; (C++, C#, CORBA, COM, SOAP, WCF, REST, WinForms, WPF, Silverlight en meer) via tech lead, software architect, solution architect en domain architect naar enterprise architect en VP. Ze houden van puzzels, spelen in een band (het t-shirt was een hint) en noemden hun kinderen naar personages uit Legend of Zelda. Ze werken in de <strong>casino- en gokindustrie<\/strong>, dus &#8220;the stakes are real&#8221;. Ze zijn geen consultant en hebben geen framework te verkopen: \u201cIk ben hier gewoon om te vertellen wat er kapotgaat en soms wat wel werkt.\u201d<\/p>\n<h3>Het businessdoel: time to market<\/h3>\n<p>Eerder dit jaar vroeg hun CTO om de <strong>time to market twee tot drie keer te verkorten<\/strong>. Dat is een overlevingsdoel voor het bedrijf, geen technisch doel, maar Dwight vroeg zich af hoe dat samenhangt met Domain Driven Design (DDD) en Enterprice Architecture.<\/p>\n<p><strong>Zo doen startups het:<\/strong> vijf briljante engineers (vaak de oprichters) bouwen en shippen gewoon in enkele dagen, zonder toestemming te vragen. <strong>Snelheid is een structurele eigenschap<\/strong> van het systeem, want als ze niet snel waren, gingen ze failliet. Daarna slaagt de startup en groeit ze, en neemt ze meer briljante engineers aan, en misschien enterprise architects.<\/p>\n<h4>De wet van Brooks, op systeemniveau<\/h4>\n<p>Fred Brooks (<em>The Mythical Man-Month<\/em>, 1975): mensen toevoegen aan een te laat softwareproject maakt het nog later. De wiskunde: met vijf mensen zijn er <strong>10<\/strong> communicatielijnen, met 14 mensen <strong>91<\/strong>, en Dwights engineeringorganisatie telt ongeveer 190 tot 200 mensen. \u201cAls je manager denkt dat meer mensen het sneller maken, koop hem dan dit boek.\u201d<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_112059_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<h4>Twee mislukte reacties<\/h4>\n<p><strong>1. Het management haalt het grote geschut erbij.<\/strong><\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_112539_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<p>Governance via frameworks (SAFe v6, TOGAF 10, ITIL v4, Zachman, FEAF): goedbedoeld, duur en \u201czeer lucratief voor de mensen die het verkopen\u201d. Ze beantwoorden het probleem met <strong>proces<\/strong>. Dwight maakte een grapje over &#8220;Form 7012-Bis-B&#8221;, merkte op dat SAFe v6 136 rollen en 19 ceremonies heeft, en haalde een bedrijf aan dat een illustrator 200.000 dollar betaalde voor \u00e9\u00e9n tekening in een strategiepresentatie van 287 slides. Niemand ging er sneller van werken.<\/p>\n<p><strong>2. Engineering duwt terug.<\/strong><\/p>\n<p>Engineers schetsen op whiteboards en besluiten het landschap op te delen in domeinen op basis van zelfstandige naamwoorden (Game, Player, Payment, Betting Odd, Communication, Shop). Goedbedoeld, briljante mensen, een andere invalshoek op hetzelfde probleem. Maar de stukken moeten nog steeds met elkaar communiceren, en het resultaat lijkt op de dependency graphs van microservices die mensen met een Death Star vergelijken: \u201cde mandala op stero\u00efden\u201d.<\/p>\n<h4>Twee uitersten in spanning<\/h4>\n<p>Met een techniek uit het boek <em>No Rules Rules<\/em> (Netflix) zette Dwight de twee benaderingen tegenover elkaar:<\/p>\n<ul>\n<li><strong>Rules:<\/strong> governance boards, approval gates, review cycles, comit\u00e9s. \u201cTraag by design: elke gate is een dependency.\u201d <strong>Verkeerd uitgevoerde governance is coupling in vermomming.<\/strong><\/li>\n<li><strong>Rock &#8216;n&#8217; roll:<\/strong> autonome teams, &#8220;no guardrails&#8221; (ze hebben natuurlijk wel CI\/CD), snel shippen, later uitzoeken. \u201cSnel, tot het niet meer snel is.\u201d Bij microservices <strong>verhuist de coupling naar de netwerklaag<\/strong>: latency is niet nul en services vallen uit. <strong>Verkeerd uitgevoerde autonomie is ook coupling in vermomming.<\/strong><\/li>\n<\/ul>\n<p>Geen van beide leverde time to market op: de ene zat vanaf het begin in een bottleneck en de andere uiteindelijk. Zo eindigen bedrijven met een monoliet, of erger, een <strong>distributed monolith<\/strong>. Wat schaalt er dan wel?<\/p>\n<h3>Oorlogsverhaal 1: toen de Enterprice Architect afwezig was<\/h3>\n<p>Bij het casinobedrijf verkopen ze games van game providers, en spelers spelen erop. <strong>Finance<\/strong> vond niet dat ze enterprise architecture nodig hadden. Om gametransacties af te stemmen op facturen van leveranciers moest Finance weten welke game welke was, dus:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_112923_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<ul>\n<li><strong>Dupliceerden ze de data van de gamecatalogus.<\/strong> De catalogus heeft ingewikkelde deduplicatieregels, dus ze deden het fout.<\/li>\n<li><strong>Bouwden ze een billing engine in Finance<\/strong>, terwijl de complexe regels bij de casinomanagers horen, die de deals met providers onderhandelen (bijvoorbeeld 15% extra korting als jouw game een maand lang op plek vijf staat).<\/li>\n<\/ul>\n<p>De slide toont een casinoflow (speler start game, gametransactie wordt vastgelegd, billing <strong>ontbreekt<\/strong>) en Finance met het verkeerde eigenaarschap: de gamecatalogus in Finance, de billing engine daar gebouwd, en gedupliceerde data. De gevolgen: games die het casino live had gezet en waarop spelers hadden gespeeld, werden mogelijk niet herkend in de catalogus van Finance, waardoor het <strong>afsluitproces van de CFO stilvalt<\/strong>.<\/p>\n<p>Dwight werd twee weken voor go-live erbij gehaald. Een snelle schets van de capabilities liet zien dat het niet klaar zou zijn, en <strong>het project moest van nul opnieuw beginnen<\/strong>. De oplossing: de gamecatalogus wordt beheerd door Casino, en de billing engine verhuisde (omstreden) naar Casino omdat zij de intrinsieke regels kennen, zodat <strong>billing een first-class capability wordt, in handen van de juiste mensen<\/strong> met de juiste data.<\/p>\n<p>\u201cEen capability map had Billing benoemd voordat er \u00e9\u00e9n regel code was geschreven.\u201d Enterprise architects zien het landschap dat niemand anders ziet, inclusief duplicatie, terwijl mensen binnen een systeem de neiging hebben vooral binnen dat systeem te kijken. Maar: \u201cde kaart kwam na het terrein\u201d. Het instinct was juist, ze waren alleen te laat.<\/p>\n<h3>Oorlogsverhaal 2: toen Enterprice Architectuur en DDD (Domain driven design) allebei in de kamer zaten<\/h3>\n<p>In een ander project (in Malaga) keek Enterprice Architectuur, \u201cvanuit de ivoren toren\u201d, naar de capability map en zei: bouw een <strong>Sales Order<\/strong>-domein. De teams namen dat voor waar aan en pasten DDD (Domain driven design) toe (event storming, grenzen tekenen), en <strong>er ontstonden twee domeinen: Customer Basket en Sales Order<\/strong>. Toen ze terugkwamen bij Enterprice Architectuur, zeiden ze nee: \u201cdat is een front-endprobleem\u201d. De engineers gingen toch door (\u201cwat doen engineers als Enterprice Architectuur zegt dat ze iets niet moeten doen? Ze doen het gewoon\u201d).<\/p>\n<p>De slide toont de sales funnel: \u00e9\u00e9n journey over meerdere domeinen, de klant browst, een item wordt geselecteerd, de basket wordt bevestigd, de sales order wordt aangemaakt en bevestigd, de factuur wordt getriggerd.<\/p>\n<p>Het resultaat: <strong>dataduplicatie en coupling<\/strong>. Alle data in de basket moest worden gedupliceerd naar de sales order, ze omzeilden zelfs een enterprise service bus om het te verplaatsen, en het ene team kon niets wijzigen zonder met het andere te overleggen. \u201cHoeveel van jullie denken dat dat een eigenschap is van snel zijn?\u201d<\/p>\n<p>Op een avond besefte Dwight dat de <strong>lijn fout was<\/strong> (die had horizontaal in plaats van verticaal gesneden moeten worden): het domein duwde terug. Ze hadden het model als vaststaand geaccepteerd, \u201ceen hypothese behandeld als een verklaring\u201d. Evans zelf zegt dat het model een hypothese is, geen verklaring, en dat het zal evolueren.<\/p>\n<p>Een slide vatte het samen: de grens was een startpunt, ze behandelden die als bestemming. Een tweede slide: Enterprice Architectuur miste het domein, Domain Driven Design miste het landschap: geen van beide was ontworpen om te zien wat de ander ziet.<\/p>\n<p><strong>De les:<\/strong> in het eerste verhaal miste Enterprice Architectuur het domein. In het tweede misten de Domain Driven Design-practitioners het landschap. Geen van beide disciplines is fout: \u201cgeen van beide was ontworpen om te zien wat de ander ziet, en precies in die blinde vlek verstopt de coupling zich.\u201d De regel op de slide: <em>Enterprice Architectuur zonder domeinkennis is een kaart zonder terrein. Domain Driven Design (DDD) zonder landschapsoverzicht trekt grenzen in het donker.<\/em><\/p>\n<h3>Evans deed de hele tijd al enterprise architecture<\/h3>\n<p>Een <strong>bounded context<\/strong> (Eric Evans) is een context waarin een model geldt, met drie rollen:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_114320_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<ol>\n<li><strong>Isolation boundary:<\/strong> wat erbinnen leeft blijft schoon, wat de grens oversteekt is expliciet.<\/li>\n<li><strong>Coherence boundary:<\/strong> het model klopt als geheel. (&#8220;Favourites&#8221; betekent favoriete games in gameplay en favoriete betaalmethodes in payment: \u00e9\u00e9n model om ze allemaal te regeren werkt niet.)<\/li>\n<li><strong>Autonomy boundary:<\/strong> zodat teams kunnen bewegen zonder 22 mensen te bellen.<\/li>\n<\/ol>\n<p>\u201cTrek de grens verkeerd en je breekt het model, en het vermogen van het team om te bewegen.\u201d<\/p>\n<p><strong>Business capabilities<\/strong> beschrijven <em>wat<\/em> een bedrijf doet, niet <em>hoe<\/em>. Bijvoorbeeld: inchecken bij een luchtvaartmaatschappij bestond in 1980 (uren in de rij) en bestaat vandaag (online inchecken): de capability is dezelfde, maar anders gerealiseerd. Door capabilities te articuleren en uit te dagen kun je eigenaarschap bij \u00e9\u00e9n team leggen, en cartografie is \u201cde echte voorwaarde voor autonomie\u201d, zolang je de kaart als hypothese behandelt.<\/p>\n<p>De slide stelt de twee werelden aan elkaar gelijk:<\/p>\n<table>\n<tr>\n<th>Domain Driven Design (DDD)<\/th>\n<th>Enterprice Architectuur<\/th>\n<\/tr>\n<tr>\n<td>Bounded context<\/td>\n<td>Level 1 capability<\/td>\n<\/tr>\n<tr>\n<td>Context map<\/td>\n<td>Capability map + integration stack<\/td>\n<\/tr>\n<tr>\n<td>Integration pattern<\/td>\n<td>Integration interface<\/td>\n<\/tr>\n<\/table>\n<h4>Samen: evolvability<\/h4>\n<p>Door ze te combineren krijg je <strong>evolvability: het vermogen om te veranderen zonder toestemming te vragen.<\/strong><\/p>\n<ul>\n<li><strong>Domain Driven Design (DDD)<\/strong> brengt nederigheid (laat het domein spreken, pas je kaart aan) en denken en eigenaarschap op teamniveau.<\/li>\n<li><strong>Enterprice Architectuur<\/strong> brengt het grotere plaatje (zodat je het landschap aan een chief marketing officer kunt uitleggen in marketingtermen), capability mapping en <strong>computational governance<\/strong>, een idee uit data mesh: governanceregels die berekenbaar zijn, deel uitmaken van de pipelines en automatisch worden uitgevoerd, en waar mensen tegenin kunnen gaan. Dwights organisatie zet governanceregels om in computationele regels.<\/li>\n<\/ul>\n<p>\u201cGeen van beide is compleet op zichzelf. Samen: een houding, geen framework.\u201d Autonomie is een enabler richting dat doel, en architectuur zou niet over controle moeten gaan, maar over het <strong>ontwerpen van de regels, omstandigheden en beperkingen waarbinnen ontwerpen kunnen worden gemaakt en kunnen evolueren.<\/strong><\/p>\n<h3>De wet van Conway en de inverse manoeuvre<\/h3>\n<p>Organisaties produceren ontwerpen die hun communicatiestructuren kopi\u00ebren. Als een bedrijf met zeven teams zeven onderdelen krijgt, heeft het systeem dezelfde coupling als de organisatie. Je architectuur weerspiegelt je organisatie, of je dat nu gepland hebt of niet.<\/p>\n<p>De meeste organisaties ontwerpen het systeem, hopen dat de organisatie zich aanpast (dat gebeurt niet, want managers geven zelden territorium op), zien de coupling oplopen, reorganiseren en herhalen. De <strong>inverse manoeuvre<\/strong>: ontwerp eerst de teamgrenzen, om bewust de architectuur te produceren die je wilt. \u201cConway is een wet, geen suggestie. Gebruik hem met opzet.\u201d<\/p>\n<p>En de wet van Brooks geldt ook op systeemniveau: <strong>elk integration pattern is een co\u00f6rdinatiecontract tussen teams, en die overhead stapelt zich op.<\/strong> \u201cCoupling is geen technische smell. Het is een organisatorische belasting.\u201d<\/p>\n<h3>De prime directive: autonomie versus coupling<\/h3>\n<p>Dwight toonde een schaal van <strong>zero coupling (maximale autonomie)<\/strong> tot kritieke coupling. Elk integration pattern dat je kiest schuift een markering naar rechts en heeft een co\u00f6rdinatieprijs. De beste integratie is \u201cdegene die niet bestaat\u201d, net zoals de beste code de code is die je niet schrijft. Ze liepen de niveaus door.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_115043_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<h4>Level 00: geen integratie<\/h4>\n<p>Daag eerst <strong>de domeingrens uit.<\/strong> Voorbeeld: iedereen ging ervan uit dat de <em>deposit limit<\/em> moest praten met het <em>player profile<\/em>. Maar de limiet leeft eigenlijk in het Payment-domein. Verplaats hem daarheen en de integratie verdwijnt. Dit sluit aan bij de <strong>anti-requirements<\/strong> van Udi Dahan: waarom zou een kortingsdomein zich druk maken over of iemand Dwight heet of een naam van zes letters heeft? \u201cEerst anti-requirements. Dan pas integratie.\u201d<\/p>\n<h4>Level 01: visuele compositie (micro-frontends)<\/h4>\n<p>Als de gebruiker data van twee capabilities alleen maar samen moet <em>zien<\/em> (de deposit limit en profielinformatie), hoeft de data niet te reizen, alleen de presentatie. Bouw <strong>micro-frontends<\/strong> die samenkomen in de shell- of channellaag. Elke capability bezit haar eigen UI-stuk volledig, met behavioural contracts, geen data contracts. Dwight geeft de voorkeur aan teams die zowel de pixels als de API&#8217;s bezitten, en waarschuwt voor een apart &#8220;webteam&#8221;, dat niet autonoom is.<\/p>\n<h4>Level 02: niet-visuele compositie<\/h4>\n<p>Wanneer je geco\u00f6rdineerde dataopvraging nodig hebt (kolommen in een grid, dashboards), kun je niet van elke cel een micro-frontend maken. Een co\u00f6rdinerende (niet-visuele) component haalt data op bij meerdere capabilities. Dat vraagt om expliciete afstemming tussen teams over het contract.<\/p>\n<h4>Level 03: event-driven (async)<\/h4>\n<p>Als je moet reageren op iets wat in een ander domein is gebeurd zonder dat te controleren, gebruik je <strong>business events<\/strong> (&#8220;tell, don&#8217;t ask&#8221;), zoals <code>PlayerSessionEnded { playerId, sessionTxId }<\/code>. Een licht contract: een polyseme-identifier, timestamp, correlation ID en minimale feitelijke data. <strong>Geen domeinlogica, geen commands, geen verwachtingen.<\/strong> (Geen event sourcing, en geen events die elk detail meedragen.) Een jackpotdomein dat gameplay observeert, zou &#8220;speler heeft de jackpot gewonnen&#8221; kunnen uitsturen met een speler-ID en timestamp, en verder niets. Het is vrij autonoom, maar je moet nog steeds contracten onderhouden (en versioneren). Het blijft communicatie-overhead.<\/p>\n<p>Een <strong>polyseme<\/strong> is een concept op landschapsniveau, een gedistribueerde entiteit die over domeingrenzen is opgedeeld en door \u00e9\u00e9n identifier bij elkaar wordt gehouden. Het is <strong>geen shared model<\/strong>. Het heeft een naam, een identifier en open context. Voorbeeld: <code>ShopSaleTransactionId<\/code>, niet <code>txId<\/code>: de naam codeert de eigenaar en de context. \u201cDat is ubiquitous language op landschapsniveau.\u201d<\/p>\n<h4>Level 04 en verder<\/h4>\n<p>Dwight beschreef de volgende stappen, waarin een domein een ander domein nodig heeft om echt werk te doen (bijvoorbeeld gameplay die vraagt of een speler mag spelen), wat niet met events op te lossen is als je een consistent antwoord nodig hebt. Hier gebruiken ze <strong>governance patterns<\/strong> uitgedrukt als templates die <em>computationeel<\/em> zijn, zichtbaar in je repositories, want \u201choe meer je naar rechts schuift, hoe meer je hier een viewpoint op wilt, omdat het autonomie en snelheid raakt\u201d. (Deze stap is niet op de foto&#8217;s vastgelegd, dus de details ontbreken.)<\/p>\n<h4>Level 05: managed coupling: hub and spoke<\/h4>\n<p>Wanneer je de <strong>data<\/strong> van een ander domein nodig hebt op een manier die dat domein beheerst en begrijpt (Dwight noemde ERP-achtige consumenten zoals SAP, die veel meer data willen dan ze nodig hebben), orkestreert een hub, en <strong>de spokes stellen data beschikbaar als first-class surface in handen van hun domein<\/strong>, met zeer specifieke contracten voor die use case. Omdat die gestandaardiseerd en vindbaar in het landschap kunnen zijn, kun je het contract verwijderen wanneer de consumerende use case verdwijnt: \u201cgeen API&#8217;s meer, niet meer afvragen of iemand ze gebruikt\u201d.<\/p>\n<h4>Vanaf hier: autonomie is aanzienlijk aangetast<\/h4>\n<p>\u201cIn Legend of Zelda zeggen ze: waag je hier niet.\u201d Dat betekent niet nooit, het betekent: <em>weet je het zeker?<\/em> Elke stap hier is een <strong>bewuste afweging<\/strong>: motiveer hem, voel de kosten, benoem ze.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_120024_d_e_kl.jpg\" loading=\"lazy\" alt=\"Beyond DDD vs EA: Architecting Autonomous Landscapes That Actually Scale - Dwight Matthys\"><\/p>\n<ul>\n<li><strong>Level 06, hoge coupling: data-rijke domain events.<\/strong> Rijke interne events delen over een grens heen. Het contract is zwaar en de coupling echt en groeiend. Het \u201cmoet elke keer een bewuste, gemotiveerde beslissing zijn. Geen gemak. Geen default.\u201d<\/li>\n<li><strong>Level 07, hoge coupling: directe API-\/RPC-coupling.<\/strong> E\u00e9n domein hangt synchroon af van de API van een ander: van de beschikbaarheid, het contract en de versiecyclus. Elke wijziging van de producer kan de consumer breken, elke deployment is een co\u00f6rdinatiemoment, en er ontstaan <strong>availability chains<\/strong>. Als een domein dat je nodig hebt down is, raak je mogelijk je kernprocessen die omzet genereren. Version drift stapelt zich ongemerkt op, en een &#8220;API version drift checker&#8221; kan die zichtbaar maken: de afstand tussen de versie van de consumer en de huidige versie van de producer.<\/li>\n<li><strong>Level 09, kritieke coupling: databasecoupling.<\/strong> \u201cLegacy, noodgreep of technical debt? Noem het bij de naam. <strong>Geen pattern. Een wond.<\/strong>\u201d Als twee capabilities een database delen, rimpelen schemawijzigingen door zonder contract, zonder grens en zonder onderhandeling: \u201cgewoon shared state\u201d. Dwight vond ooit <strong>39 databases<\/strong> die in een wiel aan elkaar gekoppeld waren. Zit je hier, benoem het dan expliciet, neem het eigenaarschap op het hoogste niveau en plan de exit.<\/li>\n<\/ul>\n<h3>Takeaways<\/h3>\n<ul>\n<li><strong>Snelheid moet een structurele eigenschap zijn<\/strong>, geen managementinstructie of proces.<\/li>\n<li><strong>Behandel grenzen en capability maps als hypotheses<\/strong>, en laat het domein terugduwen.<\/li>\n<li><strong>Combineer het landschapsoverzicht van Enterprice Architectuur met de domeinkennis van Domain Driven Design (DDD):<\/strong> evolvability is \u201chet vermogen om te veranderen zonder toestemming te vragen\u201d.<\/li>\n<li><strong>Daag grenzen en requirements uit voordat je integratie toevoegt.<\/strong> Blijf zo dicht mogelijk bij zero coupling en motiveer elke stap daarvan weg.<\/li>\n<li><strong>Coupling is een organisatorische belasting<\/strong>, dus gebruik de wet van Conway met opzet.<\/li>\n<li><strong>Maak governance computationeel<\/strong>, zodat ze draait en uitgedaagd kan worden.<\/li>\n<\/ul>\n<p>Dwight schrijft een boek met de titel <strong><em>Architecting Autonomy<\/em><\/strong> (&#8220;beyond DDD vs EA: the principles, the patterns, the practice&#8221;), waarvan ze verwachtten dat ze bij hoofdstuk 10 zouden zijn, maar ze zitten pas bij hoofdstuk 1.<\/p>\n<p><!-- local-first-ai --><\/p>\n<h2 id=\"local-first-ai\">Local-first AI development: sovereignty, silicon and the private dev loop<\/h2>\n<p><em>Brian Randell &#8211; woensdag 13:15\u201314:15<\/em><\/p>\n<p>Brian Randell is partner bij MCW Technologies en werkte ongeveer vier jaar met GitHub. Ze opende met de belofte van \u201ceen eerlijke mening, geen marketingpraat\u201d. Om de eigen beweringen te testen kocht Brian flink wat hardware. De slides en benchmarkdata staan op GitHub (<code>github.com\/brianrandell\/localllmtests<\/code>, plus een repo met de demo\u2019s) en op <code>essentialdevops.org<\/code>.<\/p>\n<h3>De datum die de vraag veranderde: 12 juni 2026<\/h3>\n<p>Brian begon met een datum en vroeg wat er toen gebeurde. Volgens hun verhaal sneed de Amerikaanse overheid op <strong>12 juni 2026<\/strong> voor iedereen de toegang af tot een nieuw, krachtig model van Anthropic, niet alleen buiten de VS. Een paar weken later kwam het terug voor sommigen, maar de meeste mensen hebben nog altijd geen toegang tot het meest beperkte model en het model dat <em>wel<\/em> beschikbaar is, heeft beperkingen waar je \u201cmisschien niet helemaal blij van wordt\u201d. Voor wie erop gebouwd had, ging de les over <strong>vendor exposure<\/strong>.<\/p>\n<p>De slide vat de verschuiving samen: in <strong>2024<\/strong> was local AI een hobby met een reserve-GPU en in <strong>2026<\/strong> is het <strong>een beslissing die gereguleerde teams moeten nemen<\/strong>: \u201cDe vraag is niet langer \u2018kan ik het\u2019, maar \u2018waar moet het draaien\u2019.\u201d De slide aan het einde van de talk merkt op dat teams die deze keuze al bewust hadden gemaakt, 12 juni niet eens opmerkten.<\/p>\n<p>Twee zinnen om te onthouden:<\/p>\n<ol>\n<li><strong>Het model is een commodity input.<\/strong> De echte keuzes zijn waar het draait, wat dat kost en hoe je het verwisselt zonder de app te herschrijven.<\/li>\n<li><strong>Local is eerst een policy-beslissing en pas daarna een hardwarebeslissing.<\/strong><\/li>\n<\/ol>\n<p>Brian vergeleek de modelmarkt met de maakindustrie: China besteedt aan modellen dezelfde toewijding als aan het goedkoper produceren van spullen en elk land wil dat de eigen burgers toegang hebben tot AI-technologie, dus er komen steeds meer modellen uit steeds meer plekken. (Sommige organisaties trainen ook hun eigen modellen, maar dat viel buiten de scope.)<\/p>\n<h3>Deel 1: Sovereignty, waarom de prompt de deur niet uit mag<\/h3>\n<p>Vier drijfveren voor local, \u201cin volgorde van hoe vaak ze de echte reden zijn, in tegenstelling tot de opgegeven reden\u201d:<\/p>\n<ol>\n<li><strong>Broncode en eigen prompts.<\/strong> \u201cSource\u201d in de ruimste zin: niet alleen de code van ontwikkelaars, maar alle data die gebruikers invoeren in AI-extensies en chatinterfaces in jouw applicaties. De zorg is niet alleen of een provider erop traint. Het gaat ook om de dag waarop legal zegt \u201cwe hebben een dagvaarding gekregen, stuur ons de logs van vorige maand\u201d, plus je <strong>retentieregels<\/strong>. Mensen vertellen chatbots ook dingen die ze nooit in een e-mail zouden zetten en ze doen dat op werksystemen, bijvoorbeeld als hun gratis account op is.<\/li>\n<li><strong>Dataresidentie en wetgeving.<\/strong><\/li>\n<li><strong>Vendor exposure<\/strong>, zoals 12 juni liet zien. Als je ontwerp op \u00e9\u00e9n provider leunt, sta je met lege handen als die verdwijnt.<\/li>\n<li><strong>Voorspelbare uitgaven.<\/strong> Providers veranderen hun tokenmodellen (\u201ctoken maxing\u201d) en finance wil voorspelbaarheid. Een capital expense voor hardware die overeenkomt met een aantal tokens is iets wat accountants en aandeelhouders begrijpen. Microsoft werkt ook aan het standaard combineren van local en cloud (hun \u201cHybrid\u201d-aanpak), want de grote providers kunnen compute ook niet cadeau blijven doen.<\/li>\n<\/ol>\n<h4>De wet, zoals die deze maand geldt<\/h4>\n<p>De slide (data gecontroleerd op 23 oktober 2026, \u201cgeen juridisch advies\u201d; Brian zei ook geen jurist te zijn):<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_132549_d_e_kl.jpg\" loading=\"lazy\" alt=\"Local-First AI Development: Sovereignty, Silicon, and the Private Dev Loop - Brian Randell\"><\/p>\n<ul>\n<li><strong>GDPR:<\/strong> een prompt met persoonsgegevens is een verwerking. De modelprovider is een verwerker of subverwerker. De doorgifteregels gelden voor de API-call precies zoals ze gelden voor een databasereplica.<\/li>\n<li><strong>EU AI Act, artikel 50:<\/strong> transparantieverplichtingen die sinds 2 augustus 2026 gelden (zeg dat het AI is; markeer gegenereerde output machineleesbaar). De AI Omnibus (Verordening (EU) 2026\/1744, van kracht sinds 27 juli 2026) schoof de verplichtingen voor high-risk op naar 2 december 2027 (Annex III) en 2 augustus 2028 (Annex I). Artikel 50 werd niet uitgesteld, behalve het markeren voor bestaande generatieve systemen, dat naar 2 december 2026 ging.<\/li>\n<li><strong>US CLOUD Act (2018):<\/strong> een Amerikaanse provider kan gedwongen worden data te leveren die onder zijn beheer valt, waar de server ook staat. Daarom verkoopt elke hyperscaler nu een <strong>sovereign-cloud<\/strong>-variant (alleen EU-operatie, soms met een Europese rechtspersoon ertussen). Of dat je toezichthouder tevredenstelt, is een vraag voor je juristen.<\/li>\n<\/ul>\n<p>Brian gaf het voorbeeld van Microsofts Duitse sovereign cloud (in samenwerking met Deutsche Telekom als beherende rechtspersoon) en merkte op dat sovereign regions \u201cgeen wondermiddel zijn\u201d (ze noemden de poging van het VK om Apple te dwingen tot toegang tot versleutelde data), \u201cmaar wel een goed begin\u201d.<\/p>\n<h4>Provider of deployer?<\/h4>\n<p>De eigen terminologie van de AI Act: een <strong>provider<\/strong> bouwt een AI-systeem, brengt het op de markt en draagt de meeste zware verplichtingen (conformiteit, documentatie, markering). Een <strong>deployer<\/strong> gebruikt het onder eigen verantwoordelijkheid en de meeste teams die een API aanroepen, zitten hier, met transparantieplichten als het systeem met mensen in aanraking komt. Er is nog weinig jurisprudentie en de waarschuwing op de slide: als je een <strong>open-weight model fine-tunet<\/strong>, in je product verpakt en onder je eigen merk uitlevert, <em>ben je langs deze lijn opgeschoven<\/em>. \u201cLokaal draaien laat de regelgeving niet verdwijnen, het verandert wie hem draagt. Maak die afweging bewust.\u201d<\/p>\n<h4>De policy page<\/h4>\n<p>De uitkomst van de policy-beslissing is <strong>\u00e9\u00e9n pagina, geschreven voordat je iets koopt<\/strong>: voor elk soort content welke route is toegestaan (frontier API, cloud in een sovereign region of hardware die je zelf beheert). Brians voorbeeldrij: <em>\u201cBroncode uit klantrepositories: alleen local of sovereign region, alleen door frontier-modellen te reviewen met schriftelijke toestemming van de klant.\u201d<\/em> Veel mensen in de zaal kunnen deze beslissing niet zelf nemen, dus je moet opwaarts managen richting directeuren, de C-suite en <strong>legal<\/strong>. Denk ook aan wat je klanten je toestaan te doen met hun informatie.<\/p>\n<h3>Deel 2: Silicon, wat het kost, gemeten<\/h3>\n<p>Brian bouwde gedurende enkele maanden een benchmarksuite (nog bijgewerkt op de dag ervoor), gericht op <strong>Windows (CUDA 13) en macOS (Metal)<\/strong> (ze houden van Linux, maar hadden maar beperkt tijd).<\/p>\n<p>Methode, want \u201ceen benchmark zonder methode is een advertentie\u201d:<\/p>\n<ul>\n<li><strong>Workload:<\/strong> <code>llama-bench<\/code> met prompts van ongeveer 2.000 tokens en 512 gegenereerde tokens, 10 herhalingen, om ontwikkelaarsprompts te simuleren. Dezelfde <strong>GGUF-bestanden<\/strong>, geverifieerd als byte-identiek (ze vonden ooit een verschil). Een groot voordeel van lokale modellen is dat je het exacte model kunt vastpinnen voor reproduceerbare <strong>evaluations<\/strong>, terwijl gehoste modellen worden aangepast (\u201cop Reddit juichen mensen over een nieuwe release en een paar dagen later is hij \u2018generfd\u2019\u201d).<\/li>\n<li><strong>Twee getallen, \u00e9\u00e9n woord:<\/strong> <strong>prefill<\/strong> (tokens per seconde waarmee je prompt wordt gelezen) en <strong>decode<\/strong> (tokens per seconde waarmee het antwoord wordt geschreven), en het woord is <strong>fits<\/strong>: de modelgewichten moeten in het geheugen passen, plus de overhead van het draaien van de machine (vooral een laptop), plus ruimte voor denken en context. Let op de grootte van nieuwe modellen.<\/li>\n<\/ul>\n<h4>De bevinding die alles ordent<\/h4>\n<p><strong>Decodesnelheid volgt de geheugenbandbreedte. Niets anders op het spec sheet voorspelt hem.<\/strong> De grafiek zet de decodesnelheid af tegen de geheugenbandbreedte van elk apparaat. Een Core Ultra 9 CPU met ongeveer 90 GB\/s haalt bijvoorbeeld zo\u2019n 15 tokens per seconde op het kleine Llama-model, een M3 Max (400 GB\/s) ongeveer 60 en een M5 Max (614 GB\/s) ongeveer 89, terwijl de klasse van 1.792 GB\/s (RTX 5090, RTX PRO 6000) boven de 200 uitkomt.<\/p>\n<h4>Wat de hardware wel en niet is<\/h4>\n<p>Brians geteste bereik omvatte een Intel Ultra 9, een M3 Max en M5 Max, een RTX 2080 (te oud, want de software is doorgeschoven), een RTX 3090 en 4090, een RTX 5090 en een RTX PRO 6000 (vorig jaar ongeveer 8.000-9.000 euro en dit jaar volgens Brian 15.000-18.000). De RTX-kaarten zijn ontworpen voor gamers, niet voor AI, en mensen posten foto\u2019s van gesmolten connectoren, dus er een hele dag vol gas op draaien is een risico, terwijl de PRO-lijn bedoeld is om altijd te draaien. Een waarschuwend zijpad: Brian maakte het eigen moederbord kapot met <strong>statische elektriciteit<\/strong>, en daarom draaide de PRO 6000 tijdens de benchmarks als externe GPU (eGPU).<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_134029_d_e_kl.jpg\" loading=\"lazy\" alt=\"Local-First AI Development: Sovereignty, Silicon, and the Private Dev Loop - Brian Randell\"><\/p>\n<p>RTX 5090 versus RTX PRO 6000 versus M5 Max versus een M5 Ultra Mac Studio: bij dezelfde geheugenbandbreedte krijg je dezelfde decodesnelheid en <strong>je betaalt voor de andere 64 GB<\/strong>.<\/p>\n<p><strong>\u201cGeheugencapaciteit bepaalt het model. Bandbreedte bepaalt de snelheid. Koop in die volgorde.\u201d<\/strong> De fit-tabel laat zien welke modellen op welk apparaat draaien (een model met een kruisje past niet, \u201cniet langzaam, maar iets anders en slechters\u201d). Kerncijfers van de slide voor decode in tokens per seconde:<\/p>\n<table>\n<tr>\n<th>Apparaat<\/th>\n<th>gpt-oss-120b<\/th>\n<th>Qwen 3.5 122B<\/th>\n<\/tr>\n<tr>\n<td>RTX PRO 6000 (eGPU)<\/td>\n<td>182<\/td>\n<td>90<\/td>\n<\/tr>\n<tr>\n<td>M5 Max<\/td>\n<td>93<\/td>\n<td>35<\/td>\n<\/tr>\n<tr>\n<td>M3 Max<\/td>\n<td>61<\/td>\n<td>21<\/td>\n<\/tr>\n<tr>\n<td>AMD HX 370 (Radeon 890M)<\/td>\n<td>15<\/td>\n<td>17 (alleen CPU)<\/td>\n<\/tr>\n<\/table>\n<p>Brians visie: 24 GB lijkt genoeg, maar dan komen er modelgewichten, het scherm en context bij, dus de praktische sweet spot begint rond 32 GB en hoger. Piepkleine apparaten (de M6 mini was een voorbeeld) geven geen bevredigende codeerervaring. Machines met unified memory, zoals Apple Silicon en de AMD- en Snapdragon-laptops, openen de deur naar grote modellen. En \u201csneller is niet altijd een voordeel\u201d: als je baas de snelste hardware koopt, verwacht die dat jij sneller bent, terwijl tragere hardware je meer tijd geeft om na te denken (de XKCD \u201ccompiling, carry on\u201d wordt \u201cprompting, carry on\u201d).<\/p>\n<p>Brians eerste observatie over de nieuwe Surface-laptop op basis van Snapdragon die ze vooraf hadden besteld: gepubliceerde data suggereerde dat die voor AI-werk <strong>langzamer was dan de M5 Max<\/strong>, wat niet was wat ze hadden gehoopt van een machine op basis van NVIDIA. Ze zeiden dat ze het zelf zouden testen.<\/p>\n<h4>Prefill is compute, decode is bandbreedte<\/h4>\n<p>Over 14 modellen, de PRO 6000 versus de M5 Max: <strong>prefill 9 tot 16 keer sneller<\/strong> op dense modellen (3 tot 6 keer bij mixture-of-experts), maar <strong>decode slechts ongeveer 2,3 tot 2,6 keer sneller<\/strong> op dense modellen (de verhouding in specbandbreedte is 2,9). Een groot model van schijf laden telt ook mee en Brian merkte op dat de prijzen van SSD\u2019s zijn ge\u00ebxplodeerd: een 8 TB PCIe Gen 5 SSD die ze op Black Friday 2025 voor $799 kochten, stond op ongeveer $3.000.<\/p>\n<h4>Mixture of experts verandert de aankoop<\/h4>\n<p>Een MoE-model \u201cheeft het geheugen nodig van zijn totale omvang en draait op de snelheid van zijn actieve omvang\u201d, dus een grote MoE kan verrassend snel zijn op een machine met veel geheugen.<\/p>\n<h4>De eGPU-tax<\/h4>\n<p>Een kaart van 96 GB aan een laptop koppelen is een manier om met een beperkt budget de markt op te gaan en het werkt, maar het kost iets: <strong>3DMark onderschat de straf met een factor 2,5<\/strong> (raster -7,6% tegenover LLM-decode -19,1% op dezelfde verbinding en kaart), dus dimensioneer een dock niet met een gamebenchmark. Thunderbolt 5 en USB4 v2 presteerden gelijk (binnen 3% van elkaar). Brian meldde ook dat voor de Blackwell-kaarten alleen Thunderbolt-behuizingen werkten en dat OcuLink- en USB4 v2-docks in hun lab faalden.<\/p>\n<h4>E\u00e9n ontwikkelaar of een team<\/h4>\n<p>Voor \u00e9\u00e9n gebruiker (\u201cbatch 1\u201d) is de PRO 6000 maar ongeveer <strong>2,5 keer sneller<\/strong> dan de M5 Max en is de laptop een serieuze optie. Maar met concurrency verandert het beeld: bij prefill is het verschil 10 tot 15 keer en bij 16 gelijktijdige sequences ging de kaart van 64 naar 639 tokens per seconde in totaal, waarbij elke gebruiker nog steeds op ongeveer 40 tokens per seconde zat (ongeveer 10 keer). Daarom kopen datacenters NVIDIA en geen Macs: <strong>kopen voor \u00e9\u00e9n ontwikkelaar is een andere beslissing dan kopen voor een team<\/strong>, en de serving-software verandert ook mee.<\/p>\n<h3>Demo 1: hetzelfde model, twee machines<\/h3>\n<p>Brian draaide dezelfde prompt (\u201cExplain the difference between prefill and decode in LLM inference to a .NET developer in eight sentences\u201d) op <code>gpt-oss:120b<\/code> met Ollama op de M5 Max-laptop (128 GB) en op de RTX PRO 6000 (96 GB) thuis via RDP.<\/p>\n<p>Resultaat: ongeveer <strong>84 tokens per seconde<\/strong> voor decode op de laptop tegenover ongeveer <strong>183<\/strong> op de PRO 6000 (de totale duur was 5,3 seconden tegenover 2,3 seconden) en prompt processing van ongeveer 131 tegenover 1.711 tokens per seconde. \u201cKijk naar het tempo, niet naar de woorden: minder dan de helft van de snelheid, in een tas, met hetzelfde model.\u201d De engine maakt uit: Ollama is de makkelijkere ervaring, maar <code>llama.cpp<\/code> eronder geeft meer controle en op Linux haal je er meer uit.<\/p>\n<h3>Deel 3: De private developer loop<\/h3>\n<h4>Modelkeuze per taak<\/h4>\n<p>Namen per 23 oktober 2026, \u201cover zes maanden zijn ze anders, dat is juist het punt van de seam\u201d. Open-weight opties op de slide:<\/p>\n<table>\n<tr>\n<th>Taak<\/th>\n<th>Voorbeelden<\/th>\n<th>Geheugen<\/th>\n<\/tr>\n<tr>\n<td>Coding<\/td>\n<td>Qwen 2.5 Coder 32B, gpt-oss-20b en 120b, Qwen 3.x Coder MoE, MAI Code 1.1 Flash<\/td>\n<td>24 tot 96 GB<\/td>\n<\/tr>\n<tr>\n<td>Chat en reasoning<\/td>\n<td>Qwen 3.5-familie (4B tot 122B), Gemma 4, Llama 3.3 70B<\/td>\n<td>8 tot 128 GB<\/td>\n<\/tr>\n<tr>\n<td>Embeddings<\/td>\n<td>nomic-embed-text, qwen3-embedding<\/td>\n<td>elk<\/td>\n<\/tr>\n<tr>\n<td>Vision en documenten<\/td>\n<td>Gemma 4, Qwen 3.5<\/td>\n<td>16 GB en meer<\/td>\n<\/tr>\n<\/table>\n<p><strong>Regel \u00e9\u00e9n:<\/strong> match het model met de sport op de capaciteitsladder die je echt kunt draaien. <strong>Regel twee:<\/strong> evalueer op je eigen taken, met je eigen prompts, voordat je een leaderboard vertrouwt, \u201cdeze inclusief\u201d. (Brian waarschuwde ook dat de CEO\u2019s van de grote AI-bedrijven bezwaren uiten tegen open modellen, wat ze zelfbedienend vinden.)<\/p>\n<h4>Hosting: vier runtimes, \u00e9\u00e9n interface<\/h4>\n<p>Ollama, LM Studio, Foundry Local (van Microsoft) en <code>llama-server<\/code> spreken allemaal het <strong>OpenAI chat-completions-protocol op een lokale poort<\/strong>, \u201cdat is de seam\u201d, dus voor applicatiecode maakt de keuze nauwelijks uit. Ollama begon als een CLI die llama.cpp makkelijker maakte en Brian was kritisch over de opeenhoping van features en een cloudaanbod (\u201censhittification\u201d). Foundry Local is gebouwd door Microsoft-mensen die \u201cwisten dat de kosten uit de hand zouden lopen\u201d.<\/p>\n<h4>De seam in .NET: IChatClient<\/h4>\n<p>In .NET zorgt de <code>IChatClient<\/code>-abstractie ervoor dat de applicatie nooit een provider ziet. \u201cLocal of cloud\u201d en \u201cwelk model\u201d worden regels in <code>appsettings<\/code>, per omgeving, klant of repository in te stellen, en dat is precies wat de policy page vroeg.<\/p>\n<h4>Copilot, BYOK en on-device: de eerlijke stand van zaken<\/h4>\n<ul>\n<li><strong>VS Code:<\/strong> bring your own model in Chat- en Agent-modus via de Ollama-extensie, de Foundry Toolkit-extensie of een custom endpoint. Niet voor inline completions (die blijven op de modellen van GitHub). Er is een adminpolicy op Business en Enterprise (standaard aan). De ingebouwde Ollama-provider is deprecated, gebruik de extensie.<\/li>\n<li><strong>Visual Studio 2026:<\/strong> bring your own model alleen in \u201cAgent (Preview)\u201d (Microsoft Foundry, OpenAI, Anthropic, Ollama). De eerdere Ask- en Agent-BYOM-integratie is in september verwijderd.<\/li>\n<li><strong>On-device, experimenteel:<\/strong> MAI Code 1.1 Flash (137B MoE, 6,8B actief, ongeveer 53 GB), dat llama.cpp b11658 of nieuwer nodig heeft en een NVIDIA-GPU met 96 GB of meer (unified memory telt mee) plus Copilot-aanmelding. Het zit in een beperkte rollout sinds eind oktober 2026, waarbij \u201cAuto\u201d kan schakelen tussen dit model en de cloud. \u201cTold, not shown, juist daarom.\u201d<\/li>\n<\/ul>\n<h4>Hybrid by policy, niet per ongeluk<\/h4>\n<p>De <strong>inner loop<\/strong> (editor, agent, tests: \u201ctweehonderd keer per dag met je code in de context\u201d) draait <strong>local<\/strong>: \u201csnel genoeg, priv\u00e9 door ontwerp, gratis aan de marge\u201d. De <strong>outer loop<\/strong> (pull request, review, CI-gate) gebruikt <strong>frontier<\/strong>-modellen \u201cwaar frontier-capaciteit haar kosten waard is en er al een mens in de loop zit\u201d. Daartussen zit de policy page: welke rijen mogen de grens over, per klant, per repository. \u201cHybrid by Auto is hybrid volgens het beleid van iemand anders. Pin het vast.\u201d<\/p>\n<p>Brian wees Europese teams ook op een retentiedetail: bij nieuwere Claude-modellen is er volgens hen een <strong>retentieperiode van 30 dagen<\/strong> bij de provider, wat misschien niet past bij je wettelijke verplichtingen (terwijl oudere Claude Code-ontwerpen prompts als vluchtig behandelden). Met bring-your-own-key in Copilot kun je een leverancier kiezen die je vertrouwt, zoals Mistral.<\/p>\n<h4>Agents zijn een supply chain<\/h4>\n<p><strong>Hackerbot-Claw<\/strong> was een AI-agent die CI-pipelines vond en uitbuitte: een patroonindex van 9 klassen en 47 subpatronen, een proof of concept per doelwit, itererend op mislukkingen, tegen doelwitten waaronder Microsoft, Datadog, CNCF-projecten en Trivy. Of je nu local of frontier-modellen gebruikt, als je data levert aan een AI-oplossing ben je wettelijk aansprakelijk.<\/p>\n<p>\u201cDe keten is langer geworden. De mitigaties niet, op \u00e9\u00e9n na.\u201d De <strong>vijf nieuwe inputs<\/strong> (elk een dependency) zijn instructiebestanden in de repository, skills, MCP-servers (packages die draaien met de rechten van de agent), modellen (als je ze zelf host: code met gewichten eraan) en toolpermissies. Dezelfde pijlers gelden, <strong>plus sandboxing<\/strong>: geef de agent een eigen scoped identity (niet de jouwe), review agentconfiguratie zoals een workflowbestand (met hooks voor een deterministische log), pin en allow-list servers en modellen en <strong>draai nooit zonder sandbox<\/strong>, want \u201ceen agent is onbetrouwbare code die je zelf hebt uitgenodigd\u201d. (Bron op de slide: <em>Threats from the Shadows<\/em>, 2026.)<\/p>\n<h3>Demo 2: de inner loop, volledig lokaal<\/h3>\n<p>In VS Code opende Brian Copilot chat in agent mode en koos een <strong>lokaal Qwen coder-model (30B)<\/strong> dat door Ollama op de MacBook Pro werd geserveerd (context tot 262.000 tokens). Met een opgeslagen prompt vroegen ze het een klein .NET-programma zo aan te passen dat het de prompt als command-line-argument accepteert. De agent paste de code aan, draaide de build, schreef en draaide een test, \u201cen niets verliet mijn machine\u201d. Je kon de ventilatoren van de laptop horen: \u201cjust get some AI, you can make them scream\u201d. Een complexere poging eerder met een library (Polly) liep \u201cstrak gespannen\u201d vast en vereiste dat Brian ingreep, daarom was het een eenvoudigere demo. Brians eigen stijl is \u201cin the loop\u201d, waarbij meekijken prima is, ook als het niet super snel gaat.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_140531_d_e_kl.jpg\" loading=\"lazy\" alt=\"Local-First AI Development: Sovereignty, Silicon, and the Private Dev Loop - Brian Randell\"><\/p>\n<p>Ze noemden beperkingen: lokale modellen hebben sturing nodig via configuratiebestanden en skills, schrijven soms code die niet de beste of veiligste is en kennen geen CVE\u2019s die na de training zijn gevonden. Vandaar de hybrid: commit en push, en laat dan <strong>Copilot code review in de cloud<\/strong> de pull request beoordelen, met controle over welk model het gebruikt, tegen aparte kosten.<\/p>\n<h3>Demo 3: wissel het endpoint, geen code aangepast<\/h3>\n<p>Dezelfde app, gebouwd op <code>IChatClient<\/code>, draaide eerst tegen Ollama op de laptop (ongeveer 1,5 seconde voor 27 tokens in en 151 uit) en daarna tegen een model op <strong>Azure OpenAI in West US<\/strong> (ongeveer 2 seconden, 26 tokens in en 68 uit), na authenticatie met een managed identity-token (\u201cwe slaan geen API-keys op waar ze ge\u00ebxfiltreerd kunnen worden\u201d). \u201cE\u00e9n commando. Dezelfde prompt, ander antwoord, ander continent. De applicatie veranderde niet. De build veranderde niet.\u201d Brian merkte op dat de modellen verschilden, dus het was geen eerlijke vergelijking, maar met opties als Mistral kun je hetzelfde model lokaal en in de cloud draaien.<\/p>\n<h3>Drie maten van local<\/h3>\n<ul>\n<li><strong>Tier 1, \u00e9\u00e9n apparaat:<\/strong> capaciteit voor de sport die je nodig hebt, dan bandbreedte. Gemeten voorbeelden: een drie jaar oude M3 Max draait gpt-oss-120b op 61 tokens\/s, een 3090 of 4090 draait een 32B-coder op 36 tot 42, een HX 370-minipc met 96 GB draait gpt-oss-120b op 15 tot 17 en een Snapdragon X-laptop draait gpt-oss-20b op 19 op de CPU. Wat ze zouden kopen: een machine uit de klasse van de M5 Max met 128 GB, of eerst een week huren. Policy: de data verlaat het apparaat nooit en operations ben jij.<\/li>\n<li><strong>Tier 2, een workgroup:<\/strong> \u00e9\u00e9n PRO 6000-klasse box, of twee, in een kast. De throughput schaalt met concurrency op de kaart (MIG kan hem splitsen in vier ge\u00efsoleerde instances van 24 GB), serving met llama-server of vLLM, plafond: 96 GB bevat het model plus ieders context. Operations: <strong>\u00e9\u00e9n benoemd persoon die patcht, bewaakt en om 2 uur &#8217;s nachts opneemt<\/strong>.<\/li>\n<li><strong>Tier 3, een organisatie:<\/strong> multi-GPU-servers, tensor parallelism, vLLM of NIM, een platformteam en een capaciteitsplan. Brian zei dit <em>niet<\/em> te hebben gebouwd en er ook niet mee te doen alsof. Op deze schaal is de vraag niet meer local versus cloud maar \u201cwiens datacenter\u201d, en voor de meeste organisaties betekent dat een <strong>cloud in een sovereign region, met on-prem gereserveerd voor de policy-rijen die zelfs dat verbieden<\/strong>. Verhuurbare dedicated hardware is een optie en Brian klaagde dat de vraag van hyperscalers de hardwareprijzen opdrijft.<\/li>\n<\/ul>\n<h3>Drie hybrid-patronen<\/h3>\n<p>In de volgorde waarin ze slagen:<\/p>\n<ol>\n<li><strong>Local inner loop, cloud review<\/strong> (wat de demo liet zien): een toolinginstelling en een policyregel, geen architectuur. Het goedkoopst om in te voeren.<\/li>\n<li><strong>Local retrieval, cloud generation:<\/strong> het corpus wordt ge\u00efndexeerd en doorzocht op hardware die je zelf beheert en alleen de vraag en de opgehaalde passages reizen mee. Voor veel gereguleerde teams is dit het hele antwoord.<\/li>\n<li><strong>Sovereign-region cloud als standaard:<\/strong> local alleen voor de rijen die zijn gemarkeerd met \u201cmoet in het gebouw blijven\u201d.<\/li>\n<\/ol>\n<p>\u201cKies er \u00e9\u00e9n. Schrijf het op de policy page. Koop dan de hardware, als het al nodig is.\u201d<\/p>\n<h3>Zoek het uit voordat je geld uitgeeft<\/h3>\n<ol>\n<li><strong>Draai de benchmark op wat je al hebt.<\/strong><\/li>\n<li><strong>Gebruik een week lang een lokaal model.<\/strong><\/li>\n<li><strong>Schrijf de policy page.<\/strong><\/li>\n<\/ol>\n<p>\u201cKoop niets eerst. Huur, of draai wat je hebt.\u201d Draai ook je eigen <strong>evaluations<\/strong>, niet alleen op snelheid: bekijk de antwoorden en beoordeel of ze bij je behoeften passen.<\/p>\n<p><!-- hybrid-ai-platform --><\/p>\n<h2 id=\"hybrid-ai-platform\">Building a hybrid AI platform for agent-heavy engineering<\/h2>\n<p><em>Willem Meints &#8211; woensdag 14:30\u201315:30<\/em><\/p>\n<p>Willem Meints, chief AI architect bij Info Support, nam het publiek mee door het platform dat Info Support de afgelopen zes maanden bouwde: een <strong>hybrid AI platform met focus op software engineering<\/strong>. Het was volgens Willem \u201cgeen cloudtalk\u201d: ze gebruiken er geen cloud of Microsoft-technologie meer voor. Het project kostte <strong>vier teams ongeveer zes maanden<\/strong>, van netwerken, via het kopen van GPU\u2019s (\u201ceen heel interessant verhaal\u201d) en het bouwen van een AI gateway, tot uitzoeken wat er nodig is om software te bouwen met agents op open-sourcemodellen. Willem zei dat ze er \u201cdrie of vier dagen\u201d over kunnen praten en \u00e9\u00e9n uur hadden. Een handopsteking liet zien dat maar \u00e9\u00e9n persoon in de zaal geen AI gebruikt op het werk.<\/p>\n<h3>Waarom agentic engineering, en wat daarvoor nodig is<\/h3>\n<p>Info Support heeft flink ge\u00efnvesteerd in agentic engineering. Omdat code zo snel wordt gegenereerd, innoveren ze veel meer, bijvoorbeeld met <strong>rapid prototypes<\/strong>: in plaats van met een klant te discussi\u00ebren over abstracte requirements kun je in twee of drie uur \u201claten zien wat je bedoelt\u201d (niet voor productie).<\/p>\n<p>Maar \u201chet is niet zo makkelijk als het klinkt\u201d:<\/p>\n<ul>\n<li><strong>Al het andere moet ook werken.<\/strong> Willem vertelde over een PostNL-applicatie waar features in minuten in plaats van dagen werden gebouwd, maar die na drie maanden vastliep omdat kwaliteit, continuous delivery en de oude werkwijzen waren losgelaten in de veronderstelling dat AI ze overbodig maakt.<\/li>\n<li><strong>Architectuur en het documenteren van specificaties zijn belangrijker dan ooit.<\/strong> \u201cAI maakt alles keer vijf: wat goed gaat, gaat vijf keer zo goed, en wat waardeloos was, wordt vijf keer zo erg.\u201d<\/li>\n<li><strong>Het doel is niet sneller bouwen, maar beter bouwen en het juiste bouwen.<\/strong> Het begin van de pipeline (het juiste idee vinden) en het einde (adoptie; een postbode wil geen app die elk uur verandert) zijn dun, en het middenstuk (code) is groot. \u201cAlles wat je niet hoeft te bouwen kost je geen tokens, veroorzaakt geen problemen en is uiteindelijk goedkoper.\u201d<\/li>\n<\/ul>\n<p>De tweede drijfveer is de verschuiving <strong>van how naar what<\/strong>: code en implementatiedetails worden steeds vaker door agents gegenereerd, terwijl engineers het verschil maken bij doelen, requirements en design. \u201cEngineering gaat over het ontwerp, niet over de code.\u201d Je moet nog steeds controleren wat de agents opleveren. Ze zien een beweging richting declaratieve, intent-driven software.<\/p>\n<h3>De agentic software factory<\/h3>\n<p>Info Support noemt de hele stack de <strong>agentic software factory<\/strong>, al hoeft het geen fabriek te zijn: je kunt nog gewoon op je laptop ontwikkelen in VS Code of IntelliJ en veel onderdelen zijn optioneel. De lagen, volgens de slide: een <strong>AI marketplace<\/strong> (agents, skills, instructions, hooks, scripts), de <strong>agent harness<\/strong>, de <strong>AI gateway<\/strong>, <strong>autonomous agentic engineering<\/strong>, <strong>frontier inferencing<\/strong> (Anthropic, OpenAI), <strong>local inferencing<\/strong> en cross-cutting concerns.<\/p>\n<h4>Laag 1: de basis<\/h4>\n<p>Consultants hebben verstandige toegang nodig tot AI-modellen en <strong>elk gebruik moet doorbelast kunnen worden aan de klant<\/strong>. Eerst weigerden klanten AI op hun projecten, daarna stonden ze het toe, en toen werd de vraag wie de tokens betaalde: \u201cWij, en dat is slecht nieuws, want je maakt hetzelfde aantal uren en geeft daarbovenop tokens uit. Het wordt niet goedkoper, het wordt duurder.\u201d Iedereen een licentie geven lost het bijhouden van kosten niet op, en geeft ook geen controle over risicovolle features zoals niet-gecontroleerde custom skills.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_144142_d_e_kl.jpg\" loading=\"lazy\" alt=\"Building a Hybrid AI Platform for Agent-Heavy Engineering - Willem Meints\"><\/p>\n<p>Daarom bouwden ze een centrale <strong>AI gateway<\/strong> die het volgende regelt:<\/p>\n<ul>\n<li><strong>Billing en usage metrics.<\/strong><\/li>\n<li><strong>PII-filtering<\/strong> (met een standaardservice): mensen sturen nog steeds weleens hun eigen e-mailadres of onvoldoende geanonimiseerde testdata naar een model.<\/li>\n<li><strong>Safeguards op toegang tot modellen<\/strong>, plus gestandaardiseerde skills en agents.<\/li>\n<\/ul>\n<p>Twee componenten, beide intern (\u201csource\u201d): de <strong>agent marketplace<\/strong>, een repository die nu gevoed wordt door zo\u2019n <strong>200 collega\u2019s<\/strong> die skills, agents, scripts en hooks delen voor tools als Claude Code en GitHub Copilot, en <strong>Turnstile<\/strong>, de AI gateway. De marketplace wordt onderhouden via inner-sourcing, omdat \u201cskills en agents constant meebewegen met je software\u201d: je kunt een standaardset van GitHub pakken, maar je gaat die toch aanpassen, dus kozen ze ervoor standaardisatie niet af te dwingen. De gateway wordt onderhouden door het platformteam.<\/p>\n<p><strong>Build or buy?<\/strong> Willem raadt <strong>Azure AI Foundry<\/strong> aan voor bedrijven op Azure: het routeert modellen goed, biedt OpenAI- en Anthropic-modellen, kan in Europa of de VS hosten en ondersteunt zelfs open modellen. \u201cHet is best moeilijk om een AI gateway te bouwen, zelfs met AI.\u201d Ze bouwden zelf om twee redenen:<\/p>\n<ol>\n<li><strong>Klanten die geen data in de cloud willen<\/strong>, maar in het eigen datacenter van Info Support (bijvoorbeeld defensie, of marineschepen).<\/li>\n<li><strong>Meerdere vendors<\/strong>, lokaal en in de cloud, zodat ze weg kunnen uit de cloud als \u201ceen of andere Amerikaanse president besluit de stekker eruit te trekken\u201d.<\/li>\n<\/ol>\n<h3>Hoe de gateway werkt<\/h3>\n<p>De gateway is een <strong>middleware pipeline<\/strong> (zoals ASP.NET middleware; een library als YARP zou dit kunnen) en het pad van een request is: client, <strong>virtual key validator<\/strong> (valideert de key van de client en vervangt die door de echte API key van de provider), reverse proxy handler, capture filter, LLM provider.<\/p>\n<p><strong>Doel:<\/strong> volledig source-compatible zijn met wat OpenAI en Anthropic morgen ook doen, zodat elke agent werkt. Dat betekent dat je de <strong>protocollen<\/strong> van beide vendors exact moet volgen (een uitdaging), want anders logt iemand de volgende ochtend in en kan die zijn werk niet doen. Buiten die twee zijn er geen andere LLM-protocollen: open-sourcemodellen spreken er een van. Providers worden geconfigureerd met een backend-URL en de echte API key.<\/p>\n<h4>Virtual API keys<\/h4>\n<p>Elke agent ondersteunt API keys (een zwak mechanisme, want met een gelekte key kan iedereen jouw geld uitgeven), dus geeft de gateway <strong>virtual keys<\/strong> uit:<\/p>\n<ul>\n<li>Ze kunnen worden <strong>ingetrokken<\/strong>.<\/li>\n<li>Elke key is <strong>gekoppeld aan een team of project<\/strong>, zodat kosten toegerekend kunnen worden.<\/li>\n<li>Voor een <strong>autonomous agent<\/strong> geeft de gateway een <strong>tijdelijke key uit voor de duur van \u00e9\u00e9n taak<\/strong> en gooit die daarna weg, zodat Info Support precies kan zien hoeveel tokens die taak verbrandde.<\/li>\n<li>OAuth 2 of andere protocollen zouden mogelijk zijn, maar Willem heeft nog geen agent gezien die ze ondersteunt. Zo\u2019n 99% van de coding agents (ook open-sourceagents) werkt.<\/li>\n<li><strong>Session recording:<\/strong> de gateway kan alle input en output tussen agent en model opslaan en tokens, totale tijd en time to first token rapporteren, handig om agents te optimaliseren. (Foundry kan dit niet, en heeft \u00e9\u00e9n API key per model die door alle projecten wordt gedeeld.)<\/li>\n<\/ul>\n<h4>Waarom Go, en hoe usage tracking werkt<\/h4>\n<p>Ze bouwden de gateway in <strong>Go<\/strong>, niet in C#, omdat YARP gebruiksvriendelijk is maar lastig te gebruiken op <strong>bytelevel<\/strong>, wat ze nodig hebben. De kern is de standaard reverse proxy uit de standard library van Go, met een rewrite-operatie voor requests en een modify-response-operatie voor responses.<\/p>\n<ul>\n<li><strong>Usage tracking:<\/strong> de JSON-response van de provider heeft een <code>usage<\/code>-sectie met tokenaantallen (hier komen de usage-balken in VS Code vandaan). OpenAI geeft geen usage terug tenzij erom gevraagd wordt, dus de gateway <strong>zet de flag voor je aan<\/strong> en verbergt de usage voor de client als die er niet om vroeg (\u201cwe liegen tegen je\u201d).<\/li>\n<li><strong>Streaming (server-sent events):<\/strong> het typeeffect in tools als Copilot is de streaming response, token voor token, als een <code>text\/event-stream<\/code> met <code>event:<\/code>&#8211; en <code>data:<\/code>-regels. Bij streaming requests onderschept het capture filter elk event, haalt er alleen de usage uit en stuurt het event direct door (\u201cevent komt binnen, doorsturen, dan verwerken\u201d), zodat er niets gebufferd wordt en de client niet ineens een muur van tekst ziet binnenkomen. Usage tracking loopt daardoor iets achter.<\/li>\n<li><strong>Valkuil: gzip.<\/strong> Anthropic comprimeert request- en response-streams. Willems eerste versie leverde onzin op in de pipeline totdat ze doorhadden dat de events gedecomprimeerd, verwerkt en weer gecomprimeerd moesten worden.<\/li>\n<\/ul>\n<p>Willems advies: <strong>bouw geen eigen gateway tenzij je deze dingen nodig hebt.<\/strong> Als je alleen centrale toegang tot modellen nodig hebt (en op Azure zit), gebruik dan een bestaand product: \u201chet is een gigantische koppijn\u201d.<\/p>\n<h3>Waarom een gateway: de cijfers<\/h3>\n<p>Drie problemen, volgens de slide:<\/p>\n<ol>\n<li><strong>Kosten waren onzichtbaar:<\/strong> geen idee wat een project kost en geen manier om de klant te factureren.<\/li>\n<li><strong>Elk team had een eigen setup:<\/strong> geen controle over welke data waarheen gaat, en cloudproviders mogen niet altijd gebruikt worden.<\/li>\n<li><strong>Vastzitten aan \u00e9\u00e9n vendor:<\/strong> een risico voor resilience en kosten dat je moet beheersen voor <strong>DORA<\/strong>.<\/li>\n<\/ol>\n<p>Onderzoek van Info Support (2026) voegt toe: <strong>44%<\/strong> van de organisaties zegt dat medewerkers op eigen initiatief met AI-tools werken, bij <strong>8%<\/strong> is AI governance formeel verankerd in development en <strong>31%<\/strong> monitort AI agents actief met logging en audits. Willem zei dat ongeveer 44% van de medewerkers een eigen priv\u00e9abonnement voor werk gebruikt (een cijfer voor de hele Nederlandse markt; bij Info Support lager, maar het komt voor, bijvoorbeeld wanneer marketing animaties wil genereren met een Claude-feature die Claude Code vereist, wat ze niet mogen gebruiken).<\/p>\n<h4>Geen quota&#8217;s, wel alerts<\/h4>\n<p>Info Support besloot <strong>geen quota\u2019s te gebruiken<\/strong>: ze volgen en meten, maar stoppen niemand, \u201cals je 10 dollar meer uitgeeft maakt het me niet uit, als het 5.000 euro is voeren we een gesprek\u201d. Dat komt voort uit ervaring: tijdens het testen van de gateway op Azure Foundry waren de quota\u2019s meegegroeid met de uitgaven (van 60.000 tokens per minuut naar een miljoen naar 100 miljoen per minuut), liep een agent 45 minuten door en kreeg Willem een <strong>rekening van 12.000 euro<\/strong> en \u201ceen mooi gesprek met een directeur\u201d. Nu zijn er <strong>alerts<\/strong> (bijvoorbeeld een waarschuwing als de uitgaven boven 500 euro komen: \u201crem af, ga je agent controleren\u201d), en ze loggen en monitoren AI-gebruik en hebben detectors voor verdacht gedrag.<\/p>\n<p>(Om een idee van de schaal te geven: Willem zei dat het bouwen van de gateway zelf ongeveer 1,8 miljard tokens kostte, grofweg 18.000 euro tegen per-tokenprijzen, op een Claude Max-abonnement.)<\/p>\n<h3>Laag 2: autonomous agents<\/h3>\n<p>In april dit jaar kwamen agentic teams in de tooling: \u00e9\u00e9n taak uitgevoerd door veel agents parallel (requirements engineer, architect, coding agent, test agent, meerdere reviewers). Het is <strong>duur<\/strong> en versnelde de beweging <strong>van how naar what<\/strong>: eerst een specificatie schrijven (met of zonder AI), die aan een stel agents geven en een pull request terugkrijgen.<\/p>\n<p><strong>Probleem:<\/strong> agents die op laptops draaien stoppen als de laptop in slaap valt. Willem zag collega\u2019s een 3D-geprinte hand in het laptopscherm klemmen en tools gebruiken om Macs wakker te houden. Het beveiligingsbeleid van Info Support vergrendelt laptops na 20 minuten, dus mensen omzeilden de beveiligingsmaatregelen. Dat leidde tot <strong>autonomous agents<\/strong> (intern \u201cdark factories\u201d genoemd, wat Willem niet mooi vindt vanwege de \u201ckwade\u201d connotatie). Het is \u201cnog steeds zeer experimenteel\u201d.<\/p>\n<h4>De orchestrator<\/h4>\n<ul>\n<li>Een <strong>agent orchestrator op Kubernetes<\/strong>, draaiend in het eigen datacenter van Info Support, is gekoppeld aan een <strong>issue management system<\/strong> (GitHub, GitLab of Azure DevOps). Je wijst een work item toe aan een agent, die voert het uit en stelt een pull request voor.<\/li>\n<li>Soorten agents: bijvoorbeeld een <strong>requirements engineer<\/strong> (breidt je spec uit tot een volledig gespecificeerd werkdocument: codewijzigingen, tests, architectuurregels, risico\u2019s), een <strong>architect agent<\/strong>, backend- en frontend-engineer-agents, QA, ops. Agents kunnen aan elkaar <strong>overdragen<\/strong> om dynamische workflows te bouwen, met beslismomenten waarop werk terug naar een mens gaat.<\/li>\n<li>Het draait op <strong>KEDA<\/strong>, dat agents terugschaalt naar nul als ze niets doen (en er een opstart zodra er iets in de backlog verschijnt), omdat sommige agents de hele dag bezig zijn en andere zelden.<\/li>\n<li>Elke agent is <strong>gewoon een container met Claude Code<\/strong>, dus de enige custom code is de orchestratielogica.<\/li>\n<li>Deployment gaat met <strong>Argo CD<\/strong>: een agentdefinitie als <strong>markdownbestand in Git<\/strong> (onder <code>.claude\/agents\/<\/code>) wordt een object in het Kubernetes-cluster, gekoppeld aan Azure DevOps of wat er ook gebruikt wordt. Een falende agent kan worden gedood en Argo CD deployt hem opnieuw.<\/li>\n<\/ul>\n<p>Op dit moment gebruiken <strong>zes teams<\/strong> dit bij ongeveer <strong>50 klanten<\/strong>. De agents pakken dependency-problemen, vulnerability scans en de bijbehorende patches op, nieuwe features, bugfixes en reviews. \u201cEn wij doen alleen nog review, review, review.\u201d Dat is een uitdaging.<\/p>\n<h4>Work items als interface<\/h4>\n<ul>\n<li>Je voegt een tag als <code>agent:&lt;name&gt;<\/code> toe aan een work item. Ze kozen voor <strong>tags<\/strong> in plaats van het aanpassen van het Azure DevOps-proces-template (wat upgrades \u201ceen nachtmerrie\u201d maakt), en tags bestaan ook in GitHub en GitLab, dus hetzelfde procesmodel werkt bij alle providers.<\/li>\n<li>De <strong>beschrijving van het work item is de prompt van de agent<\/strong>.<\/li>\n<li>Als een agent het oppakt, voegt die een <code>agent::working<\/code>-tag toe, een soort <strong>distributed lock<\/strong> zodat twee agents niet hetzelfde item pakken (\u201cmisschien iets wat we moeten fixen, maar tot nu toe gaat het prima\u201d).<\/li>\n<li>De agent plaatst comments, waardoor het <strong>werk volledig traceerbaar<\/strong> is. Transcripts worden opgeslagen en alle modelinteracties lopen via de gateway. De agent kan ook aandachtspunten plaatsen, bijvoorbeeld dat die iets anders deed dan gespecificeerd.<\/li>\n<li><strong>QA-loop:<\/strong> de ene agent implementeert, een andere reviewt, bevindingen gaan terug voor fixes, en dit kan hooguit <strong>drie keer<\/strong> herhaald worden. Daarna is het \u201ceen verspilling van tokens\u201d: de agent-tags worden verwijderd en het item gaat naar <strong>human verify<\/strong>. Afgerond of mislukt werk gaat ook naar human verify, met extra informatie als het mislukt is.<\/li>\n<\/ul>\n<h4>Welke modellen?<\/h4>\n<p>Zowel open als frontier. Voor <strong>planning<\/strong> gebruiken ze Anthropic-modellen (het nieuwste, Opus 5.5), voor <strong>implementatie<\/strong> open-sourcemodellen: \u201ceen stuk sneller en supergoedkoop\u201d. Bij lange, complexe taken zijn frontiermodellen stabieler, omdat open modellen de neiging hebben om <strong>af te dwalen van het doel<\/strong> en in de war te raken van wat er in hun context window staat. Ze testten Fable en GPT-6 (de grootste modellen) en vonden dat die in deze setting <strong>geen meerwaarde<\/strong> hebben, behalve voor securitytaken. Een tip: vraag om een <strong>\u201cdefensive security review\u201d<\/strong>, want bij de kale formulering \u201csecurity review\u201d zakt Fable 5 terug naar een ouder model of weigert het; expliciet zijn over defensieve intentie (\u201cik wil mijn huiswerk controleren\u201d) activeert het wel goed.<\/p>\n<h3>Laag 3: local inferencing<\/h3>\n<p>Tot nu toe liep alles tegen de API\u2019s van OpenAI en Anthropic, maar Info Support bouwt ook <strong>local inferencing<\/strong>, de onderste laag. \u201cIn januari begonnen we na te denken over wat er gebeurt als Mr. Orange Carrot de stekker eruit trekt\u201d (een grappige verwijzing naar het Amerikaanse politieke risico voor toegang tot modellen), dus besloten ze eigen hardware aan te schaffen: \u201choe moeilijk kan het zijn? Famous last words.\u201d<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_151549_d_1_e_kl.jpg\" loading=\"lazy\" alt=\"Building a Hybrid AI Platform for Agent-Heavy Engineering - Willem Meints\"><\/p>\n<p><strong>De hardware:<\/strong> twee servers (ongeveer 17 kg per stuk, \u201cals je twee servers koopt, kun je ook een huis kopen\u201d), <strong>8 GPU\u2019s per server, 16 GPU\u2019s in totaal, 96 GB per GPU<\/strong>, met 96 amp\u00e8re aan stroom erdoorheen. Vier GPU\u2019s in productie kunnen al de helft van Info Support bedienen, met er nog twaalf vrij.<\/p>\n<p><strong>Economie:<\/strong> alleen de stroom kost ongeveer <strong>12.000 euro per maand<\/strong>, en de hardware is een vast bedrag in plaats van per-tokenprijzen, dus \u201chet rekent uit\u201d. Een veelzeggende anekdote: iemand schakelde tijdens het testen per ongeluk de <strong>planning agents<\/strong> van een frontiermodel over naar een open-sourcemodel, <strong>en niemand merkte het<\/strong>. De kwaliteit was hetzelfde.<\/p>\n<h4>Hoe het gehost wordt<\/h4>\n<ul>\n<li><strong>vLLM<\/strong> (een Python-applicatie, \u201cvan binnen absolute rommel, maar het doet zijn werk\u201d): host het model, zet requests om in de getallen die het model nodig heeft en weer terug in een response, en stelt een HTTP-endpoint beschikbaar. Nu \u00e9\u00e9n instance, met vier of acht mogelijk.<\/li>\n<li><strong>Kubernetes<\/strong> host vLLM als container, met meerdere modellen en <strong>failover<\/strong>.<\/li>\n<li>De <strong>NVIDIA GPU Operator<\/strong> stelt GPU\u2019s beschikbaar aan Kubernetes. Ze gebruiken <strong>time slicing<\/strong> (applicaties nemen om de beurt een GPU): de goedkoopste optie, \u201cgeen security boundary\u201d. Het past bij een LLM dat 24\/7 draait en vol zit met requests. Wil je echte partitionering en isolatie (slicing and dicing), dan rekent NVIDIA <strong>een aparte licentie \u201czo duur als je videokaarten\u201d<\/strong>, waar niemand je iets over vertelt. Zij hebben het niet nodig.<\/li>\n<\/ul>\n<h4>Waarom de gateway geen stateless proxy is: de KV cache<\/h4>\n<p>LLM\u2019s hebben geen \u201cchat\u201d, alleen een reeks tokens erin en tokens eruit: er wordt \u00e9\u00e9n token voorspeld, aan de input toegevoegd (inclusief de oorspronkelijke prompt), dan het volgende, enzovoort. Met 500.000 tokens in het window betekent elk nieuw token dat ze allemaal opnieuw verwerkt moeten worden, en daarom zakt de performance. Een typisch open model heeft <strong>30 miljard berekeningen per token<\/strong> nodig. De oplossing is de <strong>KV cache<\/strong>: de outputs van transformer-lagen cachen zodat genereren een lookup wordt. \u201cDeze cache is de sleutel tot snelheid\u201d: ongeveer <strong>100 tokens per seconde zonder en 5.000 m\u00e9t<\/strong> op hun eigen hardware (op vier GPU\u2019s, \u201cdat haal je niet op Azure, dat alle GPU\u2019s met iedereen deelt\u201d).<\/p>\n<p>Op een GPU van 96 GB nemen de modelgewichten grofweg de eerste 24 GB in beslag en <strong>de rest is cache<\/strong>. De hoeveelheid cache bepaalt <strong>hoeveel developers parallel kunnen werken<\/strong>. Grotere context windows en meer developers vragen meer cache, dus begrenst Info Support context windows op <strong>128.000 tokens<\/strong>.<\/p>\n<p>Het grootste deel van de optimalisatietijd gaat naar:<\/p>\n<ul>\n<li><strong>Latency<\/strong> (de tijd tot het eerste token),<\/li>\n<li><strong>Snelheid<\/strong> (gegenereerde tokens per minuut),<\/li>\n<li><strong>De cache niet kapotmaken.<\/strong><\/li>\n<\/ul>\n<p>Omdat de cache van een sessie op \u00e9\u00e9n GPU leeft, doet de gateway <strong>KV-cache-aware routing<\/strong>: die herkent een sessie die hij eerder zag en stuurt hem naar dezelfde server. Anders \u201cbetaalt\u201d die persoon de prijs van een koude cache en houdt de andere server een nutteloze cache vast die ruimte inneemt. Daarom kostte het zes maanden om dit goed te krijgen.<\/p>\n<h3>Q&amp;A<\/h3>\n<ul>\n<li><strong>Wie gebruikt het platform?<\/strong> Iedereen heeft nog steeds een licentie. Ongeveer zes teams gebruiken het, waaronder de afdeling managed services en \u00e9\u00e9n klantteam, samen zo\u2019n <strong>40 mensen<\/strong>. Tot nu toe wordt het gebruikt voor interne ontwikkeling, met \u00e9\u00e9n extern klantteam, en het wordt aan klanten aangeboden.<\/li>\n<li><strong>Favoriete open modellen?<\/strong> <strong>Qwen 3.8<\/strong> is erg goed voor coding (volgens Willem vergelijkbaar met Opus 5), maar niet voor Nederlands, omdat het willekeurig Chinese tekens tussendoor gooit. Het heeft ook <strong>censuur<\/strong> ingebouwd: het antwoordt anders op onderwerpen waar de Chinese overheid een mening over heeft, wat voor code niet uitmaakt. Het model draait in het datacenter van Info Support achter een firewall op uitgaande verbindingen en ze hebben nog nooit een verbinding naar China gezien (\u201chet is een bak floating points\u201d). DeepSeek is ook goed in coding, met dezelfde kanttekeningen. Ze kijken naar <strong>Mistral<\/strong>, dat open weights publiceert, en hopen op een groter nieuw model. Voor Nederlandse ondersteuning wees Willem op modellen van Google of Microsoft, die beter zijn in tekst dan in coding. Info Support overweegt ook om collega\u2019s modellen te laten indienen om te draaien.<\/li>\n<li><strong>Fine-tuning?<\/strong> Bewust niet gedaan: het is duur en je hebt veel meer dan 10 tot 12 GB aan voorbeelddata nodig om te beginnen.<\/li>\n<\/ul>\n<p><!-- verify-me --><\/p>\n<h2 id=\"verify-me\">From &#8220;Trust Me&#8221; to &#8220;Verify Me&#8221;: verifiable trust in the software supply chain<\/h2>\n<p><em>Tom van den Berg &#8211; woensdag 16:00\u201317:00<\/em><\/p>\n<p>Tom van den Berg is lead platform engineer bij Info Support en werkt via Info Support voor de Nederlandse Spoorwegen aan het mission-critical deel van het platform. Hun talk, de laatste sessie van Techorama, ging over <strong>verifieerbaar vertrouwen tussen producenten en consumenten<\/strong> van software. De kernzin, op de eerste slide: <em>\u201cEchte supply chain security bestaat pas als consumenten de claims van de producent zelfstandig kunnen verifi\u00ebren.\u201d<\/em> De sessie behandelt beide kanten: wat een producent kan doen om verifieerbare claims te maken en wat een consument kan doen om ze te controleren.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_160326_d_e_kl.jpg\" loading=\"lazy\" alt=\"From &quot;Trust Me&quot; to &quot;Verify Me&quot; - Tom van den Berg\"><\/p>\n<h3>Waarom supply chain security<\/h3>\n<p>Tom opende met geschiedenis:<\/p>\n<ul>\n<li><strong>SolarWinds<\/strong> (2020): een van de eerste publiek gedocumenteerde supply chain-aanvallen op de Amerikaanse overheid. Een backdoor in software die een leverancier uitbracht, werd gebruikt om de klanten aan te vallen. \u201cToen begon de hele wereld ernaar te kijken: wij zijn misschien niet meer het doelwit, maar ze richten zich op onze dependencies.\u201d<\/li>\n<li><strong>Shai-Hulud<\/strong> (eerder in 2026): een worm in NPM die credentials steelt. Wie een ge\u00efnfecteerd package installeerde, kreeg side effects die sleutels en secrets naar een externe locatie wegsluisden.<\/li>\n<\/ul>\n<p>Het punt: <strong>aanvallers verplaatsen zich<\/strong> van het rechtstreeks aanvallen van je firewall of systeem naar alles wat je van derden binnenhaalt: code die je niet zelf schreef en waarvan je de inhoud niet kent. \u201cWe hebben veel software draaien in productie die niemand van ons ooit gezien heeft, maar we hebben genoeg vertrouwen om het te deployen.\u201d<\/p>\n<p>Toms eigen omgeving maakt dit concreet: op hun platform draaien ze tooling van derden zoals <strong>cert-manager<\/strong>, de <strong>External Secrets Operator<\/strong> en <strong>Envoy<\/strong>, allemaal met gevoelige data, \u201cop naam van de uitgever\u201d. Een naam is niet meer genoeg: ze noemden een maintainer van de Linux-kernel die kwade bedoelingen had. Een onderzoeker die Tom citeerde stelt dat ongeveer <strong>80%<\/strong> van de software in productie van iemand anders is, dus je kent alleen de 20% die je zelf schreef.<\/p>\n<h3>Artifact signing<\/h3>\n<p><strong>Artifact signing<\/strong> betekent dat je een artifact in een registry (een OCI-registry) neemt, met een private key en een tool een signature maakt en die signature naast het artifact opslaat.<\/p>\n<h4>Sign the digest, not the tag<\/h4>\n<p>Je kunt een artifact op twee manieren aanwijzen:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_160746_d_e_kl.jpg\" loading=\"lazy\" alt=\"From &quot;Trust Me&quot; to &quot;Verify Me&quot; - Tom van den Berg\"><\/p>\n<ul>\n<li><strong>Via tag<\/strong> (<code>1.0.0<\/code>, <code>latest<\/code>, <code>stable<\/code>): leesbaar voor mensen en passend bij releaseprocessen, maar <strong>tags zijn mutable<\/strong>: je kunt een ander artifact met andere inhoud opnieuw taggen en de tag identificeert de inhoud niet uniek.<\/li>\n<li><strong>Via digest<\/strong>: je gaat van \u201cik vertrouw wat er op dit moment achter deze tag zit\u201d naar <strong>\u201cik vertrouw deze exacte inhoud\u201d<\/strong>. Een digest kan niet naar iets anders wijzen en is reproduceerbaar: verandert de inhoud, dan verandert de digest en geldt de signature niet meer.<\/li>\n<\/ul>\n<p>Je hebt een artifact, een signature, een certificaat en een <strong>system of record<\/strong> nodig dat bewijst dat het signen heeft plaatsgevonden.<\/p>\n<h4>Demo 1: signen met Cosign en Sigstore<\/h4>\n<p>Tom pushte een image naar <strong>Azure Container Registry<\/strong> (met de tag <code>latest<\/code>, \u201cvoor de demo, doe dit alsjeblieft niet\u201d), noteerde de digest en signde die:<\/p>\n<ul>\n<li><code>cosign sign &lt;registry&gt;\/crafted-specially@sha256:...<\/code> waarschuwde dat dit op een private repository lijkt en vroeg om te bevestigen dat er ge\u00fcpload wordt naar het <strong>Rekor transparency log<\/strong>, een publiek system of record (\u201cprima voor een demo, voor private resources wil je misschien geen publiek log\u201d).<\/li>\n<li>Cosign genereerde <strong>ephemeral keys<\/strong> en vroeg Tom om bij Sigstore in te loggen met een identity provider (GitHub, Google of Microsoft). Tom koos GitHub: er werd een certificaat voor die identiteit uitgegeven, waarmee de digest werd gesigned.<\/li>\n<\/ul>\n<p>Daarna toont de registry een <strong>Sigstore bundle<\/strong> die als referrer aan de image hangt. \u201cDit is pas de eerste stap om je artifacts veilig te maken.\u201d<\/p>\n<h3>Waarom signen alleen niet genoeg is: twee aanvallen<\/h3>\n<h4>Stale branch attacks<\/h4>\n<p>Je main branch heeft alle beveiligingen (verplichte reviews, geen directe pushes), maar een oude <strong>proof-of-concept- of experiment-branch<\/strong> misschien niet. Aanvallers kunnen er rechtstreeks naar pushen, pipelines triggeren, een oude kwetsbaarheid misbruiken of <strong>eerdere approvals hergebruiken<\/strong>. Zulke verlaten, niet-gemonitorde Git-branches worden gebruikt om security checks te omzeilen, kwaadaardige workflows uit te voeren of toegang te krijgen tot gecompromitteerde credentials.<\/p>\n<h4>De confused deputy: Dependabot<\/h4>\n<p>Een <strong>confused deputy<\/strong> is een vertrouwde partij die door een aanvaller wordt gemanipuleerd tot een onbedoelde actie. Het voorbeeld: het commando <code>@dependabot recreate<\/code> van Dependabot maakt een pull request opnieuw aan, <strong>en de auteur wordt Dependabot<\/strong>. Stel je een repo voor die patch-updates van Dependabot automatisch merget als de pipeline groen is. Een kwaadwillende forkt de repo, injecteert kwaadaardige code in de fork, opent een PR (die niet automatisch gemerget wordt omdat de auteur niet Dependabot is) en vraagt Dependabot dan om die opnieuw aan te maken. De auteur is nu Dependabot, dus de auto-merge-regel kan van toepassing zijn, waardoor code uit een fork in de main repo terechtkomt. (Tom merkte op dat er wat extra context nodig is om dit te laten werken, maar \u201cmensen doen dit soort auto-merge wel\u201d.)<\/p>\n<h3>SLSA: vertrouwen standaardiseren<\/h3>\n<p><strong>SLSA<\/strong> (Supply-chain Levels for Software Artifacts) is geen tool of techniek, maar een <strong>vocabulaire, een set richtlijnen en een checklist<\/strong> voor producenten en consumenten. Er zijn twee tracks: de <strong>source track<\/strong> (waar en hoe code wordt opgeslagen en geconfigureerd) en de <strong>build track<\/strong> (hoe artifacts worden gebouwd en gebruikt). De talk richt zich op de build track.<\/p>\n<p>Twee partijen produceren een artifact: de <strong>producent<\/strong> (jij) en het <strong>build platform<\/strong>. De producent hoort een passend build platform te kiezen, een consistent buildproces te volgen en provenance te distribueren. Het build platform bepaalt vervolgens het level:<\/p>\n<table>\n<tr>\n<th>Level<\/th>\n<th>Provenance generation<\/th>\n<th>Isolation<\/th>\n<\/tr>\n<tr>\n<td>L1<\/td>\n<td>Exists<\/td>\n<td>Hosted<\/td>\n<\/tr>\n<tr>\n<td>L2<\/td>\n<td>Authentic<\/td>\n<td>Hosted<\/td>\n<\/tr>\n<tr>\n<td>L3<\/td>\n<td>Unforgeable<\/td>\n<td>Isolated<\/td>\n<\/tr>\n<\/table>\n<p>Tom zei dat Azure DevOps standaard alleen <strong>SLSA level 1<\/strong> haalt, omdat het platform geen provenance genereert die authentiek en niet te vervalsen is (je kunt er zelf een bouwen, zoals een proof-of-concept provenance generator voor Azure DevOps, maar het platform levert die niet).<\/p>\n<h4>Build provenance en attestations<\/h4>\n<p><strong>Build provenance<\/strong> is \u201cverifieerbare informatie over software-artifacts die beschrijft waar, wanneer en hoe iets is geproduceerd\u201d.<\/p>\n<p>Het bevat het <strong>build type<\/strong> (bijvoorbeeld welke runner), <strong>internal parameters<\/strong> (door het platform gezet), <strong>external parameters<\/strong> (door de producent meegegeven), <strong>resolved dependencies<\/strong> en de <strong>output<\/strong> (het subject, dat naar de digest van het artifact wijst).<\/p>\n<p>Een <strong>attestation<\/strong> is een geauthenticeerde verklaring (metadata) over een of meer artifacts. Ze bestaat uit een <strong>subject<\/strong>, een <strong>predicate<\/strong> (wat voor soort verklaring: bijvoorbeeld een SBOM of build provenance) en een <strong>envelope<\/strong> met een digitale signature. Attestations kunnen gebundeld worden. Meestal gebruiken ze de <strong>in-toto<\/strong>-specificatie.<\/p>\n<h4>Demo 2: een signature verifi\u00ebren<\/h4>\n<p>Tom downloadde de signature (via de referrers index) en las daaruit de <strong>OIDC issuer<\/strong> (GitHub) en het e-mailadres van de ondertekenaar met een script dat Rekor bevraagt.<\/p>\n<p><code>cosign verify<\/code> controleert vervolgens de signature tegen een <strong>verwachte certificate identity en OIDC issuer<\/strong>. Toen Tom bewust de verkeerde identity opgaf, <strong>faalde<\/strong> het (\u201cno matching certificate identity found\u201d).<\/p>\n<h4>OCI artifacts en referrers<\/h4>\n<p><strong>OCI<\/strong> (Open Container Initiative) artifacts bestaan uit een <strong>manifest<\/strong>, <strong>blobs<\/strong> (zoals image layers), een <strong>digest<\/strong> en een <strong>media type<\/strong>.<\/p>\n<p>Het sleutelconcept is <strong>referrers<\/strong>: een cryptografisch gekoppelde verwijzing naar een ander artifact, dat zelf ook ieder OCI-artifact kan zijn. Een signature, een SBOM en een provenance attestation kunnen dus allemaal naar dezelfde image wijzen, waardoor een boom van bewijs ontstaat.<\/p>\n<p>Omdat een registry een OCI-registry is, ben je niet beperkt tot Docker-images: met <strong>ORAS<\/strong> kun je ook andere bestandstypes (markdown, Terraform-modules, machine-learningmodellen) als OCI-artifact pushen, ze daarna signen en er attestations aan toevoegen.<\/p>\n<p>Tom demonstreerde dit met een simpel markdownbestand (\u201cHello, Techorama\u201d), gepusht met \u00e9\u00e9n <code>oras push<\/code>-commando, dat daarna net als een image gesigned kan worden.<\/p>\n<p>Hetzelfde idee is belangrijk voor <strong>skills van AI-agents<\/strong>. Tom vroeg hoeveel mensen de inhoud controleren van custom skills die ze uit marketplaces installeren (een of twee handen) en citeerde onderzoek dat zegt dat ongeveer <strong>26% van de skills<\/strong> beveiligingslekken heeft, zoals kwaadaardige injecties. \u201cEr is een grote use case voor verifieerbaar bewijs voor agent skills.\u201d<\/p>\n<p>In de live demo genereerde een <strong>GitHub Action<\/strong> build provenance, signde die en hing die aan de image, zodat de registry een tweede referrer (een tweede Sigstore bundle) naast de oorspronkelijke signature toonde.<\/p>\n<h3>De kant van de consument<\/h3>\n<p>\u201cBewijs genereren is maar de helft van het verhaal. Bewijs dat niemand controleert is slechts documentatie.\u201d SLSA beschrijft het perspectief van de consument in drie stappen:<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_163357_d_e_kl.jpg\" loading=\"lazy\" alt=\"From &quot;Trust Me&quot; to &quot;Verify Me&quot; - Tom van den Berg\"><\/p>\n<ol>\n<li><strong>Controleer het SLSA build level.<\/strong> Is een artifact niet op het door jou verwachte level gebouwd (idealiter level 3), gebruik het dan niet.<\/li>\n<li><strong>Controleer de verwachtingen:<\/strong> verifieer de claims van de producent (geen kwetsbaarheden, toegestane licenties, enzovoort).<\/li>\n<li><strong>Controleer de dependencies, recursief.<\/strong><\/li>\n<\/ol>\n<p>(De slide brengt ook de hele keten in kaart, van producent tot consument, van authoring en review tot packageselectie en gebruik.)<\/p>\n<p>De pragmatische CLI-variant: <code>gh attestation verify<\/code> op de image digest, waarbij je opgeeft uit welke <strong>repository<\/strong> het moet komen, de <strong>certificate identity<\/strong> (je verwachte workflow), de <strong>OIDC issuer<\/strong> (GitHub), het <strong>predicate type<\/strong> (bijvoorbeeld SLSA provenance v1 of een SPDX SBOM) en bijvoorbeeld dat het gebouwd is vanaf de <code>main<\/code>-branch, wat beschermt tegen de stale-branch- en confused-deputy-aanvallen. Uit het publiek kwam een vraag in dezelfde geest: attesten van SBOM&#8217;s, geen bekende kwetsbaarheden (bijvoorbeeld voor de EU Cyber Resilience Act) en licenties. Het antwoord: daar maak je ook attestations voor. (Tom verduidelijkte dat \u201cv1\u201d in het provenance predicate de <strong>versie van het provenance-formaat<\/strong> is (SLSA provenance heeft v1, v1.1, v1.2) en niet het securitylevel, dat in de attestation zelf wordt vastgelegd.)<\/p>\n<h4>Een kanttekening voor .NET: NuGet<\/h4>\n<p>Er staat een al lang openstaand NuGet-issue (sinds 2024): als je een package uploadt, <strong>past NuGet.org het aan<\/strong> (om de publisher- en repository-signature toe te voegen), waardoor de <strong>digest verandert<\/strong> en elk bewijs dat voor het originele package is gemaakt niet meer klopt. Vergelijk je het package uit je build artifact met het package dat je van NuGet downloadt, dan verschillen ze.<\/p>\n<h3>Hoe de Nederlandse Spoorwegen het doet<\/h3>\n<h4>Artifact promotion model<\/h4>\n<p>Het platformteam bouwt veel artifacts (Terraform-modules, pipeline steps en meer) die teams gebruiken. Elk artifact gaat door een \u201cwasstraat\u201d:<\/p>\n<ol>\n<li><strong>Build and attest:<\/strong> provenance en SBOM.<\/li>\n<li><strong>Verify (gate):<\/strong> signature, provenance, SBOM en trusted builder, inclusief security scanning, secret scanning en controles op kwetsbaarheden en licenties (bijvoorbeeld met <strong>Trivy<\/strong>). De uitkomsten van de tools worden aan het artifact geattesteerd.<\/li>\n<li><strong>Promote<\/strong> naar een trusted registry: het Mission Critical Platform-team \u201czet er een stempel op\u201d op basis van bewijs dat iedereen kan controleren.<\/li>\n<li><strong>Consume<\/strong> in de hele organisatie. Faalt een gate, dan wordt het artifact niet gepromoot.<\/li>\n<\/ol>\n<h4>Docker Hardened Images<\/h4>\n<p>Tom demonstreerde <strong>Docker Hardened Images<\/strong> (gratis te gebruiken, met betaalde enterprise-tiers en strengere SLA&#8217;s). Ze nemen een base image en hardenen die, met een lijst van packages, specificaties, bekende kwetsbaarheden en <strong>attestations<\/strong>.<\/p>\n<p>De genoemde attestation-types omvatten een <strong>CycloneDX SBOM<\/strong>, een changelog, image sources, <strong>CVE&#8217;s<\/strong>, <strong>VEX<\/strong> (vulnerability exploitability exchange), SLSA provenance, een secrets scan, tests en een virusscan. Met dezelfde verificatiemethode controleer je de claims van de publisher zelf en als je iets als RabbitMQ uit de hardened catalogus pullt, krijg je ook de <strong>licenties<\/strong> (die in jouw bedrijf misschien niet zijn toegestaan), anders dan bij een gewone pull van Docker Hub. De Nederlandse Spoorwegen kijkt naar een overstap naar hardened images.<\/p>\n<h4>Afdwingen bij deployment<\/h4>\n<p>Security vroeg om <strong>geautomatiseerd, verifieerbaar bewijs op deploymentmoment<\/strong> dat workloads compliant zijn. Ze implementeerden dat met <strong>Open Policy Agent<\/strong> en <strong>Gatekeeper<\/strong> op AKS (Azure Kubernetes Service). Gewone OPA kan alleen de gedeployde definities controleren, maar de <strong>external data provider<\/strong>-plugin en een <strong>artifact attestations OPA provider<\/strong> kunnen de attestations van een image in een externe registry opzoeken en gebruiken als <strong>input voor policies<\/strong> in Kubernetes <strong>admission control<\/strong>. Een policy kan bijvoorbeeld een deployment toestaan of weigeren op basis van de SBOM, licenties of kwetsbaarheden.<\/p>\n<p>In de praktijk dwingen ze workloadteams nu af hun <strong>images te signen<\/strong> en onderzoeken ze of die ook <strong>kunnen bewijzen dat er geen bekende kwetsbaarheden<\/strong> en geen niet-toegestane licenties zijn. \u201cSecurity wordt leuker: weg van Word-templates en screenshots, naar automatiseren.\u201d Security hoort geautomatiseerd, observeerbaar, verifieerbaar en developer-friendly te zijn.<\/p>\n<h3>Een waarschuwing: het is geen wondermiddel<\/h3>\n<p>Tom sloot af met een kanttekening. Volgens een onderzoeksnotitie van de Cloud Security Alliance over de Shai-Hulud-cascade \u201cMegalodon\u201d (gemeld op 25 mei 2026, met meer dan 5.500 ge\u00efnfecteerde GitHub-repositories) was de eerste golf (29 april tot 12 mei, Mini Shai-Hulud) de eerste publiek gedocumenteerde aanval die <strong>cryptografisch geldige SLSA Build Level 3 provenance attestations<\/strong> produceerde, door <strong>een legitieme buildpipeline<\/strong> en de bijbehorende credentials <strong>te kapen<\/strong>. Verificatie is dus \u201cgeen wondermiddel\u201d, maar <strong>een extra laag bovenop bestaande security<\/strong>. \u201cJe moet er nog steeds verdomd zeker van zijn dat wat je binnenhaalt het juiste spul is.\u201d<\/p>\n<p>Toms demo-repository staat op GitHub (<code>tom171296\/craftedspecially<\/code>)<\/p>\n<p><!-- fresh-perspective-brain --><\/p>\n<h2 id=\"fresh-perspective-brain\">A Fresh Perspective on Behaviour, Change and the Brain<\/h2>\n<p><em>Paul Smit &#8211; woensdag 17:15\u201318:15<\/em><\/p>\n<p>Paul Smit is spreker en neurowetenschappelijk onderzoeker aan de Universiteit Leiden en schreef meerdere boeken over het brein (ze noemden er veertien in de introductie). Dit was de laatste sessie van Techorama, deels psychologiecollege, deels goochelshow, met veel videoclips, experimenten met het publiek en grappen. Hun vraag voor het slotuur: <strong>waarom veranderen we, of juist niet?<\/strong> Een groot deel van de talk ging over hoe het brein snelle, onbewuste beslissingen neemt en waarom dat ertoe doet voor technologie, AI en samenwerken.<\/p>\n<h3>Opening: drie snelle vragen<\/h3>\n<ul>\n<li><strong>Hoeveel jaar is George Clooney ouder dan Brad Pitt?<\/strong> De meeste mensen in de zaal gokten negen. Het juiste antwoord is <strong>twee<\/strong>. Aannames komen binnen een seconde op in het brein.<\/li>\n<li><strong>Hoe lang heeft het brein nodig om bij een sollicitatiegesprek ja of nee te beslissen?<\/strong> Een gesprek duurt gemiddeld 45 minuten, maar het brein beslist in ongeveer <strong>0,2 seconde<\/strong>.<\/li>\n<li><strong>Een gezichtstest van \u00e9\u00e9n seconde.<\/strong> Het publiek zag \u00e9\u00e9n seconde lang twee mannen en koos een toekomstige collega. Zo&#8217;n 98% koos dezelfde persoon, omdat het brein een gezicht scant en intelligentie afleidt uit signalen zoals jukbeenderen en kin. Een tweede paar liet het omgekeerde zien: de meesten kozen de man die, zo grapte Paul, een seriemoordenaar bleek te zijn. \u201cJe eerste aanname klopt niet altijd.\u201d<\/li>\n<\/ul>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_173015_d_e_kl.jpg\" loading=\"lazy\" alt=\"A Fresh Perspective on Behaviour, Change and the Brain - Paul Smit\"><\/p>\n<h3>Onze zintuigen zijn subjectief<\/h3>\n<p>Paul liet een reeks illusies zien om te laten zien dat <strong>wat we zien altijd een subjectieve constructie is<\/strong>:<\/p>\n<ul>\n<li>Een holle mal van een masker die lijkt alsof de neus naar je toe steekt: het brein is zo geconditioneerd om een gezicht met de neus aan de buitenkant te zien dat het beeld omklapt.<\/li>\n<li>Slechts een klein gebied (ongeveer zo groot als je duimnagel op armlengte) zien we scherp. \u201cAls ik nu tegen jullie praat, is alles vrij wazig.\u201d Door naar een stip te staren leken beroemde gezichten vervormd, maar \u201cer is niets mis met de foto&#8217;s, het gebeurt alleen in je hoofd\u201d.<\/li>\n<li>Een zwart-witfoto die gekleurd leek te worden na staren naar een versie met hoog contrast, en draaiende kleuren die leken te bewegen toen de gele lijnen werden weggehaald.<\/li>\n<\/ul>\n<h3>11,2 miljoen bits versus 60 bits<\/h3>\n<p>Het centrale idee van de eerste helft: het brein is extreem snel.<\/p>\n<ul>\n<li><strong>Het onbewuste brein verwerkt ongeveer 11,2 miljoen bits per seconde.<\/strong> Ons <strong>bewustzijn is maar ongeveer 60 bits<\/strong>.<\/li>\n<li>Beslissingen, bijvoorbeeld iets kopen, worden onbewust genomen. Achteraf \u201cverzinnen\u201d de 60 bits \u201ceen verhaal over waarom je het kocht\u201d.<\/li>\n<li>Met 60 bits kunnen we ons <strong>maar op \u00e9\u00e9n ding tegelijk richten<\/strong>. Je kunt een gezicht van voren of van opzij zien, maar niet allebei tegelijk. Zo houden <strong>goochelaars<\/strong> ons voor de gek en merkt iemand die op zijn telefoon let een vermist kind niet op, of merkt een zangeres niet dat ze in een fles zingt.<\/li>\n<li><strong>Gevolg voor design:<\/strong> houd informatie zo simpel mogelijk, <strong>\u00e9\u00e9n boodschap tegelijk<\/strong> (Paul toonde een website met \u00e9\u00e9n boodschap als goed voorbeeld).<\/li>\n<li>Het onbewuste brein handelt eerst en het <strong>bewustzijn komt met een kleine vertraging<\/strong>. Een woordleestest, een draaiende-frame-illusie (het Ames-venster) en een snelle dierennaamtest (een dromedaris die kameel werd genoemd) lieten dat zien. Het is ook waarom je soms iets eruit flapt en pas daarna beseft \u201cdat had ik niet moeten zeggen\u201d. Een korte slide met het bedankje van een voetballer na de wedstrijd (\u201cMijn vrouw en mijn vriendin. Ik bedoel mijn vrouw\u201d) diende als voorbeeld.<\/li>\n<li>Reflexen zitten in het onbewuste brein. De spreker noemde een reactietijd van 44 ms voor een slang en 20 ms voor een kat.<\/li>\n<\/ul>\n<h4>Leugens en micro-expressies<\/h4>\n<p>Paul trainde vroeger de Nederlandse politie in het herkennen van leugens. \u201cDe 60 bits zeggen nee, maar het onbewuste brein knikt ja\u201d of laat <strong>micro-expressies<\/strong> zien (zoals minachting) die je niet kunt controleren. Ze toonden bekende interviewfragmenten als voorbeeld en concludeerden: \u201cons onbewuste brein wint altijd.\u201d<\/p>\n<h4>Framing, met het voorbeeld van de penaltyserie<\/h4>\n<p>We zijn gemakkelijk te be\u00efnvloeden: volgens Paul worden beelden 60.000 keer sneller verwerkt dan tekst. Het voorbeeld van <strong>framing<\/strong> was Tim Krul in de Nederlandse penaltyserie op het WK: door naar \u00e9\u00e9n kant te lopen, de penaltynemer op de schouder te tikken en aan de andere kant een \u201clege ruimte\u201d te laten, stuurde hij het onbewuste brein van de nemer, zodat hij de goede kant op kon duiken. \u201cDie man denkt met zijn 60 bits dat hij zijn eigen beslissing neemt.\u201d<\/p>\n<h3>AI en de dood van wat echt is<\/h3>\n<p>Voor het eerst in de geschiedenis heeft het brein concurrentie: <strong>supercomputers en AI<\/strong>. Paul liet door AI gegenereerde video&#8217;s zien (een beroemde zanger die een nummer \u201czingt\u201d dat hij nooit opnam, een voetballer die Nederlands praat, twee wereldleiders in een circusact en Paul zelf in een western met beroemde acteurs die \u201cverandert in Brad Pitt\u201d). De gevolgen:<\/p>\n<ul>\n<li><strong>De \u201cdood van het internet\u201d:<\/strong> binnenkort weten we niet meer of wat we zien echt is.<\/li>\n<li><strong>AI slop:<\/strong> een stortvloed aan rommel.<\/li>\n<li>Een test met het publiek: bij twee paren portretten was er telkens \u00e9\u00e9n door AI gegenereerd en het publiek raadde meestal fout.<\/li>\n<\/ul>\n<h4>AI heeft geen bewustzijn<\/h4>\n<p>Omdat AI geen bewustzijn heeft, <strong>doet het geen reality check<\/strong>. Pauls voorbeelden: de vraag om een \u201crealistische\u201d versie van een afbeelding met <strong>vierkante wielen<\/strong> leverde ronde wielen op (omdat rond het meest voorkomt in de trainingsdata), en opnieuw nadat het in Photoshop was aangepast en om een video werd gevraagd. \u201cAI is nooit zo creatief.\u201d Gevraagd waarom een klassieke grap (\u201ckamer voor twee nachten\u201d, een woordspeling met \u201cknights\/nights\u201d) grappig is, legde AI de woordspeling uit, maar \u201chet kent de ervaring van humor niet\u201d. AI kan geweldige remixes maken, maar kan niet <em>genieten<\/em> van wat het maakt: \u201calleen wij kunnen dat\u201d. De 60 bits bewustzijn zijn \u201chet mooiste wat we hebben\u201d, want daarmee kunnen we genieten van muziek en vertrouwen voelen.<\/p>\n<h3>Het brein met drie lagen<\/h3>\n<p>Paul gebruikte het populaire \u201ctriune brain\u201d-model (een vereenvoudiging) met drie lagen en drie motieven: <strong>routine<\/strong>, <strong>plezier<\/strong> en <strong>doel<\/strong>.<\/p>\n<h4>1. Het reptielenbrein: routine en veiligheid<\/h4>\n<p>Het oudste deel wil <strong>routine<\/strong> om energie te besparen en ongeveer <strong>99% van wat we doen komt voort uit routine<\/strong>. Test: sla je armen over elkaar en wissel dan welke arm bovenop ligt: \u201cproblemen\u201d. Het scant ook op <strong>veiligheid<\/strong> (\u201cben ik veilig?\u201d, bijvoorbeeld een kat die schrikt van een komkommer die op een slang lijkt). Voorbeelden:<\/p>\n<ul>\n<li><strong>Conditionering:<\/strong> een hond die wacht tot de deur opengaat, en een man die <strong>drie maanden<\/strong> dagelijks moest oefenen om te fietsen met omgekeerd stuur en de dag erna niet meer op een gewone fiets kon rijden. \u201c<strong>Verandering is een kwestie van herhaling.<\/strong>\u201d<\/li>\n<li><strong>Bungeejumpen:<\/strong> je betaalt 150 euro en kijkt ernaar uit, maar op het platform zegt het reptielenbrein nee. \u201cHet oudste deel wint altijd.\u201d<\/li>\n<li>Een winkel in Parijs met een perfect vlakke vloerbedekking die eruitziet alsof er gaten in zitten: iedereen loopt voorzichtig.<\/li>\n<li><strong>Vertrouwen en oxytocine:<\/strong> elkaar persoonlijk ontmoeten, handen schudden en (bij leeuwen) knuffelen verhogen oxytocine, wat het vertrouwen verhoogt. Daarom is het waardevol om elkaar te ontmoeten op Techorama.<\/li>\n<\/ul>\n<h4>2. Het zoogdierenbrein (emotioneel brein): plezier<\/h4>\n<p>Dit deel wil <strong>plezier<\/strong>. Grote emoties onthoud je (Pauls voorbeeld: waar je was op 9\/11), daarom werkt een emotionele reclame. <strong>Dopamine<\/strong> verhoogt het plezier:<\/p>\n<ul>\n<li>In een test met het publiek vroeg Paul een vrijwilliger een concert te kiezen en die koos het concert met de meeste dopamine: \u201cje kiest altijd wat je de meeste dopamine geeft\u201d.<\/li>\n<li>Dopamine stijgt ook bij <strong>verrassing<\/strong> (een virale grap in een fitnessclub) en vooral <strong>wanneer mensen over zichzelf praten<\/strong>: \u201claat de klant over zichzelf praten en je kunt alles verkopen\u201d.<\/li>\n<li>Dit brein is ook <strong>lui<\/strong>: het neemt de weg van de minste weerstand (zelfs mensen in de sportschool mijden de trap; op een Nederlands toilet drukken mensen op de grote spoelknop). Dus <strong>de customer journey moet zo soepel en simpel mogelijk zijn<\/strong>.<\/li>\n<\/ul>\n<h4>3. De neocortex: doelen en rationeel denken<\/h4>\n<p>Die regelt <strong>rationeel denken, doelen en duidelijkheid<\/strong> en is pas rond je 25e volledig ontwikkeld (plannen en risico&#8217;s nemen is daarvoor moeilijker). Het visitekaartje van een mentalist dat openvouwt tot een heel pak liet zien hoe de neocortex probeert iets te begrijpen wat rationeel onmogelijk is.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_175250_d_e_kl.jpg\" loading=\"lazy\" alt=\"A Fresh Perspective on Behaviour, Change and the Brain - Paul Smit\"><\/p>\n<p><strong>Het emotionele brein is sterker dan het rationele.<\/strong> In een interview werd er met Bryan Adams geflirt en hij verloor zijn woorden doordat zijn neocortex uitviel. Pauls advies voor emoties, bij een partner of een klant: <strong>onderdruk ze nooit, benoem ze gewoon<\/strong>, wat Adams deed om te herstellen. Paul gaf ook het voorbeeld van de marshmallowtest: de neocortex zegt \u201cniet opeten\u201d, de twee oudere delen zeggen \u201copeten\u201d. Een ander voorbeeld was de Nederlandse premier die tijdens corona aankondigde dat we geen handen meer zouden schudden en vervolgens meteen weer handen schudde.<\/p>\n<h4>Wanneer gebeurt verandering echt?<\/h4>\n<p>Wanneer <strong>alle drie de delen van het brein samenwerken<\/strong>, wat in twee situaties gebeurt:<\/p>\n<ol>\n<li><strong>Passie:<\/strong> intrinsieke motivatie (\u201cmensen die zo gepassioneerd zijn over AI gaan veel sneller\u201d).<\/li>\n<li><strong>Urgentie:<\/strong> we moeten echt veranderen.<\/li>\n<\/ol>\n<p>Passie is \u201cveel fijner\u201d. En de beste manier om te veranderen is <strong>in kleine, concrete stappen<\/strong>: het reptielenbrein denkt in routines, dus iets \u00e9\u00e9n keer anders doen brengt het in de war (ge\u00efllustreerd met een truc van een voetballer).<\/p>\n<h3>Te veel informatie: FOBO, rust en dopamine<\/h3>\n<p>Technologie groeit exponentieel en Paul zei zelf overweldigd te zijn door de hoeveelheid dagelijks AI-nieuws. Dat veroorzaakt <strong>FOBO<\/strong>, door de spreker hier gedefinieerd als \u201cfreaks out, but optimistic\u201d. Het medicijn: neem <strong>rust<\/strong> en focus.<\/p>\n<h4>Hoe dopamine werkt<\/h4>\n<ul>\n<li>Dopamine geeft plezier <strong>en motivatie<\/strong>. Kinderen hebben er veel van: een meisje dat voor het eerst een trein ziet is opgetogen en kinderen zijn gemotiveerd om nieuwe dingen te proberen. Mensen met te veel dopamine worden <strong>thrill seekers<\/strong>.<\/li>\n<li>&#8217;s Ochtends stijgt dopamine (koffie geeft ook een boost), met een <strong>piek in de eerste acht uur na het wakker worden<\/strong> (gemotiveerd en geconcentreerd op werk), en daarna \u201cis er niet veel meer over voor de rest van de dag\u201d.<\/li>\n<li><strong>Hoogtepunten worden gevolgd door dieptepunten.<\/strong> Paul vergeleek het effect van coca\u00efne (zou dopamine vervierdubbelen) met de \u201cdinsdagdip\u201d die hun zoon en vrienden voelen na een hardstylefestival (het brein duwt alles omlaag). Dat is niet erg: rust laat het brein herstellen.<\/li>\n<li><strong>Het moderne probleem:<\/strong> we proberen de leegte in de avond op te lossen met drinken (volgens de spreker verdubbelt alcohol dopamine en schakelt het de neocortex uit) of snacken, en uiteindelijk met <strong>TikTok<\/strong>, dat neurowetenschappers <strong>\u201cdigitale coca\u00efne\u201d<\/strong> noemen: elke swipe is een dopamineshot.<\/li>\n<li><strong>De baseline daalt.<\/strong> Volgens onderzoek van de spreker hebben mensen die zichzelf met zulke prikkels overladen een lagere dopamine-baseline en minder gevoelige receptoren, waardoor het gewone leven saai voelt. \u201cDat is de grootste uitdaging voor onze jeugd.\u201d De reactie op verveling is <strong>multilayering<\/strong> (telefoon bij het ontbijt, twee schermen tegelijk) en \u201cmeer en meer\u201d willen, wat niet goed is voor het brein. Smartphones zijn zeer verslavend en ouders geven niet het goede voorbeeld. Het medicijn opnieuw: <strong>rust<\/strong>, het brein de tijd geven om te herstellen van alle prikkels.<\/li>\n<\/ul>\n<h3>Generaties op het werk<\/h3>\n<p>Paul sloot het hoofdgedeelte af met een rondgang langs generaties, \u201comdat we samenwerken met verschillende generaties\u201d, met muziek, nostalgie en quizzen (met de generatielabels zoals op de slides):<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_181449_d_e_kl.jpg\" loading=\"lazy\" alt=\"A Fresh Perspective on Behaviour, Change and the Brain - Paul Smit\"><\/p>\n<ul>\n<li><strong>Babyboomers (1946 tot 1964):<\/strong> opgegroeid in een tijd van economische groei met weinig technologie (een pitstop van 67 seconden als \u201cwereldrecord\u201d, de stratenatlas als navigatiesysteem). Hun motto: een <strong>baan voor het leven<\/strong>, \u201cje brood verdienen\u201d.<\/li>\n<li><strong>Generatie X:<\/strong> opgegroeid met de Commodore 64 en geconfronteerd met een recessie bij het verlaten van school, waardoor ze <strong>loyaal<\/strong> en <strong>pragmatisch<\/strong> werden (en, zo grapte Paul, thuis een mand met kabels hebben die ze nooit zullen gebruiken).<\/li>\n<li><strong>Generatie Y (millennials, 1980 tot 1994):<\/strong> <strong>digitalisering<\/strong>, flexibel, \u201cYOLO\u201d (you only live once). Ze zijn digitaal sterk, maar denken soms dat ze alles zelf kunnen.<\/li>\n<li><strong>Generatie Z:<\/strong> anders geconditioneerd (de piramide van Maslow is veranderd), <strong>vanaf de geboorte altijd online<\/strong>, met alles <strong>instant en snel<\/strong>, en behoorlijk <strong>idealistisch<\/strong>.<\/li>\n<\/ul>\n<p>Paul illustreerde de wereld van Gen Z met cijfers: volgens Paul heeft ongeveer 39% van de Nederlandse babyboomers een Netflix-account tegenover 79% van Generatie Z (de rest gebruikt het account van de ouders). Over hoe snel platforms 100 miljoen gebruikers bereiken: ChatGPT \u201cverbrak alle records\u201d met <strong>ongeveer twee maanden<\/strong>, tegenover ongeveer anderhalf jaar voor YouTube en TikTok en drie tot vier jaar voor Instagram, Facebook en WhatsApp. De volgende generatie, <strong>Generatie Alpha<\/strong>, wordt onze collega: \u201cdie gaan de wereld redden, zeker weten\u201d.<\/p>\n<p>Paul gebruikte AI ook om hun eigen boek te promoten (met een nagemaakte, door AI gegenereerde aanbeveling) en om een oude demo-cassette uit 1994 en een VHS-opname van een band te herstellen tot \u201cstudiokwaliteit\u201d. Dat laat de \u201cmagische\u201d kant van AI zien.<\/p>\n<h3>Conclusie<\/h3>\n<p>Pauls samenvatting (recap):<\/p>\n<ul>\n<li><strong>Het brein is geweldig, maar alles wat we zien is een subjectieve kijk<\/strong>, en illusies (een metro die naar je toe of van je af beweegt, een draaiende figuur die van richting verandert als je je hoofd kantelt) zijn \u201callemaal een kwestie van waarneming\u201d.<\/li>\n<li><strong>Het onbewuste brein doet alles<\/strong> en we zijn gemakkelijk te be\u00efnvloeden (zelfs filmmuziek verandert hoe een vechtsc\u00e8ne voelt).<\/li>\n<li><strong>AI<\/strong> kan kanker genezen of slop maken.<\/li>\n<li><strong>We veranderen uit passie of urgentie<\/strong>, en <strong>het best in kleine concrete stappen<\/strong>.<\/li>\n<li><strong>Dopamine<\/strong> geeft motivatie en plezier en soms heb je <strong>rust<\/strong> nodig voor balans.<\/li>\n<li>Paul merkte ook op dat mensen van <strong>20 tot 30 jaar<\/strong> de meeste dopamine hebben en in hun meest creatieve fase zitten: in de Nederlandse Top 2000 zijn veel van de all-time klassiekers geschreven door mensen in die leeftijdsgroep.<\/li>\n<\/ul>\n<p>Ze eindigden met een medley van klassieke nummers (\u201cdeze jongens zingen alsof ze gaten boren\u201d) en een uitnodiging om wat te gaan drinken.<\/p>\n<p><!-- conclusie --><\/p>\n<h2 id=\"conclusie\">Conclusie van het hele event<\/h2>\n<p>Twee dagen Techorama laten een duidelijk beeld zien: de technologie gaat razendsnel, maar de beste resultaten komen nog altijd uit goede engineering, heldere afspraken en aandacht voor mensen.<\/p>\n<h3>AI versnelt wat er al is<\/h3>\n<p>Meerdere sessies kwamen op hetzelfde punt uit: AI maakt het schrijven van code goedkoop en snel, maar vermenigvuldigt ook wat al in je organisatie aanwezig is, zowel het goede als het slechte. Wie slordige code, trage reviews, onduidelijke eigenaarschap of een chaotische aanpak heeft, krijgt dat sneller en groter terug. Het knelpunt verschuift van code schrijven naar reviewen, verifi\u00ebren en besluiten wat gebouwd moet worden. Dezelfde kwaliteitslat voor elke wijziging, wie of wat die ook schreef, en een mens die de eindverantwoordelijkheid draagt (\u201cyou prompt it, you own it\u201d), kwamen in meer dan \u00e9\u00e9n talk terug. Agents en automatisering werken het best als ze begrensd zijn: beperkte rechten, gecureerde context, een duidelijk eindresultaat en een mens die het laatste woord heeft.<\/p>\n<h3>Vertrouwen moet je kunnen controleren<\/h3>\n<p>Van MITRE ATT&amp;CK en antipatterns tot supply chain-aanvallen: aanvallers richten zich steeds meer op wat we van derden binnenhalen en op de manier waarop we bouwen en uitrollen. De boodschap is om vertrouwen te verdienen met bewijs: ondertekende artifacts, provenance, scans, back-ups die je echt hebt teruggezet en een beperkte blast radius. Geen enkele maatregel is een wondermiddel, het gaat om meerdere lagen die elkaar aanvullen.<\/p>\n<h3>Autonomie vraagt om goede grenzen<\/h3>\n<p>Of het nu ging om microservices, DDD en enterprise architecture of het versioneren van events: koppeling is het echte probleem. Begin eenvoudig (een modulaire monoliet, geen integratie als het niet hoeft), behandel grenzen als hypothese, maak contracten expliciet en bedenk dat elke integratie ook een afspraak tussen teams is. Organisatie en architectuur be\u00efnvloeden elkaar, en wie dat bewust gebruikt, bouwt systemen die kunnen veranderen zonder toestemming te vragen.<\/p>\n<h3>Het blijft mensenwerk<\/h3>\n<p>Ten slotte kwamen de mens en de ziel nadrukkelijk terug: de keynote over schaal versus ziel, de sessie over burn-out en de afsluiter over gedrag en het brein. Verandering vraagt herhaling, kleine concrete stappen, rust en een veilige omgeving waarin slecht nieuws welkom is. Technologie en mens versterken elkaar het best wanneer we beide serieus nemen.<\/p>\n<h3>Praktisch aan de slag<\/h3>\n<p>Wil je maandag iets doen met wat je gelezen hebt? Kies \u00e9\u00e9n ding en begin klein: schrijf je teamstandaarden op, maak \u00e9\u00e9n pipeline of review sneller, controleer of je back-up echt terug te zetten is, bepaal wat je met AI wel en niet laat doen, of praat in je team over wat je energie kost. Zoals meerdere sprekers adviseerden: begin klein, meet het effect en bouw van daaruit verder.<\/p>\n<p><img decoding=\"async\" width=\"470\" height=\"313\" src=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261028_184203_d_1_e_kl.jpg\" loading=\"lazy\" alt=\"Borrel - Techorama\"><\/p>\n<figure class=\"blog-image\">\n\t<img\n\t\tsrc=\"https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_081132_d_e_kl.jpg\"\n\t\tdata-gps=\"52.086781,5.104575\"\n\t\tsrcset=\"\n\t      https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_081132_d_e_kl.jpg 300w,\n\t      https:\/\/media.qdraw.nl\/log\/techorama-2026\/500\/20261027_081132_d_e_kl.jpg 500w,\n\t      https:\/\/media.qdraw.nl\/log\/techorama-2026\/1000\/20261027_081132_d_e_kl1k.jpg 1000w\"\n\t\tsizes=\"auto, (max-width: 600px) 100vw, (max-width: 1000px) 80vw, 700px\"\n\t\twidth=\"4032\" height=\"2688\"\n\t\tloading=\"lazy\"\n\t\tdecoding=\"async\"\n\t\talt=\"Techorama (2026), Techorama, Techorama\"\n\t><figcaption>Techorama | foto 1<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"Op Techorama 2026 werden inzichten gedeeld over actuele thema\u2019s binnen de IT en softwareontwikkeling. Deze blog is geschreven voor IT-professionals. In dit blog bespreken we enkele hoogtepunten van dinsdag 27 en woensdag 28 oktober. Voor elke sessie die we bezochten vind je een samenvatting met de belangrijkste lessen, voorbeelden en praktische tips. Een paar rode&#8230; <a class=\"view-article\" href=\"https:\/\/qdraw.nl\/blog\/technologie\/techorama-2026-de-hoogtepunten\/\">Bekijk artikel<\/a>","protected":false},"author":2,"featured_media":10815,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"qdraw_kf_afstand":"","qdraw_kf_uren":"","qdraw_kf_minuten":"","qdraw_kf_startpunt":"","qdraw_kf_eindpunt":"","qdraw_kf_waardering":"0","footnotes":""},"categories":[624],"tags":[2841],"content_hub":[],"class_list":["post-10809","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technologie","tag-net"],"_links":{"self":[{"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/posts\/10809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/comments?post=10809"}],"version-history":[{"count":7,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/posts\/10809\/revisions"}],"predecessor-version":[{"id":10817,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/posts\/10809\/revisions\/10817"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/media\/10815"}],"wp:attachment":[{"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/media?parent=10809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/categories?post=10809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/tags?post=10809"},{"taxonomy":"content_hub","embeddable":true,"href":"https:\/\/qdraw.nl\/blog\/wp-json\/wp\/v2\/content_hub?post=10809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}