feat(okr): deterministisk skriveledd for status.md (1.10.0)

Kjeden /okr:rapport -> /okr:sporing -> status.md var beskrevet i prosa, men
manglet et mekanisk ledd: ingenting foerte en generert rad inn i status.md --
fila coaching-hook teller at-risk-KR i, /okr:moeter bygger agenda fra, og
/okr:oppsett arkiver leser sluttscorer fra. Rot-aarsaken var at HELE
sporings-stien var lesende (ingen Write/Edit/Bash i allowed-tools).

scripts/syklus-status.mjs tar confidence som JSON paa stdin og bygger radene
gjennom statusrapport() i lib/syklus-rapport.mjs -- samme kode som
tertialrapporten. Aritmetikken kan derfor ikke drifte fra /okr:rapport, fordi
det ikke finnes en andre implementasjon av den. En LLM skriver ikke av et tall
paa veien, og en maskin utleder ikke et trafikklys: beslutning 9 staar, presist
formulert som at generatoren PLASSERER en etikett den faar inn som data og
UTLEDER aldri en.

Haandhevet i kode, ikke i prosa: lukket vokabular (On Track/At Risk/Off Track),
full dekning (en tom confidence-celle ville lest som groenn hos hver konsument),
typo-fangst paa ukjente KR-navn, og kuratert-fil-vern -- en status.md uten
provenans-noekkelen `kilde: sporing` er haandholdt og overskrives aldri (samme
mekanikk som innboks-write bruker med `kilde: innboks`).

Suite 329 -> 343. Fem vakter mutasjons-verifisert: rad-drift mot
tertialrapporten, vokab, dekning (baade alene og sammen med vokab-vakten som
overlapper den), og kuratert-vernet.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-10 20:56:26 +02:00
commit 3a0cbcfbf9
13 changed files with 618 additions and 50 deletions

View file

@ -1,4 +1,4 @@
# OKR Offentlig Sektor v1.9.0
# OKR Offentlig Sektor v1.10.0
Expert OKR guidance for Norwegian public sector. Google/Doerr methodology adapted for 4-month tertial cycles.
@ -9,7 +9,7 @@ Expert OKR guidance for Norwegian public sector. Google/Doerr methodology adapte
| `/okr:skriv` | Write new OKR with guided Objective and KR creation |
| `/okr:kvalitet` | Quality check OKR against rubric and antipatterns |
| `/okr:kaskade` | Cascade OKR from org to team, visualize alignment |
| `/okr:sporing` | Track progress, calculate scores, generate check-ins |
| `/okr:sporing` | Track progress, calculate scores, generate check-ins. Owns the *confidence assessment* and writes `status.md` through `scripts/syklus-status.mjs` — never by hand, so the arithmetic cannot drift from `/okr:rapport` |
| `/okr:møter` | Plan OKR workshops, check-ins, reviews, 1:1s |
| `/okr:innføring` | OKR adoption planning, resistance handling, maturity |
| `/okr:governance` | Tildelingsbrev translation, Riksrevisjon compliance |
@ -72,6 +72,7 @@ Context files carry OKF v0.1 Documents-style frontmatter (conforms to the OKF v0
- `scripts/okf-index.mjs` — regenerate a root's per-level `index.md` (verbatim OKF index format).
- `scripts/okf-check.mjs` — validate each concept file carries `type:` (exit 1 + count otherwise); echo `okf_version` + `okf_layout` per root (pure echo, no value validation).
- `scripts/compose-org-profile.mjs` — build the nested org-profile YAML with top-level OKF keys (`type`/`resource`/`timestamp`) before piping to `write-org-profile.mjs`.
- `scripts/syklus-status.mjs` — deterministic writer for `syklus/[id]/status.md` (`/okr:sporing`): reads confidence as JSON on stdin (KR name → `On Track` | `At Risk` | `Off Track`), builds the rows through `statusrapport()` in `lib/syklus-rapport.mjs` — the same code the tertial report uses, so the arithmetic has no second implementation to drift from. Full coverage is required (an empty confidence cell would read as green to every consumer), the vocabulary is closed, and an existing `status.md` without the provenance key `kilde: sporing` is treated as hand-curated and never overwritten. Atomic write; `OKR_NOW` makes runs byte-identical.
- `scripts/innboks-ingest.mjs` — inbox-ingestion orchestrator (`/okr:innboks`): walks `.claude/okr/innboks/`, converts (txt/md/docx/eml/pdf via `lib/convert/index.mjs`), heading-splits, stamps OKF frontmatter + `kilde: innboks`, routes by type, then gates each document with `okf-check --strict-ingest` — a failing document is discarded alone (staging + per-document rollback), survivors get relations and index entries. Non-destructive (originals stay in the inbox), idempotent by construction (timestamp = source mtime), path-confined (realpath). Binary formats need `npm install --ignore-scripts` (4 exact-pinned pure-JS deps); txt/md run dependency-free.
Retrieval is on-demand via the `okr-second-brain-search` skill. The UserPromptSubmit hook no longer pre-injects the full context-file enumeration — it emits the core profile plus one resolved pointer to `index.md` (< 512 B, independent of file count).
@ -88,7 +89,7 @@ Retrieval is on-demand via the `okr-second-brain-search` skill. The UserPromptSu
/okr:skriv ──→ kvalitetssjekker (auto)
/okr:kvalitet ──→ kvalitetssjekker
/okr:kaskade ──→ kaskadebygger
/okr:sporing ──→ fremdriftssporer ──→ Linear MCP (optional)
/okr:sporing ──→ fremdriftssporer ──→ scripts/syklus-status.mjs (skriver status.md) ──→ Linear MCP (optional)
/okr:møter ──→ møtefasilitator
/okr:governance ──→ styringsrådgiver
/okr:innføring ──→ (inline, no agent)