From 4050c8bc21ee011b4d6b75d98615e671669cf9bc Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Fri, 3 Jul 2026 00:39:59 +0200 Subject: [PATCH] =?UTF-8?q?docs(ms-ai-architect):=20skill-validerings-ruti?= =?UTF-8?q?ne-brief=20(AI-Engineer-lens,=20Trinn=200-4)=20=E2=80=94=20inpu?= =?UTF-8?q?t=20til=20R15=20/trekplan=20[skip-docs]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../skill-validation-routine-brief-2026-07.md | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 docs/skill-validation-routine-brief-2026-07.md diff --git a/docs/skill-validation-routine-brief-2026-07.md b/docs/skill-validation-routine-brief-2026-07.md new file mode 100644 index 0000000..a0ac1fa --- /dev/null +++ b/docs/skill-validation-routine-brief-2026-07.md @@ -0,0 +1,174 @@ +# Skill-valideringsrutinen — hvordan den er tenkt å virke (AI-Engineer-lens) + +_Task-brief. Skrevet 2026-07-01. Stier relative til plugin-rot. Durabel (overlever `/clear`). Grunnlaget er verifisert mot disk (to Opus-speidere), ikke gjettet — se §8 verifiseringslogg._ + +> **Status:** BRIEF / ikke startet. Beskriver hvordan rutinen for å validere **én skill** er tenkt å virke ende-til-ende, og bærer **AI-Engineer-perspektivet** (behandle en skill som en ML-komponent: valider på atferd/effekt, ikke bare form) som forbedringsaksen. +> +> **Forhold til søsken-doc:** `docs/skill-eval-routine-improvement-2026-06.md` fordyper **Trinn 1 (form-scoringen)** via Pocock-lens. Denne briefen legger til **Trinn 2–3 (atferd/effekt)** + den samlende «valider én skill»-rutinen. De to overlapper ikke; de dekker hvert sitt lag. `docs/skill-quality-scoring-plan.md` er den bindende spec-en for Trinn 1. + +--- + +## 0. Mål / hvorfor + +**Nordstjerne:** en skill anses ikke som «gyldig» fordi artefaktet er velformet, men fordi den **måles** å (a) trigge når den skal og bare da, og (b) faktisk forbedre modellens output på representative oppgaver — med statistisk sikkerhet og regresjonsvern. I dag måler den kjørende rutinen kun (a) som en proxy og (b) ikke i det hele tatt. + +Dette er **AI-Engineer-perspektivet**: du sender ikke en ML-komponent i produksjon fordi config-filen er velformet — du sender den på målt atferd mot et held-out eval-sett, med varians-tall, gated av regresjonstester. Pluginen har allerede en `ms-ai-engineering`-skill som lærer bort nettopp «MLOps for generativ AI / evals»; den forbedrede valideringsrutinen skal **praktisere det pluginen forkynner** (dogfooding), og mekanismen skal være portabel til søster-plugins ([[showcase-reusable-patterns]]). + +**Anti-mål for briefen:** ikke flere kriterier for kriterienes skyld. Hvert nytt trinn må enten fange en reell feilklasse dagens rutine slipper, eller erstatte et svakere signal med et sterkere. + +--- + +## 1. Kontekst — de to valideringslagene (verifisert) + +Det finnes to helt separate ting som begge kalles «validere en skill». Å blande dem er den vanligste feilkilden. + +| Lag | Spørsmål | Hvor det bor i dag | +|---|---|---| +| **KB-/referansefil-korrekthet** | Er påstandene i `references/*.md` sanne mot kilde? | `generate-skills` «født-verifisert»-judge (v3.1) + `validate-kb-file.mjs` create-guard | +| **Skill-kvalitet/triggering** | Er `SKILL.md` godt formet, trigger den riktig, overlapper den søsken, **hjelper den**? | `scripts/kb-eval/` (K1–K10 + N1–N5 → 0–100-score) | + +Denne briefen handler om **det andre laget** — men KB-korrekthet er en *forutsetning* (Trinn 0 under), så den nevnes eksplisitt, ikke utdypes. + +### 1a. Hva den kjørende rutinen måler i dag (Trinn 1 — form) + +Kilde: `scripts/kb-eval/eval.mjs` (deterministiske sjekker) + `lib/skill-score.mjs` (ren scoring) + CLI `score-skill.mjs`. Bindende spec: `docs/skill-quality-scoring-plan.md`. + +- **16-kriteriers vektet rubrikk → én 0–100-score per skill.** `TARGET = 90`, `FLOOR_CAP = 89`. +- **Hardt gulv** på to last-bærende kriterier — **K1 trigger-presisjon** (vekt 3) og **K10 søsken-overlapp** (vekt 3): feiler en av dem, kappes scoren til ≤89 og skillen kan aldri passere, uansett formatering. +- Aggregering: `Σ(vekt · delpoeng for TILGJENGELIGE kriterier) / Σ(vekt tilgjengelige) × 100`. +- Øvrige: K3 body ≤500 linjer, K4 ingen duplisering (judge), K9 ingen volatil tid-info (judge), K2 description-format, K5 progressiv disclosure, K6 routing, K7 imperativ stil (judge), CT5 sourcedness, refCount, N1 name-validitet (≤64, `[a-z0-9-]`, ingen `claude`/`anthropic`), N2 description ≤1024, N3 refs én nivå dypt, N4 TOC i ref-filer >100 linjer, N5 forward-slash-stier. +- **Gate:** `node scripts/kb-eval/score-skill.mjs --gate 90` → exit≠0 hvis noen skill <90. Kjøres etter skill-mutasjon i `apply-skill-op.mjs`, og signaleres ved sesjonsstart (Spor D-hook, viser skills <90 %). +- **Cache:** `scripts/kb-eval/data/skill-score-report.json`. +- **Nåværende status:** advisor=91, de fire andre=96, alle `meetsTarget`. Toppfiks stort sett N4 (TOC). + +### 1b. Hvordan K1 «trigger-presisjon» faktisk måles i dag — og hvorfor det er en proxy + +- Operatør-kuratert **20-prompt-sett per skill** (`data/k1-trigger-prompts.json`): 10 in-domain + 10 adversarielle out-of-domain (søsken-domene-prompter valgt for å teste over-trigging-grensen). PASS = ≥90 % hits / ≤10 % falske positive. +- Avgjøres av en **blindet judge** (`judge-prompt.md`) som resonnerer **kun fra `description`-teksten** — ikke ved å faktisk kjøre prompten gjennom modellen. +- Judge-kriteriene (K1/K4/K7/K9) krever et **manuelt, operatør-gated subagent-steg** (Opus, én dommer per skill). Uten fersk judge merkes scoren `provisional` og K1-gulvet kan ikke håndheves. + +Dette fungerer og har fanget ekte feil (governance K1 var 0.85 før Schrems-II-recall-fiksen; advisors NOT-liste validert som over-trigging-fiks). Men det er en **proxy**: en dommer som vurderer teksten, ikke atferd. Den fanger ikke at Claude i praksis *undertrigger* enkle queries — fordi modellen kun konsulterer en skill for oppgaver den ikke lett løser selv. + +--- + +## 2. Problemet — AI-Engineer-gapet + +Dagens kjørende rutine er i praksis **strukturell hygiene + en trigger-proxy**. Seks konkrete hull, alle verifisert: + +1. **Form vs. effekt.** Rutinen måler kun *form*, aldri *uplift*: hjelper skillen faktisk vs. en ingen-skill-baseline? Dokumentert som eksplisitt roadmap-hull (skill-quality-scoring-plan §Fase 2), men ikke bygget. +2. **K1 er en proxy, ikke live triggering.** En judge resonnerer om description-teksten; ingen query kjøres gjennom modellen. Fanger ikke undertrigging. +3. **Ingen varians-analyse.** Judge kjøres **én gang** per skill. Ingen mean±stddev, ingen flaky-deteksjon, ingen repetisjon. LLM-output er stokastisk; ett kall er ett sample. +4. **Judge er manuell og kan bli stale.** Ingen automatisk re-judge når `description` endres; scoren faller stille til `provisional`. +5. **`generate-skills` validerer aldri skill-kvalitet.** Kommandoen som produserer mest innhold gater kun referansefil-korrekthet — aldri K1/K10/score. En skill kan drifte i triggering uten at noe fanger det. +6. **Ingen samlende «valider én skill»-rutine.** I dag er det 3–4 uavhengige spor (født-verifisert KB-judge, create-guard, kb-eval-score, ekstern skill-reviewer/skill-creator). Ingen enkelt inngang binder KB-korrekthet + form + atferd sammen til én verdikt. + +**Nøkkelfunn:** mekanismene for hull #1–#3 finnes **ferdig-designet** i Anthropics `skill-creator`-skill, men er **ikke adoptert** i dette repoet: +- **Effekt-eval (3a):** spawn with-skill OG baseline i samme tur → assertions + timing → grader → `aggregate_benchmark` gir pass-rate/tid/tokens med **mean±stddev + delta**; analyzer flagger ikke-diskriminerende og høy-varians-evals. +- **Triggering-optimizer (3b):** 20 eval-queries (should/should-not, near-miss-negative), `run_loop.py` splitter **60/40 train/held-out**, kjører **hver query 3× for pålitelig trigger-rate** via live `claude -p`, og velger `best_description` **på test-score, ikke train** (unngår overfitting). + +Briefen finner altså ikke opp noe — den **adopterer og binder sammen** eksisterende byggeklosser under AI-Engineer-lensen. + +--- + +## 3. Hvordan rutinen er tenkt å virke — mål-tilstand + +Én inngang, `validate-skill `, kjører fem trinn i rekkefølge og emitterer én verdikt. Billige/deterministiske trinn først (fail-fast), dyre atferds-trinn sist. + +``` +validate-skill + Trinn 0 KB-korrekthet (forutsetning) ── født-verifisert + create-guard grønn? + Trinn 1 Form/hygiene-score (FINNES) ── K1–N5 → 0–100, --gate 90 + Trinn 2 Live triggering (NY · AI-Eng) ── precision + recall, N× repetisjon, varians, train/held-out + Trinn 3 Effekt / uplift (NY · AI-Eng) ── with-skill vs baseline, mean±stddev + delta + Trinn 4 Gate + regresjon ── behavioral gate ved siden av form-gate; auto re-run ved endring + → verdikt: PASS / NEEDS-WORK / FAIL + forbedringspekere +``` + +### Trinn 0 — KB-korrekthet (forutsetning, finnes) +Referansefilene skal være født-verifisert (`Verified by: judge-v3.1`) og bestå create-guard (`validate-kb-file.mjs`: Source, TOC, kontrakt-header). Ikke en del av skill-*kvaliteten*, men må være grønt før atferds-evals gir mening — en skill kan ikke «hjelpe» hvis KB-en den ruter til er feil. + +### Trinn 1 — Form/hygiene-score (finnes; fordypes av Pocock-doc) +Behold uendret som den **billige, deterministiske gaten**: K1–N5 → 0–100, `--gate 90`, hardt gulv på K1/K10. Dette er raskt, kjører i CI, og fanger regresjoner i struktur/scope uten modell-kall. Pocock-doc'et (`skill-eval-routine-improvement-2026-06.md`) utvider dette trinnet — ikke reforhandlet her. + +### Trinn 2 — Live triggering (NY · kjernen i AI-Eng-løftet) +Erstatt/suppler K1-judge-proxyen med **behavioral triggering-måling**: +- Utvid det kuraterte 20-prompt-settet til et **merket eval-sett** med should-trigger + should-not-trigger, der negative er **near-misses** (deler nøkkelord med skillen, men trenger noe annet — typisk en søster-skill). +- Kjør hver query **N× (default 3) gjennom modellen live** og mål **trigger-rate**, ikke ja/nei. Rapporter **precision OG recall** (dagens K1 måler i praksis kun presisjon/over-trigging; recall/undertrigging er ugated). +- **60/40 train/held-out-splitt**; velg/juster description på **held-out-score** for å unngå å overfitte teksten til eval-settet. +- Rapporter **varians** (mean±stddev per query); flagg høy-varians-queries som flaky. +- Mekanisme: adopter/wrap `skill-creator` `run_loop.py`, eller reimplementer i repoets `mjs`/TDD-stil (se §7 åpen beslutning). + +### Trinn 3 — Effekt / uplift (NY · AI-Eng) +Svar på det rubrikken aldri svarer på: **gjør skillen output bedre enn ingen skill?** +- For hvert eval-case: spawn **with-skill OG baseline i samme tur** (adopter `skill-creator` 3a — ikke sekvensielt). +- Objektivt verifiserbare **assertions** der oppgaven tillater det; kvalitativ grading der den ikke gjør det (skriv aldri kunstige assertions for subjektiv kvalitet). +- Aggregér til **pass-rate + tid + tokens med mean±stddev og delta** vs. baseline. +- **Analyzer-pass:** flagg ikke-diskriminerende assertions (består med ELLER uten skill → måler ingenting) og høy-varians/flaky-evals. + +### Trinn 4 — Gate + regresjon +- **Behavioral gate ved siden av form-gaten:** en skill-/description-/KB-endring som senker trigger-recall eller uplift-delta under terskel **feiler gaten** (i dag gates kun form via `--gate 90`). +- **Auto re-run ved endring:** når `SKILL.md`/`description` eller rutet KB endres, re-kjør minst Trinn 1–2 (Trinn 3 er dyrere — periodisk/på forespørsel). Fjerner stale-judge-problemet (hull #4). +- **Wire inn i `generate-skills`** (lukker hull #5): batch-genereringen kaller `validate-skill` for berørte skills, ikke bare KB-korrekthet. +- Resultater caches med provenans (som dagens `judge-results.json` / `skill-score-report.json`), slik at Spor D-signalet og gatene leser ferske tall. + +--- + +## 4. AI-Engineer-perspektivet — disiplin → hull → mekanisme + +| AI-Eng-prinsipp | Dagens hull | Importert mekanisme | +|---|---|---| +| **Evals er sannheten, ikke lint** — en komponent vurderes på målt atferd, ikke på at config er velformet | Kun form måles (#1) | Trinn 3 uplift-benchmark (`skill-creator` 3a) | +| **Triggering = en klassifikator → mål precision OG recall, live** | K1 = judge-proxy, kun presisjon (#2) | Trinn 2 live `run_loop` (`skill-creator` 3b) | +| **Stokastisk output → repetisjon + varians** | Judge kjøres 1×, ingen stddev (#3) | 3× repetisjon, mean±stddev, flaky-flag | +| **Unngå overfitting til eval-settet** | Judge ser hele settet | 60/40 train/held-out, velg på test-score | +| **Regresjonsvern i CI** | Kun form gated (#4/#5) | Behavioral gate + auto re-run, wired i `generate-skills` | +| **Ikke-diskriminerende evals er verdiløse** | Ingen sjekk | Analyzer-pass (flagger no-op-assertions) | +| **Én reproduserbar pipeline, ikke spredte spor** | 3–4 uavhengige spor (#6) | Samlende `validate-skill ` → én verdikt | + +--- + +## 5. Suksesskriterier (testbare) + +En implementasjon av denne rutinen er ferdig når: + +1. `validate-skill ` finnes, kjører Trinn 0→4 sekvensielt, og emitterer én verdikt (PASS/NEEDS-WORK/FAIL) + rangerte forbedringspekere. **Test:** kjør mot en skill, verifiser exit-kode + strukturert output. +2. **Trinn 2 måler live trigger-rate** (ikke judge-proxy) med **både precision og recall**, hver query kjørt ≥3×, med mean±stddev per query. **Test:** output inneholder recall-tall og stddev; en bevisst under-triggende description gir recall < terskel. +3. **Trinn 3 produserer with-skill-vs-baseline-delta** med mean±stddev. **Test:** en skill med kjent uplift viser positiv delta; en no-op-skill viser ~0 delta og flagges av analyzer. +4. **Behavioral gate håndhever regresjon:** en description-endring som knuser recall/uplift gir exit≠0. **Test:** injiser en dårlig description, verifiser at gaten feiler. +5. **`generate-skills` kaller `validate-skill`** for berørte skills. **Test:** kjør batch, verifiser at valideringen trigges (ikke bare create-guard). +6. **Alt TDD-gated:** nye moduler har failing test først; suiten (`node --test tests/kb-eval/*.test.mjs …`) grønn. **Test:** exit-kode, ikke glyph-grep. +7. **Ingen regresjon i eksisterende Trinn 1:** dagens 5 skills scorer fortsatt ≥90 og `skill-score-report.json`-skjemaet er uendret (eller versjonert bevisst). + +--- + +## 6. Non-Goals (scope-grenser) + +- **Ikke** endre/reforhandle Trinn 1-rubrikken (K1–N5) — det eies av Pocock-doc'et og scoring-planen. +- **Ikke** bygge KB-korrekthets-judgen (Trinn 0 finnes; det er Spor 1 / judge v3.1-territorium). +- **Ikke** røre Cosmo-persona eller legacy-generatorer (S-Cosmo-sporet). +- **Ikke** auto-fikse en skill basert på eval-resultat — rutinen **måler og flagger**; menneske bekrefter og endrer (samme disiplin som «aldri auto-fiks KB»). +- **Ikke** bestemme build-vs-adopt for `skill-creator`-verktøyene her — det er en åpen beslutning (§7), ikke en del av briefen. + +--- + +## 7. Åpne beslutninger (trenger operatør) + +1. **Adopter vs. reimplementer `skill-creator`-verktøyene.** De er Python (`run_loop.py`, `aggregate_benchmark`); repoet er `mjs` + TDD. *Anbefaling:* wrap/adopter først for å **måle verdien** på de 5 skillene, reimplementer i `mjs` kun hvis adoptert og verdt vedlikeholdet ([[faktabasert-build-both-measure]]). +2. **Kostnad for live triggering.** Full Trinn-2-kjøring ≈ 20 queries × 3 repetisjoner × 5 skills = ~300 live modell-kall; Trinn 3 kommer i tillegg. Pris er operatør-gated. *Anbefaling:* behold den billige K1-judge-proxyen som CI-gate hver commit; kjør de dyre live-trinnene periodisk / før release / ved description-endring. +3. **Behold K1-proxy eller erstatt?** *Anbefaling:* behold begge — proxy = billig hyppig gate, live triggering = dypere periodisk sannhet. To signaler, ikke ett erstatter det andre. + +--- + +## 8. Verifiseringslogg + løse tråder + +**Grunnlaget** er verifisert 2026-07-01 av to Opus-speidere mot disk (ikke STATE-påstander): +- Rubrikk/vekter/gulv/aggregering: `scripts/kb-eval/lib/skill-score.mjs`, `eval.mjs`, `score-skill.mjs` + `tests/kb-eval/*` (invariantene asserteres). +- K1-metoden: `judge-prompt.md` + `data/k1-trigger-prompts.json` + `data/judge-results.json` (alle 5 precision 1.0). +- `skill-creator`-rutinen: `plugins/skill-creator/skills/skill-creator/SKILL.md` §163–404 (effekt-eval + triggering-optimizer). +- Roadmap-hullet: `docs/skill-quality-scoring-plan.md` §Fase 2 + `docs/skill-eval-routine-improvement-2026-06.md`. + +**Løse tråder å adressere i planen (ikke her):** +- **Doc-drift:** `skill-quality-scoring-plan.md` §2-tabellen lister fortsatt **K8**; koden har erstattet K8 med den deterministiske **CT5**. Koden er kilden; planen bør oppdateres. +- **Git-inkonsistens:** `skill-score-report.json` er både `.gitignore`-matchet OG faktisk tracked (committet før den ble ignorert). Hook-kommentaren i `session-start-context.mjs` antar «gitignored ⇒ fraværende i fresh clone» — som ikke stemmer. Trivielt, men verdt å rydde når rutinen røres. + +**Neste steg:** operatør-review av denne briefen → `/trekplan --brief docs/skill-validation-routine-brief-2026-07.md` for implementeringsplan (TDD-gated, sesjons-dekomponert).