feat(okr): KR-datakontrakt i skriv-malen
This commit is contained in:
parent
2c42e422c1
commit
e3a99b02ff
2 changed files with 84 additions and 0 deletions
|
|
@ -104,6 +104,54 @@ KR[n]: [Formulering med baseline → target]
|
|||
- Type: Committed / Aspirational
|
||||
```
|
||||
|
||||
### Maskinlaget: KR-datakontrakten i frontmatter
|
||||
|
||||
Punktprosaen over er for mennesker og beholdes uendret. Ved siden av den legges
|
||||
**samme tall som maskinlesbar frontmatter** i `okr-*.md`, slik at rapport-
|
||||
generatorene (`/okr:rapport`) kan lese syklusen uten å tolke prosa.
|
||||
|
||||
Emitter fem nøkler per KR `n`, nummerert fra 1:
|
||||
|
||||
```yaml
|
||||
---
|
||||
type: OKR
|
||||
kr1_navn: Saksbehandlingstid førerkort (dager)
|
||||
kr1_baseline: 14
|
||||
kr1_target: 5
|
||||
kr1_naa: 11
|
||||
kr1_type: committed
|
||||
kr2_navn: Andel digitale søknader (%)
|
||||
kr2_baseline: 60
|
||||
kr2_target: 85
|
||||
kr2_naa: 72
|
||||
kr2_type: aspirational
|
||||
---
|
||||
```
|
||||
|
||||
| Nøkkel | Innhold |
|
||||
|--------|---------|
|
||||
| `krN_navn` | Tekst. Kortform av KR-en. **Enheten hører hjemme her** (og i prosaen) |
|
||||
| `krN_baseline` | Utgangspunktet ved syklusstart |
|
||||
| `krN_target` | Målverdien ved syklusslutt |
|
||||
| `krN_naa` | Nåverdien. **Oppdateres ved hver check-in** |
|
||||
| `krN_type` | `committed` eller `aspirational` — små bokstaver |
|
||||
|
||||
**Tre regler som gjør kontrakten lesbar for generatoren:**
|
||||
|
||||
1. **Rene tall uten enhet.** `kr1_baseline: 14`, aldri `14 dager` eller `60 %`.
|
||||
Enheten bæres av `krN_navn` og av prosaen — et tall med enhet er ikke et tall.
|
||||
2. **Score skrives aldri til fil.** Den beregnes av generatoren som
|
||||
`(nåværende − baseline) / (target − baseline)`. En lagret score er en andre
|
||||
sannhetskilde som drifter fra tallene den ble utledet av. Ingen `krN_score`.
|
||||
3. **Nedadgående mål trenger ingen særbehandling** — `baseline: 14, target: 5`
|
||||
fungerer som-er, fordi teller og nevner begge blir negative.
|
||||
|
||||
For binære KR (milepæl): sett `krN_baseline: 0` og `krN_target: 1`, og la
|
||||
`krN_naa` være `0` eller `1`.
|
||||
|
||||
`/okr:skriv` skriver ikke til disk. Emitter frontmatteren sammen med OKR-teksten
|
||||
og be brukeren lagre den i `.claude/okr/syklus/[syklus-id]/okr-[navn].md`.
|
||||
|
||||
## Strategi-til-OKR
|
||||
|
||||
Når brukeren har strategidokument eller tildelingsbrev som input:
|
||||
|
|
|
|||
|
|
@ -511,3 +511,39 @@ test('(m2) D4: kommunal-styring siterer ikke DFO-notat 2026:2 (sektoravgrensning
|
|||
'DFO-notat 2026:2 er avgrenset mot kommunal sektor og kan ikke siteres her',
|
||||
);
|
||||
});
|
||||
|
||||
// --- (n) D5 steg 6: KR-datakontrakten (beslutning B-1) er dokumentert i skriv-malen ---
|
||||
// Generatorene i lib/syklus-*.mjs leser KR-tall fra `krN_`-noekler i okr-*.md sin
|
||||
// frontmatter. Kontrakten har ingen skjema-fil aa haandheve seg mot -- den haandheves
|
||||
// av at DEFINISJONSFLATEN (skriv-malen) dokumenterer den, siden /okr:skriv er stedet
|
||||
// tallene oppstaar. Vakten binder de to sidene sammen: endres kontrakten i lib/ uten
|
||||
// at malen foelger etter, produserer brukeren filer generatoren ikke kan lese.
|
||||
const KR_KONTRAKT_NOEKLER = ['navn', 'baseline', 'target', 'naa', 'type'];
|
||||
|
||||
test('(n) D5: skriv.md dokumenterer alle fem krN_-noeklene i KR-datakontrakten', () => {
|
||||
const doc = readDoc('commands/skriv.md');
|
||||
const missing = KR_KONTRAKT_NOEKLER.filter(
|
||||
(k) => !new RegExp(`kr(?:N|\\d+)_${k}\\b`).test(doc),
|
||||
);
|
||||
assert.deepEqual(
|
||||
missing,
|
||||
[],
|
||||
`KR-datakontrakten (B-1) mangler noekler i commands/skriv.md: ${missing.join(', ')}`,
|
||||
);
|
||||
});
|
||||
|
||||
// B-2: score BEREGNES, lagres aldri. En `krN_score`-noekkel i malen ville skapt en
|
||||
// andre sannhetskilde som kan drifte fra (naa - baseline) / (target - baseline).
|
||||
// Fravaers-invariant paa NOEKKELFORMEN slik lib/frontmatter.mjs:29 leser den
|
||||
// (`^\s*key:`) -- ikke paa ordet "score", som malen legitimt bruker om
|
||||
// moonshot/roofshot-kalibrering (:124), og ikke paa prosa som FORBYR noekkelen.
|
||||
// Det er noekkelen i frontmatter som skaper den andre sannhetskilden; en omtale
|
||||
// av den gjoer det ikke.
|
||||
test('(n2) D5: skriv.md introduserer ingen krN_score-noekkel (score lagres aldri)', () => {
|
||||
const offenders = linesMatching(readDoc('commands/skriv.md'), /^\s*kr(?:N|\d+)_score\s*:/m);
|
||||
assert.deepEqual(
|
||||
offenders,
|
||||
[],
|
||||
'score skal beregnes fra baseline/target/naa, aldri lagres som egen noekkel',
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue