05 – Tweede agent

OttoOps maakt DexterDev

afgerond

Van één agent naar twee — en vooral: eerst zorgen dat de basis klopt.

Dit was de aflevering waarvan ik vooraf dacht dat hij vooral over DexterDev zou gaan. Een tweede agent erbij, eigen ingang geven, rol uitleggen en klaar.

In de praktijk zat het meeste werk ergens anders.

Tot nu toe was OttoOps alleen. Daardoor maakte het niet zoveel uit dat zijn naam op allerlei plekken in de inrichting zat. De dienst die hem startte heette naar hem, scripts wisten waar zijn bestanden stonden en zijn eigen map bevatte zowel persoonlijke spullen als onderdelen die iedere agent nodig zou hebben. Zolang er maar één agent is, werkt dat prima.

Maar zodra er een tweede komt, wil ik geen tweede kopie van OttoOps maken. Ik wil één basis waarop meerdere agents kunnen draaien, met ieder een eigen rol, eigen rechten en eigen ingang.

Dat betekende dat OttoOps eerst zichzelf uit elkaar moest halen.

En precies daar bleek weer iets wat ik in de vorige aflevering ook al merkte: het fundament goed krijgen kost tijd. Soms zie je in Telegram niet of OttoOps nog druk bezig is, vastzit of helemaal niets meer hoort. Een paar keer heb ik daarom LocalClaude, de Claude op mijn laptop, laten kijken wat er op de server gebeurde. Soms om alleen mee te kijken, soms omdat er echt iets mis was.

Dat voelt af en toe ongemakkelijk. Je geeft een opdracht, het blijft stil en je weet niet of je vijf minuten moet wachten of moet ingrijpen. Soms moet je dus ook gewoon even vertrouwen hebben ;-).

LocalClaude beantwoordt de vraag of OttoOps nog bezig is en somt op waar hij op dat moment mee werkt
Stilte in Telegram zegt niets. Van buitenaf is wel te zien waar hij mee bezig is.

Aan het eind stond er wel iets wezenlijk anders dan aan het begin: twee agents, op één gedeelde basis.

Eerst: waar bestaat OttoOps eigenlijk uit?

Voordat OttoOps iets kon delen, moest hij eerst inventariseren wat er op dat moment werkelijk was. Niet wat we ooit hadden bedacht, maar wat er daadwerkelijk op de server draaide en in zijn map stond.

Dit was mijn eerste opdracht:

Maak een lijst van alles waaruit jij bestaat. Ga uit van wat er op de server staat, niet van wat je je herinnert.

  • Wat is de machinerie: de dingen die draaien of je aan de praat houden.
  • Wat is van jou persoonlijk: je naam, je rol, je geheugen, en waarmee je bij mijn berichten komt.
  • Zet bij elk ding in één regel wat het doet, en of jouw naam er letterlijk in staat.

Zet de lijst in een eigen bestand met de datum van vandaag erbij, en stuur me de korte versie.

De lijst die terugkwam was meteen nuttig. OttoOps maakte onderscheid tussen de machinerie die hem aan de praat hield en de dingen die echt van hemzelf waren: zijn rol, geheugen, Telegram-ingang en eigen bestanden.

Daar zat ook meteen een kleine correctie van mijn kant in. OttoOps had de dagelijkse controle op serverupdates bij de algemene machinerie gezet. Ik vond dat juist onderdeel van zijn rol als beheerder.

Ik stuurde hem dus terug dat de server-update-check bij hem persoonlijk hoorde. Hij paste de inventaris aan.

Telegram: OttoOps stuurt zijn inventaris in twee delen, machinerie en persoonlijk, en past hem daarna aan op Jacco's correctie
De inventaris, in twee stapels. De dagelijkse updatecontrole verhuisde op mijn verzoek naar de persoonlijke kant.

Dat lijkt een detail, maar dit is precies waarom ik deze stap belangrijk vond. OttoOps kan prima zien wat er staat. Maar ik bepaal nog steeds waarom iets er is en bij welke rol het hoort.

Van OttoOps naar een basis voor iedere agent

Met die inventaris kon de echte verbouwing beginnen.

Mijn opdracht aan OttoOps was:

Je bent hier de enige agent, en dat verandert. Ga je eigen spullen langs met de lijst die je net gemaakt hebt, en haal eruit wat niet van jou is maar van iedere agent die hier komt.

  • Loop de lijst regel voor regel af en zeg me van elk ding: is dit van jou persoonlijk, of zou een tweede agent precies hetzelfde nodig hebben? Twijfelgevallen wil ik horen, die beslis ik.
  • Wat van iedere agent is, zet je op een plek die niet van jou is. Alle agents mogen die lezen en gebruiken; veranderen mag alleen jij, als beheerder.
  • Wat van jou persoonlijk is blijft in je eigen map: wie je bent, waar je sleutel staat, welk gesprek van jou is. Zorg dat de gedeelde machinerie dat opvraagt in plaats van het te weten.
  • Maak van de dienst waarmee de server je draait één beschrijving die voor elke agent werkt, met de naam als invulling in plaats van als tekst. Ik wil er geen tweede bij als er een agent bij komt.
  • Er mag daarna nergens in de gedeelde machinerie een agentnaam meer staan. Controleer dat en zeg me waar je nog iets vond.
  • Wat je als beheerder hebt en een bouwende agent niet hoort te krijgen, laat je staan waar het staat. Dat hoort niet in de basis.
  • Zet jezelf daarna over op die basis en zorg dat je gewoon blijft draaien. Doe dat in één keer af; ik wil niet vannacht een halve verhuizing hebben staan.

Tijdens die verhuizing kwamen er een paar keuzes terug waarop ik zelf antwoord moest geven. Welke scripts zijn echt generiek? Welke lessen zijn bruikbaar voor iedere agent? Wat blijft juist bij OttoOps? En gebruikt iedere agent straks dezelfde aanmelding of krijgt iedereen een eigen?

Mijn keuzes waren vrij duidelijk: alles wat iedere agent nodig heeft mag naar de gedeelde basis, maar dan ook echt generiek. Algemene lessen mogen mee als ze in de gedeelde werkwijze passen. Het script voor een agentverslag mag gedeeld worden als het geen OttoOps-specifieke dingen meer bevat. Een hulpscript waarmee OttoOps Telegram-updates opvraagt mag bij hem blijven. En iedere agent krijgt zijn eigen login.

Telegram: OttoOps legt zes twijfelgevallen voor over wat gedeeld wordt en wat persoonlijk blijft, met daaronder Jacco's antwoorden per nummer
Zes twijfelgevallen, genummerd voorgelegd en genummerd beantwoord.

OttoOps bouwde daarop een gedeelde basis in /opt/agents-base. De scripts en documenten die voor iedere agent hetzelfde zijn staan daar nog maar één keer. OttoOps zelf gebruikt diezelfde basis. In zijn eigen map blijven de dingen staan die echt van hem zijn.

Telegram: OttoOps meldt dat de verhuizing naar de gedeelde basis in een keer is uitgevoerd en noemt de nieuwe opdrachten
De verhuizing in een keer, met de nieuwe opdrachten erbij.

Ik controleerde dat met twee heel simpele vragen:

Waar staat de basis nu, en wie mag hem veranderen?

en:

Waar staat jouw naam nu nog in?

Het antwoord was zoals ik het wilde hebben. De basis staat buiten de thuismap van een agent. OttoOps beheert hem; andere agents mogen hem gebruiken, maar niet zomaar veranderen. Zijn naam staat nog wel waar hij persoonlijk hoort te staan: in zijn eigen bestanden, zijn Linux-gebruikersnaam en als naam waarmee zijn exemplaar van de algemene dienst wordt gestart. Maar niet meer ín de gedeelde basis zelf.

Telegram: twee korte vragen over waar de gedeelde basis staat en waar de naam van OttoOps nog voorkomt, met zijn antwoorden
Twee vragen waren genoeg om te zien of het klopte.

Dat laatste is belangrijk. De basis weet niet meer dat OttoOps bestaat. Hij weet alleen hoe een agent moet draaien.

Controleren van buitenaf

Daarna wilde ik weten of OttoOps na deze verhuizing nog gewoon goed terugkwam. Dat kun je lastig aan OttoOps zelf vragen als je hem daarvoor eerst moet stoppen.

Daar gebruik ik LocalClaude voor.

Ik gaf hem deze opdracht:

Herstart OttoOps via de server. Kijk daarna of hij weer draait, en of er in zijn eigen map nog machinerie staat die ook in de gedeelde basis staat.

