Elk team heeft iemand die weet hoe het hier hoort.

Hoe we onze endpoints noemen. Welk result-type we teruggeven. Waarom we nooit vanuit een handler een exception gooien. Hoe een migratie wordt gereviewd voordat hij gemerged wordt. Niets ervan staat opgeschreven. Het zit in het hoofd van één of twee mensen en verspreidt zich via osmose — hier een opmerking in een code review, daar een “nee, wij doen het zo”.

Die persoon is een bottleneck. En als je Claude Code gebruikt, heb je dat waarschijnlijk erger gemaakt zonder het te merken.

Want je hebt Claude Code jouw conventies geleerd. In je CLAUDE.md, in de manier waarop je prompt, in de honderd correcties die je per week maakt. Jouw Claude Code schrijft code zoals jij het wilt. Die van je collega niet. Die van de nieuwe collega al helemaal niet.

De kennis zit nu op twee plekken in plaats van één: in jouw hoofd, en in jouw persoonlijke setup. Geen van beide is van het team.

Skills lossen dat op.


CLAUDE.md is persoonlijk. Skills zijn deelbaar.

Even een onderscheid, want de twee overlappen.

CLAUDE.md is altijd-aan-context voor een repo. Claude leest het elke sessie — het is wat een code review laat klinken als je meest ervaren teamlid in plaats van als een generieke linter. Het is de juiste plek voor feiten die altijd waar zijn: “dit is een ASP.NET Core 9 API, we gebruiken EF Core, target framework net9.0”. Maar het is één groeiende lap tekst, en in de praktijk is een groot deel ervan persoonlijk of lokaal aan hoe jij werkt.

Een skill is een map met een SKILL.md die Claude op aanvraag laadt — alleen wanneer de taak bij de beschrijving past. Het is een benoemde, herbruikbare vaardigheid. En cruciaal: hij staat in de repo, in versiebeheer, dus iedereen die de repo cloont krijgt hem.

Een vuistregel:

  • CLAUDE.md — context die Claude altijd moet hebben. De stack, het target framework, de non-negotiables.
  • Skill — een specifieke manier om een specifiek ding te doen. “Hoe we een HTTP-endpoint toevoegen.” “Hoe we een migratie schrijven.” “Hoe we een PR reviewen.”

Het verschil dat telt voor een team: een skill is vindbaar en overdraagbaar. Je hoeft er niet zelf bij te zitten.


De conventie die in je hoofd zit

Even concreet. Bij ons is een nieuw API-endpoint niet zomaar een controller-action. Het moet:

  • de input valideren en een 400 met een problem-details body teruggeven als het fout is,
  • een Result<T> teruggeven in plaats van een exception te gooien,
  • nooit rechtstreeks de DbContext aanraken vanuit de handler,
  • met een xUnit-test worden opgeleverd.

Nergens staat dat opgeschreven. Het is gewoon hoe wij het doen.

Nu komt er een nieuwe developer bij die aan zijn Claude Code vraagt:

“Voeg een endpoint toe om een trip te annuleren.”

Hij krijgt een prima controller. Die gooit een InvalidOperationException als de trip niet bestaat. Die geeft de Trip-entity rechtstreeks uit de DbContext terug. Er is geen test. Niets eraan is fout — het is alleen niet hoe wij het doen.

Dus de pull request komt binnen, en een reviewer schrijft dezelfde drie opmerkingen die hij elke week schrijft. De nieuwe developer fixt het. Iedereen is twintig minuten kwijt. En er is niets geleerd dat de volgende nieuwe developer niet opnieuw hoeft te leren.


Er een skill van maken

De oplossing is de conventie één keer opschrijven, in een vorm die Claude kan toepassen. Maak een bestand aan op .claude/skills/add-endpoint/SKILL.md:

---
name: add-endpoint
description: >
  Gebruik dit bij het toevoegen of wijzigen van een HTTP-endpoint in
  deze API. Dwingt onze validatie-, result-type- en testconventies af.
---

# Een endpoint toevoegen

Elk endpoint in dit project volgt dezelfde vorm.

## Regels

1. Valideer eerst de input. Geef bij fouten een `400` met een
   `ProblemDetails` body — gooi nooit een exception voor foute input.
