Premiss-verifisering mot ground truth (simulert R7-stempler insertVerifiedFields
over 327 non-advisor-filer): RX-HDR-populasjonen kollapser fra påstått 10 til 2.
De 9 'base-felt forbi 500B'-filene er falske positiver — stempleren setter Verified
øverst, uavhengig av hvor Status/Category ligger. Kun 2 filer er ekte ustempelbare
(gpt5-gpt41-pricing-models, entra-agent-id-zero-trust): headere med fete **Status:**-
prosahaler (175B/199B) der begge stempler (Verified + Verified by, judge-v3.1) ikke
får plass i 500B. Feltomstokking løser dem ikke — verdi-slanking kreves (utenfor
RX-HDRs scope), så de folder inn i R7s eksisterende 'header-slanking kreves'-flagg-sti.
audit-corpus-headers.mjs: ny ren isStampable() kjører R7s ekte stempler med fast
representativ probe (dato + judge-v3.1); per-fil 'stampable' + aggregat 'unstampable'
+ FLAG-liste. Gjør populasjonen permanent så den ikke stille kan vokse (gap-disiplin).
+2 tester (dense→ustempelbar, clean→stampable). Suite 924→926 exit 0.
Løser dual-header der filer bærer BÅDE **Dato:** (opprettelse) OG **Last updated:**
(endring). Ground truth 2026-07-16 + git first-commit-map (2026-04-08 for alle 5):
- 4 distinkte (**Dato:** 2026-02-04, FØR git first-commit → ekte opprettelsesdato):
relabel **Dato:** → **Created:**, verdi byte-bevart (norsk→engelsk label-rename).
- 1 identisk (mlops-security-access-control: **Dato:**=**Last updated:**=2026-06-19,
ETTER git first-commit → metadata-artefakt, ikke ekte opprettelsesdato): drop redundant
**Dato:**. Relabel ville påstått falsk opprettelsesdato — drop er sannferdig.
Ny ren primitiv dropRedundantBoldField (kaster uten identisk-verdi bevis-felt),
gjenbrukt relabelHeaderDialect m/ CREATED_MAP. Manifest-drevet dedup-dato.mjs med
hard per-fil-invariant FØR skriv (relabel: 1 linje, kun label-token; drop: net -1,
Last updated bevart), atomicWriteSync, idempotent. Ingen validator håndhever lukket
feltliste → **Created:** er additiv/konform.
+15 tester (dropRedundantBoldField, CREATED_MAP-relabel, applyOp, manifest, 2 corpus-
guards) + oppdatert stale Enhet-2 carve-out-guard til post-3b-sannhet. Suite 910/910
exit 0. validate-plugin 250 PASS/0 FAIL. Datoløse dual-**Dato:**-filer 5→0.
De 87 referansefilene bar en plain-text `| Verified: <dato>`-hale på **Last updated:**-linjen
i 500B-header-vinduet — usynlig for den bold-only kontrakt-stacken (kb-headers.mjs / audit
RE_VERIFIED), og claimet en verifisering judgen aldri gjorde (samme poison-klasse som de 14
bold **Verified:** MCP Spor 1 fjernet). Uhåndtert springer den også dual-Verified-fellen: R7s
insertVerifiedFields ville stemplet en bold-verdi ved siden av den plain → to motstridende
provenance-claims per fil.
- ny driver strip-stale-verified-pipe.mjs: frosset 87-manifest (18 advisor + 45 eng + 8 gov +
16 sec), pure verdi-bevarende strip (kun ` | Verified: …`-halen; **Last updated:**-dato
byte-eksakt), hard per-fil-invariant (linjeantall uendret, body byte-identisk, dato bevart),
idempotent, atomicWriteSync (RX-OPS2 recovery-kontrakt).
- audit-corpus-headers.mjs: ny plain-Verified-deteksjon (RE_PLAIN_VERIFIED + plainVerifiedPipe)
— gjør M4-blindheten synlig så en stale plain-hale ikke kan gjenoppstå stille (non-advisor scope).
- 87 filer strippet; plain Verified i vinduet 0/389; live-audit plainVerifiedPipe 0.
Mekanisme: +15 tester (12 strip + 3 audit). Suite 875→890 exit 0. validate-plugin.sh 250/0.
Utsatt → RX-KB1b: footer-dato-avvik + label-whitelist (annen dialekt, flag-to-human).
Rotårsak-mekanisme: scripts/kb-update/data/ai-act-deadlines.json er nå eneste
kilde for AI Act-frister; CLAUDE.md-tabellen, assessor-malen og begge hooks
synk-testes mot den (tests/kb-update/test-ai-act-deadlines-sync.test.mjs, 9
tester, TDD rød→grønn). Suite 815/815.
- B2: «Kommisjonen kan fremskynde»/«ytre grense» fjernet (trigger droppet i
endelig Omnibus-tekst)
- B3: status oppdatert i alle 3 lag — formelt vedtatt (EP 2026-06-16, Rådet
2026-06-29), trer i kraft ved OJ-publisering (ikke publisert per 2026-07-15,
verifisert mot EUR-Lex 32024R1689)
- B4: Art. 50-raden «Gjeldende» → «Fra 2026-08-02»
- B5: stop-hooken feilmerket 2026-08-02 som «GPAI-frist» — begge hooks leser
nå kilden, 0 hardkodede frist-literals
- R3-5: 2026-12-02-raden (Art. 50(2)) inn i assessor-malen
- M10: Nkom navngitt som koordinerende markedstilsynsmyndighet + nasjonalt
kontaktpunkt (kilde: nkom.no/ki/regulering/hvem-handhever)
- pending_oj-markører i kilden for RX-REG² (nudifiserings-forbud, Art. 111)
- .gitignore: whitelist for den kuraterte frist-kilden
To operasjoner, én økt (⊥ R7), begge ren metadata-normalisering (verdi aldri fabrikkert).
Premiss-korreksjon (ground truth 2026-07-07): roadmap sa «27 none + 4 ai-act».
Målt: 29 mangler bold **Status:** = 25 rene none + 4 ai-act (plain Status: GA).
De «27» inkluderte 2 for mye — 2 filer (custom-dashboards-ai-operations,
zero-trust-ai-services) har bold **Status:** KUN forbi byte 500 (present for
full-fil-audit, usynlig for 500B header-parser) → egen header-slanking-residual
(§8-register), utenfor Enhet 3.
Op A — Status-backfill 25 rene none: utvidet backfill-status.mjs MANIFEST 14→39
(samme statusForFile + insertMetaField + hard per-fil-invariant, idempotent skip
på de 14 R21-gjorte). Alle 25 → **Status:** Established Practice (ingen matcher
template|matrix|benchmarks|register). Diff +25/-0.
Op B — ai-act dual-header-dedup (4 filer): ny driver dedup-plain-header.mjs + 2
rene primitiver i transform.mjs — boldifyPlainField (plain→bold, verdi bevart
byte-eksakt, header-scoped, idempotent) + dropRedundantPlainField (sletter plain
KUN når bold m/ identisk verdi beviser redundans; kaster ved avvik/manglende bold).
Per fil: plain Last updated: + Status: GA → bold (2026-06-18/2026-02, GA bevart),
redundant plain Category: fjernet. Hard per-fil-invariant (net -1 linje, begge
felt bold m/ bevart verdi, ingen plain-header igjen, body byte-identisk). Diff -12/+8.
Verifisering: test-backfill-status 8/8 + test-dedup-plain-header 13/13; audit
Missing Status 29→0, Missing English Last updated 4→0; skills-diff 29 filer
+33/-12 (kun **Status:** + 8 bold-swaps), diff-kontekst inspisert per fil; begge
drivere idempotent (re-run 0 writes); suite 806/806 exit 0; none=8 uendret (Enhet 4).
Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/
infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk
(fra første ## seksjon), advisor urørt (0 endringer).
To applier-fixes oppdaget under kjøring (TDD, RED→GREEN):
- insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer
500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor
scan-vinduet, applierens post-write-assertion fanget + restaurerte).
- normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i
500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var
ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent
utvidelse av carve-out; kun stray metadata-linjer, aldri prosa.
test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet
(fila bærer nå Source). Suite 728/728 grønn.
Det rapporterende gulvet (§4 Port 3, P3b): SessionStart-hooken surfacer en
KB-tillit-énlinjer fra cachet verified-staleness-report.json. Et GULV, ikke en
gate (§4c — unngå alarm-tretthet på 84 %-signal).
summarizeTrustFreshness (detection-schedule.mjs, ren, speiler
summarizeSkillQuality): surfacer KUN drift (stale-since-verified) +
kontraktbrudd (unverified) — det handlingsbare «bekreft mot kilde»-settet.
unmigrated (Spor-1-backlog, 306 i dag) ekskluderes bevisst: ved det volumet
ville det fyre hver økt og bli støy; migrerings-censusen hører i CT5 (P3c).
Tolererer manglende/malformed cache → null (gitignored, fraværende i fersk
klon, krasjer aldri hooken).
session-start-context.mjs: leser cachen read-only (samme mønster som
skill-quality-blokken), dytter linjen når den finnes.
Ende-til-ende verifisert: injisert stale-rapport → «KB-tillit: 3 filer driftet
siden verifisering, 1 uverifisert — bekreft mot kilde (aldri auto-fiks)»; ekte
korpus (306 unmigrated) → taus (ingen falsk alarm).
TDD (Iron Law): 8 nye tester. Suite 612/612. Plugin-validering PASS.
1b-premisset (ikke-advisor storfiler er Cosmo-frie, trygt å TOC-e nå) er
motbevist mot ground truth: 11/12 har en `## …Cosmo…`-overskrift → en TOC
bygget fra `##`-overskriftene ville emittert ny Cosmo-anker (bryter «aldri
ny Cosmo-innhold»), og å nøytralisere overskriften er selve persona-fjerningen
(ikke en sidehandling — scope-guard). Store-fil-TOC (de 20 filene >800 linjer,
advisor + ikke-advisor) folder derfor inn i Cosmo-utfasingen. Denne committen
leverer kun det gjenbrukbare verktøyet; ingen ref-filer rørt.
- transform.insertToc: retrofitter `## Innhold` i en eksisterende storfil rett
før første ikke-fence `## `-seksjon (samme slot som composeKbFile), robust mot
de 3 legacy-header-variantene (med/uten `---`), idempotent, fence-aware.
- scripts/kb-update/backfill-toc.mjs: dry-run/--write applier (ren glue rundt
insertToc; transform.mjs forblir write-fri — arkitektur-invariant).
- docs/cosmo-removal-brief: «Sammenfall»-seksjon dokumenterer fold-inn + bruk.
- TDD: +6 transform-tester. Suite 509/509 (kb-update 355 + kb-eval 154).
Update-mekanismen lot siterte URL-er stå som not_in_sitemap fordi deres docset
aldri ble pollet, og skjemaløse citater (tabellceller: bare learn.microsoft.com/...
uten https://) ble aldri ekstrahert.
- Taxonomy: +5 docsets (graph, ai-builder, power-apps, power-automate,
microsoftsearch) — hver ett child-sitemap, verifisert live mot indeksen.
Bevist: 21/24 not_in_sitemap-URL-er i disse docsetene blir nå tracked.
- url-normalize: extractUrls fanger skjemaløse citater-med-sti (krever /path
etter domenet → avviser bare-domene-prosa og JSON-eksempler); normalizeUrl
kanonikaliserer scheme til https. Bevist: +19 nye URL-er ekstraherbare.
- Bugfix: backtick fra inline-kode-citat (`learn.microsoft.com/...`) lekket inn
i URL-en — ekskludert i regex + trailing-strip.
TDD: tests/kb-update/test-url-normalize.test.mjs (ny, 14) + test-taxonomy
prefiks-count 18→23 + Fase 1a-assertion. Full suite 338/338, 0 regresjon.
Registry-refresh (build-registry --merge + poll) bevisst utsatt — unngår
552KB re-order-churn; effekten er empirisk verifisert read-only.
summarizeSkillQuality(cache) (pure) in detection-schedule.mjs: one-liner
"Skill-kvalitet: N skills < 90 % (navn)"; null when all skills meet target,
when the cache is missing (gitignored → absent in a fresh clone), or when the
shape is malformed. Reads the CACHED skill-score-report.json (from Steg B) —
never scores live (buildReport reads ~400 ref-files). Wired into
session-start-context.mjs after the course-signals block (same
existsSync/try-catch pattern). 7 new tests (kb-update 316 → 323).
[skip-docs]: README is the public end-user doc; skill-quality scoring is
maintainer-only tooling (the cache is gitignored, so the signal never surfaces
for end-users). The right doc homes ARE updated: CLAUDE.md hook table + a
caveat note (this commit), and docs/skill-quality-scoring-plan.md §3 komponent 4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Eier-CLI kan nå sette include_course_detection uten å hand-edite den gitignored
local.md: `write-schedule-config.mjs --enabled true --cadence daily --courses true`.
Flagget er VALGFRITT (opt-in inni opt-in) — utelates det, bevares en verdi satt
andre steder gjennom onboarding-rewriten (samme merge-semantikk som
interval_days / include_skill_lifecycle).
Tester (+3): --courses true setter nøkkelen, string-coercion (CLI-args er
strenger), og non-clobbering når flagget utelates. kb-update 313→316.
docs/development.md: C3-workflow peker nå på CLI-flagget framfor manuell local.md.
Live-probe (2) kjørt mot ekte Learn Platform API: baseline-registry etablert
(1093 kurs: 843 modules + 250 learning-paths), 0 leads (korrekt baseline §8 b).
Registry/report er detektorens gitignored private state — ingen filer committet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tredje ledger-kolleksjon (courses), additivt ved siden av decisions (URL,
Spor A) og actions (skill, Spor B). De tre rene helperne speiler
recordAction-trioen 1:1:
- recordCourseLead(led, uid, lead) (ren, UID-nøklet)
- setCourseLeadStatus(led, uid, status, at) (ren transisjon, kaster på ukjent UID)
- isCourseLeadDecided(led, uid) (dedup policy A: any status)
createLedger()->courses:{}; loadDecisions backfiller courses ??= {} (bakoverkompat).
Strukturell ingen-ingest-invariant: apply-pathene leser ALDRI courses
(apply-skill-op.mjs->kun actions, discover-new-urls.mjs->kun decisions),
så et godkjent kurs-lead trigger aldri fetch/transform/KB-skriving.
commands/kb-update.md §3c: operatør-gate som leser course-detection-report.json,
dedup'er via isCourseLeadDecided, skriver godkjente leads via recordCourseLead
(--dry-run viser leads uten å skrive).
Tester (+16): test-decisions-courses.test.mjs. Eksisterende test-decisions-io
+ test-decisions-actions URØRT grønne (ikke-regresjons-bevis, samme mønster
som Spor B). kb-update 291->307 · validate 239/0 · kb-eval 100/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>