En toen ging het mis.

LocalClaude gebruikte bij de eerste herstart nog een oude dienstnaam van vóór de verhuizing. Daardoor kwam er kort een tweede exemplaar van OttoOps op. Beide probeerden hetzelfde slot te gebruiken: de ene draaide al, de andere stond te wachten.

LocalClaude zag dat gelukkig zelf, zocht uit welke dienst inmiddels de juiste was en stopte de oude. Daarna bleek er nóg een oude dienst actief te staan die eigenlijk niet meer nodig was. Ook die werd opgeruimd.

LocalClaude ontdekt dat de herstart een oude, achterhaalde dienstnaam trof en dat er daardoor kort twee exemplaren van OttoOps draaiden
De herstart trof de oude naam. Even draaiden er twee, wachtend op hetzelfde slot.

Alleen liep dat opruimen ongeveer tegelijk met werk dat OttoOps zelf aan zijn eigen inrichting deed. Daardoor werd zijn nieuwe dienst ook geraakt en liep die uiteindelijk tegen een timeout aan. LocalClaude heeft hem daarna opnieuw gestart en gecontroleerd of er weer precies één OttoOps draaide.

Dit is zo’n moment waarop een technisch detail in één keer heel tastbaar wordt: als twee partijen tegelijk aan dezelfde inrichting sleutelen, kunnen ze elkaar in de weg zitten. Ook als ze allebei op zichzelf iets verstandigs doen.

LocalClaude legt uit dat het opruimen samenviel met werk dat OttoOps zelf aan zijn inrichting deed, waardoor de dienst in een timeout liep
Twee partijen die tegelijk aan dezelfde inrichting sleutelen: negentig seconden wachten en daarna hard afgebroken.

En we waren er nog niet.

Niet veel later stuurde ik OttoOps een bericht en kwam er niets terug. Was hij nog bezig? Was mijn opdracht lang? Of zag hij mijn bericht helemaal niet?

Via LocalClaude bleek dat de Telegram-ontvanger niet meer draaide. De server dacht wel dat alles goed was, omdat de dienst alleen had gecontroleerd of het starten gelukt was. Het proces dat daarna de berichten bleef ophalen was stilletjes verdwenen.

Dat is precies het lastige van deze fase. Vanuit Telegram ziet “OttoOps is druk bezig” er hetzelfde uit als “OttoOps hoort me niet meer”.

LocalClaude stelt vast dat de Telegram-ontvanger helemaal niet draait terwijl de server hem als gezond beschouwt
De server zag niets bijzonders, omdat hij alleen had gekeken of het starten lukte.

Ik liet LocalClaude eerst uitzoeken wat er aan de hand was. Daarna wilde ik niet dat LocalClaude de hele inrichting van OttoOps ging overnemen. OttoOps is tenslotte degene die deze server moet beheren.

Dus vroeg ik LocalClaude simpelweg:

schrijf een instructie aan OttoOps om alles na te lopen en te verbeteren

Dat werkte prettig. LocalClaude had de storing van buitenaf bekeken en kon heel concreet uitleggen wat OttoOps moest nalopen: de ontvanger moest een echt bewaakt proces worden, en OttoOps moest voorkomen dat hij zichzelf tijdens onderhoud stillegde zonder in dezelfde handeling ook weer terug te komen.

LocalClaude schrijft op verzoek een instructie voor OttoOps met twee benoemde problemen en wat er structureel aan moet gebeuren
Niet zelf repareren, maar een instructie schrijven die ik kan doorsturen.

Die instructie stuurde ik vervolgens aan OttoOps.

Voor mij is dat een bruikbare manier van werken geworden. LocalClaude hoeft niet automatisch degene te zijn die iets repareert. Hij kan ook alleen kijken wat er gebeurt en mij helpen een goede opdracht voor OttoOps te formuleren. Dan blijft het beheer waar ik het hebben wil.

Zwart op wit wat een agent hier is

Toen de gedeelde basis eenmaal stond, wilde ik voorkomen dat die alleen in het hoofd van OttoOps bestond. Er moest één document komen waarin letterlijk staat wat een agent op deze server is.

Mijn opdracht:

