fix(okr): seksjons-bevisst confidence-telling i coaching-hook (patch-lane #1)

Hooken talte alle tabellrader merket At Risk/Off Track under ett. okr-framework.md:605
sier samtidig at de fleste stretch-KR BOER staa At Risk, og at permanent groent er selve
sandbagging-signalet. For en sunn aspirational-portefoelje pekte varselet dermed feil vei:
eneste maate aa dempe det paa var aa merke stretch-KR groenne -- noeyaktig det kanon
advarer mot. Fra 1.10.0 fylles kolonnen deterministisk, saa kollisjonen inntraff alltid.

Tellingen foelger naa seksjonen raden staar under:
  committed     -> At Risk OG Off Track teller
  aspirational  -> KUN Off Track ("progresjonen har stoppet opp" er reelt ogsaa for stretch)
  uplasserbar   -> telles som committed

Fallbacken er en operatoerbeslutning, ikke en default: haandskrevne status.md fra foer
1.10.0 har ingen seksjonsstruktur, og en fil som varsler for lite er farligere enn en som
varsler for mye. Samme verdi som dekningsvakten i statusrapport() haandhever paa skrivesiden.

Rad-predikatene er navngitte konstanter, og de to testfilene som leser dem ut av hookens
kilde henter dem naa ved NAVN i stedet for ved posisjon -- hooken har flere predikater enn
to, saa "det foerste og det andre literalet" ville vaert en vakt som stille plukket feil regex.

Test (7) i syklus-status.test.mjs kunne ikke bare endres fra 3 til 2: den SIMULERTE hookens
aritmetikk med skrapte rad-predikater, og en seksjons-bevisst regel er ikke uttrykkbar per
rad. Splittet i (7) rad-form og (7b) ekte ende-til-ende-telling som kjoerer hooken mot
generatorens fil paa disk.

Suite 343 -> 348. Fire mutasjoner verifisert: seksjons-bevissthet fjernet -> ROED (4),
aspirational teller aldri -> ROED (1), fallback snudd -> ROED (3), navne-forankring brutt
-> ROED (6).

Ingen versjonsbump: bugfix paa releaset kode (presedens 8a7bc08). CHANGELOGs "Kjent avvik"
under 1.10.0 er ikke slettet -- 1.10.0 BLE utgitt med avviket -- men lukket med hva som
gjelder naa.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-10 21:20:51 +02:00
commit 43a84d2326
5 changed files with 233 additions and 38 deletions

View file

@ -44,21 +44,19 @@ const byggFor = (bygger, opts = {}) => bygger(lesSyklus(SYKLUS_DIR), { naa: NAA,
// literalene ut av coaching-hook.mjs' egen kilde blir en fremtidig endring i
// hooken en ROED suite her, i stedet for en stille inkompatibilitet.
// Hooken er i forbidden_paths for dette steget -- forbudt aa ENDRE, ikke aa LESE.
// Hentes ved NAVN, ikke ved posisjon. Hooken ble seksjons-bevisst i S61 og har
// flere predikater enn de to rad-predikatene; «det foerste og det andre
// literalet i fila» ville da vaert en vakt som stille plukket feil regex.
function hookPredikater() {
const src = readFileSync(join(ROOT, 'hooks/scripts/coaching-hook.mjs'), 'utf8');
const funnet = [...src.matchAll(/(\/(?:[^/\\\n]|\\.)+\/[gimsuy]*)\.test\(line\)/g)].map(
(m) => m[1],
);
assert.equal(
funnet.length,
2,
`parser-sanity: forventet 2 rad-predikater i coaching-hook.mjs, fant ${funnet.length}`,
);
const kompiler = (lit) => {
const hent = (navn) => {
const m = src.match(new RegExp(`^const ${navn} = (/(?:[^/\\\\\\n]|\\\\.)+/[gimsuy]*);`, 'm'));
assert.ok(m, `parser-sanity: fant ikke konstanten ${navn} i coaching-hook.mjs`);
const lit = m[1];
const siste = lit.lastIndexOf('/');
return new RegExp(lit.slice(1, siste), lit.slice(siste + 1));
};
return { radForm: kompiler(funnet[0]), fareOrd: kompiler(funnet[1]) };
return { radForm: hent('ER_KR_RAD'), fareOrd: hent('FARE_ORD') };
}
const erKrRad = (linje) => /^\s*\|/.test(linje) && !/^\s*\|[\s|:-]+\|\s*$/.test(linje)