Ders 08 / 09
Uygulama Güvenlik Ölçütleri
Yüz kırk iki bulgunun ortalama düzeltme süresi 17,0 gün, medyanı 6 gündür: ortalamayı aşan 30 kalem toplam günün yüzde 75'ini taşır. Aynı küme iki gruplama kuralıyla ters yön verir — açılış yarısına göre 23,6'dan 7,6'ya iner, kapanış yarısına göre 13,2'den 20,0'a çıkar — ve açık kuyruğun ortalama yaşı 30,4 günden 59,8 güne yükselirken kalem sayısı 24'ten 21'e düşer. Sekiz sorunun beşi tam, biri kısmi cevaplanır, ikisi cevapsızdır. Ölçütü iyileştiren üç müdahale sıfır kalem düzeltir: ortalama 12,6 güne, açık yaşı 23,4 güne, hedefte oran yüzde 94,2'ye gider.
İçindekiler
Önceki ders kanıtın nerede üretildiğini ölçtü ve kalemleri dönemin tamamını, son doksan günü ya da tek günü cevaplayanlar diye ayırdı; ölçülen şey kanıtın varlığıydı. Denetim maddelerinin bir bölümü ise varlık değil sayı ister: açık tanımlı süre içinde kapatıldı mı, kapatılmayan ne kadar süredir açık.
Bu ders o iki sayıyı — ortalama düzeltme süresi ve açık yaşı — bir uygulama ekibi ölçeğinde hesaplar. Yönetişim, Risk ve Uyumluluk kursu aynı ölçütleri program düzeyinde ele almıştı; o kuyruk burada girdidir. Sorulan şey dardır: ölçütler neyi söylüyor, neyi söylemiyor ve söylemediği şey kaç soruyu cevapsız bırakıyor.
Bulgu Kümesi ve Soru Kümesi
UY14. Bulgu kümesi 142 kalemdir, beş kaynaktan gelir, 180 günlük bir döneme aittir ve kurgu bölgesel ölçüm ağının abone portalı ekibine ait bir modeldir; üreteç bu blokta, tohum görünürdür. UY15. Kalemin üç zaman damgası olabilir: açılış hepsinde vardır, doğrulama bazı kaynaklarda hiç yazılmaz, kapanış yalnız kapananda bulunur. UY16. Şiddet sınıflarının hedef süreleri veridir (7, 21, 45 ve 90 gün) ve kurgudur. UY17. Dönem ortasında öncelik kuralı değişti: hattan gelen kalem öne alındı, hat dışından gelen bekletildi — modelin varsayımıdır.
// olcut/bulgu.mjs — bulgu kumesi MODELDIR: kurgu bolgesel olcum agi, 180 gunluk tek donem. // Uretec kendi yazilmistir, tohum gorunurdur; kume her kosumda ayni cikar. export const gen = (B) => (...h) => h.map((v, j) => (j ? String(v).padStart(B[j]) : String(v).padEnd(B[0]))).join(""); export const DONEM = 180, TOHUM = 20250, HAT = ["bagimlilik", "statik", "imaj"]; let s = TOHUM; const rnd = () => (s = (Math.imul(s, 1664525) + 1013904223) >>> 0) / 4294967296; // kaynak | bulgu | taban gun | triyaj gun | dogrulama damgasi eksik olasiligi const KAYNAK = [["bagimlilik", 44, 16, 1, 0], ["statik", 34, 26, 2, 0], ["imaj", 24, 22, 2, 0], ["denetim", 16, 52, 7, .5], ["bildirim", 24, 70, 11, .7]]; export const HEDEF = { kritik: 7, yuksek: 21, orta: 45, dusuk: 90 }; const CARPAN = { kritik: .4, yuksek: .7, orta: 1, dusuk: 1.4 }; const SIRA = { hat: "orta dusuk orta yuksek dusuk orta kritik yuksek".split(" "), dis: "yuksek orta kritik yuksek dusuk orta yuksek kritik".split(" ") }; export const BULGU = []; for (const [kaynak, adet, taban, triyaj, eksik] of KAYNAK) { for (let i = 0; i < adet; i++) { const hat = HAT.includes(kaynak); const siddet = SIRA[hat ? "hat" : "dis"][Math.floor(rnd() * 8)]; const acilis = 1 + Math.floor(rnd() * DONEM); // Sure dagilimi carpiktir: cogu kalem kisa surer, birkaci cok uzun. let sure = taban * CARPAN[siddet] * (0.15 + 4 * Math.pow(rnd(), 3.5)); // Donem ortasinda oncelik kurali degisti: hat kalemi one alindi, oteki bekletildi. sure *= hat ? (acilis > 90 ? .45 : 1) : (acilis > 90 ? 3.2 : 1.8); const tur = hat && rnd() < .12 ? "gecersiz" : "duzeltildi"; sure = Math.max(1, Math.round(tur === "gecersiz" ? sure * .15 : sure)); const kapanis = acilis + sure <= DONEM ? acilis + sure : null; const d = rnd() < eksik ? null : acilis + Math.round(triyaj * (.4 + 1.2 * rnd())); BULGU.push({ kaynak, siddet, hedef: HEDEF[siddet], acilis, kapanis, tur, dogrulama: d === null ? null : Math.min(d, kapanis ?? DONEM) }); } } export const kapali = BULGU.filter((b) => b.kapanis !== null); export const damgasiz = BULGU.filter((b) => b.dogrulama === null); if (import.meta.url === `file://${process.argv[1]}`) { console.log(`model: ${BULGU.length} bulgu, ${KAYNAK.length} kaynak, ${DONEM} gun, tohum ${TOHUM}`); console.log(`${kapali.length} kalem kapandi, ${BULGU.length - kapali.length} kalem acik kaldi`); console.log(`dogrulama damgasi eksik ${damgasiz.length} kalem: ` + KAYNAK.map(([k]) => `${k} ${BULGU.filter((b) => b.kaynak === k && !b.dogrulama).length}/` + `${BULGU.filter((b) => b.kaynak === k).length}`).join(", ")); // Donem sonunda sorulacak sorular, istedikleri kayit alani ve o alani tasiyan kalem sayisi. const K = kapali.length, D = BULGU.length - damgasiz.length; const SORU = [["ortalama duzeltme suresi", "acilis+kapanis", K], ["hedefte kapatilan oran", "acilis+kapanis", K], ["acik kalemin yasi", "acilis", BULGU.length], ["surenin kaci triyajda gecti", "dogrulama", D], ["kapananin kaci duzeltildi", "kapanis turu", K], ["kalem kac kez yeniden acildi", "durum gecisi", 0], ["duzeltmeyi hangi degisiklik yapti", "degisiklik kimligi", 0], ["olcut neden degisti", "acilis+kaynak", K]]; const cevap = (t) => t === 0 ? "yok" : t >= K ? "tam" : "kismi"; const z = gen([36, 20, 10, 8]); console.log("\n" + z("soru", "gereken kayit alani", "tasiyan", "cevap")); for (const [m, d, t] of SORU) console.log(z(m, d, t, cevap(t))); const n = (c) => SORU.filter(([, , t]) => cevap(t) === c).length; console.log(`\n${SORU.length} sorunun ${n("tam")}'i tam, ${n("kismi")}'i kismi cevaplaniyor, ` + `${n("yok")}'si cevapsiz`); }
model: 142 bulgu, 5 kaynak, 180 gun, tohum 20250 121 kalem kapandi, 21 kalem acik kaldi dogrulama damgasi eksik 25 kalem: bagimlilik 0/44, statik 0/34, imaj 0/24, denetim 10/16, bildirim 15/24 soru gereken kayit alani tasiyan cevap ortalama duzeltme suresi acilis+kapanis 121 tam hedefte kapatilan oran acilis+kapanis 121 tam acik kalemin yasi acilis 142 tam surenin kaci triyajda gecti dogrulama 117 kismi kapananin kaci duzeltildi kapanis turu 121 tam kalem kac kez yeniden acildi durum gecisi 0 yok duzeltmeyi hangi degisiklik yapti degisiklik kimligi 0 yok olcut neden degisti acilis+kaynak 121 tam 8 sorunun 5'i tam, 1'i kismi cevaplaniyor, 2'si cevapsiz
Üçüncü satır önceki dersin bıraktığı soruyu cevaplıyor. Doğrulama damgası eksik 25 kalem rastgele seçilmiş değildir: hattan gelen 102 kalemin hiçbirinde eksik değil, denetim kaydından gelenin 10’unda, dış bildirim kanalından gelenin 15’inde eksik. Damganın eksik olduğu yer, sürenin en uzun olduğu yerle aynıdır.
Cevapsız iki soru aynı sınıftandır: ölçütü denetleyen sorulardır. Yeniden açılan kalem ölçütte bir uzun süre değil, iki kısa süre olarak görünür; kapatan değişiklik bilinmiyorsa kapanışın düzeltme olduğu doğrulanamaz. Cevaplanabilir kılmanın bedeli — kalem başına dört durum geçişi kurgusuyla — 568 ek kayıt ve bulgu ile değişiklik arasında kurulacak bir bağdır.
İki Ölçüt, Aynı Küme
UY18. Ortalama düzeltme süresi yalnız kapanan kalemden hesaplanır; açık kalem ölçüte hiç girmez. Açık yaşı ise anlık bir ölçümdür. İki ölçütün tabanı bu yüzden aynı küme değildir ve ikisi aynı dönemde ters yönlere gidebilir.
// olcut/olcut.mjs — iki olcut ayni kumeden hesaplanir: ortalama duzeltme suresi ve acik yasi. import { BULGU, DONEM, HAT, kapali, gen } from "./bulgu.mjs"; const ort = (a) => a.reduce((t, x) => t + x, 0) / a.length; const dilim = (a, p) => [...a].sort((x, y) => x - y)[Math.floor(p * (a.length - 1))]; const sure = (b) => b.kapanis - b.acilis; const acikta = (t) => BULGU.filter((b) => b.acilis <= t && (!b.kapanis || b.kapanis > t)); const yas = (t) => acikta(t).map((b) => t - b.acilis); const y = gen([22, 8, 10, 9, 8, 10]); console.log(y("olcut (gun)", "kalem", "ortalama", "medyan", "p90", "en buyuk")); for (const [ad, a] of [["duzeltme suresi", kapali.map(sure)], ["acik yasi (180. gun)", yas(DONEM)]]) console.log(y(ad, a.length, ort(a).toFixed(1), dilim(a, .5), dilim(a, .9), Math.max(...a))); const s = kapali.map(sure), o = ort(s), ust = s.filter((x) => x > o); console.log(`\nortalamayi (${o.toFixed(1)}) asan ${ust.length}/${s.length} kalem toplam gunun ` + `%${(100 * ust.reduce((t, x) => t + x, 0) / s.reduce((t, x) => t + x, 0)).toFixed(0)}'ini tasiyor`); // Ayni kume iki gruplama kuraliyla, sonra iki olcum aninda acik kuyrugun anlik goruntusu. const z = gen([30, 12, 12, 12]); console.log("\n" + z("gruplama kurali", "1-90 gun", "91-180 gun", "yon")); for (const [ad, f] of [["kalem acildigi yariya sayilir", (b) => b.acilis], ["kalem kapandigi yariya sayilir", (b) => b.kapanis]]) { const a = ort(kapali.filter((b) => f(b) <= 90).map(sure)); const c = ort(kapali.filter((b) => f(b) > 90).map(sure)); console.log(z(ad, a.toFixed(1), c.toFixed(1), c < a ? "duser" : "yukselir")); } for (const t of [90, DONEM]) console.log(z(`acik kuyruk (${t}. gun)`, `${yas(t).length} kalem`, `ort ${ort(yas(t)).toFixed(1)}`, `medyan ${dilim(yas(t), .5)}`)); const w = gen([16, 9, 14, 8, 14]); console.log("\n" + w("kaynak obegi", "kapanan", "ort duzeltme", "acik", "ort acik yasi")); for (const [ad, f] of [["hat", (b) => HAT.includes(b.kaynak)], ["hat disi", (b) => !HAT.includes(b.kaynak)]]) { const kk = kapali.filter(f), aa = acikta(DONEM).filter(f); console.log(w(ad, kk.length, ort(kk.map(sure)).toFixed(1), aa.length, ort(aa.map((b) => DONEM - b.acilis)).toFixed(1))); } const h2 = BULGU.filter((b) => b.acilis > 90 && !b.kapanis); console.log(`\n91-180 arasi acilan ${h2.length} kalem hala acik ve olcute hic girmiyor; bunlarin ` + `${h2.filter((b) => !HAT.includes(b.kaynak)).length} tanesi hat disi kaynaktan. Gecersiz sayilan ` + `${BULGU.filter((b) => b.tur === "gecersiz").length} kalem cikarilinca ortalama ${o.toFixed(1)} -> ` + `${ort(kapali.filter((b) => b.tur === "duzeltildi").map(sure)).toFixed(1)} gun`);
olcut (gun) kalem ortalama medyan p90 en buyuk duzeltme suresi 121 17.0 6 57 116 acik yasi (180. gun) 21 59.8 37 148 176 ortalamayi (17.0) asan 30/121 kalem toplam gunun %75'ini tasiyor gruplama kurali 1-90 gun 91-180 gun yon kalem acildigi yariya sayilir 23.6 7.6 duser kalem kapandigi yariya sayilir 13.2 20.0 yukselir acik kuyruk (90. gun) 24 kalem ort 30.4 medyan 19 acik kuyruk (180. gun) 21 kalem ort 59.8 medyan 37 kaynak obegi kapanan ort duzeltme acik ort acik yasi hat 97 13.7 5 10.0 hat disi 24 30.2 16 75.3 91-180 arasi acilan 14 kalem hala acik ve olcute hic girmiyor; bunlarin 9 tanesi hat disi kaynaktan. Gecersiz sayilan 13 kalem cikarilinca ortalama 17.0 -> 18.8 gun
İlk satır ölçütün merkezî kusurudur: ortalama 17,0 gün, medyan 6 gün. Ortalama hiçbir kalemi anlatmıyor; 121 kalemin 30’u ortalamanın üstünde ve toplam bekleme gününün yüzde 75’ini taşıyor. Açık tarafta dağılım da çarpıktır, nedeni farklıdır: uzun kalem hiç kapanmadığı için ölçüte girmez, birikir.
İkinci tablo dersin en sert sayısıdır. Aynı 121 kalem, iki gruplama kuralı, iki zıt yön: kalem açıldığı yarıya sayılırsa ölçüt 23,6 günden 7,6 güne iner, kapandığı yarıya sayılırsa 13,2 günden 20,0 güne çıkar. İkisi de doğru hesaplanmıştır. Ölçütün iyileşip iyileşmediği sorusunun cevabı veriye değil, gruplama kuralına bağlıdır.
Alttaki iki satır kuyruğu anlatıyor: kalem sayısı 24’ten 21’e düşerken ortalama yaş 30,4’ten 59,8’e, medyan 19’dan 37’ye çıkıyor — kuyruk küçüldü, içindekiler yaşlandı. Kaynak öbeği tablosu nedenini veriyor: hat kalemleri 13,7 günde kapanıp beş açık kalem bırakıyor, hat dışı kalemler 30,2 günde kapanıyor ve on altısı 75,3 gün yaşında bekliyor. Ortalama bu iki öbeğin karışımıdır; karışım oranı değişince ortalama, hiçbir öbek hızlanmadan değişir. İkinci yarıda açılan 14 kalem ölçüte hiç girmiyor; geçersiz 13 kalem çıkarılınca ortalama 18,8 güne çıkıyor.
Ölçütü İyileştirmenin Ölçüyü Bozan Yolları
UY19. Üç müdahale de yalnız hesap kuralını ya da bir kayıt alanını değiştirir; hiçbiri bir kod satırına dokunmaz. Kabul eşiği 90 gündür ve kurgudur. UY20. Yeniden sınıflandırma kalemi bir alt şiddet sınıfına yazar ve hedef süresini genişletir.
// olcut/mudahale.mjs — olcutu iyilestiren uc mudahale ayni kume uzerinde kosturulur. import { BULGU, DONEM, HEDEF, kapali, gen } from "./bulgu.mjs"; const ort = (a) => a.reduce((t, x) => t + x, 0) / a.length; const dilim = (a, p) => [...a].sort((x, y) => x - y)[Math.floor(p * (a.length - 1))]; const sure = (b) => b.kapanis - b.acilis; const acik = BULGU.filter((b) => !b.kapanis), yas = acik.map((b) => DONEM - b.acilis); // 1) Saat acilista degil dogrulamada baslatilir; damgasi olmayan kalem olcute hic girmez. const damgali = kapali.filter((b) => b.dogrulama !== null); const A = ort(kapali.map(sure)), B = ort(damgali.map(sure)); const C = ort(damgali.map((b) => b.kapanis - b.dogrulama)); // 2) Doksan gunden yasli acik kalem kabul edilmis risk olarak kapatilir (esik kurgudur). const kabul = acik.filter((b) => DONEM - b.acilis > 90); const kalan = acik.filter((b) => DONEM - b.acilis <= 90).map((b) => DONEM - b.acilis); const D = ort([...kapali.map(sure), ...kabul.map((b) => DONEM - b.acilis)]); // 3) Hedefini kaciran kalem bir alt siddet sinifina yazilir; hedef suresi genisler. const ALT = { kritik: "yuksek", yuksek: "orta", orta: "dusuk", dusuk: "dusuk" }; const yeni = (b) => sure(b) > b.hedef ? HEDEF[ALT[b.siddet]] : b.hedef; const once = kapali.filter((b) => sure(b) <= b.hedef).length; const sonra = kapali.filter((b) => sure(b) <= yeni(b)).length; const eksik = kapali.length - damgali.length, g = (v) => v.toFixed(1); const y = gen([30, 9, 14, 11, 11]); console.log(y("mudahale", "kalem", "olcut", "oncesi", "sonrasi")); console.log(y("1 saat dogrulamada baslar", eksik, "ort duzeltme", g(A), g(C))); console.log(y(" a) damgasiz kalem duser", eksik, "ort duzeltme", g(A), g(B))); console.log(y(" b) saat geri alinir", damgali.length, "ort duzeltme", g(B), g(C))); console.log(y("2 yasli kalem kabule cevrilir", kabul.length, "ort acik yasi", g(ort(yas)), g(ort(kalan)))); console.log(y(" ayni mudahale", kabul.length, "ort duzeltme", g(A), g(D))); console.log(y("3 kacan kalem bir alt sinifa", sonra - once, "hedefte oran", `%${g(100 * once / kapali.length)}`, `%${g(100 * sonra / kapali.length)}`)); console.log(`\nmedyan acik yasi ${dilim(yas, .5)} -> ${dilim(kalan, .5)}, en yasli acik kalem ` + `${Math.max(...yas)} -> ${Math.max(...kalan)} gun`); console.log(`kabule cevrilen ${kabul.length} kalemden ` + `${kabul.filter((b) => b.siddet === "kritik").length} tanesi kritik siddettedir; ` + `uc mudahalenin toplaminda gercekten duzeltilen ek kalem: 0`);
mudahale kalem olcut oncesi sonrasi 1 saat dogrulamada baslar 16 ort duzeltme 17.0 12.6 a) damgasiz kalem duser 16 ort duzeltme 17.0 14.6 b) saat geri alinir 105 ort duzeltme 14.6 12.6 2 yasli kalem kabule cevrilir 7 ort acik yasi 59.8 23.4 ayni mudahale 7 ort duzeltme 17.0 23.3 3 kacan kalem bir alt sinifa 15 hedefte oran %81.8 %94.2 medyan acik yasi 37 -> 16, en yasli acik kalem 176 -> 87 gun kabule cevrilen 7 kalemden 2 tanesi kritik siddettedir; uc mudahalenin toplaminda gercekten duzeltilen ek kalem: 0
Birinci müdahale ortalamayı 17,0’dan 12,6 güne indiriyor; asıl bilgi düşüşün ayrışmasındadır. Saatin doğrulamada başlaması iki gün kazandırıyor, 14,6’dan 12,6’ya. Büyük parça doğrulama damgası olmayan 16 kalemin ölçüt tabanından çıkmasından geliyor ve o kalemler en yavaş öbekten. İyileşen şey ölçümün kapsamının daralmasıdır.
İkinci müdahale iki ölçütü karşı karşıya getiriyor. Doksan günden yaşlı yedi kalem kabul edilmiş riske çevrildiğinde açık yaşı 59,8’den 23,4 güne, medyan 37’den 16’ya, en yaşlı kalem 176 günden 87 güne iniyor. Aynı kapanışlar düzeltme süresine sayılırsa ortalama 23,3 güne çıkar; sayılmazsa hiç kıpırdamaz ve iki ölçüt birden iyileşmiş görünür. Yedi kalemin ikisi kritiktir. Üçüncü müdahale en ucuzudur: hedefini kaçıran 15 kalem bir alt sınıfa yazılınca hedefte oran yüzde 81,8’den 94,2’ye çıkar.
Üç müdahalenin toplamında gerçekten düzeltilen ek kalem sıfırdır. Kural buradan çıkar: ölçülen şeye dokunmadan iyileştirilebilen bir ölçüt karar aracı değil, rapor satırıdır. Ölçütün yanına iki sayı daha yazılır — hesaba girmeyen kalem sayısı ve hesap kuralının son değişme tarihi.
Özet
- Ortalama düzeltme süresi 17,0 gün, medyan 6 gündür; ortalamayı aşan 30 kalem toplam bekleme gününün yüzde 75’ini taşır. Ortalama kuyruğu gizler.
- Açık yaşı ayrı bir tabandan hesaplanır: 21 kalem, ortalama 59,8 gün, en yaşlı 176. Kuyruk 24 kalemden 21’e düşerken ortalama yaş 30,4’ten 59,8’e çıkmıştır.
- Aynı küme iki gruplama kuralıyla ters yön verir: 23,6’dan 7,6’ya iner ya da 13,2’den 20,0’a çıkar; kuralı yazılmayan ölçüt okunamaz.
- Sekiz sorunun beşi tam, biri kısmi cevaplanır, ikisi cevapsızdır; doğrulama damgası eksik 25 kalemin tamamı en yavaş iki kaynaktandır.
- Üç müdahale ölçütleri iyileştirir ve sıfır kalem düzeltir: ortalama 12,6 güne, açık yaşı 23,4 güne, hedefte oran yüzde 94,2’ye gider; kabule çevrilen yedi kalemin ikisi kritiktir.
Sonraki Adım
İki ölçüt de hesaplandı ve bozulabilir olduğu gösterildi. Geriye ölçütlerin sakladığı kalem kalıyor: kapanmayan kuyruk. On altı açık kalem hat dışı kaynaktan geliyor, ortalama 75,3 gün yaşında ve bir plana bağlı değil.
Sonraki ders bu kuyruğu güvenlik borcu olarak ele alır ve planlı kapatmayı koşturur: borç kalemleri hangi sırayla ve hangi kapasiteyle kapanıyor, kabul edilmiş bir riskin süresi ne kadar ve o süre dolduğunda kalemi yeniden değerlendirecek nokta nerede yazılı.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.