Schrijf in de basis één document dat beschrijft wat een agent hier is.

  • Zet erin welke bestanden elke agent heeft, met per bestand in twee of drie regels wat erin staat en waar het voor dient.
  • Beschrijf wat er nú staat, bij jou, en niet wat je vindt dat er zou moeten staan. Klopt iets bij jou niet met wat je opschrijft, dan repareer je het of je schrijft het anders op — maar het document en de werkelijkheid mogen niet uit elkaar lopen.
  • Zet er apart in wat juist niet in de basis hoort en bij de agent zelf blijft: wachtwoorden en sleutels, de rij met berichten die nog wachten, en de logboeken. Schrijf er in één regel bij waarom.
  • Zet erbij wie dit document mag wijzigen, en dat het bijgewerkt wordt op het moment dat er iets aan een agent verandert — niet achteraf.
  • Stuur me het document zoals het geworden is.

Daarna liet ik OttoOps zijn eigen map meteen langs dat document leggen:

Loop je eigen map na en zeg me of er iets bij je staat dat niet in het document voorkomt, en of er iets in het document staat dat bij jou ontbreekt.

Dat document is belangrijker dan het misschien klinkt. Vanaf nu hoef ik bij een derde of vierde agent niet opnieuw uit te zoeken welke bestanden nodig zijn, welke gedeeld zijn en welke persoonlijk moeten blijven. Er is nu een beschrijving van de werkelijkheid.

Telegram: de opdracht om vast te leggen wat een agent op dit systeem is, met het begin van het document dat terugkwam
Het document dat beschrijft wat een agent hier is, in drie delen teruggestuurd.

Daar staat ook expliciet in wat níet gedeeld wordt: sleutels en wachtwoorden, de wachtrij met berichten en de logboeken. Dat zijn spullen van één agent.

Nu pas vond ik de basis goed genoeg om DexterDev te maken.

OttoOps maakt DexterDev

Dit was de opdracht waarmee de tweede agent er echt bij kwam:

Maak een tweede agent op deze server: DexterDev. Volg daarbij het document dat je in de basis hebt gezet; dat beschrijft wat een agent hier is.

  • Geef hem een eigen thuismap en een eigen gebruiker. Hij hoeft nergens beheerder voor te zijn: geef hem alleen wat iemand nodig heeft om in zijn eigen map te werken.
  • Zorg dat hij niet in jouw thuismap kan kijken. Wat daar staat is van jou, en daar horen jouw sleutels bij.
  • Hij draait op de basis, niet op een kopie ervan. Er hoort niets van de machinerie in zijn map terecht te komen.
  • Zorg dat hij hetzelfde gereedschap heeft als jij, inclusief Claude Code zelf. Installeren en bijhouden is jouw werk, voor elke agent hier — ik wil niet per agent ergens anders terechtkomen. Het aanmelden doe ik van buitenaf, want dat gaat via een browser.
  • Hij krijgt zijn eigen ingang met zijn eigen sleutel. Gebruik de jouwe niet — hij moet zijn eigen berichten ophalen, niet die van jou. Ik heb die sleutel hier liggen, maar ik kom niet op de server: zeg me in welk bestand hij terecht moet komen en wie hem mag lezen, dan laat ik hem daar neerzetten. Wacht daarna tot ik zeg dat hij er staat voor je hem in gebruik neemt.
  • Zet hem op de lijst van dingen die de server hoort te draaien, met dezelfde afspraken als bij jou: mee bij het opstarten, en terug als hij omvalt. Maak er voor mij dezelfde drie opdrachten bij: starten, stoppen, en kijken hoe het ermee gaat.
  • Zijn rol vult hij zelf in, niet jij. Laat dat deel leeg.

En het belangrijkste: kwam je iets tegen dat hij nodig had en dat niet in het document stond? Zeg me precies wat, zet het daarna in het document, en zeg me of je het bij jezelf ook had.

Dit was voor mij het interessante moment van de hele aflevering: OttoOps maakte nu niet meer iets voor zichzelf, maar richtte een nieuwe agent in volgens de afspraken die we net hadden vastgelegd.

DexterDev kreeg een eigen Linux-gebruiker en een eigen thuismap. Hij kreeg geen beheerrechten. De gedeelde machinerie werd niet gekopieerd naar zijn map; hij gebruikt dezelfde basis als OttoOps. Claude Code werd ook niet nog een keer apart op een andere manier geïnstalleerd. Het gereedschap wordt centraal onderhouden.

