fix(okr): differensier samlet-aggregat i references (patch-lane #4)
Tre maler i references/ lovet EN udifferensiert samlet score, i strid med separasjonsregelen i okr-framework.md: committed og aspirational maales mot ulike standarder og skal rapporteres hver for seg. Rot-aarsak: vektings-listen i okr-framework.md oppga "noen KR-er committed og andre aspirational" som en GRUNN TIL AA VEKTE -- seks linjer over seksjonen som forbyr aa aggregere de to i det hele tatt. Malene lovet et samlet tall fordi kanon sanksjonerte det. Bulleten er fjernet og erstattet av prosa som avgrenser vekting til innenfor EN type. Malene foelger naa generatorens form (lib/syklus-rapport.mjs): committed binaert mot kravet, aspirational som snitt over N KR. ASCII-boksenes bredde er bevart. (k)-vaktens skanne-sett utvidet fra commands/+agents/ til ogsaa references/. Eksklusjonen var KATALOG-BRED for aa skaane per-Objective-aggregeringen i kalkulatoren, og tok team-aggregatene med seg -- samme lekse som R4. Per-Objective gaar fortsatt klar, men paa MOENSTERET i stedet for paa katalogen. Ny vakt (k2) mot at kanon gjenoppretter sanksjonen. Strukturell, ikke semantisk: et kulepunkt i vektings-listen som navngir begge typene er en sanksjon i kraft av posisjon. Mutasjons-verifisert -- identisk ordlyd flyttet INN i listen feller vakten, som beviser at den maaler posisjon og ikke ordlyd. Suite 328 -> 329.
This commit is contained in:
parent
9a68441161
commit
285d18ebfa
4 changed files with 68 additions and 12 deletions
|
|
@ -235,12 +235,13 @@ Neste steg: [liste]
|
||||||
|
|
||||||
```
|
```
|
||||||
Objective: [navn]
|
Objective: [navn]
|
||||||
Samlet score: [0.0-1.0]
|
Committed: [X] av [Y] KR nådd
|
||||||
|
Aspirational: [0.0-1.0] (snitt over [N] KR)
|
||||||
|
|
||||||
Key Results:
|
Key Results:
|
||||||
1. [KR1 navn]: Target [X], Actual [Y], Score [Z]
|
1. [KR1 navn] (committed): Target [X], Actual [Y], Score [Z], Avvik [ja/nei]
|
||||||
2. [KR2 navn]: Target [X], Actual [Y], Score [Z]
|
2. [KR2 navn] (committed): Target [X], Actual [Y], Score [Z], Avvik [ja/nei]
|
||||||
3. [KR3 navn]: Target [X], Actual [Y], Score [Z]
|
3. [KR3 navn] (aspirational): Target [X], Actual [Y], Score [Z]
|
||||||
|
|
||||||
Hva gikk bra:
|
Hva gikk bra:
|
||||||
- [bullet]
|
- [bullet]
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,8 @@ Oppsummering av alle OKR for et team:
|
||||||
├────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────┤
|
||||||
│ TEAM TOTALT │
|
│ TEAM TOTALT │
|
||||||
│ │
|
│ │
|
||||||
│ Samlet score: ______ (______%) │
|
│ Committed: ____ av ____ KR nådd │
|
||||||
|
│ Aspirational: ______ (snitt over ____ KR) │
|
||||||
│ │
|
│ │
|
||||||
│ On Track: ____ OKR At Risk: ____ OKR Off Track: ____ OKR │
|
│ On Track: ____ OKR At Risk: ____ OKR Off Track: ____ OKR │
|
||||||
│ │
|
│ │
|
||||||
|
|
|
||||||
|
|
@ -548,10 +548,11 @@ Vektet score = (0.7×2 + 0.5×1 + 0.8×1) / (2+1+1) = 2.7 / 4 = 0.675
|
||||||
**Når bruke vekting:**
|
**Når bruke vekting:**
|
||||||
- Når noen KR-er er tydelig viktigere enn andre
|
- Når noen KR-er er tydelig viktigere enn andre
|
||||||
- Når ressursinnsatsen varierer vesentlig mellom KR-er
|
- Når ressursinnsatsen varierer vesentlig mellom KR-er
|
||||||
- Når noen KR-er er "committed" og andre "aspirational"
|
|
||||||
|
|
||||||
**Anbefaling:** Start med uvektet gjennomsnitt. Introduser vekting kun hvis det gir tydelig verdi.
|
**Anbefaling:** Start med uvektet gjennomsnitt. Introduser vekting kun hvis det gir tydelig verdi.
|
||||||
|
|
||||||
|
**Vekting løser ikke blandet type.** Vekting hører hjemme *innenfor* én type — committed mot committed, aspirational mot aspirational — der den håndterer at noen KR veier tyngre enn andre. Blandet type er et annet problem: de to måles mot ulike standarder, og ingen vekt gjør dem sammenlignbare i ett tall. Svaret er å rapportere dem hver for seg, ikke å vekte dem sammen (se under).
|
||||||
|
|
||||||
#### Aggreger ikke committed og aspirational sammen
|
#### Aggreger ikke committed og aspirational sammen
|
||||||
|
|
||||||
Committed og aspirational OKR-scorer måles mot **ulike standarder** og bør ikke blandes til ett aggregat: committed forventes å nå **1.0** (enten grønn eller rød — et avvik krever forklaring), mens aspirational forventes å lande rundt **0.7** med høy varians og vurderes på **snittet på tvers av alle aspirational-OKR**, ikke på én enkelt. Å aggregere de to typene til ett tall blander to forskjellige målestokker og gjør resultatet tvetydig — et committed-snitt på 0.85 er en bekymring, mens et aspirational-snitt på 0.85 er svært bra. Rapportér derfor de to typene hver for seg. (Dette følger som logisk implikasjon av Doerr/Googles to-måls-struktur — ikke et ordrett Doerr-sitat; se committed-vs-aspirational-tabellen i `okr-cheatsheet.md`.)
|
Committed og aspirational OKR-scorer måles mot **ulike standarder** og bør ikke blandes til ett aggregat: committed forventes å nå **1.0** (enten grønn eller rød — et avvik krever forklaring), mens aspirational forventes å lande rundt **0.7** med høy varians og vurderes på **snittet på tvers av alle aspirational-OKR**, ikke på én enkelt. Å aggregere de to typene til ett tall blander to forskjellige målestokker og gjør resultatet tvetydig — et committed-snitt på 0.85 er en bekymring, mens et aspirational-snitt på 0.85 er svært bra. Rapportér derfor de to typene hver for seg. (Dette følger som logisk implikasjon av Doerr/Googles to-måls-struktur — ikke et ordrett Doerr-sitat; se committed-vs-aspirational-tabellen i `okr-cheatsheet.md`.)
|
||||||
|
|
@ -687,7 +688,8 @@ For team-nivå rapportering:
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ TEAM: [Teamnavn] Syklus: [X] 20XX │
|
│ TEAM: [Teamnavn] Syklus: [X] 20XX │
|
||||||
├─────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────┤
|
||||||
│ Samlet score: 0.XX (XX%) │
|
│ Committed: X av Y KR nådd │
|
||||||
|
│ Aspirational: 0.XX (snitt over N KR) │
|
||||||
│ On Track: X av Y OKR-er │
|
│ On Track: X av Y OKR-er │
|
||||||
│ At Risk: X av Y OKR-er │
|
│ At Risk: X av Y OKR-er │
|
||||||
│ Off Track: X av Y OKR-er │
|
│ Off Track: X av Y OKR-er │
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,17 @@ test('(a2) F-c: ingen parallelle confidence-etikettsett utenfor kanon', () => {
|
||||||
// (lib/syklus-rapport.mjs) haandhever det; malene gjorde det ikke. En regel med to
|
// (lib/syklus-rapport.mjs) haandhever det; malene gjorde det ikke. En regel med to
|
||||||
// lesninger er nettopp defektklassen S38-S40 kostet tre oekter.
|
// lesninger er nettopp defektklassen S38-S40 kostet tre oekter.
|
||||||
//
|
//
|
||||||
// Skanne-settet er commands/ + agents/ -- MALENE pluginen emitterer. references/
|
// Skanne-settet er references/ + commands/ + agents/ -- ALLE flater som emitterer
|
||||||
// staar utenfor med vilje: der foeres en annen diskusjon (per-Objective-aggregering
|
// en rapportform. references/ sto foerst utenfor for aa skaane en ANNEN diskusjon
|
||||||
// i kalkulatoren), og aa dra den inn her ville blandet to spoersmaal i en vakt.
|
// (per-Objective-aggregering i kalkulatoren), men eksklusjonen var KATALOG-BRED og
|
||||||
|
// tok team-aggregatene med seg: tre maler i references/ lovet et samlet tall
|
||||||
|
// (meeting-guides.md, okr-calculator.md, okr-framework.md). Samme lekse som R4 --
|
||||||
|
// en vakt smalere enn sitt eget case-navn gjoer drift usynlig.
|
||||||
|
//
|
||||||
|
// Per-Objective-aggregeringen eksklusjonen skulle skaane gaar fortsatt klar, og
|
||||||
|
// gjoer det paa MOENSTERET i stedet for paa katalogen: "Beregn samlet score for et
|
||||||
|
// Objective med flere KR" (okr-calculator.md:122) har ingen verdi paa linjen, og
|
||||||
|
// "Objective total"-radene sier ikke "samlet score".
|
||||||
//
|
//
|
||||||
// To former, fordi bruddet har to skrivemaater:
|
// To former, fordi bruddet har to skrivemaater:
|
||||||
// ETIKETT -- "Samlet score" sammen med en VERDI paa linjen (tall, X-plassholder
|
// ETIKETT -- "Samlet score" sammen med en VERDI paa linjen (tall, X-plassholder
|
||||||
|
|
@ -193,8 +201,8 @@ const MERMAID_AKSE = /^\s*[xy]-axis\b/;
|
||||||
const AGGREGAT_INSTRUKS = /\bsamlet\b[^\n]{0,25}vektet\s+gjennomsnitt/i;
|
const AGGREGAT_INSTRUKS = /\bsamlet\b[^\n]{0,25}vektet\s+gjennomsnitt/i;
|
||||||
|
|
||||||
test('(k) separasjonsregelen: ingen mal emitterer et udifferensiert samlet-aggregat', () => {
|
test('(k) separasjonsregelen: ingen mal emitterer et udifferensiert samlet-aggregat', () => {
|
||||||
const maler = [...mdFiles('commands'), ...mdFiles('agents')];
|
const maler = [...mdFiles(REF), ...mdFiles('commands'), ...mdFiles('agents')];
|
||||||
assert.ok(maler.length >= 10, `parser-sanity: forventet >= 10 maler, fant ${maler.length}`);
|
assert.ok(maler.length >= 30, `parser-sanity: forventet >= 30 maler, fant ${maler.length}`);
|
||||||
|
|
||||||
const violations = [];
|
const violations = [];
|
||||||
for (const f of maler) {
|
for (const f of maler) {
|
||||||
|
|
@ -218,6 +226,50 @@ test('(k) separasjonsregelen: ingen mal emitterer et udifferensiert samlet-aggre
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- (k2) kanon sanksjonerer ikke det (k) forbyr (patch-lane #4) ---
|
||||||
|
//
|
||||||
|
// okr-framework.md listet "Naar noen KR-er er committed og andre aspirational" som
|
||||||
|
// en GRUNN TIL AA VEKTE -- seks linjer over seksjonen som forbyr aa aggregere de to
|
||||||
|
// typene i det hele tatt. Malene lovet et samlet tall fordi kanon sa at vekting var
|
||||||
|
// svaret paa blandet type. (k) alene ville rettet symptomet og latt kilden staa.
|
||||||
|
//
|
||||||
|
// Vakten er STRUKTURELL, ikke semantisk: den leser kulepunktlisten under
|
||||||
|
// "Naar bruke vekting:" -- en liste over TILFELLER DER MAN SKAL VEKTE -- og feller
|
||||||
|
// et punkt som navngir begge typene. Et punkt DER er en sanksjon i kraft av sin
|
||||||
|
// posisjon, uansett ordlyd. Den korrigerende prosaen ("vekting gjelder innenfor EN
|
||||||
|
// type; committed og aspirational rapporteres hver for seg") navngir ogsaa begge,
|
||||||
|
// men staar UTENFOR listen og gaar derfor klar. Et negasjons-moenster som skulle
|
||||||
|
// skille sanksjon fra forbud semantisk ville vaert nettopp den falske vakten S58
|
||||||
|
// ble felt av: den ville maalt ordlyd, ikke paastand.
|
||||||
|
const VEKTING_LISTE = /^\*\*N\u00e5r bruke vekting/;
|
||||||
|
|
||||||
|
test('(k2) vektings-listen oppgir ikke blandet committed/aspirational som vektings-grunn', () => {
|
||||||
|
const linjer = readDoc(join(REF, 'okr-framework.md')).split('\n');
|
||||||
|
const start = linjer.findIndex((l) => VEKTING_LISTE.test(l.trim()));
|
||||||
|
assert.ok(start >= 0, 'parser-sanity: fant ikke "Naar bruke vekting:"-listen');
|
||||||
|
|
||||||
|
// Listen er sammenhengende; foerste ikke-kulepunkt (her: blanklinjen foran
|
||||||
|
// **Anbefaling:**) avslutter den. Skiller listen seg fra overskriften senere,
|
||||||
|
// rydder sanity-asserten under opp i det hoeylytt i stedet for aa skanne tomt.
|
||||||
|
const punkter = [];
|
||||||
|
for (let i = start + 1; i < linjer.length; i += 1) {
|
||||||
|
const tekst = linjer[i].trim();
|
||||||
|
if (!tekst.startsWith('-')) break;
|
||||||
|
punkter.push({ nr: i + 1, tekst });
|
||||||
|
}
|
||||||
|
assert.ok(punkter.length >= 2, `parser-sanity: forventet >= 2 kulepunkter, fant ${punkter.length}`);
|
||||||
|
|
||||||
|
const violations = punkter
|
||||||
|
.filter((p) => /committed/i.test(p.tekst) && /aspirational/i.test(p.tekst))
|
||||||
|
.map((p) => `okr-framework.md:${p.nr}: ${p.tekst}`);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
violations,
|
||||||
|
[],
|
||||||
|
`vekting oppgitt som svar paa blandet type -- motsier separasjonsregelen i samme fil:\n${violations.join('\n')}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// --- F-d kadens x publikum (D1 / review.md 607313e3) ---
|
// --- F-d kadens x publikum (D1 / review.md 607313e3) ---
|
||||||
// Den forrige vakten bandt kadens-adjektivet DIREKTE til check-in (\s+), og kunne derfor
|
// Den forrige vakten bandt kadens-adjektivet DIREKTE til check-in (\s+), og kunne derfor
|
||||||
// ikke feile paa den KANONISKE tabellen: etter "Maanedlig" kommer "**" og en cellevegg,
|
// ikke feile paa den KANONISKE tabellen: etter "Maanedlig" kommer "**" og en cellevegg,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue