feat(okr): okf_version emitteres i rot-indeksens frontmatter

This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 21:15:50 +02:00
commit 1da9dd878d
4 changed files with 144 additions and 12 deletions

View file

@ -2,16 +2,25 @@
// okf-index.mjs
// Genererer OKF-kompatible `index.md` per nivaa i en bundle-rot (prosjekt
// `.claude/okr/` eller home `~/.claude/okr/org/`). Verbatim OKF-«Documents/kb
// Layout»-index-form:
// Layout»-index-form. ROT-index:
// ---
// okf_version: <upstream> (frontmatter -- OKF-versjonen bundelen sikter mot)
// ---
//
// # Overskrift
//
// okf_version: <upstream> (KUN rot-index -- OKF-versjonen bundelen sikter mot)
// okf_layout: <revisjon> (KUN rot-index -- vaar egen layout-revisjon, valgfri)
// okf_layout: <revisjon> (broedtekst -- vaar egen layout-revisjon, valgfri)
//
// * [title](relativ.md) - description
// Ingen frontmatter paa index.md (OKF-reservert). Konsept-filers `title`/
// `description` leses via lib/frontmatter.mjs. Underkataloger faar en peker til
// sin egen index.md. Kjoeres PER ROT (de to bundlene har ulik livssyklus).
// UNDERKATALOG-index: samme, men uten frontmatter og uten markoerer.
//
// De to markoerene ligger paa ULIKE flater med vilje (beslutning 6, D8 steg 21):
// `okf_version` er upstream-eid og den maskinlesbare kontrakten konsumenter
// utenfor pluginen leser -> frontmatter; `okf_layout` er vaar egen revisjon ->
// broedtekst. Frontmatter paa index.md gjelder DERFOR kun roten -- underkatalog-
// indekser er fortsatt frontmatter-frie. Konsept-filers `title`/`description`
// leses via lib/frontmatter.mjs. Underkataloger faar en peker til sin egen
// index.md. Kjoeres PER ROT (de to bundlene har ulik livssyklus).
//
// Idempotens / vedlikehold (NFR): en eksisterende index.md sin `# overskrift`,
// rotens markoer-verdier, og menneske-skrevne beskrivelser for underkatalog-
@ -23,7 +32,7 @@
import { readdirSync, readFileSync, writeFileSync, existsSync, renameSync } from 'node:fs';
import { join, basename, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { parseFrontmatter } from '../lib/frontmatter.mjs';
import { parseFrontmatter, writeFrontmatter } from '../lib/frontmatter.mjs';
// To distinkte markoerer (OKF-spec §12) -- ett felt skal ikke baere to urelaterte
// konsepter. `okf_version` = upstream Google OKF-versjonen bundelen sikter mot
@ -198,11 +207,22 @@ function writeIndexFor(dir, isRoot, explicitLayout, callerRank) {
const heading = existing.heading
|| (isRoot ? 'OKF second brain' : titleFromName(basename(dir)));
const lines = [`# ${heading}`, ''];
// Beslutning 6: de to markoerene har ulike eiere og ulik livssyklus, saa de
// faar ulike flater. `okf_version` (upstream, Google-eid) er den maskinlesbare
// kontrakten konsumenter utenfor pluginen leser -> frontmatter. `okf_layout`
// (vaar egen revisjon) blir staaende i broedteksten. KUN rot-indeksen; en
// underkatalog-index faar aldri frontmatter.
const lines = [];
let rootLayout = null;
if (isRoot) {
const { version, layout } = resolveMarkers(existing, explicitLayout);
lines.push(`okf_version: ${version}`, `okf_layout: ${layout}`, '');
rootLayout = layout;
// Siste element av split er '' (writeFrontmatter avslutter med \n) -- droppes
// her og erstattes av den bevisste blanklinja mellom blokk og overskrift.
lines.push(...writeFrontmatter({ okf_version: version }).split('\n').slice(0, -1), '');
}
lines.push(`# ${heading}`, '');
if (isRoot) lines.push(`okf_layout: ${rootLayout}`, '');
for (const sd of subdirs) {
const link = `${sd}/index.md`;