Load-bearing gaten i den to-lags ingestion-sikkerheten: en deterministisk, alltid-på node-skann (unicode/injection/base64, prosa + fenced code blocks) over kandidat skills/**/*.md, wiret inn som sibling til validate-kb-file.mjs ved det ENESTE skrive-chokepunktet — dekker kb-update + generate-skills + fremtidig R7. - lib/adversarial-scan.mjs: ren disposition-kjerne (provenance-tiering + BLOCK/ WARN-matrise). Ortogonal til korrekthets-judgen. - lib/adversarial-detect.mjs: bro til de DELTE llm-security-detektorene (scanForInjection-lexikon + unicode-scanner + base64/entropi) — ingen kopi av lexikonet. Fail-closed hvis llm-security fraværende. - scan-adversarial-content.mjs: CLI (speiler validate-kb-file.mjs); exit 1=BLOCK (aldri skriv), 2=WARN (flagg → menneske), 0=ren. - 30 tester (19 kjerne + 7 CLI + 4 integrasjon mot ekte llm-security). Suite 692/0. Premiss-verifisert mot live kode: research/research-agent skriver ingenting (kun Layer A); R7-judge re-bruker samme create-guard; CLI-scan alene misset injection+base64 for markdown → importerer rene primitiver i stedet.
22 KiB
| name | description | argument-hint | allowed-tools | model |
|---|---|---|---|---|
| architect:kb-update | Manuell oppdatering av kunnskapsbasen — poller Microsoft Learn-sitemaps, sammenligner mot lokale `Last updated`-headere, oppdaterer endrede filer og oppdager nye relevante URLer | [valgfritt: --skip-discover | --priorities critical,high,medium,low | --dry-run] | Bash, Read, Edit, Write, Glob, Grep, mcp__microsoft-learn__microsoft_docs_search, mcp__microsoft-learn__microsoft_docs_fetch, mcp__microsoft-learn__microsoft_code_sample_search | opus |
/architect:kb-update — Manuell KB-oppdatering
Holder Microsoft AI-kunnskapsbasen i skills/*/references/ ferskt ved å sammenligne lokale referansefiler mot Microsoft Learn-sitemaps.
Apply (oppdatering av KB-filer) er alltid manuell og kjøres in-session — den bruker Claude og forblir under operatør-gate. Deteksjon (poll → rapport → discovery → skill-livssyklus) er ren node som aldri kontakter Claude/Anthropic, og kan valgfritt schceduleres (se «Scheduled deteksjon» under). Skillet er ToS-forankret: Consumer Terms §3.7 begrenser automatisert tilgang til Anthropics tjenester — ikke kjøring av lokale scripts som ikke rører Claude.
Hva kommandoen gjør
- Polle sitemaps: kjører
node scripts/kb-update/run-weekly-update.mjs --forcefor å hente fersk<lastmod>for hver Microsoft Learn-URL i registeret - Optional discovery: med default
--discoverfinner nye relevante URLer i sitemap som ikke er i registeret (scripts/kb-update/discover-new-urls.mjs --limit 500). Discovery leser beslutnings-ledgeren (data/decisions.json, lag 2) og utelater alt operatøren allerede har tatt stilling til (policy A: approved/rejected/pending) — så de samme kandidatene drukner ikke gaten kjøring etter kjøring - Generere endringsrapport:
report-changes.mjsprodusererdata/change-report.jsonmed per-fil prioritering (critical/high/medium/low) basert på antall endrede kilder + alder på lokal fil - Vise rapporten: lese rapport, presentere oppsummering til bruker, vente på
go - Oppdatere filer: for hver fil i valgt prioritetsbøtte (default: critical + high):
- Hente fersk innhold fra alle endrede kildene via
microsoft_docs_fetch - Oppdatere relevante seksjoner i den lokale
.md-fila - Oppdatere
Last updated:-header til dagens dato
- Hente fersk innhold fra alle endrede kildene via
- Committe: én git-commit per fil med
chore(ms-ai-architect): refresh KB <fil> [skip-docs]-format (eller én samlet commit om brukeren foretrekker det)
Argumenter
| Flagg | Effekt |
|---|---|
--skip-discover |
Hopp over discovery-passet (raskere, ingen nye URLer oppdages) |
--priorities <list> |
Komma-separert subset av critical,high,medium,low. Default: critical,high |
--dry-run |
Generer rapport, men ikke oppdater filer eller committ |
--single-commit |
Samle alle filendringer i én commit i stedet for én per fil |
Scheduled deteksjon (opt-in, Spor C / C1)
Deteksjonen kan kjøre automatisk i bakgrunnen ved sesjonsstart — av som default. Den er frivillig å sette opp, men virker når aktivert.
Slik aktiverer du den: opprett ms-ai-architect.local.md i plugin-roten (gitignored) med:
---
scheduled_detection:
enabled: true # default false — ingenting kjører før dette er true (Tier 1)
interval_days: 7 # kjør deteksjon på nytt når det er ≥ N dager siden sist poll
include_skill_lifecycle: true # ta med skill-livssyklus-deteksjon (overlapp/gap/bloat)
os_scheduler_cadence: daily # Tier 2: daily (poll hver dag) | interval (throttle på interval_days)
---
Tier 1 — sesjonsforankret (SessionStart-hook)
Når enabled: true og det er ≥ interval_days siden sist poll, spawner SessionStart-hooken scripts/kb-update/run-detection.mjs i bakgrunnen. Den kjører kun deteksjon (poll → rapport → discovery → skill-livssyklus) og skriver JSON-rapporter til data/ — aldri til skills/, og kaller aldri Claude. Ferske signaler surfaces ved neste sesjonsstart («KB: …» + «Skill-signaler: …»), og du kjører /architect:kb-update manuelt for å gjennomgå + apply-e gjennom gaten. Begrensning: Tier 1 kjører bare når en Claude-sesjon starter — starter du aldri en sesjon, kjører deteksjonen aldri.
Tier 2 — lokal launchd-scheduler (ekte bakgrunn mellom sesjoner)
For deteksjon som kjører uavhengig av sesjoner, installer en lokal launchd LaunchAgent som fyrer samme Claude-frie entrypoint daglig (kl. 03:00):
node scripts/kb-update/scheduler.mjs install # skriv plist til ~/Library/LaunchAgents + last agenten
node scripts/kb-update/scheduler.mjs status # er den lastet?
node scripts/kb-update/scheduler.mjs run-now # kjør én gang nå (verifiser uten å vente til 03:00)
node scripts/kb-update/scheduler.mjs print # vis plisten uten å skrive noe (alias --dry-run)
node scripts/kb-update/scheduler.mjs uninstall # avlast + fjern plist
- Kadens (
os_scheduler_cadence):daily(default) poller hver dag;intervalthrottler tilinterval_daysvia samme staleness-gate som Tier 1. (Onboarding setter dette senere; daglig er fornuftig default — poll av Microsoft Learn-sitemaps er billig og read-only.) - Pause = uninstall. LaunchAgenten kjører uansett
enabled:-flagget (det styrer kun Tier 1/hooken). Vil du stoppe Tier 2, kjøruninstall— det er pause-knappen. - Etter en major
brew upgrade node: kjørinstallpå nytt. Node-stien bakes inn ved install-tid (launchd har minimaltPATH); plistensPATHinkluderer/usr/local/binså barneprosessenesnodeoverlever, men det er ryddigst å re-installere. - launchd, ikke cron: Apple anbefaler launchd; cron krever Full Disk Access og er «not recommended». Vil du heller bruke cron/systemd/CI, peker du den på samme
node scripts/kb-update/run-detection.mjs.
ToS-garanti (strukturell, begge tiers): entrypointet (run-detection.mjs, og scheduler.mjs run som delegerer til det) spawner kun node på de allow-listede deteksjons-scriptene + launchctl for agent-styring; det kan ikke invokere claude. Apply (det eneste Claude-steget) forblir manuelt og in-session. Kjør node scripts/kb-update/run-detection.mjs --dry-run (eller scheduler.mjs print) for å se hva som ville kjørt uten å kjøre noe.
Instruksjoner til assistenten
1. Pre-flight
pwd— bekreft at du står iplugins/ms-ai-architect/(eller delegere via absolutt sti)git status --porcelain | grep -E '\.md$' && echo "WARN: ucommittede skill-endringer — kommandoen vil blande dem inn"— advar bruker hvis det finnes lokale skill-endringer- Parse argumenter
2. Kjør pollingsfasen
node scripts/kb-update/run-weekly-update.mjs --force${ARG_DISCOVER}
Hvor ${ARG_DISCOVER} er --discover med mindre --skip-discover ble gitt.
Output forventes å skrive data/change-report.json og evt. nye registry-entries hvis discovery kjørte.
3. Vis rapport-oppsummering
node scripts/kb-update/report-changes.mjs | head -40
Presenter til bruker:
- Antall filer per prioritet
- Hvilke prioriteter som blir behandlet (default: critical + high)
- Estimert antall
microsoft_docs_fetch-kall (≈ sum av endrede kilder per fil) - Spør: "Fortsett med oppdatering? (y/n)"
Hvis --dry-run: stopp her, ikke oppdater filer.
3b. Discovery-gate — nye URLer via decision-ledger (lag 2)
Kjørte discovery (default), lukk løkken her. Dette er operatør-gaten — det eneste stedet beslutninger om nye URLer skrives.
a. Les kandidatene: data/discovery-report.json → candidates[]. Listen er allerede dedupet av scriptet mot både registry og data/decisions.json, så alt her er genuint ubesluttet. Feltet deduped_by_ledger viser hvor mange tidligere beslutninger som ble utelatt.
b. Presenter for operatør, gruppert per suggested_skill (vis url, suggested_category, lastmod). For hver kandidat (eller batch): approve (ta inn i KB), reject (irrelevant — ikke vis igjen), eller utsett (pending — ikke avgjort, vises i pending-bøtta men re-foreslås ikke).
c. Skriv beslutningene til ledgeren — ENESTE skrivevei. Bruk lib/decisions-io.mjs (ikke håndskriv JSON):
import { loadDecisions, recordDecision, saveDecisions } from './scripts/kb-update/lib/decisions-io.mjs';
let led = loadDecisions();
led = recordDecision(led, url, { status: 'rejected', decided_at: '<i dag>', suggested_skill, suggested_category, note });
// ...én recordDecision per beslutning...
saveDecisions(led);
decided_at settes til dagens dato (caller-injisert — recordDecision er ren). decisions.json er tracket i git (overlever, til forskjell fra de genererte rapportene).
d. For approved: registrér URLen i url-registry (gated) så den fanges av polling heretter — via lib/registry-io.mjs saveRegistry. Bruk suggested_skill/suggested_category fra kandidaten. Deretter kjør transformasjonslaget (lag 4) for å lage KB-fila:
-
microsoft_docs_fetchpå den godkjente URLen → kildedokument. -
Destillér via
scripts/kb-update/transform-prompt.md(doc→KB-fil; status-påstander holdes eksplisitte). Multi-agent parallell fan-out foreslås i produksjon (roadmap §71), speilet pågenerate-skills-mønsteret. -
Født-verifisert (Spor 3 Port 2): kjør claim-judgen (
scripts/kb-eval/judge-claim-prompt-v3.1.md) over brødtekstens maskin-verifiserbare påstander mot den godkjente URLen →verdict = {pass}. Såmeta = stampVerifiedMeta({title, status, category, source: <godkjent URL>, lastUpdated: <YYYY-MM>}, verdict, <i dag>)— stemplertype='reference'+verified+verified_by='judge-v3.1'kun vedpass; ellers KASTER (ingen fil, flagg for menneske). Derettercontent = composeKbFile(meta, body)(lib/transform.mjs) — header + (store filer >100 linjer) en deterministisk## Innhold-TOC + brødtekst.Status+Source+Verified+Verified byer obligatoriske —Sourcei header-blokka (øverste 500 bytes) er det som lar lag 3 backfilleauthority_source. TOC-en fødes inn så regenerering ikke stripper den (Fase 1c). -
validateKbFile(content)MÅ værevalid: true(title + Last updated + Status + Source + Verified + Verified by; store filer også TOC) før noe gates videre (ellers be modellen fylle manglende felt). -
For hver status-/load-bearing-påstand:
buildChange({...})→ lag 5classifyChange(...)(samme gate som §4 c2). Status-påstander er alltidflagged. -
resolveTargetPath(tax, category, filename)→ eierskill-sti via taksonomien (null= ukjent kategori → flagg for operatør, ikke skriv). -
Create-guard FØR skriving (to sibling-gater): kjør BEGGE (exit ≠0 på noen av dem ⇒ ikke skriv):
node scripts/kb-update/validate-kb-file.mjs <sti>— kontrakt (Source/født-verifisert/TOC).node scripts/kb-update/scan-adversarial-content.mjs <sti>— Layer B ingestion-gate (G6 §8 / R6 punkt d): deterministisk adversariell-innhold-skann (unicode/injection/base64, prosa + fenced code blocks) via de delte llm-security-detektorene. exit 1 = BLOCK (aldri skriv — karantene, operatør adjudiserer); exit 2 = WARN (flagg → samme menneske-i-loop som en status-påstand; ikke auto-committ). Gaten er ortogonal til korrekthets-judgen: en faktakorrekt men forgiftet fil blokkeres likevel.
Først etter operatør-gate + BEGGE create-guards grønne: atomisk skriving (
lib/atomic-write.mjs+lib/backup.mjs).transform.mjsskriver aldri selv — verifisert avtests/kb-update/test-transform.test.mjs(import-invariant). Kriterium verifisert avtests/kb-eval/test-transform-criterion.test.mjs(regenerer 1 fil → eval ≥ baseline). Layer B verifisert avtests/kb-update/test-adversarial-scan.test.mjs+test-scan-adversarial-content.test.mjs+test-adversarial-detect-integration.test.mjs.
e. Invariant: discover-new-urls.mjs (deteksjon) skriver aldri ledgeren — den kun leser. Bare denne gaten skriver. Verifisert av tests/kb-update/test-discover-invariant.test.mjs.
3c. Kurs-deteksjon-gate — nye/endrede kurs via decision-ledger (courses-kolleksjon, Spor C / C3)
Operatør-gaten for kurs-sporet. Et kurs-lead er et signal om at et tema finnes — aldri en doc-side som ingestes. Å godkjenne et lead henter/transformerer/skriver ingen KB-fil (det ville vært auto-ingest, et eksplisitt ikke-mål) — det registrerer kun operatørens beslutning i den UID-nøklede courses-kolleksjonen. Dette er ENESTE skrivevei for kurs-beslutninger.
a. Sjekk rapporten: data/course-detection-report.json. Produsert av den Claude-frie detektoren (detect-courses.mjs) — enten schedulert (Tier 1/2) eller manuelt: node scripts/kb-update/detect-courses.mjs. Mangler fila, eller status:"skipped" (Keychain-creds mangler — C3 er opt-in inni opt-in): hopp over denne gaten stille. status:"error": rapportér kort og hopp over.
b. Les leads: new[] + updated[] (hver {uid, title, url, products, suggested_skill, suggested_category, updated_at}). removed[] er kun et informasjonssignal — vis det som en notis, aldri som en beslutning (et retirert kurs er ikke et tema å dekke; spec §4.2).
c. Dedup mot ledgeren (policy A): utelat leads operatøren allerede har tatt stilling til. Bruk isCourseLeadDecided (UID er den stabile nøkkelen — URL kan endres):
import { loadDecisions, isCourseLeadDecided } from './scripts/kb-update/lib/decisions-io.mjs';
const led = loadDecisions();
const fresh = [...report.new, ...report.updated].filter((l) => !isCourseLeadDecided(led, l.uid));
d. Presenter fresh for operatør, gruppert per suggested_skill (vis title, url, products, kind new/updated). For hvert lead (eller batch): approve (relevant — verdt å dekke i KB-en), reject (ikke relevant — ikke vis igjen), eller utsett (pending — ikke avgjort).
Hvis --dry-run: stopp etter presentasjonen — ikke skriv ledgeren.
e. Skriv beslutningene til ledgeren — ENESTE skrivevei. Bruk recordCourseLead (ikke håndskriv JSON):
import { loadDecisions, recordCourseLead, saveDecisions } from './scripts/kb-update/lib/decisions-io.mjs';
let led = loadDecisions();
led = recordCourseLead(led, uid, {
kind, status: 'approved', title, url, products, suggested_skill, suggested_category,
updated_at, detected_at, decided_at: '<i dag>', note,
});
// ...én recordCourseLead per beslutning...
saveDecisions(led);
decided_at settes til dagens dato (caller-injisert — recordCourseLead er ren). decisions.json er tracket i git.
f. Ingen ingest — strukturell invariant. Et godkjent kurs-lead blir værende i courses-kolleksjonen og leses av ingen av apply-pathene: apply-skill-op.mjs leser kun actions, discover-new-urls.mjs kun decisions. En kurs-beslutning trigger derfor aldri fetch/transform/KB-skriving. Skal et kurs' tema faktisk dekkes med en KB-side, er det en separat, bevisst doc-discovery-handling gjennom §3b (finn doc-URLen) — ikke en automatisk konsekvens av å godkjenne kurset. Et godkjent kurs surfaces ved sesjonsstart (C3.6: «N nye / M endrede kurs i dekkede produkter») som en påminnelse til operatøren.
4. Per-fil oppdatering (etter brukerens y)
For hver fil i valgte prioriteter:
a. Les nåværende fil: Read på filstien
b. Hent oppdaterte kilder: for hver URL i change-report.json[file].changed_urls, kjør microsoft_docs_fetch på URLen
c. Identifiser endringer: sammenlign hentet markdown mot eksisterende seksjoner i fila. Fokuser på faktuelle endringer (ny info, oppdaterte features, deprecation-varsler) — ikke små formuleringsendringer
c1. Autoritetskilde-binding (lag 3) — header-as-truth. authority_source = resolveAuthority(<fil-innhold>) (lib/authority.mjs) — fila sin **Source:**-header ER den utpekte autoriteten for dens påstander. null hvis fila mangler headeren (vokser etter hvert som lag 4 regenererer filer). Dette er inngangsdataen til lag-5 regel 3 (autoritets-mismatch): er en status-/load-bearing-endrings source_url ≠ authority_source, flagges den. Aldri gjett en autoritet fra fila sine siterte URLer (251/303 filer siterer 4–10 → ville vært gjetning).
c2. Verifisering-ut (lag 5) — FØR du skriver. Hver kandidat-endring fra (c) går gjennom lib/verify-out.mjs classifyChange({field, old_value, new_value, source_url, authority_source, refutations}) med authority_source fra (c1). Dette fanger regresjons-klassen (en status-påstand «korrigert» mot en tilfeldig sitert side og stille auto-applyet — agentic-retrieval-regresjonen):
flagged→ IKKE auto-skriv. Vis endringen til operatør medreasons[]; operatør avgjør om den tas inn. Status-påstander (GA/preview/versjon/pris) er ALLTIDflagged(spec §21) — uansett hvor sikker kilden ser ut.auto-applied→ trygt å ta inn i (d) (benign, ikke-status, ingen motbevis, autoritets-match).- Adversarial motbevis-panel (LLM-runtime): for status-/load-bearing-påstander, kjør et lite panel som prøver å motbevise
new_valuemot den utpekteauthority_source, og mat resultatene inn somrefutations[]([{refuted, reason}]). Multi-agent foreslås når lag 4/5 kjøres i produksjon (roadmap §71). - Invariant:
verify-out.mjsskriver aldri — den returnerer kun en verdict. Selve skrivingen skjer i (d), gated. Verifisert avtests/kb-update/test-verify-out.test.mjs. d. Oppdater fila:Editmed endringer som erauto-appliedeller eksplisitt godkjent av operatør i (c2). Behold "For Cosmo"-seksjonen og overordnet struktur. OppdaterLast updated: YYYY-MM-DD-header til dagens dato. Lag-4-kontrakt: kjørvalidateKbFile(<ny fil-innhold>)(lib/transform.mjs) før skriving — den skal værevalid: true. Mangler fila et**Source:**-header, legg det til i header-blokka med den utpekte autoritets-URLen for hovedkilden — da fanger lag 3 (resolveAuthority+build-registry) den somauthority_source, og lag-5 regel 3 blir virksom for fila. Mangler en stor fil (>100 linjer) en## Innhold-TOC, generer den medbuildToc(<brødtekst>)og legg den inn rett etter header----—validateKbFilekrever den nå for store filer, så in-place-oppdateringer backfiller TOC inkrementelt (Fase 1c). d1. Layer B FØR skriving/commit (ingestion-gate, G6 §8): kjørnode scripts/kb-update/scan-adversarial-content.mjs <fil>på den oppdaterte fila. exit 1 (BLOCK) ⇒ ikke skriv/committ — karantene, operatør adjudiserer; exit 2 (WARN) ⇒ flagg for operatør, ikke auto-committ. Deterministisk adversariell-innhold-skann via delte llm-security-detektorer; ortogonal til korrekthets-gatene i (c1/c2). e. Committ: kjør create-guardene (validate-kb-file.mjs+scan-adversarial-content.mjs) grønne på fila, derettergit add <fil>+git commit -m "chore(ms-ai-architect): refresh KB $(basename <fil>) [skip-docs]"med mindre--single-commitble gitt
5. Single-commit modus
Hvis --single-commit: skip committer per fil, og lag én samlet commit til slutt. Layer B FØR commit (ingestion-gate, G6 §8): skann alle endrede skills/**/*.md — en BLOCK (exit 1) tas ut av staging (aldri committet, karantene); en WARN (exit 2) flagges for operatør før commit:
node scripts/kb-update/scan-adversarial-content.mjs $(git diff --name-only --diff-filter=AM -- 'skills/**/*.md')
git add skills/
git commit -m "chore(ms-ai-architect): refresh KB — N files [skip-docs]"
6. Push (om bruker bekrefter)
Spør: "Push til Forgejo origin/main? (y/n)". Per global push-policy er direkte main-push pre-autorisert, men spør likevel her siden dette er en bulk-operasjon.
git push origin main
7. Oppsummering
Rapporter:
- Antall filer oppdatert per prioritet
- Antall commits laget
- Hvis discovery kjørte: antall nye URLer oppdaget og lagt til registry
- Eventuelle filer som ble hoppet over (f.eks. ingen reelle endringer i hentet innhold)
data/change-report.jsonblir værende på disk for diagnose
Fallgruver
- Sitemap-coverage: ~69% av URLene matche mot sitemap. ~31% (mest
azure/ai-foundry/openai/) finnes ikke pga. URL-restrukturering på Microsofts side. Disse rapporteres som "always stale" og må vurderes manuelt - Microsoft_docs_fetch latency: hver fetch tar 2-5 sek. 9 critical + 44 high filer × ~1.5 kilder hver = ~80 fetches = ~3-7 minutter
- Modellvalg: Opus brukes fordi diff-resonnering + tekst-syntese krever nyanse. For enklere "just refresh dates"-oppdateringer er Sonnet tilstrekkelig — bruker kan overstyre med eksplisitt
--model claude-sonnet-4-6i Claude Code config - MCP-tilgjengelighet: kommandoen krever at
microsoft-learnMCP-serveren er aktiv. Sjekk medclaude mcp listved første kjøring
Når kjøre
- Anbefalt: ukentlig eller månedlig, avhengig av hvor sensitive prosjektene dine er for KB-ferskhet
- Før viktig vurdering: kjør med
--priorities critical,high,mediumfør en stor/architect:utredningeller/architect:adr - Etter Microsoft-events: Build, Ignite, eller annen større Microsoft-konferanse → forvent mange endringer
Schedulering
Pluginen schedulerer ingenting før du selv aktiverer det (alt er opt-in). Du har tre nivåer, alle Claude-frie i deteksjonsfasen:
- Tier 1 (sesjonsstart):
scheduled_detection.enabled: trueims-ai-architect.local.md— se «Scheduled deteksjon» over. - Tier 2 (lokal launchd, ekte bakgrunn):
node scripts/kb-update/scheduler.mjs install— se «Scheduled deteksjon» over. - Egen scheduler: vil du heller bruke cron / systemd timer / CI, pek den på
node scripts/kb-update/run-detection.mjs(ellerrun-weekly-update.mjs --force --discoverfor den eldre poll-flyten) og la den varsle deg om å kjøre/architect:kb-updatei en interaktiv sesjon.
Apply-fasen (oppdatere filer + committe) kan ikke automatiseres innenfor denne pluginen — den krever LLM-resonnering på endringene og menneskelig vurdering, og er bevisst designet for kjøring fra en åpen Claude Code-sesjon.