Telegram: de opdracht om een tweede agent te maken, met daaronder OttoOps' melding dat DexterDev klaarstaat
De opdracht, en het antwoord: eigen gebruiker, eigen map, geen beheerrechten, geen eigen kopie van de machinerie.

Alleen zijn persoonlijke toegang moest nog van buitenaf worden aangeleverd.

Voor Telegram had ik lokaal al een bestand met zijn eigen sleutel. Ik wilde die sleutel niet in een gesprek plakken, dus LocalClaude zette het bestand rechtstreeks op de goede plek:

zet het locale bestand .tg_dexterdev op de server als /home/dexterdev/.tg-token (mode 600, eigenaar dexterdev)

LocalClaude zet het lokale sleutelbestand op de server met de juiste rechten en meldt dat hij de inhoud niet heeft gelezen
De sleutel ging rechtstreeks naar de goede plek, zonder ooit in een gesprek te staan.

Daarna moest DexterDev nog eenmalig bij Claude Code worden aangemeld. Dat gaat via een browser en kan OttoOps dus niet zelf afmaken.

De opdracht aan LocalClaude was:

Meld DexterDev daarna aan bij Claude Code, onder zijn eigen gebruiker. OttoOps heeft het al voor hem geïnstalleerd; alleen het aanmelden moet van buitenaf.

Daarmee was DexterDev technisch aanwezig.

Vervolgens liet ik OttoOps ook echt controleren of de scheiding werkte:

Probeer als DexterDev iets uit jouw map te lezen, en stuur me letterlijk wat er gebeurt. En wat zegt de server over hem — draait hij, en komt hij mee als de server opnieuw opstart?

Telegram: OttoOps stuurt de letterlijke uitvoer van drie pogingen van DexterDev om in zijn map te kijken, alle drie geweigerd
Drie pogingen, drie keer geweigerd. Geen afspraak maar een recht op de server.

Dat is voor mij een belangrijk verschil met alleen opschrijven dat agents gescheiden zijn. DexterDev hoort niet in de persoonlijke map van OttoOps te kunnen kijken. Dat is geen afspraak in een tekstbestand, maar een recht op de server.

Nu nog zorgen dat DexterDev ook echt DexterDev is

Technisch draaide er nu een tweede agent, maar een draaiend proces is nog geen teamlid.

Telegram: het eerste bericht van DexterDev, die meldt dat hij draait maar dat zijn rol nog niet is ingevuld
Hij draait. Wie hij is, weet hij nog niet.

De rol van DexterDev wilde ik bewust niet door OttoOps laten invullen. OttoOps mag de agent aanmaken en het gereedschap regelen, maar ik bepaal waarvoor ik DexterDev inzet.

Dit stuurde ik daarom rechtstreeks aan DexterDev:

Je bent nieuw hier en je weet nog niet wie je bent. Dat ga je nu vastleggen, voor jezelf, in je eigen map.

Wie je bent: je heet DexterDev en je bouwt. Ik beschrijf wat ik wil hebben, jij maakt het en legt me uit wat je gemaakt hebt. Ik bepaal wat er gebeurt en ik keur goed wat je oplevert.

Wat je werk is, in vier woorden: bouwen, repareren in code, testen, en opleveren. Testen hoort er nadrukkelijk bij — je levert niets op waarvan je alleen denkt dat het werkt. Zorg dat je kunt proberen wat je maakt, en zeg het me als je daar iets voor nodig hebt.

Wat je niet doet: beheer. Geen servers inrichten, geen diensten aan- of uitzetten, niets uitrollen, geen rechten regelen — ook niet voor de dingen die je zelf gemaakt hebt. Dat wat jij bouwt ergens moet draaien is waar, maar waar dat is en wie dat doet is niet jouw werk, en het is meestal niet eens deze server. Vraagt iemand je zoiets, dan zeg je dat het beheerwerk is en dat ik het regel. Je gaat het niet zelf proberen en je gaat het ook niet aan een ander vragen.

Leg het aan zoals het hier hoort. In de gedeelde basis ligt een document dat beschrijft welke bestanden elke agent heeft en wat erin staat; houd je daaraan en verzin geen eigen indeling. Kom je iets tegen dat het document niet dekt, zeg het me dan in plaats van het zelf op te lossen.

Houd het bestand met de stand van zaken kort — dat is een stand van zaken en geen dagboek.

