fix(okr): avviksvurderingen maa gaa gjennom score, ikke naa >= target
This commit is contained in:
parent
7d1de8049d
commit
8ef8f7a405
2 changed files with 62 additions and 1 deletions
|
|
@ -35,9 +35,19 @@ const formatScore = (score) => (score === undefined ? UDEFINERT : score.toFixed(
|
|||
|
||||
// Governance-invariant 2: committed maales binaert mot kravet, ikke paa score.
|
||||
// Aspirational har ingen Avvik-kolonneverdi -- 0.7 er forventet, ikke svikt.
|
||||
//
|
||||
// Predikatet gaar gjennom beregnScore, ALDRI gjennom `naa >= target` direkte:
|
||||
// den sammenligningen er retningsavhengig og gir feil svar begge veier for
|
||||
// nedadgaaende krav (krav 5 dager, naa 11 -> "ingen avvik"; krav 5, naa 4 ->
|
||||
// "avvik"). beregnScore haandterer retningen allerede, fordi teller og nevner
|
||||
// begge blir negative. Bonus: kolonnen kan da ikke motsi rapportens egen
|
||||
// setning om at en score under 1.0 er et avvik.
|
||||
const formatAvvik = (kr, erCommitted) => {
|
||||
if (!erCommitted) return '-';
|
||||
return kr.naa >= kr.target ? 'Nei' : 'Ja';
|
||||
const score = beregnScore(kr);
|
||||
// target == baseline: ingen ratio aa maale mot, men kravet er fortsatt et tall.
|
||||
if (score === undefined) return kr.naa === kr.target ? 'Nei' : 'Ja';
|
||||
return score >= 1 ? 'Nei' : 'Ja';
|
||||
};
|
||||
|
||||
function krRad(kr, erCommitted) {
|
||||
|
|
|
|||
|
|
@ -147,6 +147,57 @@ test('(6) tertialrapport kaster ved tom eller ufullstendig syklus', () => {
|
|||
assert.throws(() => tertialrapport(undefined), /syklus/i);
|
||||
});
|
||||
|
||||
// --- (2d) Avvik-kolonnen maa vaere retningsagnostisk ---
|
||||
//
|
||||
// `naa >= target` ser riktig ut for oppadgaaende maal og er FEIL for
|
||||
// nedadgaaende: et krav om 5 dager, naa 11, gir 11 >= 5 = "ingen avvik" -- et
|
||||
// brudd rapportert som etterlevd i et Riksrevisjon-vendt dokument. Fixturen kan
|
||||
// ikke fange det (dens committed-KR er begge oppadgaaende, og dens nedadgaaende
|
||||
// KR er aspirational, som kortslutter til "-"), saa syklusen konstrueres her.
|
||||
// Retningen hoerer hjemme i beregnScore, som allerede haandterer den.
|
||||
const NEDADGAAENDE = {
|
||||
id: 'T-avvik',
|
||||
okrer: [{
|
||||
fil: 'okr-avvik.md',
|
||||
tittel: 'Nedadgaaende krav',
|
||||
krer: [
|
||||
{ n: 1, navn: 'Saksbehandlingstid (dager)', baseline: 14, target: 5, naa: 11, type: 'committed' },
|
||||
{ n: 2, navn: 'Alvorlige hendelser (antall)', baseline: 0, target: 0, naa: 3, type: 'committed' },
|
||||
{ n: 3, navn: 'Naadd krav (dager)', baseline: 14, target: 5, naa: 4, type: 'committed' },
|
||||
],
|
||||
}],
|
||||
};
|
||||
|
||||
const avvikFor = (navn) => {
|
||||
const rad = tertialrapport(NEDADGAAENDE, { naa: NAA }).split('\n').find((l) => l.includes(navn));
|
||||
assert.ok(rad, `fant ikke raden for ${navn}`);
|
||||
return rad.split('|').map((c) => c.trim())[6];
|
||||
};
|
||||
|
||||
test('(2d) committed nedadgaaende KR under kravet merkes som avvik', () => {
|
||||
assert.equal(avvikFor('Saksbehandlingstid'), 'Ja', 'naa 11 mot krav 5 er et avvik');
|
||||
});
|
||||
|
||||
test('(2d2) committed KR med target == baseline avviker naar naa ikke er lik kravet', () => {
|
||||
assert.equal(avvikFor('Alvorlige hendelser'), 'Ja', '3 hendelser mot krav 0 er et avvik');
|
||||
});
|
||||
|
||||
test('(2d3) committed KR som naar kravet merkes ikke som avvik', () => {
|
||||
assert.equal(avvikFor('Naadd krav'), 'Nei', 'naa 4 mot krav 5 (nedadgaaende) er oppfylt');
|
||||
});
|
||||
|
||||
// Rapporten sier selv at "en score under 1.0 er et avvik som skal forklares".
|
||||
// Avvik-kolonnen maa aldri motsi den setningen paa samme rad.
|
||||
test('(2d4) Avvik-kolonnen motsier ikke rapportens egen score-setning', () => {
|
||||
const md = tertialrapport(NEDADGAAENDE, { naa: NAA });
|
||||
const motsigelser = md.split('\n').filter((l) => {
|
||||
const c = l.split('|').map((x) => x.trim());
|
||||
if (c.length < 8 || c[6] !== 'Nei') return false;
|
||||
return c[5] !== 'udefinert' && Number(c[5]) < 1;
|
||||
});
|
||||
assert.deepEqual(motsigelser, [], `score < 1.0 merket som ikke-avvik:\n${motsigelser.join('\n')}`);
|
||||
});
|
||||
|
||||
// --- (7) CLI-kontrakten (steg 10) ---
|
||||
//
|
||||
// Testet BEGGE VEIER i samme fil: direkte import for atferd, execFileSync for
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue