# Spec — Redesign av KB-kunnskapsmekanismen (ms-ai-architect) _Godkjent plan (operatør, 2026-06-19). Avløser planleggings-input i `kb-mechanism-redesign-brief.md`. Implementeres én sesjon per økt; STATE.md peker på neste sesjon._ ## Context Kunnskapen pluginen leverer (389 referansefiler over 5 skills) er dens kjerneverdi; de 29 kommandoene/12 agentene er bare leveringsmekanismer oppå den. Dagens `kb-update`-mekanisme er **URL- og metadata-forankret**: den ser bare endring i sider den *allerede* siterer, måler «endret» på sitemap-`lastmod` (ikke faktisk innhold), og forankrer status-påstander (GA/preview/versjon) mot en *tilfeldig sitert* side — som ga en reell regresjon (agentic-retrieval-status ble «korrigert» feil; hovedkontekst måtte rette manuelt). Empiri fra søk-først kvantifiserer problemet: - **35 % av KB-en (468/1344 URLer) er `not_in_sitemap`** → «alltid stale». For Azure AI Foundry er det **100 % (164/164)** fordi MS restrukturerte URL-rommet — kjerne-produktet gir aldri et currency-signal. - **0 % av filene har en maskinlesbar `Source:`-header** → en forankret per-fil-verifisering har ingen inngangsdata i dag. - **Discovery er en dead-end:** `discover-new-urls.mjs` skriver `discovery-report.json` som *leses av ingenting*; nye sider registreres aldri. Kurs (`/training/`) er eksplisitt ekskludert. - **Fire divergerende taksonomier** styrer i dag hva som er «i domenet» (poll-prefikser, discovery-INCLUDE, skill-gen-kategorier, prioritets-regex) — allerede inkonsistente. **Mål:** en mekanisme som holder de eksisterende skills *oppdatert* (currency), *komplette* (nye sider + kurs) og *optimaliserte* (målbar kvalitet), med **auto-deteksjon (scheduled) og operatør-gate på all skriving**. Utfall: pluginen «står på egne ben» — mindre avhengig av manuell hovedkontekst-verifisering, uten å miste operatør-kontroll over innholdet. ### Låst scope og retning (operatør, 2026-06-19) - **I scope:** krav 1 currency · 2 completeness (nye sider + kurs) · 4 optimalisering av eksisterende skills. - **UTE av scope:** krav 5 (lage nye skills) · krav 6 (slå sammen/slette skills). Innhold kan *vokse* (nye ref-filer ok), men **ingen destruktive ops**. - **Autonomi:** deteksjon kjører automatisk → rapport; **all** KB-skriving + URL-registrering går gjennom operatør-gate. - **Verifisering:** hver faktapåstand forankres mot en *utpekt* autoritetskilde; status-påstander (GA/preview/versjon/pris) flagges **alltid** for operatør. - **Kurs:** Microsoft Learn **Platform API** direkte (krever Entra ID app-registrering; verifisert: app-only, scope `https://learn.microsoft.com/.default`, `api-version=2023-11-01-preview` obligatorisk, 100 calls/min, ingen betaling). Legacy Catalog API er deprecated «through June 2026» → kill-switch-fallback. ## Arkitektur — 6 lag oppå delt registry ``` 0. TAKSONOMI data/domain-taxonomy.json — én sannhetskilde for "i domenet" (poll, discovery, skill-gen, prioritet leser HERFRA) 1. DETEKSJON currency + completeness + kurs → produserer KUN rapporter 2. DECISION-LEDGER data/decisions.json — eneste skrive-autoriserte bro; / OPERATØR-GATE dedup så avviste kandidater ikke re-foreslås 3. VERIFISERING-INN autoritetskilde-binding på godkjente kandidater 4. TRANSFORMASJON doc→KB-fil (LLM-destillasjon, status-felt obligatorisk) 5. VERIFISERING-UT adversarial "prøv-å-motbevis" + status-gate (fanger regresjons-klassen — kjøres ETTER transformasjon) 6. EVAL/OPTIMALISERING rubrikk K1–K9 (uavhengig av 1–5) ``` **Lag 0** og **lag 2** er ikke valgfrie: uten konsolidert taksonomi blir completeness til silent misrouting; uten decision-ledger + dedup drukner gaten operatøren → autonomien blir teater (primær-fallgruve). Verifisering er bevisst splittet i **inn** (lag 3) og **ut** (lag 5) fordi den kjente regresjonen er en *post*-transformasjons-feil. ## Roadmap (multi-sesjon, én økt per sesjon) | Sesjon | Leveranse | Verifiserbart kriterium | |---|---|---| | **1** | **Eval-baseline + ai-foundry-probe** (read-only) | `node eval.mjs --json \| jq '.skills\|length' == 5`; 10 ai-foundry-URLer kategorisert {redirect/dead/ny-sti} med beslutning | | **2** | Taksonomi-konsolidering (lag 0) + registry-skjema (`authority_source`, `status`, kurs-felt) + ai-foundry signal-fiks | `grep -c "TARGET_PREFIXES = \[" scripts/kb-update/*.mjs == 0`; ai-foundry `not_in_sitemap` < 50 % | | **3** | Decision-ledger (lag 2) + lukk discovery-løkken gjennom gaten | Discovery 2× re-foreslår ikke en `rejected` URL (dedup-diff) | | **4** ✅ | Verifisering-ut (lag 5) + adversarial regresjonstest | ✅ Kjent agentic-retrieval-regresjon som fixtur → `flagged:true`, ikke `auto-applied` (se Sesjon 4-resultater) | | **5** | Transformasjonslag (lag 4) + 2 carry-forward cleanups (foldet inn 2026-06-19) | Regenerer 1 fil → eval-score ≥ baseline | | **Parallelt spor** | Kurs / Platform API-spike (Entra-app + token + date/product-filter) — **av kritisk vei** | `poll-training.mjs` ≥1 kurs m/ `last_modified`; ELLER kill-switch→legacy dokumentert | Scheduled deteksjon (`/schedule` eller hook) + wiring i `commands/kb-update.md` = siste integrasjonssteg etter lag 1–3. ## Sesjon 1 (detaljert) **Del A — Eval-baseline (lag 6, flyttet fram):** nytt read-only script som kjører K2/K3/K5/K6 (grep/wc) på alle 5 `SKILL.md` + refs, og LLM-judge (Opus) for K1/K4/K7/K8/K9 på de 5 `SKILL.md`. Output `eval-baseline.json` (skrives kun etter operatør-gate) = referansen alt senere måles mot. **Del B — ai-foundry signal-probe (riskeste antakelse, ren read):** 10 `not_in_sitemap` ai-foundry-URLer → `microsoft_docs_fetch` → kategoriser {finnes/redirect/ny-sti}. Avgjør om Sesjon 2 er en poll-fiks eller en re-mapping-oppgave. ### Rubrikk K1–K9 (krav 4, «optimalisert skill») - K1 trigger-presisjon (LLM, 20 test-prompts ≥90 %/≤10 %) · K2 tredjeperson/format i description (regex) · K3 SKILL.md ≤500 linjer (wc) · K4 ingen SKILL.md↔ref-duplisering (LLM ≥4/5) · K5 progressive disclosure: navngitte filer ikke mapper (grep, ratio ≥20 %) · K6 kjernefil-routing-tabell finnes (grep) · K7 imperativ-stil (LLM ≥80 %) · K8 kildehenvisning i ref-filer (LLM ≥80 %) · K9 ingen tid-sensitiv info i SKILL.md body (LLM). ## Gjenbruk vs. nybygg (navngitte filer) **Gjenbruk direkte:** `scripts/kb-update/lib/sitemap-stream.mjs`, `lib/url-normalize.mjs`, `lib/registry-io.mjs`, `lib/atomic-write.mjs` + `lib/backup.mjs` (← for **all** gated skriving), `poll-sitemaps.mjs`-kjernen, `generate-skills.md` 5-parallelle fan-out + `prompt-template.md`. **Må endres:** `discover-new-urls.mjs` (INCLUDE → poll-paritet + ikke-bare-engineering; skriv decision-ledger-input); `report-changes.mjs` (`getFilePriority` leser taksonomi; datoløse filer = «uverifisert», ikke critical-støy); `build-registry.mjs` (les `Source:`-header → `authority_source`); `commands/kb-update.md` (apply leser decision-ledger); `scripts/skill-gen/category-skill-map.json` (inn i taksonomien). **Nytt:** `data/domain-taxonomy.json`, `data/decisions.json`, `data/training-registry.json`, `poll-training.mjs`, eval-script (K1–K9) + `eval-baseline.json`, doc→KB-destillasjons-prompt, adversarial motbevis-prompt. **Multi-agent gir kvalitet (senere):** lag 5 (adversarial motbevis-panel per status-påstand), lag 4 (parallell doc→KB-transformasjon). Foreslås når fasene starter. ## Risiko (rangert) og håndtering 1. **Gaten drukner operatøren → autonomi blir teater** (primær). → decision-ledger + dedup (lag 2); riktig klassifisering av datoløse/`not_in_sitemap`-filer (Sesjon 2). 2. **ai-foundry = re-mapping, ikke poll-fiks** (35 % av KB). → testes først (Sesjon 1 Del B). 3. **Platform API-onboarding blokkerer** (ekstern). → av kritisk vei + kill-switch→legacy. 4. **Taksonomi-drift → misrouting.** → lag 0 før discovery lukkes. 5. **Transformasjon innfører regresjon.** → eval-baseline før-måling; lag 5 adversarial-test før vi stoler på laget. ## Verification (overordnet) - Per-sesjon kriterier (tabell) er kjørbare sjekker. - Pluginens gates ved hver commit: `validate` (239+), `kb-integrity` (115/115), `gitleaks` clean. - Arkitektur-invariant: deteksjon skriver *aldri* til KB direkte — kun via `decisions.json` etter gate (deteksjon-scripts importerer ikke write-utils). ## Inneværende scope vs. fremtidig roadmap **Inneværende mekanisme-arbeid (Sesjon 1–5 + kurs-spor):** krav 1 currency · 2 completeness · 4 optimalisering — på de eksisterende 5 skills. Innhold kan vokse (nye ref-filer). **Utsatt til senere faser — på roadmap, IKKE forkastet** (operatørens valg 2026-06-19 var «krav 1–4 nå»; krav 5/6 var merket «ikke nå», dvs. utsatt): - **Krav 5 — lage nye skills profesjonelt.** Naturlig neste utvidelse når deteksjonen (lag 1) begynner å avdekke domener uten dekning (fra domene-taksonomien: f.eks. Power Platform AI / AI Builder / Power Automate, Dynamics365). Forutsetter lag 0–3. - **Krav 6 — slå sammen/slette skills (livssyklus, destruktive ops).** Krever egne guardrails (aldri tap av kuratert verdi) + obligatorisk operatør-gate. Vurderes etter at lag 1–6 står. Annet utsatt arbeid sporet her: **Low-currency-bøtta (51 filer)** — parkert bak redesignet; kjøres med den nye mekanikken (eller som siste enkle bøtte hvis redesignet drar ut). > Denne seksjonen ER roadmapen for fremtidige faser. Den bor i `docs/` (ikke en egen `ROADMAP.md`) per den globale «ingen lokale kontinuitets-mekanismer»-regelen, og refereres fra `STATE.md`. --- ## Sesjon 1 — resultater (2026-06-19) ✅ FERDIG Kriterier møtt: `node scripts/kb-eval/eval.mjs --json | jq '.skills|length'` = 5; 10 ai-foundry-URLer kategorisert. Tester: **kb-eval 13 PASS · kb-update 42 PASS (regresjon) · validate 239 PASS**. Node 25 krever eksplisitte filstier (`tests/X/*.test.mjs`), ikke katalog. ### Eval-baseline (referanse for senere optimalisering — lag 6) Verktøy: `scripts/kb-eval/eval.mjs` (determ. K2/K3/K5/K6 + ref-tall) + operatør-gated LLM-judge (`judge-prompt.md` → `data/judge-results.json`), flettet til `data/eval-baseline.json`. Tester i `tests/kb-eval/`. Pass-matrise (K2/K3/K7/K8 ✓ for alle 5): - **K5 (progressive disclosure): 3/5 FAIL** — advisor (1,6 %), engineering (0 %), security (16 %) bruker mappehenvisninger; infrastructure (97 %) er forbildet å kopiere. - **K9 (tid-sensitiv info i SKILL.md body): 4/5 FAIL** — GA/preview-status, modellversjoner, SLA-/perf-tall ligger i body (kun advisor ren). Hører i ref-filer (currency-sporet). - **K4 (duplisering): 2/5 FAIL** — governance (3/5: DPIA/AI-Act/Digdir dupliserer ref-filer), security (3/5). - **refTall-konsistens: 2/5 FAIL** — engineering (agent-orch tabell 20 vs faktisk 24; total 149 vs 153), governance (29 vs 30). **To konkrete bugs (operatør-beslutning kreves; fikses i optimaliserings-fase, ikke nå):** 1. **security 6×5-vekting motstrider kanonisk rubrikk:** SKILL.md body (Identity 20/Network 15/Data 20/Content 20/Compliance 15/Mon 10) ≠ `security-scoring-rubrics-6x5.md` (Compliance 25/Data 20/Identity 20/Content 15/Network 10/Mon 10). Påvirker scoring-output. → hvilken er kanonisk? 2. **governance-SKILL.md linje 191** peker på ikke-eksisterende `drift-detection-automated-retraining.md` (faktisk: `model-performance-drift-detection.md`). K1-presisjon (0,95–1,0) er **PROVISORISK** — operatør må kuratere 20 trigger-prompts/skill. Flagg: governance-description mangler Schrems II-trigger; advisor-description er bred nok til å over-trigge mot søsken-kommandoer. ### ai-foundry signal-probe → BESLUTNING for Sesjon 2 10 URLer: **8 LIVE · 0 MOVED · 2 DEAD**. Rotårsak: MS rebrandet «Azure AI Foundry» → «Microsoft Foundry»; nye canonical-URLer under `/azure/foundry/` (i `azure_en-us_7`-sitemap), gamle `/azure/ai-foundry/` serverer fortsatt innhold men matcher aldri sitemapet → 100 % `not_in_sitemap`. **→ POLL-FIKS (ikke re-arkitektur av signalet):** remap registry `azure/ai-foundry/*` → `azure/foundry/*` + 2 DEAD-remappinger (`concepts/evaluation-evaluators`→`concepts/built-in-evaluators`; `agent-service`→`agents/overview`). Sitemap-`lastmod` fra `azure_en-us_7` er tilstrekkelig signal; ingen innholdshash nødvendig. --- ## Sesjon 2 — konkret startplan (lag 0 + registry-skjema + ai-foundry poll-fiks) **Mål:** konsolidér de fire divergerende taksonomiene til ÉN sannhetskilde, utvid registry-skjemaet, og fiks ai-foundry-blindsonen (poll-fiks). **TDD: skriv test FØR kode.** Invariant: deteksjon skriver aldri til KB; ikke rør krav 5/6. **Rekkefølge:** 1. **Les først:** `scripts/kb-update/{poll-sitemaps,discover-new-urls,report-changes,build-registry}.mjs`, `lib/{registry-io,url-normalize,atomic-write,backup}.mjs`, `data/url-registry.json` (skjema), og `scripts/skill-gen/{categories.json,category-skill-map.json}`. 2. **`data/domain-taxonomy.json`** (lag 0, ny): samle dagens 4 taksonomier til én — (a) sitemap-prefikser (fra `poll-sitemaps.mjs` `TARGET_PREFIXES`), (b) discover INCLUDE/EXCLUDE (utvid til poll-paritet: mangler `microsoftteams`/`sharepoint`/`microsoft-365`/`training`/`cloud-computing`/`privacy`; og ikke-bare-engineering-skill-mapping), (c) skill+kategori-mapping (`category-skill-map.json`), (d) prioritet (`report-changes.mjs` `getFilePriority`). 3. **Refaktorer** `poll-sitemaps.mjs` + `discover-new-urls.mjs` + `report-changes.mjs` til å LESE taksonomien. **Kriterium:** `grep -c "TARGET_PREFIXES = \[" scripts/kb-update/*.mjs` == 0. 4. **Registry-skjema** (bakoverkompatibelt): legg til `authority_source`, `status`, kurs-felt. `build-registry.mjs` leser `**Source:**`/`**Primary source:**`-header når den finnes (i dag 0 % dekning — ikke krav å backfille alle nå). 5. **ai-foundry poll-fiks:** remap registry `azure/ai-foundry/*`→`azure/foundry/*` + 2 DEAD-remappinger (over). Bruk `lib/backup.mjs` + `lib/atomic-write.mjs` for skriving. **Kriterium:** ai-foundry `not_in_sitemap` < 50 % (fra 100 %). 6. **Tester** (`tests/kb-update/` el. ny `tests/kb-eval/`): taksonomi-lasting + remap-logikk. Node 25 → kjør med eksplisitt filsti. 7. **Avslutt:** `validate` 239 + alle enhetstester grønne · commit per logisk enhet · push (i vindu 20–23 hverdag) · oppdater STATE.md (Sesjon 3 neste) + denne roadmapen (Sesjon 2-resultater). **Ikke i Sesjon 2:** de 2 bug-fiksene (6×5-vekting, governance ref-path) — de hører i optimaliserings-fasen og venter på operatør-beslutning (kanonisk vekting). --- ## Sesjon 2 — RESULTATER (FERDIG, 2026-06-19) **Begge akseptansekriterier møtt:** `grep -c "TARGET_PREFIXES = \["` == 0 ✅ · foundry `not_in_sitemap` **38,4 %** (63/164, fra 100 %) < 50 % ✅. Tester: validate 239 · kb-update 66 (+24) · kb-eval 13 — alle grønne. 3 commits (8bea3a2 lag 0 · eb2a002 skjema · d3af3f7 remap) + docs. **Levert:** - **Lag 0:** `data/domain-taxonomy.json` (tracket via gitignore-negasjon `data/*` + `!domain-taxonomy.json`; generert registry/rapporter forblir ignorert). `lib/taxonomy.mjs` laster + kompilerer. `poll-sitemaps`/`discover-new-urls`/`report-changes` LESER taksonomien — ingen embeddede kopier. - **Registry-skjema (minimal-reservert, operatør-valg):** `authority_source:null` + `course:null` på alle 1343 entries. `build-registry` leser `**Source:**`-header via `lib/kb-headers.mjs` og logger dekning (0/N i dag). Eksisterende poll-`status` urørt (unngikk kollisjon). - **ai-foundry-fiks:** `lib/registry-migrate.mjs` + one-shot `migrate-ai-foundry.mjs` (backup + atomisk). 164 remappet, 2 DEAD eksplisitt, 1 kollisjon merget, remappede → `unpolled`. **Konsolideringsfunn (binding for Sesjon 3):** - **`category-skill-map.json` er stale i 4 entries** (`copilot-extensibility`, `monitoring-observability`, `performance-scalability`, `prompt-engineering` → sier `engineering`; **disk** sier advisor/governance/security/advisor). Disk er kanon; taksonomien bruker disk-sannhet. Map-en er **ukonsumert av kode** (kun README) → flagget, ikke rørt. **Sesjon 3-kandidat:** korriger/avskilt `category-skill-map.json` + README, ELLER bekreft taksonomien som eneste kilde. - **Datoløse-filer-reklassifisering** (getFilePriority: datoløs = «uverifisert» i stedet for critical-støy): **utsatt** (ekskludert fra Sesjon 2 per operatør-valg — adferdsbevarende refaktor nå). **Sesjon 3-kandidat.** - **foundry/openai-tail:** 63 gjenstående `not_in_sitemap` er nesten utelukkende `/azure/foundry/openai/*` (egen URL-struktur, ikke probet). Ingen gjettede remaps. Kandidat for målrettet probe senere. --- ## Sesjon 3 — konkret startplan (lag 2: decision-ledger + lukk discovery-løkken) **Mål:** bygg `data/decisions.json` som **eneste skrive-autoriserte bro** mellom deteksjon og KB/registry, med **dedup** så avviste kandidater aldri re-foreslås. Dette løser primær-fallgruven (gaten drukner operatøren → autonomi blir teater). **TDD: skriv test FØR kode.** **Invariant (§83): deteksjon-scripts importerer ALDRI write-utils** (`atomic-write`/`backup`/`saveRegistry`) — de kun LESER ledger for å filtrere; skriving til ledger skjer kun via operatør-gate. **Rekkefølge:** 1. **Les først:** `scripts/kb-update/discover-new-urls.mjs` (kandidat-output `discovery-report.json`: `{url, lastmod, sitemap, suggested_skill, suggested_category}`), `commands/kb-update.md` (apply-flyt = gaten), `lib/registry-io.mjs` (`saveReport`/atomisk-mønster å speile), `lib/taxonomy.mjs` + `lib/registry-migrate.mjs` (Sesjon 2-mønstre for ren-funksjon-+-tynn-script-split). 2. **`data/decisions.json`-skjema** (lag 2, nytt — tracket som `domain-taxonomy.json`, IKKE generert): ledger keyet på normalisert URL. Per entry: `{status: pending|approved|rejected, decided_at, suggested_skill, suggested_category, note?}` + toppnivå `version`/`updated_at`. **Beslutningspunkt:** dedup ekskluderer KUN `rejected`, eller alle `decided` (approved teller som «allerede håndtert»)? Anbefalt: ekskluder alle `decided` fra re-forslag; `pending` beholdes til operatør avgjør. 3. **`lib/decisions-io.mjs`** (ren I/O, speil `registry-io`): `loadDecisions`/`saveDecisions` (atomisk), `isDecided(ledger, url)`, `recordDecision(ledger, url, decision)`. TDD-test først. 4. **discover dedup:** `discover-new-urls.mjs` LESER `decisions.json`, filtrerer ut alt som er `isDecided` FØR kandidater emitteres. Nye → `pending` (eller fravær = ubesluttet). **Kriterium:** kjør discover 2×, en `rejected`-URL re-foreslås IKKE (dedup-diff-test mot fixture). 5. **Gate-wiring (`commands/kb-update.md` apply):** apply-steget viser `pending`-kandidater → operatør approve/reject → skriver `decisions.json` (ENESTE skrivevei) → `approved` registreres i `url-registry` (gated, via `registry-io`). Script-siden leverer ledger-I/O + «pending»-visning; selve interaktive apply er LLM-drevet (slash-command). Dokumentér flyten. 6. **Invariant-guard-test:** assert at `discover-new-urls.mjs` IKKE importerer `atomic-write`/`backup`/`saveRegistry` (grep-test). + decisions-io + dedup-tester. Node 25 → eksplisitt filsti. 7. **Avslutt:** `validate` 239 + alle enhetstester grønne · commit per logisk enhet · push (vindu 20–23 hverdag) · oppdater STATE.md (Sesjon 4 neste) + denne roadmapen (Sesjon 3-resultater). **Også vurder i Sesjon 3 (Sesjon 2-funn, operatør-beslutning):** (a) `category-skill-map.json` stale i 4 entries — korriger/avskilt + README, ELLER bekreft taksonomi som eneste kilde; (b) datoløse-filer-reklassifisering i `getFilePriority` (datoløs = «uverifisert», ikke critical-støy). Begge er små; ta dem hvis tid, ellers eksplisitt til Sesjon 4. **Ikke i Sesjon 3:** lag 3 (verifisering-inn), lag 4/5 (transformasjon/verifisering-ut), kurs-sporet, de 2 SKILL.md-bugene (6×5-vekting, governance ref-path — venter på kanonisk-vekting-beslutning). --- ## Sesjon 3 — RESULTATER (FERDIG, 2026-06-19) **Akseptansekriterium møtt:** dedup-diff — en `rejected` URL foreslås i runde 1, men **ikke** i runde 2 (test `dedup-diff — a rejected URL is re-proposed in round 1 but NOT in round 2`). Tester grønne: validate **239** · kb-update **82** (+16) · kb-eval **13** · kb-integrity **115/115**. **Dedup-policy = A (operatør-valg 2026-06-19):** `isDecided(url)` = enhver ledger-entry. Alt operatøren har tatt stilling til — approved, rejected *og* utsatt (pending) — dedupes; discovery re-foreslår kun URLer som er **helt fraværende** fra ledgeren. Renest å resonnere om, og den eneste som fullt nøytraliserer primær-fallgruven (gate-støy). Pending vises i egen bøtte fra ledgeren, ikke som påtrengende re-forslag. **Levert:** - **`data/decisions.json` (lag 2):** tracket via gitignore-negasjon (som `domain-taxonomy.json`; generert registry/rapporter forblir ignorert). Skjema: `{version, updated_at, decisions: {[normalisertUrl]: {status, decided_at, suggested_skill, suggested_category, note?}}}`. - **`lib/decisions-io.mjs`** (speiler `registry-io`-stil, null avhengigheter): `createLedger` · `loadDecisions` · `saveDecisions` (atomisk .tmp→rename) · `isDecided` (policy A) · `recordDecision` (ren, muterer ikke) · `filterUndecided`. TDD: 10 tester FØR kode. - **discover-wiring:** `discover-new-urls.mjs` LESER ledger (`loadDecisions`+`isDecided`), filtrerer i kandidat-løkken, rapporterer `deduped_by_ledger` i `discovery-report.json` + logg. **Importerer ALDRI write-utils.** - **Gate dokumentert** i `commands/kb-update.md` §3b («Discovery-gate»): eneste skrivevei = `recordDecision`+`saveDecisions`; `approved` → `url-registry` (gated via `saveRegistry`); `decided_at` caller-injisert. Apply er LLM-drevet per design (ikke eget apply-script — lib gir deterministisk skrivevei). - **Invariant-guard-test** (`test-discover-invariant.test.mjs`, 6 tester): import-spesifikk sjekk at discover IKKE importerer `saveDecisions`/`saveRegistry`/`atomic-write`/`backup` (kommentarer kan ikke gi falske positiver) + positiv sjekk at `loadDecisions`/`isDecided` faktisk er wiret. **Binding for Sesjon 4:** - **IKKE tatt** (var «hvis tid»): `category-skill-map.json`-stale (4 entries) og datoløse-fil-reklassifisering i `getFilePriority`. Prioriterte kjerneleveransen + sporet onboarding-redesign i stedet. **Eksplisitt til Sesjon 4.** - **Nytt sporet sidespor (operatør-flagget 2026-06-19):** onboarding-/virksomhetskontekst-mekanismen oppfyller ikke «ambient i enhver interaksjon» + «overlever oppgraderinger» + mangler fritekst-felt → egen brief `docs/onboarding-redesign-brief.md` (task #26). Utenfor KB-redesignet; design godkjennes separat. - **Neste — Sesjon 4:** verifisering-ut (lag 5) + adversarial regresjonstest. Kriterium: kjent agentic-retrieval-regresjon som fixtur → `flagged:true`, ikke `auto-applied`. --- ## Sesjon 4 — RESULTATER (FERDIG, 2026-06-19) **Akseptansekriterium møtt:** den kjente agentic-retrieval-regresjonen som fixtur → `verdict: 'flagged'`, `status_claim: true`, IKKE `auto-applied` (test `agentic-retrieval regression fixture → flagged, NOT auto-applied`). Tester grønne: validate **239** · kb-update **95** (+13) · kb-eval **13** · kb-integrity **115/115**. gitleaks: 3 PRE-EKSISTERENDE i `playground/vendor/` (utenfor scope); nye filer rene. **Hva lag 5 er:** verifisering-UT kjører ETTER transformasjon (lag 4) og FØR en kandidat-endring skrives til en KB-fil. Den fanger regresjons-klassen — en status-påstand «korrigert» mot en *tilfeldig sitert* side og stille auto-applyet. Den faktiske regresjonen ligger i KB: `agentic-rag-patterns.md` beskriver «delvis GA via REST `2026-04-01`; answer synthesis + multi-turn forblir preview» — en naiv auto-correct ville flatet dette til «GA» og slettet nyansen. **Regel (spec §21):** status-påstander (GA/preview/versjon/pris) flagges **ALLTID**, aldri auto-applyet — uansett hvor sikker evidensen ser ut. Denne regelen alene bærer kriteriet. **Levert:** - **`lib/verify-out.mjs`** (ren klassifiserer, null avhengigheter — speiler `decisions-io`): `detectStatusClaim(text)` → `{isStatus, kinds[]}` (release-stage / version / price; `\bGA\b` er case-SENSITIV for å unngå norsk «ga»; bare kalenderdato ≠ status, kun `-preview`-versjoner teller). `classifyChange(change)` → `{verdict: 'flagged'|'auto-applied', status_claim, reasons[]}` med tre flag-regler: (1) **status-gate** (§21), (2) **adversarial refutering** (`refutations[].refuted===true`), (3) **autoritets-mismatch** (`source_url` ≠ utpekt `authority_source` — regresjonens rotårsak; inert mens `authority_source` er null pre-lag-3). Konservativ med vilje: ved tvil flagges. **SKRIVER ALDRI** — returnerer kun en verdict. - **Fixtur** `tests/fixtures/kb-update/agentic-retrieval-regression.json`: den kjente regresjonens FORM (flat «generally available (GA)» mot nyansert «delvis GA … resten preview», forankret mot ikke-autoritativ `whats-new`-side). Verdiene er illustrative for regresjonen, ikke en currency-påstand (verifiseringsplikt). - **TDD:** 13 tester FØR kode (`tests/kb-update/test-verify-out.test.mjs`), inkl. import-invariant (`verify-out.mjs` importerer ingen write-utils — ren klassifiserer). - **Wiret i `commands/kb-update.md` §4 c2:** lag 5 kjører mellom (c) identifiser-endring og (d) skriv. `flagged` → operatør avgjør; `auto-applied` → trygt. Adversarial motbevis-panel er LLM-runtime (multi-agent foreslås i produksjon, §71). **Binding for Sesjon 5:** - **FOLDET INN i Sesjon 5** (operatør-valg 2026-06-19) — to carry-forward cleanups, bevisst holdt utenfor lag-5-kriteriet: - **(A) `category-skill-map.json` — 4 stale entries:** `copilot-extensibility`/`monitoring-observability`/`performance-scalability`/`prompt-engineering` sier `engineering` i map-fila, men disk-sannhet er advisor/governance/security/advisor (Sesjon 2-funn §151). Map-en er **ukonsumert av kode** (kun README). → korriger map + README, ELLER bekreft `domain-taxonomy.json` som eneste kilde og deprecér/slett map-fila. - **(B) datoløse-fil-reklassifisering i `getFilePriority` (`report-changes.mjs`):** datoløse filer skal være «uverifisert»-prioritet, ikke critical-støy (Sesjon 2-funn §152). Adferdsendrende refaktor → TDD, test FØR kode. - **`authority_source`-feltet er fortsatt 0 % dekning** (registry); lag 5-regel 3 (autoritets-mismatch) er derfor inert i praksis i dag — den aktiveres når **lag 3 verifisering-INN** (egen fremtidig fase) backfiller feltet. Status-gaten (regel 1) er full virksom uavhengig. - **Neste — Sesjon 5:** transformasjonslaget (lag 4, doc→KB-fil, LLM-destillasjon med obligatorisk status-felt) **+ cleanup (A) og (B) over**. Kriterium (lag 4): regenerer 1 fil → eval-score ≥ baseline. Lag 5 (Sesjon 4) er motbevis-gaten lag 4 mates gjennom før skriving. --- ## Sesjon 5 — RESULTATER (FERDIG, 2026-06-19) **Akseptansekriterium møtt:** «regenerer 1 fil → eval-score ≥ baseline» — test `regenerate 1 real file → valid, dated, source-anchored, body preserved, same path` + `live deterministic eval ≥ baseline for ms-ai-infrastructure` (`tests/kb-eval/test-transform-criterion.test.mjs`). Tester grønne: **validate 239 · kb-update 111 (+16) · kb-eval 15 (+2) · kb-integrity 115/115**. gitleaks: rent på changeset (3 pre-eksisterende i `playground/vendor/` urørt). **Lag 4 levert (`lib/transform.mjs`, ren lib, SKRIVER ALDRI — speiler decisions-io/verify-out):** - `buildKbHeader({title, status, category, source, lastUpdated})` → deterministisk header. **`Status` + `Source` obligatoriske** (kaster ved manglende felt). **Nøkkelfunn/-fiks:** den gamle `prompt-template.md` la kilder i en bunn-seksjon, men `build-registry`/`kb-headers.parseSourceHeader` skanner kun **øverste 500 bytes** → derfor `authority_source`-dekning = 0 %. Lag 4 legger `**Source:**` i header-blokka → det er dette som lar lag 3 (fremtidig) backfille `authority_source` og lag-5 regel 3 fyre. - `validateKbFile(content)` → `{valid, missing[]}` (title/last_updated/status/source); bruker `parseSourceHeader` så «hva er en Source-header» har én sannhetskilde med build-registry. - `buildChange({field, oldValue, newValue, sourceUrl, authoritySource, refutations})` → eksplisitt lag-4→lag-5-bro; mater rett inn i `classifyChange` (verifisert: status-endring → `flagged`, ikke-status → `auto-applied`). - `resolveTargetPath(tax, category, filename)` → ruter via taksonomiens `getCategorySkill` (disk-sann); `null` = ukjent kategori → gate, ikke skriv. - **Prompt:** `scripts/kb-update/transform-prompt.md` (doc→KB-destillasjon; gjenbruker husformatet fra `prompt-template.md`, men Source i header + status-påstander eksplisitt for lag-5-gaten). Deterministisk header bygges av lib-en, ikke modellen. - **Wiret i `commands/kb-update.md`:** §3.d (ny godkjent URL → fetch → destillér → buildKbHeader → validateKbFile → buildChange→lag 5 → resolveTargetPath → operatør-gate → atomisk skriving) + §4.d (oppdateringer må også passere `validateKbFile`; legg Source-header der pre-lag-4-filer mangler den). `eval.mjs` eksporterer nå `evalSkill` for kriterium-testen. - **TDD:** 12 lib-tester (`test-transform.test.mjs`) inkl. import-invariant (ingen write-utils) + 2 kriterium-tester FØR kode. **Carry-forward A — `category-skill-map.json` (operatør-valg 2026-06-19: SLETT + rydd README):** premiss verifisert mot kode — fila var ukonsumert av all runtime (`docs/development.md:60` erklærte allerede taksonomien som eneste kilde; kun `README.md:654` kalte den feilaktig «used by generate-skills»). Slettet (`git rm`); README peker nå på `domain-taxonomy.json` via `lib/taxonomy.mjs` `getCategorySkill`. Fjerner en divergerende taksonomi helt (redesignets mål). `test-taxonomy.test.mjs`-kommentarer beholdt som historikk (leser kun taksonomien, ikke map-fila). **Carry-forward B — datoløse filer (TDD):** rotårsak: datoløs fil fikk `effectiveDate='0000-01-01'` (alltid «stale») **+** path-basert prioritet (kunne bli `critical`) → flommet critical-bøtta. Fix: ny **`unverified`-tier** deklarert i `domain-taxonomy.json` (lag 0). `makePriorityFn` tar nå valgfri `hasDate` (default `true` → bakoverkompatibelt); `report-changes` sender `Boolean(fileDate)`. `unverified` rangerer sist i sorteringen (metadata-hygiene, ikke currency-hast). Verifisert mot ekte registry: `Unverified: 1` skilt ut fra path-bøttene. TDD: 4 tester FØR kode (`test-priority-unverified.test.mjs`). **Binding for neste fase (numerert roadmap Sesjon 1–5 er nå FERDIG):** - 6-lags-arkitekturen står strukturelt: lag 0 (Sesjon 2) · lag 1 currency+completeness (eksisterende + Sesjon 3) · lag 2 (Sesjon 3) · lag 3 (Sesjon 6) · lag 4 (Sesjon 5) · lag 5 (Sesjon 4) · lag 6 eval (Sesjon 1). - **Gjenstår (ikke numerert — operatør prioriterer):** ~~(1) lag 3 verifisering-INN~~ ✅ FERDIG Sesjon 6. (2) **Optimaliserings-fase (krav 4-anvendelse):** fiks de målte eval-FAIL-ene (K5 progressive disclosure advisor/eng/security, K9 tid-sensitiv i body, K4 duplisering, refTall) + de 2 SKILL.md-bugene (6×5-vekting kanonisk? + governance ref-path) — krever operatør-beslutning på kanonisk vekting. (3) **Kurs-spor** (task #25, parallelt, av kritisk vei). (4) **Scheduled deteksjon** + siste integrasjon. (5) **Low-currency-bøtta (51 filer).** --- ## Sesjon 6 — RESULTATER (FERDIG, 2026-06-19) **Akseptansekriterier møtt:** `authority_source`-dekning **0,22 % (3/1353)** fra 0 ✅ · lag-5 regel 3 demonstrert virksom ende-til-ende med ekte data (test `rule 3 fires end-to-end on a real authority: source_url ≠ header authority → flagged`, `test-authority.test.mjs`) ✅. Tester grønne: **validate 239 · kb-update 122 (+11) · kb-eval 15 · kb-integrity 115/115**. gitleaks: rent på changeset. **Designvalg (operatør 2026-06-19): HEADER-AS-TRUTH.** En fils `**Source:**`-header ER den utpekte autoriteten for dens påstander. Vi gjetter ALDRI autoritet fra en fils mange siterte URLer — datagrunnlaget viste **251/303 ref-filer siteres av 4–10 URLer hver** (ingen entydig kilde å utlede; en gjettet autoritet ville fått regel 3 til å bomme + 303 operatør-beslutninger = primær-fallgruven). Dekning vokser organisk når lag 4 regenererer filer (lag 4 skriver alltid Source i header). **Levert:** - **`lib/authority.mjs`** (ren lib, SKRIVER ALDRI — speiler decisions-io/verify-out/transform; importerer kun read-only `kb-headers` + `url-normalize`): `resolveAuthority(content)` → deklarert `**Source:**`-URL (validert som http(s); fri tekst avvises — verifiseringsplikt; ikke-MS-autoritet som EU-forordning tillates) · `collectDeclaredSources(contents[])` → normalisert Set (kun MS Learn, matcher registry-nøkler) · `markUrlAuthority(url, set)` → url|null · `authorityCoverage(registry)` → `{withAuthority,total,ratio}`. - **`build-registry.mjs` wiret:** samler deklarerte kilder fra headere, setter per URL-entry `authority_source = url` iff en fil deklarerer den (recomputes fra headere = sannhet, ikke carry-over), logger dekning. - **`commands/kb-update.md` §4 c1 (ny):** `authority_source = resolveAuthority()` mates inn i lag-5 `classifyChange` (c2). §4.d/§3.d oppdatert: lag 3 er live (ikke «senere»). - **Bootstrap (gated KB-skriving):** `**Source:**`-header skrevet til de **3 entydige** (1-sitert-URL) filene med rent topisk treff: `late-chunking-patterns.md` → embeddings-tutorial · `ai-red-team-operations-practical.md` → ai-red-team/training · `batch-api-usage-optimization.md` → batch-blob-storage. - **TDD:** 11 tester FØR kode inkl. import-invariant + ende-til-ende regel 3. **Verifiseringsfunn (binding):** den 4. «entydige» fila — `ai-act-annex-iii-checklist.md` → `purview/compliance-manager-assessments` — ble **bevisst utelatt** fra bootstrap: dens egentlige autoritet er EU-forordningen selv (fila deklarerer allerede `**Hjemmel:** Regulation (EU) 2024/1689, Annex III`), ikke en MS Purview compliance-tool-side. Å sette Purview-URLen som autoritet ville vært en gjetning som får regel 3 til å bomme. **Kandidat for senere:** sett `**Source:**` til EUR-Lex-URLen (`resolveAuthority` aksepterer ikke-MS-autoriteter; den normaliseres bare ikke inn i den MS-keyede registryen — som er riktig). - **`url-registry.json` er gitignored (generert):** `authority_source` er derfor avledet on-demand fra de committede `**Source:**`-headerne (sannhetskilden), ikke en committet verdi. `build-registry --merge` regenererte registryen à jour (1343→1353 URLer; build-registry er det utpekte verktøyet). --- ## Sesjon 7 (SPOR A — krav 4-optimalisering, deterministisk del) — RESULTATER (FERDIG, 2026-06-20) **Akseptansekriterier møtt:** K5 PASS for advisor/eng/security · refTall PASS for eng+gov · eval ellers ikke regredert (`eval --json` = akseptansemål). Tester grønne: **validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 181/181** (opp fra 115). gitleaks: rent på changeset. **Steg 1 — refTall-konsistens (commit `3c097f5`):** engineering `agent-orchestration` 20→24 (faktisk på disk) + total 149→153; fjernet inkonsistent 24/20-dobbeltsitering. governance `norwegian-public-sector-governance` 29→30. Verifisert: eval `refCountConsistency` PASS for alle 5. **Steg 2 — døde ref-paths (commit `3c097f5`):** governance §4 monitoring-bullets pekte på ikke-eksisterende filer. STATE flagget kun L191; **verifiseringsfunn:** L190 var også død. Begge fikset til ekte disk-filer: `azure-monitor-ai-services-setup`→`azure-monitor-setup-ai-workloads`, `drift-detection-automated-retraining`→`model-performance-drift-detection`. **Løser den ene av de «2 SKILL.md-bugene» (governance ref-path).** **Steg 3 — K5 progressive disclosure (commit `abac74f`, operatør-gated kuratering godkjent 2026-06-20):** fulgte infrastructure-forbildet (0,97) — full-sti `references//.md`-pekere til kjernefiler. - **Nøkkelfunn:** security + advisor hadde filene navngitt allerede, men som **bare-filnavn uten `references/`-prefiks** → ufanget av både eval-regex OG kb-integrity Check 2 (samme klasse som de døde ref-paths). K5-«failure» for disse to var i stor grad et sti-format-artefakt. Fiks = konverter bare→full sti (konservativt, bruker eksisterende kuratering). - **security:** 10→16 navngitte (0,16→0,26). Konverterte 5 perf-filer (§3) + owasp (§1). Beholdt eksisterende kuratering (inkl. `gpu-compute-sizing` m/ `/architect:cost --capacity`-note) i stedet for å bytte sett. - **advisor:** 1→25 navngitte (0,016→0,40). Konverterte ~18 bare-filnavn i Kunnskapsbasen + la til `model-catalog-2026` og entry-points for `copilot-extensibility`/`prompt-engineering` (40 filer som manglet ALLE navngitte pekere). - **engineering:** 0→35 navngitte (0,0→0,23). Genuint 0 før (kun mappe-refs); la til `> **Kjernefiler:**`-linje med 4-6 kuraterte filer per §1-7. - **Bivirkning (positiv):** kb-integrity Check 2 valideringer 115→181 (de nye full-sti-refsene fanges nå), orphan-warnings 260→223. **Gjenstår i SPOR A (beslutning-gated — krever operatør-input, tas «når vi når dem»):** 1. **6×5-vekting (den andre SKILL.md-bug-en):** security SKILL.md body-vekting (Identity 20/Network 15/Data 20/Content 20/Compliance 15/Mon 10) ≠ kanonisk `security-scoring-rubrics-6x5.md` (Compliance 25/Data 20/Identity 20/Content 15/Network 10/Mon 10). **HVILKEN er kanonisk?** Påvirker scoring-output. 2. **K9 (tid-sensitiv info i SKILL.md body): 4/5 FAIL** — GA/preview-status, modellversjoner, SLA-/perf-tall i body. Hører i ref-filer (overlapper currency-sporet). Body-rydding = adferdsendrende → TDD. 3. **K4 (duplisering): 2/5 FAIL** — governance + security dupliserer ref-filer i body. Krever vurdering av hva som flyttes ut. 4. **K1 (trigger-presisjon):** PROVISORISK — operatør må kuratere 20 trigger-prompts/skill. Flagg: governance-description mangler Schrems II-trigger; advisor-description over-trigger mot søsken-kommandoer. **Spor B (senere, samme tema):** scheduled deteksjon · kurs-spor (task #25) · low-currency-bøtta (51 filer) · bredere `**Source:**`-backfill. --- ## Sesjon 8 (SPOR A — 6×5-vekting) — RESULTATER (FERDIG, 2026-06-20) **Akseptansekriterier møtt** (commit `1c0da88`): `grep` security SKILL.md → ingen 3-kolonne divergerende vekttabell; rubrikken har én Standard (kanonisk) + 2 dokumenterte varianter; agent+skill peker samme kilde. `eval --json` security: **K3 212→203 (pass) · K5 0,2581 uendret (16 navngitte, pass) · K6 16 (pass) · refConsistency 0 mismatch** — ingen deterministisk regresjon. Tester grønne: **validate 239 · kb-eval 15 · kb-integrity 182/182** (opp fra 181). gitleaks rent. **Antakelse-test (FØR sletting):** `grep -r` på vekttallene bekreftet at INGEN kode/test asserter SKILL.md-vektene — `security-assessment-agent` (L24) refererer kun rubrikken som OBLIGATORISK. Eneste andre treff var eval-bevis (`judge-results.json` L38 / `eval-baseline.json` L476) som beskriver selve K4-bug-en. Trygt slettet. **Endring 1 — rubrikk:** ny seksjon «Arbeidsbelastnings-profiler (adaptiv vekting)» under Vektingsmodell. Standard = kanonisk (Compliance 25/Data 20/Identity 20/Content 15/Network 10/Mon 10). Variantene utledet ved å bevare de godkjente retningsdeltaene fra SKILL.md-modellen, re-forankret til kanonisk baseline (sum 100 % begge): - **Eksternt eksponert:** Identity 25/Content 20/Network 15 ↑ (angrepsflate mot anonyme); Compliance 20/Data 15/Mon 5 ↓. - **Persondata-intensiv:** Compliance 30/Data 25 ↑; Content 10/Mon 5 ↓. **Endring 2 — SKILL.md:** fjernet divergerende 3-kolonne vekttabell → peker til rubrikken. **Risikoklassifiserings-tabellen beholdt** (per roadmap). **K4-status:** body-divergensen er løst, men K4-re-judgen er operatør-gated og hører i S9 — judge-cachen er IKKE rørt i S8 (ville fabrikkert en verdict). S9 plukker opp K4-rejudge for security. **⚠ Funn utenfor scope (flagget, ikke handlet):** SKILL.md-risikotabellen (L63-69: `3.1–3.5 = Moderat`) **divergerer** fra rubrikkens risikokategori-mapping (`2.50–3.49 = Høy`; egen «Uakseptabel»-kategori under 1,50). Roadmap sa eksplisitt «behold risikoklassifiserings-tabellen», så urørt — men dette er en reell andre-divergens på linje med vekt-bug-en. **Kandidat for egen sesjon / S9-tillegg** (operatør avgjør). --- ## Sesjon 9 (SPOR A — K4+K9 body-cleanup: security + governance) — RESULTATER (FERDIG, 2026-06-20) **Begge S9-kriterier møtt for begge skills** (operatør-gated LLM-judge, fersk kald re-judge): security **K4 5/5 PASS · K9 PASS**; governance **K4 5/5 PASS · K9 PASS**. Deterministisk ikke regredert — faktisk forbedret: **validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 192/182→192/192** (opp fra 182). gitleaks: 3 pre-eksisterende i `playground/vendor/` (utenfor changeset). Body krympet: security K3 203→191, governance K3 304→289; K5 sec 16→20 / gov 24→25 (full-sti-pekere fanges nå). **Metode (verifiseringspliktig):** to parallelle read-only verifiserings-agenter kartla FØR sletting hvor hvert body-faktum bor i ref-filer (PRESENT/PARTIAL/ABSENT). Funn styrte hva som ble *flyttet* (alt i ref), *droppet* (uverifiserte tall) eller *beholdt* (unik/stabil logikk). **Security (operatør-gated, 5 endringer):** - **K9:** Defender GA/preview/Azure-Gov-status → peker (alt verbatim i `defender-threat-protection-ai-services.md`). §3 ytelse: droppet **uverifiserte** tall (20-50ms, 5-10x, 80 % latens — fantes INGEN steder) + Batch/caching → pekere til faktiske ref-tall. GPT-4o-par → generisk. PTU «60-70 %» → ref. OWASP «2025» beholdt (stabil standard-versjon). - **K4:** risikoklassifiserings-tabellen (DIVERGERTE: 6 bånd vs 5, manglet «Uakseptabel») → peker til kanonisk rubrikk (operatør-godkjent, S8-konsistent). **Re-judge avdekket NY divergens:** P10/P50/P90-tabellen (flat ×0.6/×1.8) motsa kanonisk per-komponent-modell i `deterministic-cost-calculation-model.md` (agentens OBLIGATORISK-kilde). Antakelse-test bestått (ingenting asserter body-multiplikatorene) → tynnet til peker (samme klasse som S8-vekt + risikotabell). K4 3→5. - **Flagg lukket:** S8s «andre divergens» (risikotabell L63-69) er nå løst. **Governance (operatør-gated, 2 endringer):** - **K9:** EU Data Boundary §2.3 — droppet volatile regioner «(Sweden Central, West Europe)» (body MOTSA refs som sier «Norway East / West Europe»); behold prinsipp + lovsaksnr; repek kryss-ref → `gdpr-compliance-ai-systems.md`. Stabile identifikatorer (2024/1689, C-311/18) beholdt. - **K4:** §6.2 AI Act-tre — kollapset oppramset (og ufullstendig: 4 av 8) Art.5- + Annex III-lister → pekere til `ai-act-classification-methodology.md`; §2.1 eneste oversiktstabell. §6.1/§1.2/§6.3 beholdt (orientering/ruting, ikke verbatim-dup). K4 3→5. **K9-rubrikk strammet (operatør-godkjent):** `judge-prompt.md` K9 = «ingen VOLATIL info; stabile identifikatorer (forordningsår, OWASP 2025, MADR v3.0, saksnr) ute av scope» — gjør K9 PASS deterministisk oppnåelig per operatør-policyen. `judge-results.json` oppdatert med ferske sec+gov-verdikter (operatør-gated cache). **Binding for S10:** K9-destale engineering + infrastructure (feiler kun K9). Samme mønster: volatil status (GA/preview/modellversjon/SLA/perf) ut av body → ref. Antakelse: verifiser at innhold finnes i ref FØR sletting (ellers skriv ref-fil først, gated). --- ## Sesjon 10 (SPOR A — K9-destale: engineering + infrastructure) — RESULTATER (FERDIG, 2026-06-20) **Begge S10-kriterier møtt** (operatør-gated kald LLM-judge): engineering **K9 PASS** (findings: []); infrastructure **K9 PASS** (findings: "None"). Deterministisk ikke regredert: **validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 192/192**. gitleaks: 3 pre-eksisterende i `playground/vendor/` (utenfor changeset). K5 uendret (eng 0,23 · infra 0,97); refTall konsistent; K4 hevet eng 4→5 / infra 4→5 (mindre body-dup). Body krympet: infra K3 290→279 (eng uendret — generaliseringene byttet ord, ikke linjer). **Metode (verifiseringspliktig):** to parallelle read-only verifiserings-agenter kartla FØR sletting hvor hvert volatilt body-faktum bor i ref (PRESENT/PARTIAL/ABSENT) → flytt (i ref) / dropp (uverifisert) / generaliser. **Engineering (operatør-gated, 6 endringer):** §2 MAF-«erstatter Semantic Kernel»-transisjon → peker (ref bærer GA-dato/versjon); §intro/§3/§6 modellversjoner GPT-4o/Whisper/Florence/text-embedding-3 → generisk kapabilitets-framing (alle PRESENT i `azure-ai-services/*`+`multi-modal/*`); «Start med GPT-4o for prototyping» (ABSENT i ref) → dropp modellnavn, behold prinsipp; §8 Dekning «Foundry Agent Service GA»+«A2A/CUA/Foundry Workflows» → generiske topic-navn u/«GA» (filtall 24 urørt); «130+ språk» → «bred språkstøtte». **Infrastructure (operatør-gated, 8 endringer):** §1.8 SLA-tabell (99.9/99.999/99.95 % — **ABSENT i ref**) → relativ-veiledning + MCP/`research-agent`-peker (ingen tall i body); §1.2 RTO/RPO-tabell → sammendrag + peker (ref `rto-rpo-planning-ai-services.md` bærer hele tier-modellen i 265 linjer; minuttverdier fjernet); §1.7 «peak + 30 % buffer» (ref sier 1.2×/20 %, avvikende) → «kapasitetsbuffer»; §2.2 «(tidl. Azure Stack HCI)» → dropp (ref bærer rename); §2.3/2.4/2.8/3.4 «Phi-3/Phi-4»+«(3.8B)/(14B)» → «Phi-familien» u/versjon+parametertall (fjerner også **faktafeil**: body sa «Phi-4 (14B)», ref tilskriver 14B til Phi-3 Medium); §1.1 «(bredere modellutvalg)» → dropp (ref bærer). **To judge-runder for infra (dommeren er bindingen — ikke overstyrt):** runde 1 fanget at min FØRSTE SLA-omskriving introduserte et nytt konkret «99,9 %»-tall + flagget RTO-tabellens «< 5 min» (borderline). Fix: fjern alle SLA-prosenter fra prosa + flytt RTO/RPO-tabellen til peker → runde 2 **K9 PASS clean**. **Judge-cache:** `judge-results.json` oppdatert med ferske kalde eng+infra-verdikter (operatør-gated; `_updated: S10`). **Binding for S11:** K1 (#4) — 2 description-fikser (governance +Schrems II-trigger, advisor strammere) + draft 20 kandidat-prompts/skill → operatør-review. Merk: S10-judgen ga provisorisk K1 1.0 for begge eng+infra (rene description-grenser), men K1 forblir **PROVISORISK** til operatør kuraterer. --- ## Sesjon 11 (SPOR A — K1 trigger-presisjon) — RESULTATER (FERDIG, 2026-06-20) **Begge S11-kriterier møtt.** LLM-judge **K1 PASS for alle 5** (blindet) — hit-rate **1.0** / false-positive-rate **0.0** / presisjon **1.0** / 0 feilklassifiserte hver. K2 (description-format) fortsatt **PASS** etter edits (advisor quoted=6/useWhen=true; governance quoted=8/useWhen=true). Deterministisk ikke regredert: **validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 192/192**. K1 er ikke lenger provisorisk — `provisional=false` for alle 5. **(a) 2 description-fikser (operatør-godkjent ordlyd):** - **governance +Schrems II-trigger:** la til prosa «cross-border personal-data transfer assessment (Schrems II / TIA)» + to triggere «Schrems II data transfer», «overføring av persondata til tredjeland». Lukker recall-gapet (0.85→1.0). Verifisert FØR skriving at governance *eier* domenet (20 ref-filer + `data-residency-audit-monitoring.md` med EDPB seks-stegs-TIA). - **advisor strammere mot over-trigging:** byttet bred ledesetning «Microsoft AI architecture guidance» + trigger «Microsoft AI architecture» → selection-forankret «Microsoft AI platform selection …» + eksplisitt negativ scope «NOT for how to build (engineering), secure (security), operate (infrastructure), or legally assess (governance)». Fjernet den brede triggeren som kolliderte med søsken. **(b) Kuraterte 20 prompts/skill + blindet måling:** - Ny `data/k1-trigger-prompts.json` (100 prompts: 10 in-domain + 10 out-of-domain/skill). Out-of-domain er adversarielt — hver er en søsken-domene-prompt (`belongs_to`) som tester over-trigging-grensen, + 1 urelatert kontroll. Bilingvalt (no/en). - **Mekanikk-endring:** `judge-prompt.md` K1-bulleten endret fra *generer* prompts → *konsumer* det kuraterte settet; nytt output-skjema (`inDomainHitRate`/`outDomainFalsePositiveRate`/`pass`/`misclassified`, `provisional=false`). - **Blindet kjøring:** 5 parallelle Opus-dommere, hver ser KUN sin skills description + 20 **stokkede, umerkede** prompts (speiler skill-routeren); ground-truth holdt utenfor dommeren; scoret deterministisk etterpå. Begge fikser validert i dommernes begrunnelser: governance trigget på Schrems II/tredjeland via de nye triggerne; advisor avviste alle 4 søsken-prompts med eksplisitt sitat til den nye eksklusjonsklausulen. **Judge-cache:** `judge-results.json` oppdatert med S11 K1-verdikter for alle 5 (`_updated: S11`, `provisional=false`); K4/K7/K8/K9 urørt (uendret av description-edits — frontmatter, ikke body). **Binding for S12 (lukk SPOR A):** K4/K7/K8/K9 er uendret av S11 (description ≠ body), alle PASS fra S9/S10 kalde re-judges. Gjenstår kun: regenerer `eval-baseline.json` (gated `--write`) så baseline fanger S9+S10+S11 judge-oppdateringer. Trivielt — ett kommando-steg. --- ## SPOR A — gjenstående sesjoner (PLANLAGT, operatør godkjente alle 4 anbefalinger 2026-06-20) De 4 beslutning-gated punktene er nå **avgjort** (operatør: «følger anbefalingene gjennomgående»): 1. **6×5-vekting → A:** den kanoniske rubrikken (`security-scoring-rubrics-6x5.md`, Compliance 25/Data 20/Identity 20/Content 15/Network 10/Mon 10) er autoritativ. `security-assessment-agent` bruker den allerede som OBLIGATORISK. SKILL.md slutter å gjengi vekttall (peker til rubrikken); den adaptive 3-profil-modellen (Standard / Eksternt eksponert / Persondata-intensiv) foldes inn i *rubrikk-fila* med **Standard = kanonisk**. 2. **K9 → pragmatisk:** volatil status (GA/preview/versjon/SLA-/perf-tall) ut av SKILL.md body → ref-filer (currency-mekanismen holder dem ferske). Stabile refs blir (MADR v3.0, forordningsår 2024/1689, filnavn, generisk forklarende «preview»). 3. **K4 → orient+rute:** body beholder *hva/når/hvilken-fil*; *hvordan* flyttes til ref-fil. 4. **K1:** fiks 2 descriptions nå (governance +Schrems II-trigger; advisor strammere mot over-trigging); draft 20 kandidat-prompts/skill for operatør-review → mål presisjon. **Rød tråd (operatør-validert):** #1/#2/#3 har felles rotårsak for security — body bærer tall som hører i ref-filene. Ett disiplinert body-pass per skill løser flere kriterier samtidig. **Verifiseringsmekanisme:** K4/K9/K1 dømmes av den **operatør-gated LLM-judgen** (`scripts/kb-eval/judge-prompt.md` → `data/judge-results.json`, merges av `eval.mjs`). Hver sesjon som rører disse kjører judgen (scoped til relevante skills/kriterier) FØR ferdig-erklæring. Deterministiske kriterier (K2/K3/K5/K6/refTall) skal **aldri** regrederes (`eval --json` = akseptansemål). | Sesjon | Leveranse | Verifiserbart kriterium | |---|---|---| | **8** ✅ FERDIG (`1c0da88`, se «Sesjon 8 — RESULTATER») | **6×5-vekting (#1).** Fold adaptive workload-varianter inn i `security-scoring-rubrics-6x5.md` (Standard = kanonisk; foreslå eksakte varianttall, gated). Fjern divergerende vekttabell fra security SKILL.md → peker til rubrikken (behold risikoklassifiserings-tabellen — den er stabil). | `grep` security SKILL.md: ingen 3-kolonne-vekttabell med divergerende tall; rubrikken har én Standard + dokumenterte varianter; agent+skill peker samme kilde. `eval --json`: refTall/K5/K3 ikke regredert · validate 239 · kb-integrity grønt. **Antakelse testet:** ingen kode/test asserter SKILL.md-vekttallene (agenten bruker rubrikken — verifisert i S7-diskusjon; bekreft med `grep -r` på vekttallene før sletting). | | **9** ✅ FERDIG (se «Sesjon 9 — RESULTATER») | **K4+K9 body-cleanup: security + governance** (begge feiler begge kriteriene). Tynn dupliserte avsnitt → pekere; flytt volatil status → ref. Gated forslag per skill FØR endring. | ✅ LLM-judge: security **K4 5/5 · K9 PASS** · governance **K4 5/5 · K9 PASS**. `eval`: K5 sec 16→20/gov 24→25, K3/refTall ikke regredert · kb-integrity 192/192 · validate 239. Antakelse testet (read-only verifiserings-agenter kartla ref-dekning FØR sletting). | | **10** ✅ FERDIG (se «Sesjon 10 — RESULTATER») | **K9-destale: engineering + infrastructure** (feiler kun K9). Volatil status ut av body. Gated forslag FØR endring. | ✅ LLM-judge: **K9 PASS** eng+infra (kald re-judge). `eval --json` ikke regredert (K5/refTall) · validate 239 · kb-integrity 192/192 · K4 hevet 4→5 begge. | | **11** ✅ FERDIG (se «Sesjon 11 — RESULTATER») | **K1 (#4).** (a) 2 description-fikser: governance +Schrems II-trigger; advisor strammere (foreslå ordlyd, gated — K2-format må holdes). (b) draft 20 kandidat-prompts/skill → operatør-review → mål presisjon via judge. | ✅ Blindet LLM-judge: **K1 PASS alle 5** (hit 1.0 / fp 0.0 / presisjon 1.0, `provisional=false`). K2 fortsatt PASS · validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 192/192. Ny `data/k1-trigger-prompts.json` (kuratert 20/skill); `judge-prompt.md` konsumerer settet. | | **12** | **Lukk SPOR A.** Full LLM-judge re-run (K1/K4/K7/K8/K9) alle 5 → bekreft alle kriterier PASS → skriv ny `eval-baseline.json` (operatør-gated `--write`). (Kan foldes inn i S11 hvis lett.) | `eval-baseline.json`: ingen åpen eval-FAIL på tvers av K1–K9 for de 5 skills. STATE: SPOR A FERDIG → Spor B neste. | **Invariant gjennom alle sesjoner:** SKILL.md-/rubrikk-skriving er **gated** (presenter forslag FØR endring, som K5 i S7). Subagenter committer ALDRI. Validate + relevante tester grønne før commit. Push i vindu (hverdag 20–23 / helg fritt / operatør-go). Verifiseringsplikt: flyttet/endret fakta verifiseres mot kilde før skriving. **Etter SPOR A → Spor B:** scheduled deteksjon + siste integrasjon · kurs-spor (task #25) · low-currency-bøtta (51) · bredere `**Source:**`-backfill · onboarding-redesign (task #26, egen godkjenning).