ms-ai-architect/docs/kb-mechanism-redesign-plan.md
Kjell Tore Guttormsen c1f75f9c78 fix(ms-ai-architect): Sesjon 11 — K1 trigger-presisjon, blindet judge PASS alle 5
(a) 2 description-fikser (operatør-godkjent):
- governance: +Schrems II/TIA-trigger (recall-gap 0.85→1.0; governance eier
  domenet — 20 ref-filer + data-residency-audit-monitoring.md)
- advisor: strammere — selection-forankret + eksplisitt negativ scope
  (NOT for build/secure/operate/legally-assess); fjernet bred
  "Microsoft AI architecture"-trigger som kolliderte med søsken

(b) Kuratert testsett + mekanikk:
- ny data/k1-trigger-prompts.json (100 prompts: 10 in + 10 adversarielt out/skill)
- judge-prompt.md K1: generer→konsumer kuratert sett + nytt skjema
  (inDomainHitRate/outDomainFalsePositiveRate/pass/misclassified, provisional=false)
- blindet måling: 5 Opus-dommere ser kun description + 20 stokkede umerkede
  prompts; ground-truth scoret deterministisk utenfor dommeren

Resultat: K1 PASS alle 5 — hit 1.0 / fp 0.0 / presisjon 1.0 / 0 miss.
Begge fikser validert i dommer-begrunnelsene. K2 fortsatt PASS.
Ikke regredert: validate 239 · kb-eval 15 · kb-update 122 · kb-integrity 192/192.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-20 10:00:47 +02:00

383 lines
53 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 K1K9 (uavhengig av 15)
```
**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 13.
## 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 K1K9 (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 (K1K9) + `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 15 + 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 14 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 03.
- **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 16 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,951,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 2023 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 2023 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 15 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 410 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(<fil>)` 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/<mappe>/<fil>.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.13.5 = Moderat`) **divergerer** fra rubrikkens risikokategori-mapping (`2.503.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 K1K9 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 2023 / 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).