feat(okr): okf-check leser okf_version fra frontmatter og broedtekst

This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 21:11:58 +02:00
commit 049259d9a6
2 changed files with 155 additions and 11 deletions

View file

@ -58,23 +58,51 @@ function walkConcepts(root) {
return out;
}
// Les rotens to markoerer (markdown-tekst i index.md, ikke frontmatter).
// `okf_version` = upstream OKF-versjon (spec §3), `okf_layout` = emitterens egen
// layout-revisjon (spec §12, valgfri). Fravaerende markoer -> null. Ren ekko:
// verdiene valideres ikke (spec §3 er ikke haandhevende paa form ennaa).
// Les rotens to markoerer fra index.md. `okf_version` = upstream OKF-versjon
// (spec §3), `okf_layout` = emitterens egen layout-revisjon (spec §12, valgfri).
// Fravaerende markoer -> null. Ren ekko: verdiene valideres ikke (spec §3 er
// ikke haandhevende paa form ennaa).
//
// Verdien unquotes med SAMME konservative regel som produsent-siden (okf-index
// unquote(), delt import -- ikke en kopi). Uten den ga samme fil to lesninger:
// produsenten tolket `okf_version: "0.2"` som 0.2, checkeren ekkoet «"0.2"».
// Anfoerselstegn er YAML-strengsyntaks, ikke del av verdien -- og siden
// upstreams eneste kanoniske eksempel med verdi (SPEC.md:773) er sitert, er
// dette den formen en spec-tro bundle faktisk har paa disk.
// TO PLASSERINGER, bevisst (D8 steg 20). Beslutning 6 flytter `okf_version` til
// frontmatter mens `okf_layout` blir i broedteksten, men bundles paa disk
// migrerer ikke samtidig -- en bundle skrevet av en eldre okf-index baerer
// fortsatt begge i broedteksten. Lesingen proever derfor frontmatter FOERST og
// faller tilbake til broedteksten. Presedensen er en REGEL her, ikke en
// bivirkning av at frontmatter tilfeldigvis staar oeverst i fila.
//
// De to lagene har ULIKE tolkningsregler, og det er hele grunnen til at de er
// skilt:
// - frontmatter ER YAML -> parseFrontmatter haandterer sitering OG trailing
// ` # kommentar` (lib/frontmatter.mjs:39). En raa `^key:`-scan lot
// kommentaren lekke inn i verdien.
// - broedteksten er IKKE YAML -> der er unquote() alene riktig regel, delt
// import fra okf-index (produsent-siden) og ikke en kopi. Uten den ga samme
// fil to lesninger: produsenten tolket `okf_version: "0.2"` som 0.2,
// checkeren ekkoet «"0.2"». Upstreams eneste kanoniske eksempel med verdi
// (SPEC.md:773) er sitert, saa det er formen en spec-tro bundle har paa disk.
function rootMarkers(root) {
const idx = join(root, 'index.md');
if (!existsSync(idx)) return { okfVersion: null, okfLayout: null };
const raw = readFileSync(idx, 'utf8');
const { raw: fmRaw, get: fmGet } = parseFrontmatter(raw);
// Broedteksten = alt UNDER frontmatter-blokken, slik at de to lagene kan feile
// hver for seg (mutasjon M1 roedner (20a)/(20d) NETTOPP fordi fallbacken ikke
// ser frontmatter-linjene).
//
// AERLIG OM DEKNINGEN: uttrekket er ikke produksjonsobserverbart i dag. Naar
// noekkelen finnes i frontmatter i en form parseFrontmatter i det hele tatt
// returnerer, vinner fm-laget foer fallbacken kjoeres -- saa `body = raw`
// roedner ingen test (maalt, ikke antatt). Det beholdes likevel: fjernes det,
// ligger en latent defekt og venter paa at lib/frontmatter.mjs's list-key-
// kontrakt (:13-15) blir sann. I dag returnerer get() paa en list-key foerste
// LIST-ELEMENT, ikke null, fordi `\s*` i :29-regexen spiser linjeskiftet.
// Fikses det (patch-lane), begynner fallbacken aa kjoere for list-keys -- og
// uten dette uttrekket ville den plukket «- a» ut av frontmatter.
const body = fmRaw === null ? raw : raw.slice(raw.indexOf('\n---', 3) + 4);
const pick = (key) => {
const m = raw.match(new RegExp(`^${key}:\\s*(.+)$`, 'm'));
const fromFm = fmGet(key);
if (fromFm !== null) return unquote(fromFm);
const m = body.match(new RegExp(`^${key}:\\s*(.+)$`, 'm'));
return m ? unquote(m[1].trim()) : null;
};
return { okfVersion: pick('okf_version'), okfLayout: pick('okf_layout') };