Bas de Kort

 ██████╗  █████╗ ███████╗    ██████╗ ███████╗    ██╗  ██╗ ██████╗ ██████╗ ████████╗
 ██╔══██╗██╔══██╗██╔════╝    ██╔══██╗██╔════╝    ██║ ██╔╝██╔═══██╗██╔══██╗╚══██╔══╝
 ██████╔╝███████║███████╗    ██║  ██║█████╗      █████╔╝ ██║   ██║██████╔╝   ██║
 ██╔══██╗██╔══██║╚════██║    ██║  ██║██╔══╝      ██╔═██╗ ██║   ██║██╔══██╗   ██║
 ██████╔╝██║  ██║███████║    ██████╔╝███████╗    ██║  ██╗╚██████╔╝██║  ██║   ██║
 ╚═════╝ ╚═╝  ╚═╝╚══════╝    ╚═════╝ ╚══════╝    ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝   ╚═╝

isoleer-wat-je-niet-vertrouwt.md

Isoleer wat je niet vertrouwt: de architectuur achter Pulse en Aura

Isoleer wat je niet vertrouwt: de architectuur achter Pulse en Aura

Datum
07-07-2026
Leestijd
6 min
Tags

De standaard-stack lekt en kijkt achteruit

De doorsnee WordPress-site meet en optimaliseert op de automatische piloot: Google Analytics erop, een SEO-plugin uit het vorige decennium ernaast, klaar. Twee gewoontes, twee problemen.

Google Analytics vraagt om een cookiebanner en stuurt bezoekersdata naar een advertentiebedrijf voordat je de eerste grafiek ziet; juridisch is dat in de EU al jaren wankel. En de klassieke SEO-plugin optimaliseert nog altijd voor een web met één zoekmachine, terwijl steeds meer mensen hun antwoord uit een AI-systeem halen dat structuur en context wil, geen keyword-dichtheid.

Ik bouwde twee plugins om dat recht te trekken: Pulse voor cookieloze analytics en Aura voor AI-ondersteunde SEO en GEO. Verschillende domeinen, maar onder de motorkap delen ze één principe dat ik in bijna elk project terug laat komen: isoleer het deel dat je niet vertrouwt.

Pulse: alles blijft op je eigen server

Bij analytics is het onbetrouwbare deel de bezoekersdata zelf. Zodra je persoonsgegevens vasthoudt of doorstuurt, heb je een probleem; met de wet, met je bezoeker, of met allebei. De ontwerpkeuze van Pulse is daarom simpel: er verlaat niets de server, en er wordt niets opgeslagen wat naar een persoon herleidbaar is.

Geen cookies, dus geen cookiebanner. In plaats van een bezoeker te taggen, bouwt Pulse een vluchtige, gehashte identifier op uit request-signalen, met een salt die roteert. Je kunt er sessies mee onderscheiden, maar niemand mee terugvinden; ook ikzelf niet, en dat is de bedoeling.

En nee, dit is nadrukkelijk geen fingerprinting. Een browser-fingerprint is juist bedoeld om je overal en langdurig te herkennen; hier roteert de salt, zodat dezelfde bezoeker morgen niet meer te matchen valt met vandaag. Het tegenovergestelde van een stille vingerafdruk.

De plugin is strak gelaagd (PHP 8.4, PSR-4, ruim veertig testklassen):

  • Een lichte ingestion-endpoint valideert en normaliseert elk event voordat het de database in gaat. User-agent-classificatie en herkomstbepaling gebeuren server-side, niet in de browser.
  • De privacy-laag (salt-store, visitor-hasher, exclusion-policy) is bewust een apart, geïsoleerd onderdeel. Anonimisering is geen bijzaak die je ergens tussen de regels regelt; het is een eigen module met eigen tests.
  • Een set presenters rekent de ruwe events om naar de cijfers achter elke grafiek: bezoekers over tijd, drukste uren, verkeersbronnen, bounce, sessieduur en paginatrajecten.
  • Onderhoud draait op WP-cron: een aggregate-roller verdicht oude events tot samenvattingen en een retention-policy ruimt de rest op, zodat de tabellen niet oneindig groeien.
Paginatrajecten als Sankey-diagram in Pulse
Paginatrajecten als Sankey-diagram in Pulse

Het aardige effect: omdat de ruwe data kort leeft en meteen wordt geaggregeerd, is "privacy by design" hier geen sticker maar een gevolg van de architectuur. Je kúnt niet lekken wat je niet bewaart.

Aura: SEO voor een web waar ook AI meeleest

