AI i praksis CV Kontakt
✦ AI & Udvikling

AI i praksis for teams der bygger rigtige systemer

Jeg bygger .NET/Angular-systemer og designer AI-workflows, der skaber fart uden at skabe kognitiv gæld.

.NET  ·  Angular  ·  AI Workflows  ·  København / Remote
10+ års erfaring .NET / Angular specialist AI workflows i praksis Løsningsarkitektur Internal AI Tooling / RAG Systemtænkning

Kognitiv gæld — den usynlige risiko ved AI-assisteret udvikling

01

Teknisk gæld kan ses i koden. Kognitiv gæld kan ikke. Det er tabet af den fælles forståelse af, hvordan systemet virker, hvorfor beslutningerne blev truffet, og hvad grænserne er. AI accelererer akkumuleringen — fordi koden er for god til at stille spørgsmålstegn ved.

01
Princip 01
Kognitiv gæld

AI-genereret kode kan være perfekt, smuk og velstruktureret — og stadig farlig. Ikke fordi den er forkert, men fordi ingen på teamet kan forklare hvad den gør, hvordan den virker, eller hvorfor den er designet sådan. Den mest farlige kode i en codebase er koden ingen forstår. Selvom den virker.

02
Princip 02
Shared Theory

Shared theory er den kollektive forståelse teamet har af, hvordan systemet virker, hvorfor beslutningerne blev truffet, og hvad grænserne er. Det er ikke dokumentation. Det er den levende forståelse — og det er præcis det kognitiv gæld eroderer. Kode fortæller hvad der sker. Shared theory fortæller hvorfor.

03
Princip 03
Lånt fart

Hastighed uden forståelse er ikke velocity. Det er held. Et team der shipper hurtigt med AI er kun produktivt, hvis de kan debugge, udvide og refaktorere koden uden at gå tilbage til AI'en. Kan de ikke det, er hastigheden lånt — og lånt hastighed forfalder altid.

Hastighed uden forståelse er ikke velocity. Det er held. Dit team shipper hurtigt med AI — men det er kun reelt, hvis de kan debugge, udvide og refaktorere koden uden at gå tilbage til AI'en. Kan de ikke det, er hastigheden lånt. Og lånt hastighed forfalder altid.

Prakash Raman — Engineering Lead, Brex
Tre praksisser — ingen af dem sænker farten

Disse tre praksisser fanger 80% af kognitiv gæld og gør teamet bulletproof når noget bryder ned.

01
Review som junior
— ikke som senior

Reviewer ikke AI-genereret kode for at fange bugs. Reviewer den for at forstå den. Tre spørgsmål inden merge: kan jeg forklare hver linje til en kollega? Forstår jeg hvorfor denne tilgang frem for alternativerne? Kan jeg modificere koden trygt uden at prompte igen?

Hvis svaret på ét spørgsmål er nej — merge ikke. Forstå det, eller omskriv de dele du ikke forstår.

3-am testen: Kunne jeg debugge dette klokken 3 om natten? Ja → ship it. Nej → brug 10 minutter nu.
02
Forklar shipment
inden merge

Inden AI-genereret kode merges: ét afsnit. Ikke en kodekommentar, ikke en commit-besked — en beslutningspost. Hvad gør det, hvorfor er det designet sådan, og hvad er de kendte edge cases.

Skrives i det øjeblik du forstår koden — ikke retroaktivt. Det tager fem minutter. Det sparer to dage med arkæologi.

Praksis 1 + 2 tilsammen fanger 80% af kognitiv gæld.
03
Rotér konteksten
på kritiske flows

Rotér regelmæssigt gennem AI-genererede moduler — ikke for at genopbygge dem, men for at forstå og opdatere beslutningsposter. Start med auth, betalinger og kritiske dataflows.

Baren er ikke at kunne skrive det fra hukommelsen. Baren er at kunne forklare det — og finde fejlen når det bryder ned.

Resultat: Et team reducerede MTTR (Mean Time To Resolution — gennemsnitlig tid fra fejl opstår til den er løst) fra 4 timer til 45 minutter. Samme codebase. Samme team. Eneste forskel: de forstod den.
Koncepter
Kognitiv gæld Shared Theory Lånt fart Review som junior Beslutningsposter 3-am testen

