ms-ai-architect/docs/kb-mechanism-redesign-plan.md
Kjell Tore Guttormsen 17865a251b docs(ms-ai-architect): konkret Sesjon 3-startplan i roadmap (handoff)
7-stegs startplan for lag 2 (decision-ledger data/decisions.json + dedup som
lukker discovery-loopen gjennom operator-gaten), m/ kjorbart kriterium
(discovery 2x re-foreslar ikke rejected URL) og invariant-guard (deteksjon
importerer aldri write-utils). Speiler Sesjon 2-monsteret (ren-funksjon-lib +
tynn script + TDD). Sikrer at neste sesjon starter uten re-utledning.

Inkluderer 2 Sesjon 2-funn som Sesjon 3-kandidater (category-skill-map stale,
datolose-reklassifisering) + eksplisitt ikke-i-scope.

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

19 KiB
Raw Blame History

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
5 Transformasjonslag (lag 4) 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.mddata/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-evaluatorsconcepts/built-in-evaluators; agent-serviceagents/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).