2. De handler geeft `Result<T>` terug, nooit de EF-entity, en gooit
   geen exception voor verwachte fouten (not-found, conflict).
3. De handler raakt de `DbContext` niet rechtstreeks aan. Hij roept een
   repository of een domain service aan.
4. Elk endpoint wordt opgeleverd met een xUnit-test die het happy path
   en minstens één failure path dekt.

## Vorm om te volgen

```csharp
public async Task<Result<TripDto>> CancelTrip(Guid tripId, CancellationToken ct)
{
    var trip = await _trips.Find(tripId, ct);
    if (trip is null)
        return Result.NotFound($"Trip {tripId} bestaat niet.");

    var outcome = trip.Cancel();          // de beslissing zit in het domein
    if (outcome.IsFailure)
        return Result.Conflict(outcome.Error);

    await _trips.Save(trip, ct);
    return Result.Ok(trip.ToDto());
}
```

Nu stelt de nieuwe developer exact dezelfde vraag — “voeg een endpoint toe om een trip te annuleren” — en Claude Code herkent de taak, laadt de skill, en produceert het endpoint in onze vorm: validatie vooraan, een Result<T>, geen DbContext in de handler, en de xUnit-test ernaast.

De reviewer schrijft die drie opmerkingen niet. Omdat het nooit nodig was.


Zet het in versiebeheer

Dit is het stuk dat een persoonlijk trucje verandert in een teamvoorziening.

.claude/skills/ is gewoon een aantal bestanden in je repo. Commit ze. Vanaf dat moment krijgt elke developer die het project cloont de skill automatisch — geen setup, geen “installeer mijn config”, geen Slack-bericht met een gist eraan.

Het effect op onboarding is het interessante. Een nieuwe collega hoeft de conventie niet te kennen om hem te volgen. Hij vraagt Claude Code om een endpoint en krijgt er een die meteen past. Hij leert de conventie door de code te lezen die eruit kwam, niet door hem eerst fout te doen in een PR. De kennis is uit één hoofd verhuisd naar de repository, waar hij thuishoort.

En omdat skills code zijn, worden ze gereviewd als code. Een wijziging in hoe je endpoints toevoegt is een pull request tegen add-endpoint/SKILL.md — zichtbaar, besproken, geversioneerd. Je conventies krijgen een changelog.


Waar dit dun wordt

Twee eerlijke beperkingen, want een skill is geen toverstaf.

Skills verouderen, en een verouderde skill is erger dan geen. Een skill die de conventie van vorig kwartaal beschrijft, past vol vertrouwen het verkeerde toe — snel en overal. Dus een skill heeft een eigenaar nodig en moet worden gereviewd als de conventie verandert. Houd ze klein en specifiek. Een gigantische “hoe we alles doen”-skill wordt niet op het juiste moment geladen en niet onderhouden — die rot gewoon weg.

Een skill is richting, geen garantie. Hij vormt wat Claude produceert; hij dwingt niets af. Iemand kan nog steeds een endpoint mergen dat hem negeert. Afdwingen is een andere laag — checks die in je pipeline draaien en review-gates met een mens aan het eind — en daar gaat deze serie naartoe.


Probeer het deze week

Kies de ene conventie die je jezelf hardop hoort uitleggen aan elke nieuwe persoon. Precies één. De endpoint-vorm, het migratieritueel, de manier waarop je een handler opbouwt — wat je ook beu bent om te herhalen.

Schrijf er een SKILL.md voor: een naam, een beschrijving van één alinea, en één before/after C#-voorbeeld. Commit het. De volgende keer dat iemand — of zijn Claude Code — die taak doet, kijk of ze je nog nodig hebben in de kamer.

Welke conventie leg jij steeds met de hand uit? Zet ’m in de comments — de kans is groot dat het een skill is die erop wacht geschreven te worden, en ik ben benieuwd wat ieders “wij doen het zo” blijkt te zijn.


Dit is deel 1 van een korte serie over Claude Code inzetten over een heel team, niet alleen aan je eigen bureau.

Volgende — deel 2, op 27 juli: als je eenmaal een skill hebt die het delen waard is, hoe verscheep je die dan — samen met je subagents en hooks — als één plugin die je hele team met één commando installeert? Deel 3 volgt op 3 augustus.