Second Brain — et lokalt RAG-system der giver Claude Code hukommelse

02
Second Brain RAG system
Kørende lokalt

Obsidian-noter chunkes ved H1/H2-overskrifter, embeddes med sentence-transformers og gemmes i ChromaDB. Claude Code kalder /ask?raw=true automatisk inden ny implementering — og får de præcise regler tilbage fra vidensbasen.

Et tilbagevendende problem ved at arbejde med AI over tid: viden akkumuleres i markdown-filer, men AI starter hver session på bar bund. Second Brain løser det — et lokalt RAG-system bygget over Obsidian, der giver Claude Code semantisk søgning over 837 chunks af arkitekturregler, kodestandarder og patterns.

Pipeline — fra markdown til svar
📝
Obsidian .md
97 filer
✂️
chunk_ markdown
837 chunks
🧮
sentence-transformers
all-MiniLM-L6
🗄️
ChromaDB
semantisk
🔍
BM25
keyword
RRF + FastAPI
hybrid rank
🤖
Claude Code
raw=true
Hybrid search — semantisk + keyword

Det største problem i RAG er ikke at finde data — det er at finde de rigtige data. Ren semantisk søgning misser eksakte kodeord som HasSentinel, DbContext og ErrorOr. Løsningen er hybrid search: semantisk søgning via ChromaDB kombineres med BM25 keyword-søgning og rangeres med Reciprocal Rank Fusion. Chunks der scorer højt i begge vinder — tekniske kodeord matches eksakt, konceptuelle spørgsmål matches semantisk.

Obsidian som single source of truth

Hele vidensbasen lever i Obsidian — arkitekturregler, DDD-mønstre, gotchas og kodestandarder. Markdown-filer chunkes ved H1/H2-overskrifter frem for fast størrelse, fordi en sektion er en meningsenhed. Frontmatter strippes, rene wikilink-sektioner filtreres væk. Resultatet er 592 semantisk afgrænsede chunks fra 69 filer — inkl. beslutningsdokumenter (ADRs) der forklarer hvorfor vi valgte Wolverine, gRPC og Signals.

6 namespaces — præcis kontekst
csharp— regler, DDD, Wolverine, EF Core, Modular Monolith angular— signals, Material, UI-mønstre, skills architecture— Clean Architecture blueprints og patterns workflow— Claude Code, TDD, AI-principper projects— lessons learned fra side-projekter setup— trin-for-trin guides til nye projekter
Web UI — søg og udforsk vidensbasen

Second Brain er primært bygget til Claude Code — men et indbygget web-interface gør det muligt for mennesker at inspicere vidensbasen direkte. Her kan man stille de samme spørgsmål som Claude ville stille, se hvilke chunks der returneres, og forstå hvorfor et svar er præcist eller upræcist. Guide-panelet forklarer hvordan man skriver markdown-filer der chunkes rigtigt.

Second Brain søgegrænseflade
Søgegrænseflade — namespace-filter, chunk-scores og suggestion chips
Second Brain guide-panel
Guide-panel — filstruktur, namespace-oversigt og frontmatter-regler
Claude Code integrationen — raw=true

CLAUDE.md fortæller Claude Code at kalde Second Brain inden ny implementering. raw=true returnerer chunks direkte uden GPT-omgang — Claude er selv en LLM og læser dem direkte. Hurtigere, billigere og mere præcist.

# Tjek regler inden implementering curl "http://localhost:8000/ask?q=regler+for+value+object&namespace=csharp&raw=true" # Angular signals mønster curl "http://localhost:8000/ask?q=signals+state+management&namespace=angular&raw=true"
Hvad det løser i praksis

Uden Second Brain starter hver session på bar bund — regler skal gentages, kontekst gen-etableres. Med Second Brain ved Claude Code at HasSentinel er påkrævet for strongly-typed IDs, at queries returnerer ErrorOr<T> ligesom commands, og hvorfor vi valgte Wolverine frem for MediatR. En file watcher holder databasen automatisk opdateret ved Obsidian-ændringer, og et /reload endpoint genindlæser indekset uden server-genstart.

Teknologier
Python FastAPI ChromaDB BM25 Hybrid Search sentence-transformers Obsidian RAG raw=true CLAUDE.md

Plan først. Kod bagefter. — et struktureret AI-udviklingsflow