Bij Aura is het onbetrouwbare deel iets heel anders: een taalmodel. Handig om meta-teksten te genereren, maar je wilt de output nooit blind vertrouwen. De hele plugin is eromheen gebouwd om die output te temmen.

Aura pakt drie dingen op die je normaal over drie plugins en een handmatig proces zou verdelen:

  • Generatie van meta-titels, descriptions en andere SEO-velden via Claude of OpenAI, in twee modi: alleen lege velden vullen, of bestaande overschrijven. De mens houdt de regie; de AI doet het typewerk.
  • Structured data: een samenhangende JSON-LD entity-graph in plaats van losse snippets. Uit een dienstpagina leidt Aura bijvoorbeeld een Service met bijbehorende Offer-entiteiten af (naam, prijs, valuta) en schrijft die naar de <head>, zodat zowel Google als een AI-systeem begrijpt wat je aanbiedt en wie erachter zit.
  • Scoring op twee assen, SEO én GEO, live bijgewerkt in de Gutenberg-editor terwijl je typt, met een checklist per onderwerp en historische snapshots.
De SEO- en GEO-content-analyse van Aura in de editor
De SEO- en GEO-content-analyse van Aura in de editor

Die scoring is geen vaag stoplicht. Per pagina zie je per onderwerp of iets aanwezig, gedeeltelijk of afwezig is: van canonieke URL en leesbaarheid tot citeerbare feiten, openingsantwoord en rijke pagina-entiteiten. Dat laatste rijtje is precies waar generative engine optimization over gaat; niet "scoor ik op dit trefwoord", maar "kan een AI mijn pagina begrijpen, citeren en vertrouwen".

De afgeleide schema.org-entiteiten in Aura
De afgeleide schema.org-entiteiten in Aura

Onder de motorkap is Aura de grootste van mijn plugins (PHP 8.4, PSR-4, zo'n vijfenzeventig testklassen), en de laag die het model afschermt is de kern:

  • Een provider-abstractie met inwisselbare clients voor Claude en OpenAI. Request-builders, response-mappers en een JSON-fence-stripper vangen de eigenaardigheden van elke API op, achter één interface.
  • Een generation-pijplijn (prompt-builder, post-reader, field-writer) die inhoud leest, een prompt opbouwt en het resultaat gecontroleerd terugschrijft naar de juiste velden; nooit rechtstreeks, altijd via een review-stap.
  • Een output-laag die de entity-graph opbouwt uit een eigen schema.org-vocabulaire, met page-type-resolver en breadcrumb-trail.
  • Een scoring-engine met axis-scorers, een topic-catalogus en een aggregator die pagina-scores optelt tot een site-analyse.

Het gedeelde principe: isoleer wat je niet vertrouwt

Zet de twee naast elkaar en je ziet dezelfde beweging. Pulse duwt het onbetrouwbare (persoonsgegevens) naar een geïsoleerde privacy-laag en zorgt dat het er zo snel mogelijk weer uit is. Aura duwt het onbetrouwbare (een LLM) achter een provider-interface en een review-UI, en laat de output nooit ongefilterd doorstromen.

Dat is geen toeval maar een ontwerpregel. Het onvoorspelbare deel van een systeem, of dat nu gevoelige data of een generatief model is, hoort achter een smalle, expliciete grens die je volledig kunt testen. Alles daarbuiten, het grootste deel van de plugin, wordt daardoor saai en voorspelbaar; en saai is precies wat je wilt in code die jaren mee moet.

Het is ook waarom beide plugins zo goed te testen zijn. Je vervangt de salt-store door een fake, of de LLM-client door een stub die een vast antwoord teruggeeft, en de rest van de logica draait er gewoon omheen. Het onbetrouwbare deel is dun genoeg om te vervangen, en de rest weet niet beter.

Wat het oplevert

Voor de eigenaar van de site is het resultaat prozaïsch, en dat is een compliment. Statistiek die je aanzet en vergeet, zonder banner en zonder juridische kater. SEO die meebeweegt met hoe er in 2026 gezocht wordt, inclusief de AI die meeleest. En in beide gevallen: je data en je logica blijven op je eigen server, zonder vendor lock-in.

Voor mij als bouwer is de winst de architectuur eronder. Twee plugins met totaal verschillende doelen, gebouwd op hetzelfde principe. Zodra je het onvoorspelbare hebt afgeschermd, wordt de rest een kwestie van rustig, testbaar en onderhoudbaar werk. En dat is uiteindelijk waar goede software over gaat; niet de slimme trucs, maar de saaie randen die blijven kloppen.