feat(ms-ai-architect): Spor D — skill-quality score-motor (ren lib + rubrikk grunnet i Anthropic) (TDD)

Objektiv 0-100 kvalitetsscore per skill, operatør-besluttet modell: vektet
delpoeng + hardt gulv på de load-bearing kriteriene (K1 trigger-presisjon, K10
søsken-overlapp) — en skill som ikke trigger riktig eller overlapper en søster
kan aldri «bestå» 90 %, uansett form.

Rubrikken er VERIFISERT mot Anthropics faktiske skill-authoring-guidance
(platform.claude.com best-practices + skill-creator + plugin-dev + engineering-
bloggen) og er nesten 1:1 med deres kanoniske sjekkliste — ikke akademisk
oppfunnet. Kilder + vekter/gulv låst i docs/skill-quality-scoring-plan.md.

scripts/kb-eval/lib/skill-score.mjs (NY, ren): scoreSkill(evalObj) konsumerer
eval.mjs-objektet (K1-K10 + judge-cache) → {score, rawScore, floored, judged,
provisional, criteria[], improvements[], meetsTarget}. Degraderer pent når
ujudget (judge-kriterier ekskludert, K1-gulv kan ikke håndheves → provisional;
K10-gulvet deterministisk → gjelder alltid). scoreReport() summerer < 90.

Tester (+10): 100-score, gulv kapper ved K1/K10-fail (også ujudget), delkreditt
(K3 lengde / K4 score/5), degradering ekskluderer judge, forbedringsliste
sortert på poeng-tap m/ fix, null-toleranse. kb-eval 100→110, validate 239/0.

GJENSTÅR (neste): N1-N5 deterministiske Anthropic-sjekker i eval.mjs + CLI
score-skill.mjs --gate 90 + summarizeSkillQuality-surfacing; DERETTER eval+
oppgradering av alle 5 skills én-og-én. Roadmap i docs + STATE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-06-23 16:57:31 +02:00
commit bab9f2d23d
3 changed files with 424 additions and 0 deletions

View file