03

De fleste bruger AI til at skrive kode hurtigere. Det er det forkerte spørgsmål. Det rigtige spørgsmål er: hvordan sikrer vi at AI-genereret kode altid er sporbar, forståelig og knyttet til en klar forretningsbeslutning? Svaret er et struktureret flow — plan → GitHub → branch → execution.

ProjectSetup API — det mellemlag der eksekverer mod GitHub — er et konkret projekt jeg har udviklet sammen med Claude Code. Det er et eksempel på hvad der sker når AI ikke bare skriver kode, men er aktiv deltager i at designe og bygge et system fra bunden.

Claude tænker
API handler
GitHub ejer
AI pipeline — menneske planlægger, Claude eksekverer autonomt via MCP
01
Planning

RAG henter regler og arkitekturmønstre. Claude genererer epics, stories og tasks ud fra projektbeskrivelsen. ProjectSetup API opretter strukturen i GitHub. Ingen kode skrives før planen er godkendt.

02
Definition of Ready

API'et afviser tasks der ikke starter med et imperativ verbum eller mangler description. Det er ikke en guideline — det er enforcement. En task må max dække ét endpoint og ét lag. Mangler noget, får du 400 tilbage.

03
Branch & Execution

Branch navngives med issue ID: feat/123-create-auth-endpoint. Claude implementerer én task ad gangen med RAG-kontekst. Small Bites — afvent godkendelse inden næste trin startes.

04
Failure & Retry

Når execution fejler: POST /api/tasks/{id}/fail kommenterer issue med årsag og sætter task tilbage til Ready. Pipelines der kun håndterer happy path er ikke pipelines — de er scripts.

05
PR & Afslutning

PR indeholder Fixes #123 — task lukkes automatisk ved merge. Sporbarhed bevaret hele vejen: story → task → branch → PR → kode.

Context Builder

Inden Claude implementerer bygger systemet automatisk en token-optimeret prompt: task fra GitHub + de 2–3 mest relevante RAG-chunks. Claude modtager præcis det den har brug for — ikke mere. Kvaliteten af output afhænger direkte af kvaliteten af RAG-indholdet. Et system der kun håndterer happy path er ikke et system — det er et script.

Mange laver fejlen at lade AI styre alt direkte. Det giver kaos. Den korrekte model er at behandle AI som en tænker, ikke en controller. AI genererer og foreslår — et dedikeret API eksekverer og standardiserer — GitHub ejer sandheden. Det gør systemet konsistent og sporbart. Og når noget fejler, ved systemet hvad det skal gøre: dokumentér årsagen, sæt task tilbage til Ready, og prøv igen.

Teknologier & koncepter
GitHub Projects ProjectSetup API RAG Claude Code Definition of Ready Context Builder Failure Loop Sporbarhed

Master Prompt Template — token-kontrol og conditional context

04

At få konsistent output fra AI kræver ikke perfekte prompts — det kræver et system. Jeg bruger en Master Prompt Template med conditional context: kun de regler der er relevante for opgaven aktiveres, resten forbliver i Obsidian.

Conditional context — token-kontrol i praksis

Compact Core Rules ligger altid passivt som fundament og koster minimalt i tokens. De komplette regler for C#, Angular og integration trækkes kun ind via eksplicitte @-blokke, når opgaven kræver det. Det holder AI'en fokuseret og reducerer støj.

Tre lag i templaten
1
Rolle + Opgave

Én sætning der definerer AI'ens perspektiv og den præcise opgave. Ingen vague "hjælp mig med" — konkret domæne og handling.

2
Kontekst-aktivering

Vælg @C#-Core-Rules, @Angular-Core-Rules eller @Integration-Rules. Kun de relevante. Dermed læser AI'en præcis de regler der gælder — ikke alt på én gang.

3
Failure Pattern-tjekliste

Builtin verifikationstrin i prompten: ingen ErrorOr fra queries, signals ikke BehaviorSubject, CDK overlays via panelClass. AI'en checker mod listen inden output leveres.

Token-fordeling
Aktiv token-brug per session-type
Compact Core
Altid
@C#-Core-Rules
Ved behov
@Angular-Core-Rules
Ved behov
Komplet regelbase
Aldrig
Hvorfor dette er værdifuldt for firmaer

Interne AI-agenter der styres med denne struktur er forudsigelige, auditérbare og billige at drifte. Failure Patterns dokumenterer præcis hvilke fejl agenten er trænet ud af — ikke som en fejlliste, men som et styringsgrundlag.

Koncepter
Conditional Context Token-kontrol Master Prompt Template CLAUDE.md Failure Patterns Small Bites Obsidian

Evals — automatiseret test af AI-output i den fulde pipeline

05

At kalde Claude med en prompt og håbe på det rigtige output er ikke et system — det er et eksperiment. Evals er den mekanisme der gør forbedringer målbare: RAG returnerer de rigtige chunks, prompten er præcis nok, og Claude genererer output der følger arkitekturreglerne. Uden evals ved man ikke om en ændring hjalp.

To typer evals

En direkte eval sender prompten direkte til Claude og tester prompt-kvaliteten isoleret. En pipeline eval kalder POST /api/tasks/build-prompt på ProjectSetup API — det er ContextBuilderService der bygger prompten præcis som i produktion. Derefter sendes den til Claude og outputtet valideres af asserters. Pipeline eval er den vigtige — ikke en simulering, men det faktiske system.

Pipeline eval flow — RAG, ContextBuilderService, Claude og Promptfoo asserters i loop
RAG er det eneste der virker ved API-kald

Når Claude kaldes direkte via API er der ingen CLAUDE.md, ingen hooks, ingen projektkontekst. Claude starter uden kontekst. RAG er den eneste mekanisme der bringer reglerne ind — og evals er det der afslører om RAG leverer nok. En regel der ikke er i den chunk der returneres, er en regel Claude aldrig ser.

Enhance-rytmen
1
Kør eval — find fejlmønster

Promptfoo kører testcases og returnerer score per assertion. Regex-asserters fanger konkrete mønstre som strongly-typed IDs og ErrorOr<T>. LLM-as-judge scorer helhedsvurderingen mod golden eksempler.

2
Verificér RAG-chunk — billigt

Inden eval køres igen: tjek at den relevante chunk faktisk returneres og indeholder reglen. En curl-kald mod RAG koster intet. En fuld eval med LLM-as-judge koster tokens.

3
Ret RAG — én ændring ad gangen

Kritiske regler placeres i introteksten inden første sektion — den del der returneres med højest relevans. Regler begravet i en undersektion får sit eget embedding og returneres muligvis aldrig.

Hvad der ikke løser problemet

At rette asserters så de passer til forkert output er den klassiske fælde. En test der accepterer readonly record struct RunId i stedet for record RunId skjuler et reelt EF Core-problem. Testen er sandheden — RAG er det der skal rettes.

Koncepter
Promptfoo LLM-as-judge RAG Pipeline eval Enhance Mode Målbar forbedring

Failure Patterns — hvad AI konsekvent gør forkert, og hvordan jeg træner den ud af det

06

Dokumenterede mønstre fra egne projekter: hvad AI gør forkert på tværs af Angular og .NET Clean Architecture — og de præcise regler der er kodet ind i CLAUDE.md og rules.md for at eliminere dem permanent.

Angular

Signals vs RxJS blanding

AI gør

Bruger RxJS BehaviorSubject og Subject til lokal komponentstate — blander Observables og Signals i samme service.

Fix

Signals til al state i services og komponenter. RxJS kun til debounced validators, WebSocket streams og kompleks event-koordinering.

Start med signal(). Introducér kun RxJS når signals ikke kan løse det naturligt.
Angular

::ng-deep på Material overlays

AI gør

Bruger ::ng-deep i komponent-SCSS til at style mat-select, mat-menu og mat-dialog — virker ikke, fordi CDK overlay renderes udenfor komponentens DOM.

Fix

Brug panelClass + global styling i styles.scss. Det er den eneste pålidelige måde at ramme CDK overlay-elementer.

CDK overlay er udenfor komponentens DOM. ::ng-deep har ingen effekt. Brug panelClass.
Angular

mat-select null→null

AI gør

Bruger (selectionChange) event binding — som ikke fyrer når ny value matcher gammel value, fx null→null ved reset af filter.

Fix

FormControl + valueChanges observable. Fyrer altid — uanset om ny value matcher gammel.

(selectionChange) er upålidelig ved null-værdier. Brug altid FormControl + valueChanges.
C# Backend

