feat(ms-ai-architect): Spor D N1–N5 — Anthropic-deterministiske skill-sjekker (TDD) [skip-docs]

Legger de fem deterministiske sjekkene fra Anthropics «Skill authoring best
practices» som K1–K10-rubrikken manglet, i begge lag av score-motoren:

- eval.mjs (disk-laget): extractName + checkN1..checkN5
  - N1 name-validitet (≤64, a-z0-9-, ingen «claude»/«anthropic»; gerund rapporteres, gater ikke)
  - N2 description ikke-tom + ≤1024 tegn
  - N3 refs én nivå dypt (ref-fil lenker ikke til annen ref-fil)
  - N4 TOC i ref-filer >100 linjer (delpoeng = andel store filer med TOC)
  - N5 forward-slash-stier (ingen Windows-backslash-stier i body)
  wiret inn i evalSkill.deterministic (leser nå ref-fil-innhold for N3/N4)
- lib/skill-score.mjs (ren): N1–N5 i CRITERIA (vekt 1, ikke-gulv, det)

Live-sanity mot de 5 skills: N1/N2/N5 rene, N3 fanger ekte nøstet ref i
advisor (licensing-matrix.md → 3 andre ref-filer), N4 avdekker 387 store
ref-filer uten TOC (primær forbedringsspak for oppgraderingsfasen).

Tester: kb-eval 110→134 (+24). validate 239, kb-update 316 uendret grønt.
[skip-docs]: N1–N5 alt spesifisert i docs/skill-quality-scoring-plan.md §2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-06-23 17:09:29 +02:00
commit e87289d929
4 changed files with 323 additions and 0 deletions

View file

@ -126,6 +126,43 @@ export const CRITERIA = [
return { available: true, sub: k.consistent ? 1 : 0, pass: !!k.consistent, detail: k.consistent ? 'OK' : `${(k.mismatches || []).length} avvik` };
},
},
{
key: 'N1', label: 'name-validitet', weight: 1, floor: false, source: 'det',
fix: 'Rett skill-name: ≤64 tegn, kun a-z0-9-, ingen «claude»/«anthropic».',
read: (e) => readBinary(e.deterministic?.N1_nameValidity),
},
{
key: 'N2', label: 'description ≤1024', weight: 1, floor: false, source: 'det',
fix: 'Hold description ikke-tom og ≤1024 tegn.',
read: (e) => readBinary(e.deterministic?.N2_descriptionLength),
},
{
key: 'N3', label: 'refs én nivå dypt', weight: 1, floor: false, source: 'det',
fix: 'Fjern lenker fra ref-filer til andre ref-filer (unngå nøstede referanser).',
read: (e) => {
const k = e.deterministic?.N3_refNestingDepth;
if (!k) return { available: false };
return { available: true, sub: k.pass ? 1 : 0, pass: !!k.pass, detail: k.pass ? 'OK' : `${(k.nested || []).length} nøstede` };
},
},
{
key: 'N4', label: 'TOC i store ref-filer', weight: 1, floor: false, source: 'det',
fix: 'Legg innholdsfortegnelse i ref-filer >100 linjer (eksplisitt TOC-heading eller anker-cluster).',
read: (e) => {
const k = e.deterministic?.N4_refToc;
if (!k) return { available: false };
return { available: true, sub: clamp01(num(k.ratio)), pass: !!k.pass, detail: `${num(k.withToc)}/${num(k.largeFiles)} store filer med TOC` };
},
},
{
key: 'N5', label: 'forward-slash-stier', weight: 1, floor: false, source: 'det',
fix: 'Erstatt Windows-stier (\\) med forward-slash i SKILL.md.',
read: (e) => {
const k = e.deterministic?.N5_forwardSlashPaths;
if (!k) return { available: false };
return { available: true, sub: k.pass ? 1 : 0, pass: !!k.pass, detail: k.pass ? 'OK' : `${(k.windowsPaths || []).length} Windows-stier` };
},
},
];
function num(v) {