@ -0,0 +1,78 @@
# Skill-kvalitetsscore (Spor D) — spec
_Objektiv 0100 %-kvalitetsscore per skill, med 90 %-bar, forbedringsrapport og SessionStart-surfacing. Grunnet i Anthropics faktiske skill-authoring-guidance (ikke oppfunnet akademisk). Skrevet 2026-06-23 (S37). Stier relative til plugin-rot._
---
## 0. Mål
En **rutine som objektivt måler skill-kvalitet** og rapporterer hva som må forbedres, med målsetning **alle skills ≥ 90 % til enhver tid**. Bygger oppå den eksisterende K1K10-rubrikken i `scripts/kb-eval/eval.mjs`, som research (under) viser er nesten 1:1 med Anthropics kanoniske «Skill authoring best practices»-sjekkliste — altså allerede grunnet i reell praksis, ikke akademisk oppfunnet.
## 1. Verifiseringskilder (Anthropic primær)
- **«Skill authoring best practices»** — platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices (hentet 2026-06-23). Kanonisk sjekkliste + eksakte tall.
- **`skill-creator` (Anthropic-shippet skill)** — `~/.claude/plugins/.../skill-creator/SKILL.md`. Description-optimizer (trigger-presisjon via 20 queries / 60-40 train-test / 3 kjøringer), eval-loop.
- **`plugin-dev:skill-development` (Anthropic-shippet)** — third-person description, imperativ form, progressiv disclosure, «avoid duplication».
- **«Equipping agents for the real world with Agent Skills»** — anthropic.com/engineering (hentet 2026-06-23). Progressiv disclosure, evaluering fra capability-gaps, baseline-uplift.
### Eksakte, målbare regler funnet (med kilde)
| Regel | Tall | Kilde |
|---|---|---|
| `name` | ≤64 tegn, `a-z0-9-`, ingen XML, ingen reserverte ord («claude»/«anthropic»), gerund-form anbefalt | best-practices §Skill structure |
| `description` | ≤1024 tegn, ikke-tom, 3.-person, «hva + når», spesifikke triggere | best-practices §Writing effective descriptions |
| SKILL.md body | **< 500 linjer** («token budget», «optimal performance») | best-practices §Token budgets + §Progressive disclosure |
| Refs én nivå dypt | ingen nøstede refs | best-practices §Avoid deeply nested references |
| TOC i ref-filer | for filer **> 100 linjer** | best-practices §Structure longer reference files |
| Ingen tid-sensitiv info i body | flytt til «old patterns»/`<details>` | best-practices §Avoid time-sensitive information |
| Forward-slash-stier | aldri Windows-stier | best-practices §Avoid Windows-style paths |
| Imperativ form | verb-først, ikke 2.-person | plugin-dev §Writing Style |
| Ingen duplisering SKILL.md↔refs | info bor ett sted | plugin-dev §Avoid duplication |
| Evaluering = sannhetskilde | ≥3 evals, **baseline uten skill → mål uplift** | best-practices §Evaluation and iteration |
## 2. Rubrikk → score-mapping (binding)
K1K10 er allerede implementert i `eval.mjs` og validert mot tabellen over. Scoren legger til **fem nye deterministiske sjekker** fra Anthropic-sjekklista som rubrikken manglet (N1N5), og aggregerer alt til 0100.
**Modell: vektet delpoeng + hardt gulv** (operatør-besluttet S37).
| Kriterium | Kilde | Vekt | Gulv | Delpoeng (01) |
|---|---|---|---|---|
| **K1** trigger-presisjon | judge | 3 | **JA** | `precision` (korrekte/20) |
| **K10** søsken-ikke-overlapp | det | 3 | **JA** | `pass?1 : max(0, 1-(maxCombined-terskel)/terskel)` |
| **K3** body ≤500 linjer | det | 2 | — | `lines≤500?1 : max(0, 1-(lines-500)/500)` |
| **K4** ingen duplisering | judge | 2 | — | `score/5` |
| **K9** ingen volatil tid-info | judge | 2 | — | `pass?1:0` |
| **K2** description-format | det | 1 | — | `pass?1:0` |
| **K5** progressiv disclosure | det | 1 | — | `min(1, namedRatio/0.2)` |
| **K6** routing-pekere | det | 1 | — | `pass?1:0` |
| **K7** imperativ stil | judge | 1 | — | `ratio` |
| **K8** kildehenvisning refs | judge | 1 | — | `ratio` |
| ref-tall-konsistens | det | 1 | — | `consistent?1:0` |
| **N1** name-validitet | det | 1 | — | `pass?1:0` |
| **N2** description ≤1024 + ikke-tom | det | 1 | — | `pass?1:0` |
| **N3** refs én nivå dypt | det | 1 | — | `pass?1:0` |
| **N4** TOC i ref-filer >100 linjer | det | 1 | — | andel store filer med TOC |
| **N5** forward-slash-stier | det | 1 | — | `pass?1:0` |
**Aggregering:** `score = Σ(vekt·delpoeng for TILGJENGELIGE kriterier) / Σ(vekt for tilgjengelige) × 100`. «Tilgjengelig» = deterministiske alltid; judge-kriterier kun når `skill.judge` finnes (cachet i `data/judge-results.json`).
**Hardt gulv:** feiler et tilgjengelig gulv-kriterium (K1 eller K10) → `score = min(score, 89)`. En skill som ikke trigger riktig (K1) eller overlapper en søster (K10) kan aldri «bestå» 90 %, uansett form. (Anthropic: description/triggering «critical for skill selection».)
**Degradering:** mangler/stale judge → judge-kriteriene ekskluderes fra både teller og nevner; `judged:false` flagges + nudge om å kjøre judge-passet. K1-gulvet kan da ikke håndheves → `score` merkes `provisional`. K10-gulvet (deterministisk) gjelder alltid.
## 3. Komponenter (TDD, deterministisk-først)
1. **`scripts/kb-eval/eval.mjs` (utvidelse):** N1N5 deterministiske sjekker under `deterministic`. Disk-tilgang bor her (har allerede body/frontmatter/ref-filer).
2. **`scripts/kb-eval/lib/skill-score.mjs` (NY, ren):** `scoreSkill(evalObj)``{name, score, rawScore, floored, judged, provisional, criteria[], improvements[], meetsTarget}`. Ingen disk — konsumerer eval-objektet → fullt testbar med fixtures.
3. **CLI `scripts/kb-eval/score-skill.mjs` (NY):** kjører eval-pipelinen → scorer alle skills → rapport. `--json`, `--gate 90` (non-zero exit + forbedringsrapport hvis noen < 90).
4. **`summarizeSkillQuality(report)` (i detection-schedule.mjs):** one-liner «Skill-kvalitet: N skills < 90 %», `null` ved alle ≥ 90. Wires i `session-start-context.mjs` (speiler kurs-/skill-signaler).
## 4. Verifisering (kjørbar)
- `node --test tests/kb-eval/test-skill-score.test.mjs` grønn: vektet aggregering, gulv kapper ved K1/K10-fail, degradering ekskluderer judge når `judge:null`, forbedringsliste sortert på poeng-tap, `meetsTarget`-grense.
- N1N5 enhetstester i `test-eval.test.mjs` (gyldig/ugyldig name, >1024 description, nøstet ref, manglende TOC, Windows-sti).
- `score-skill.mjs --gate 90` returnerer non-zero når en fixture-skill er < 90; 0 når alle ≥ 90.
- `summarizeSkillQuality`-test (one-liner + null).
- kb-eval-suite + validate uendret-grønn (ingen regresjon).
## 5. Fase 2 (roadmap, ikke nå) — effektivitet/uplift
Anthropics *dypeste* mål: «does the skill actually help vs. no-skill baseline». Krever eval-harness (Claude-in-loop, operatør-gated) modellert på `skill-creator`s benchmark (with-skill vs baseline, `pass_rate`-delta, mean±stddev). Egen, tyngre fase — form-scoren over er nødvendig, men uplift er det endelige beviset. Spec-es separat ved opt-in.