Queries returnerer ErrorOr

AI gør

Returnerer ErrorOr<T> fra query handlers — korrekt for commands, men forkert mønster for queries i Clean Architecture.

Fix

Queries kaster en exception eller returnerer null. ErrorOr er forbeholdt commands — aldrig queries.

Commands returnerer ErrorOr<T>. Queries returnerer ALDRIG ErrorOr — kast exception eller returner null.
C# Backend

Domain events krydser BC-grænsen

AI gør

Eksponerer domain events som integration events der konsumeres af andre bounded contexts — bryder DDD-isolationen.

Fix

Domain events er interne til en bounded context. BC-kommunikation sker via gRPC (synkront) eller Wolverine Outbox (asynkront).

Domain events er interne. BC-grænser krydses kun via gRPC eller integration events via Outbox.
Workflow

AI springer TDD Red over

AI gør

"Ser noget der virker hurtigt" — det er præcis signalet for at hoppe direkte til implementering og springe Red-fasen over.

Fix

Hold AI eksplicit på: "Hvad er din Red test?" inden implementering starter. Testen skal køre og fejle af den rigtige grund.

Red skal køre og fejle af den rigtige grund. Ingen grøn kode inden testen er rød.
Kategorier
Angular C# Backend Workflow CLAUDE.md rules.md

AI i praksis — erfaringer fra en løsningsarkitekt

07
Live demo

Angular-klient der kalder et GraphQL API for at validere et produktnavn i realtid — bygget med AI som aktiv medudvikler og struktureret kontekst via CLAUDE.md.

Jeg har de seneste måneder arbejdet målrettet med at forstå, hvordan AI kan blive en reel del af min arbejdsdag som løsningsarkitekt og udvikler — ikke som et buzzword, men som et konkret værktøj.

Fra idé til kørende kode

Mit udgangspunkt var enkelt: kan jeg bruge AI til at bygge et fuldt Angular-projekt fra bunden, og hvad kræver det at gøre det rigtigt? Resultatet er et frontend-projekt koblet til et GraphQL API bygget oven på AdventureWorks-databasen. Undervejs har jeg lært, at gevinsten ikke kun ligger i kodegenerering — den ligger i de beslutninger man træffer inden man skriver den første linje.

Kontekst er alt

Det vigtigste jeg har lært: AI er kun så god som den kontekst du giver den. Jeg har investeret tid i at bygge et system af markdown-filer — koderegler, arkitekturbeslutninger, arbejdsprocesser og skills — som AI'en læser ved hver session. Det betyder at Claude kender vores navnekonventioner, ved hvornår RxJS er bedre end Signals, og følger vores Small Bites-arbejdsproces med checkpoints og godkendelser.

Mennesket er stadig arkitekten

AI skriver kode hurtigt. Men det er stadig mig der beslutter hvad der skal bygges, hvordan det skal struktureres, og hvornår vi stopper og reflekterer. Jeg har bevidst valgt en arbejdsform hvor AI er et kraftfuldt værktøj under min styring — ikke en autopilot.

Hvad jeg arbejder med nu

Angular 20 med signals-first arkitektur og Angular Material · Strukturerede AI-workflows med CLAUDE.md, rules.md og custom skills · Frontend ↔ backend samarbejde med GraphQL. Jeg deler løbende mine erfaringer her på siden.

Teknologier
Angular 20 Signals GraphQL Angular Material CLAUDE.md

Clean Architecture med AI — backend som håndværk

08

Parallelt med frontend-projektet har jeg brugt AI til at bygge et .NET backend-system fra bunden — med de samme krav til kvalitet og struktur som jeg ville stille til et produktionssystem.

Fra database til domænemodel

Mit udgangspunkt var AdventureWorks-databasen og et klart arkitekturmål: Clean Architecture, Domain-Driven Design og CQRS. Resultatet er et API med GraphQL udadtil og in-process Contracts-interfaces til kommunikation mellem bounded contexts. AI har skrevet store dele af koden — men inden den første fil blev oprettet, havde jeg defineret lagstrukturen, navnekonventionerne og de regler der ikke måtte brydes.

Regler som sikkerhedsnet