Stuur me daarna in je eigen woorden terug wat je rol is en wat je niet doet, zodat ik kan zien of het is aangekomen.

Telegram: de rolbeschrijving voor DexterDev en zijn eigen samenvatting daarvan terug
In zijn eigen woorden terug, zodat ik kon zien of het was aangekomen.

De scheiding is daarmee eenvoudig: OttoOps beheert, DexterDev bouwt.

DexterDev mag code bouwen, repareren, testen en opleveren. Hij richt geen servers in, zet geen diensten aan of uit en rolt niets uit. Dat onderscheid gaat later belangrijk worden, want ik wil niet dat degene die iets bouwt automatisch ook beslist hoe en waar het in productie komt.

Telegram: op de vraag wat hij doet als de schijf volloopt antwoordt DexterDev dat dit beheerwerk is en niet bij hem hoort
De grens meteen uitgeprobeerd.

Daarna liet ik hem opnieuw starten:

Herstart DexterDev

Dat is een kleine test met een belangrijk doel: zijn rol en stand van zaken moeten van hemzelf zijn. Na een herstart moet hij nog steeds weten wie hij is.

Telegram: na een herstart vat DexterDev zelf samen waar het werk stond en waarop hij wacht
Na de herstart wist hij nog wie hij was en waar we stonden.

De echte proef

Aan het eind wilde ik niet alleen weten of beide agents op dat moment antwoordden. Ik wilde weten of de server nu werkelijk twee zelfstandige agents kon dragen.

Daarvoor ging de hele server opnieuw op.

Mijn laatste opdracht aan OttoOps was:

Start de server opnieuw op.

Jullie gaan daar allebei mee onderuit, dus zeg het me vóór je het doet. Ik verwacht daarna niets meer van je tot je er weer bent.

Na zo’n herstart moeten er twee terugkomen. OttoOps via zijn eigen ingang, DexterDev via de zijne. Allebei op dezelfde gedeelde machinerie, maar ieder met zijn eigen rol, eigen geheugen, eigen sleutel en eigen rechten.

Telegram: de opdracht om de server opnieuw op te starten, OttoOps die het aankondigt, en daarna de bevestiging met de uptime van de server
De opdracht, de aankondiging, en daarna de uptime als eerste controle.

Dat is ook het moment waarop deze aflevering voor mij geslaagd is.

Telegram: ook DexterDev is na de herstart van de server terug en weet nog waar het werk stond
En de tweede ook.

Niet omdat DexterDev bestaat. Een tweede proces starten is niet zo bijzonder.

Het verschil is dat er nu een fundament ligt waarop een volgende agent veel minder spannend hoort te zijn.

Wat ik hiervan meeneem

Deze aflevering kostte meer tijd dan ik vooraf verwachtte. Niet door DexterDev zelf, maar doordat de basis eerst echt generiek moest worden. Oude diensten moesten weg, onderdelen moesten verhuizen, de ontvanger bleek niet goed bewaakt en op een paar momenten wist ik simpelweg niet of OttoOps nog bezig was of dat er iets stuk was.

Dat laatste vind ik op dit moment misschien nog wel het lastigste van werken met een agent die op afstand zelfstandig taken uitvoert. Je ziet niet voortdurend wat hij doet. Als een opdracht wat langer duurt, is stilte normaal. Maar als de ontvanger uitvalt, is stilte óók normaal.

Je moet dus leren wanneer je wacht en wanneer je kijkt.

LocalClaude is daarbij voor mij heel waardevol. Niet als tweede beheerder die steeds tussendoor alles oplost, maar als iemand die van buitenaf kan kijken. Hij kan me vertellen of OttoOps nog draait, waar hij mee bezig is en — als iets echt misgaat — helpen om de juiste instructie voor OttoOps te formuleren.

En soms moet ik gewoon niet na dertig seconden nerveus worden.

Soms moet je vertrouwen hebben ;-).

De opbrengst is in ieder geval concreet: er staan nu twee agents op de server. OttoOps beheert de omgeving. DexterDev bouwt. Ze hebben ieder hun eigen ingang en eigen rechten, maar draaien op dezelfde gedeelde basis.

Voor het eerst begint het daarmee echt op een team te lijken.

Jouw reactie

Je eerste reactie lees ik eerst even mee voor hij verschijnt. Daarna staat hij er meteen op. Geen account nodig.