# Doc → KB-fil destillasjonsprompt (lag 4) Brukes av `commands/kb-update.md` (apply-flyten) for å destillere et **hentet** Microsoft Learn-dokument til en KB-referansefil i pluginens husformat. Pares med `scripts/kb-update/lib/transform.mjs`: den deterministiske header-byggeren (`buildKbHeader`), kontrakt-valideringen (`validateKbFile`) og lag-5-broen (`buildChange`). Skiller seg fra `scripts/skill-gen/prompt-template.md` (som genererer fra MCP-research, fritt) ved at denne **destillerer én utpekt kilde** og **forankrer** innholdet mot den. ## Hvorfor Source ligger i headeren `build-registry`/`lib/kb-headers.mjs` skanner kun de **øverste 500 bytene** etter `**Source:**`. Den gamle malen la kilder i en bunn-seksjon → usynlig for skanneren → `authority_source`-dekning = 0 %. Lag 4 legger `**Source:**` i header-blokka. Det er det som lar lag 3 (verifisering-INN, fremtidig) backfille `authority_source` og lag-5 regel 3 (autoritets-mismatch) faktisk fyre. ## Variabler (caller injiserer) - `{{TITLE}}` — engelsk tittel (h1) - `{{STATUS}}` — release-stage fra kilden: `GA` | `Public Preview` | `Private Preview` | `Announced` | `Deprecated` | `Retired` - `{{CATEGORY}}` — taksonomi-kategorinøkkel (f.eks. `rag-architecture`) — bestemmer eierskill via `resolveTargetPath` - `{{SOURCE_URL}}` — den **utpekte autoritetskilden** (kanonisk Learn-URL dokumentet ble hentet fra) - `{{LAST_UPDATED}}` — `YYYY-MM` (dagens måned, caller-injisert) - `{{FETCHED_DOC}}` — den hentede markdownen fra `microsoft_docs_fetch` - `{{EXISTING_CONTEXT}}` — sammendrag av overlappende eksisterende ref-filer (unngå duplisering — K4) ## Header (deterministisk — IKKE la LLM-en skrive den) Header-blokka bygges av `buildKbHeader({title, status, category, source, lastUpdated})`, ikke av modellen. Den ser slik ut og MÅ stå først: ```markdown # {{TITLE}} **Last updated:** {{LAST_UPDATED}} **Status:** {{STATUS}} **Category:** {{CATEGORY}} **Source:** {{SOURCE_URL}} --- ``` Modellen skriver **kun brødteksten under `---`**. Etterpå kjører `validateKbFile(header + body)` og MÅ returnere `valid: true` (title + Last updated + Status + Source til stede) før noe gates videre. ## Prompt (brødtekst) ``` Du er Cosmo Skyberg, senior Microsoft AI Solution Architect. Destillér kildedokumentet under til en kunnskapsreferanse på norsk (engelske tekniske termer beholdes) for et Claude Code-plugin som hjelper norsk offentlig sektor med Microsoft AI. KILDE (utpekt autoritet — forankre alt mot denne, ikke mot generell kunnskap): {{SOURCE_URL}} KILDEDOKUMENT: {{FETCHED_DOC}} Skriv KUN brødteksten (under header-`---`). Seksjoner (alle påkrevd): 1. Introduksjon (2-3 avsnitt) — hva, hvorfor, plassering i MS-økosystemet 2. Kjernekomponenter / nøkkelegenskaper — tabeller for sammenligning 3. Arkitekturmønstre — 2-3 mønstre, når hvert passer, fordeler/ulemper 4. Beslutningsveiledning — «Velg X når …», vanlige feil, røde flagg 5. Integrasjon med Microsoft-stakken 6. Offentlig sektor (Norge) — GDPR, Schrems II, AI Act, datasuverenitet 7. Kostnad og lisensiering — prismodell på oversiktsnivå 8. For arkitekten (Cosmo) — 5-8 nøkkelspørsmål, fallgruver 9. Kilder og verifisering — pek på {{SOURCE_URL}} + evt. relaterte, konfidensnivå per seksjon REGLER (strenge): 1. Forankring: hver faktapåstand skal kunne spores til kildedokumentet. Fyll ALDRI hull med gjetninger — skriv «(uverifisert)» eller utelat. 2. STATUS-PÅSTANDER EKSPLISITT: enhver GA/preview/versjon/pris-/SLA-påstand skal stå som en tydelig, isolerbar setning. Disse blir ALLTID operatør-gated av lag 5 (spec §21) — ikke skjul dem i prosa, og ikke flat ut en nyansert status («delvis GA, resten preview») til en enkel «GA». 3. Norsk prosa, engelske tekniske termer. Tabeller over løpende tekst der det passer. 4. Balansert (fordeler OG ulemper), konkret over vagt, 200-400 linjer. 5. Ingen duplisering av: {{EXISTING_CONTEXT}} Ingen innledning eller avslutningskommentar — kun markdown-brødteksten. ``` ## Etter destillasjon (caller, gated) 1. `content = buildKbHeader({...}) + body` 2. `validateKbFile(content)` → må være `valid: true` (ellers: be modellen fikse manglende felt). 3. For hver status-/load-bearing-påstand: `buildChange({field, oldValue, newValue, sourceUrl, authoritySource})` → `classifyChange(...)` (lag 5). `flagged` → operatør avgjør; status-påstander er alltid `flagged`. 4. `resolveTargetPath(tax, category, filename)` → eierskill-sti (null = ukjent kategori → gate, ikke skriv). 5. Først etter operatør-gate: atomisk skriving (`lib/atomic-write.mjs` + `lib/backup.mjs`). Transform-libben skriver aldri selv. ```