Det vigtigste jeg tog med fra frontend-arbejdet: AI skal have præcis kontekst. Jeg byggede et system af markdown-filer der beskriver arkitekturen, kodereglerne og arbejdsprocessen. Claude ved at domain events er interne til en bounded context, at queries returnerer ErrorOr<T> ligesom commands, og at en ny aggregate ikke må røre infrastrukturlaget før domænet er testet. Det er ikke begrænsninger — det er det der gør outputtet brugbart.

Arkitekturtests som vagthund

Et af de mest værdifulde greb var at indføre automatiske arkitekturtests med NetArchTest. De kører efter hver ændring og sikrer at ingen lagafhængigheder brydes — uanset om det er mig eller AI der har skrevet koden. Det giver en frihed til at arbejde hurtigt uden at miste overblikket.

Wolverine som mediator og Outbox

Til intern beskedorkestrering bruger jeg Wolverine — både som mediator til at håndtere commands og queries, og til at sikre pålidelig beskedlevering via Outbox-mønstret. Outbox sikrer at domænehændelser aldrig går tabt, selv hvis noget fejler efter at en transaktion er committed. Det er et af de greb der løfter systemet fra "det virker som regel" til "det virker altid".

TDD som arbejdsform

Hver bid følger Red→Green→Refactor. AI skriver den minimale test først — den skal fejle af den rigtige grund inden der skrives en linje produktionskode. Domæntests er rene unit tests uden infrastruktur. Application tests bruges kun til de stier der ikke kan dækkes fra domænet: NotFound, outbox-adfærd, validator-integration. Architecture tests med NetArchTest kører automatisk efter hver bid og sikrer at ingen lagafhængigheder brydes.

Tre spor — én proces

Arbejdet er struktureret i tre spor: Full til ny adfærd (med Naming First, Acceptance Criteria og micro-bids), Lightweight til bugfixes og simple queries, og Refactoring til omstrukturering uden ny adfærd. Hvert spor har sine egne checkpoints — herunder et præ-krav om characterization tests inden refactoring starter. Sporene giver et fælles sprog og sikrer at AI og udvikler altid er enige om scope inden kode skrives.

Observabilitet med Aspire og OpenTelemetry

Løsningen er orkestreret med .NET Aspire, som starter alle services og eksponerer et Dashboard med traces, strukturerede logs og metrics. OpenTelemetry er konfigureret centralt i ServiceDefaults og dækker HTTP-requests, GraphQL resolver spans, Wolverine command- og event-handlers samt EF Core SQL-queries med fuldt statement. Det giver et komplet billede af hvad der sker fra GraphQL-kald til database — uden at instrumentere de individuelle services.

Mennesket sætter grænsen

AI kan generere en handler, en value object og tilhørende tests på få minutter. Det er imponerende — og potentielt farligt. Jeg har bevidst valgt en Small Bites-arbejdsproces med checkpoints: vi aftaler hvad der bygges, AI leverer, jeg vurderer og godkender. Ikke fordi AI laver fejl hele tiden, men fordi arkitekturansvar ikke kan delegeres.

Teknologier
.NET 9 Clean Architecture DDD CQRS GraphQL Modular Monolith TDD xUnit Shouldly NetArchTest Wolverine Outbox Aspire OpenTelemetry FluentValidation

Sales Dashboard — datadrevet UI med ECharts og draggable widgets

09
Live demo

Sales dashboard med ECharts-grafer og CDK DragDrop — træk et widget op i expand-zonen for at se detaljeret data, træk det tilbage for kompakt visning. Globalt år-filter opdaterer alle widgets simultant.

Et dashboard er et godt prøvested for mødet mellem datakompleksitet og brugervenlighed. Her byggede jeg et salgs-dashboard oven på AdventureWorks GraphQL API'en — med fokus på hvad Angular Signals og moderne biblioteker kan, når de bruges rigtigt.

Signals hele vejen ned

Al state — valgt år, indlæsningsstatus, data fra fem GraphQL-queries — lever som Angular Signals i en enkelt service. Chart-options beregnes som computed() signals der reagerer automatisk når data eller år-filter ændres. Ingen manuel change detection, ingen subscription management.

ECharts med tree-shaking

Graferne er bygget med ngx-echarts og Apache ECharts — med fuld tree-shaking via provideEchartsCore. Linjegraf, vandret søjlediagram og donut-chart importerer kun de komponenter de faktisk bruger. Chart-konfigurationen er rene dataobjekter uden sideeffekter.

Draggable widgets med CDK

Angular CDK DragDrop forbinder en grid-zone og en expand-zone. Træk et widget op — det flytter sig til expand-zonen og viser udvidet indhold. Træk det tilbage — det kollapser. Ghost-elementet roterer let og skalerer op under drag, drop-zonen lyser op ved modtagelse. Alt med CSS-only animationer.

Parallelle data-kald

Alle fem GraphQL-queries — summary, måneder, territorier, kategorier og sælgere — hentes parallelt med Promise.all ved år-skift. Ingen vandfaldseffekt, ingen unødvendig ventetid. Resultatet sættes direkte i signals som grafer og lister reaktivt læser.

Teknologier
Angular 20 Signals ECharts ngx-echarts CDK DragDrop GraphQL computed() Promise.all

Executor Mode — når AI ignorerer sine egne regler, og hvad der stoppede det

10

Jeg bruger CLAUDE.md til at definere regler for AI-adfærd — obligatoriske stop, teknologivalg, læringsrytme. Reglerne virker. Indtil prompten er detaljeret nok. Så skifter Claude fra rådgiver til executor og ignorerer dem. Fire gange i træk. Løsningen var ikke bedre dokumentation — det var et shell-script.

Problemet

Planning-pipelinen kræver at Claude stiller fire spørgsmål inden den gør noget: ny løsning eller eksisterende? Arkitektur? API-type? Shared Theory? Det er dokumenteret i CLAUDE.md, i RAG, i memory-filer. Claude læser det — og springer alligevel over, hvis prompten indeholder nummererede trin og curl-kald. En detaljeret prompt aktiverer executor-mode og overskygger reglerne.

Test 1
CLAUDE.md + RAG

Regler dokumenteret. Claude læser dem og går alligevel direkte i gang. Sprunget over fordi "opgaven var veldefineret".

Test 2
Tilføjet memory-filer

Eksplicit feedback gemt på tværs af sessioner. Samme resultat — detaljeret prompt vinder over memory.

Test 3
Kortere planning-prompt

Én sætning i stedet for nummererede trin. Virker — Claude stiller spørgsmålene. Men afhænger af at prompten altid er kort.

Test 4
Detaljeret prompt igen

Samme fejl. Konklusionen: adfærden kan ikke løses med dokumentation. Problemet er strukturelt.

Indsigten

Regler i tekst kan overskrives af kontekst. Kode kan ikke. Løsningen er ikke bedre formulering — det er at flytte ansvaret ud af Claudes fortolkning og ind i noget deterministisk.

Løsningen — 20 linjer bash

Claude Code understøtter UserPromptSubmit hooks: shell-scripts der kører ved hver besked inden Claude ser prompten. Scriptet detekterer Mode: planning og injicerer en CRITICAL OVERRIDE direkte i Claudes kontekst — uden om prompten.

Hooken kører på harness-niveau. Den kan ikke overstyres af en detaljeret prompt. Det er ikke afhængigt af Claudes selvdisciplin — det er deterministisk.

# Kører ved hver besked
INPUT=$(cat)

if echo "$INPUT" | grep -qi "mode: planning"; then
  cat <<'EOF'
{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "CRITICAL OVERRIDE
Stil de 4 spørgsmål. Ingen kode. Ingen curl."
  }
}
EOF
fi

exit 0

Det interessante er ikke at AI bryder regler — det er hvornår. En vag prompt giver plads til at konsultere reglerne. En detaljeret, instruerende prompt aktiverer en anden tilstand: Claude eksekverer. Løsningen er ikke at skrive bedre regler. Det er at acceptere begrænsningen og designe systemet derefter.

Teknologier & koncepter
Claude Code Hooks UserPromptSubmit CLAUDE.md AI-adfærd Deterministisk pipeline Executor Mode
✦ Urelateret frontend-eksempel

Hvad kan AI i frontend?

En selvstændig HTML-side bygget med frontend-design skillen, der kalder PokeAPI. Ingen frameworks, ingen forretningskrav — bare et eksperiment i hvad AI kan levere i design og funktionalitet fra bunden.

Har du et komplekst system
eller vil bruge AI rigtigt?

Lad os tage en uforpligtende snak.