---
title: 'Tespit, Müdahale ve Uyumluluk'
source: 'https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk'
language: tr
updated: '2026-08-17T04:38:36+00:00'
license: 'CC BY-SA 4.0'
lessons: 9
outcomes:
    - 'Uygulama telemetrisinden güvenlik tespiti üretir'
    - 'Uygulama ihlallerinde müdahale sürecini yürütür'
    - 'Mühendislik pratiklerini uyumluluk kontrollerine eşler'
---

# Tespit, Müdahale ve Uyumluluk

Olaydan sonra sorulacak soruların kaçının cevaplanabildiğinin ölçülmesi: soru kümesinin kayıt şemasıyla eşleştirilmesi, cevaplanamayan sorunun alan eksikliğinden mi bağ eksikliğinden mi saklama penceresinden mi doğduğu, her ek alanın hacme ve saklama süresine bedeli, iş mantığına dayalı kötüye kullanım uyarılarında eşik seçiminin kaçırdığı ile yanlış uyandırdığı, uygulama ihlali müdahalesinde hangi adımın hangi kayda bağlı olduğu ve kayıt yoksa adımın kaç dakika uzadığı, kısa ömürlü iş yüklerinde toplanabilen kalem penceresi, dış bildirim kanalı ve ödül programında bildirimden doğrulamaya ve doğrulamadan düzeltmeye geçen süre, denetim kontrolünün mühendislik karşılığı, kanıt üretiminin hatta taşınması, ortalama düzeltme süresi ile açık yaşı ölçütleri ve güvenlik borcunun planlı kapatılması.

## Tespit ve Müdahale

Uygulama telemetrisinin olaydan sonra sorulan soruları cevaplayabilme kapasitesinin ölçülmesi: soru kümesi ile kayıt şemasının eşleştirilmesi ve cevaplanamayan sorunun sayılması, her ek alanın hacim ve saklama bedeli, iş mantığına dayalı tespit senaryolarında eşiğin kaçırdığı ve yanlış uyandırdığı, uygulama ihlali müdahalesinde adım–kayıt bağımlılığı ve kayıt yokluğunun dakika bedeli, kısa ömürlü iş yüklerinde dışarı yazılabilen kalem penceresi, dış bildirim kanalı ve ödül programında doğrulama ve düzeltme süreleri.

### Denetim Kaydı Tasarımı

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/denetim-kaydi-tasarimi

On altı soruluk bir soru kümesi üç kayıt kaynağıyla eşleştirildiğinde altısı cevaplanıyor, onu cevaplanamıyor: dördü yazılmayan alan, beşi kaynaklar arasında kurulmayan bağ, biri saklama penceresi yüzünden. Üç ek alan cevaplananı 13'e çıkarıyor, ama beşinin tamamı eklendiğinde günlük hacim 1,45 kata çıkıyor, sabit bütçedeki saklama 65 günden 45 güne iniyor ve 60 günlük denetim dönemine uzanan beş soru yeniden cevapsız kalarak cevaplanan 10'a düşüyor.

Çalışma Zamanı Güvenliği ve Sır Yönetimi kursu katmanları kurdu ve her katmanın neyi kaçırdığını
yazdı. Kaçırılan kalemin varlığı orada modelin doğrusundan okunuyordu. Gerçek bir kurumda böyle
bir doğru yoktur: kaçırılanın kaçırıldığı ancak bir kayıttan anlaşılır. Bu kurs o kaydı ölçer ve
tek soru sorar — olaydan sonra sorulacak soruların kaçı cevaplanabiliyor.

Ölçü birimi **cevaplanamayan sorudur**. Bir kayıt tasarımı "kapsamlı" ya da "yetersiz" diye
nitelenmez; önüne bir soru kümesi konur, eşleştirme koşturulur ve cevapsız kalan soru sayılır.
Aynı ölçünün ikinci yarısı bedeldir: cevaplanabilir kılmak kaç ek alan, kaç kat hacim ve kaç
kişisel veri kalemi getiriyor. Bu ders ikisini birlikte koşturur. Kaydın nasıl yazıldığı,
değiştirilemez biçimde tutulduğu ve bütünlüğünün korunduğu Sunucu Güvenliği ve Üretime Alma kursunda ölçülmüştü;
burada tekrarlanmaz, girdi olur.

- **UM1.** Örnek ağ **kurgudur**: bölgesel bir ölçüm ağının abone portalında bir yetkisiz erişim
  ihlali, dokuz servis, üç kayıt kaynağı ve 60 günlük bir denetim dönemi. Bütün sayılar bir
  modelin çıktısıdır.
- **UM2.** **Soru kümesi**, olaydan sonra sorulacak soruların veri yapısı olarak modellenmiş
  hâlidir. Her sorunun iki niteliği vardır: cevaplamak için gereken **alanlar** ve kaç gün geriye
  uzandığı.
- **UM3.** Bir soru ancak gereken alanlarının tamamı **tek bir eşlenebilir kaynak kümesi** içinde
  bulunuyorsa cevaplanır. İki ayrı kaynaktaki alan, aralarında ortak bir bağ alanı yoksa
  birleştirilemez; iki kayıt yan yana durur ama aynı olaya ait olduğu gösterilemez.
- **UM4.** Cevaplanamama üç nedene ayrılır: **alan yok** (hiçbir kaynak yazmıyor), **bağ yok**
  (alanlar var ama eşleşmiyor), **pencere** (alanlar ve bağ var ama kayıt o kadar geriye
  saklanmıyor).
- **UM5.** Saklama süresi kararla değil aritmetikle belirlenir: sabit bir saklama bütçesi günlük
  hacme bölünür. Bütçe modelde 600 GB, günlük olay sayısı 42 milyondur; 1 GB 10⁹ bayt sayılır.
- **UM6.** Kişisel veri **tür olarak** sayılır: istemci adresi, oturum tanımlayıcısı ve değişiklik
  öncesi alan değeri birer kalemdir. Her kalem saklama süresine ayrı bir üst sınır getirir.

#### Soru Kümesini Şemayla Eşleştirmek

```js
// kayit-esleme.mjs — soru kumesi kayit semasiyla eslestirilir; cevaplanamayan soru
// bu kursun olcu birimidir. MODELDIR: ag, kayitlar ve sorular kurgudur.
export const BUTCE_B = 600e9, GUN_OLAY = 42e6;  // sabit saklama butcesi ve gunluk olay

// Kaynak = bir kayit akisi. `iz` alani olan kaynaklar birbirine eslenebilir;
// olmayan kaynak tek basina kalir ve alanlari baska alanla birlestirilemez.
export const KAYNAK = [
  { ad: "uygulama denetim kaydi", pay: 0.18, bayt: 240,
    alan: ["zaman", "iz", "aktor", "eylem", "sonuc"] },
  { ad: "ag gecidi erisim kaydi", pay: 0.62, bayt: 180,
    alan: ["zaman", "iz", "yol", "yontem", "durum", "istemci_ip"] },
  { ad: "veritabani degisiklik kaydi", pay: 0.20, bayt: 320,
    alan: ["zaman", "tablo", "nesne", "islem"] },
];

// Soru = [metin, gereken alanlar, kac gun geriye uzandigi]. Denetim donemi 60 gundur.
export const SORU = [
  ["hangi hesap hangi abone kaydini okudu", ["aktor", "nesne", "eylem"], 30],
  ["okuma kabul mu edildi ret mi", ["aktor", "eylem", "sonuc"], 30],
  ["istek hangi istemci adresinden geldi", ["istemci_ip", "iz"], 7],
  ["hangi hesap hangi tabloyu degistirdi", ["aktor", "tablo", "islem"], 30],
  ["degisiklik oncesi deger neydi", ["tablo", "once_deger"], 30],
  ["hangi uygulama surumu calisiyordu", ["aktor", "eylem", "surum"], 30],
  ["ayni oturumda baska ne yapildi", ["oturum", "eylem"], 7],
  ["yetki karari neydi ve neye dayandi", ["aktor", "eylem", "yetki_karari"], 30],
  ["donem basindaki ilk ret ne zaman", ["aktor", "eylem", "sonuc"], 60],
  ["donem boyunca kac abone kaydi okundu", ["nesne", "eylem"], 60],
  ["hangi uc noktalar cagrildi", ["yol", "yontem", "durum"], 30],
  ["hangi istek hangi satiri degistirdi", ["iz", "tablo", "nesne"], 60],
  ["ayni adresten kac hesap denendi", ["istemci_ip", "aktor"], 30],
  ["olaydan onceki ceyrekte ayni hesap ne yapti", ["aktor", "eylem"], 90],
  ["disari yazilan kayit kumesi neydi", ["aktor", "eylem", "nesne", "sonuc"], 60],
  ["donem boyunca kac satir degisti", ["tablo", "islem"], 60],
];

// Bir soru ancak gereken alanlarinin tamami TEK bir eslenebilir kume icindeyse
// cevaplanir; ayri kumelerdeki alanlar birlestirilemez.
export function kumeler(k) {
  const bagli = k.filter((s) => s.alan.includes("iz"));
  const tekil = k.filter((s) => !s.alan.includes("iz"));
  const birlesik = [...new Set(bagli.flatMap((s) => s.alan))];
  return [birlesik, ...tekil.map((s) => s.alan)].filter((a) => a.length);
}

export function esle(k, saklama) {
  const kume = kumeler(k), tum = new Set(k.flatMap((s) => s.alan));
  return SORU.map(([metin, alanlar, gun]) => {
    const eksik = alanlar.filter((a) => !tum.has(a));
    if (eksik.length) return { metin, gun, durum: "alan yok", eksik: eksik[0] };
    if (!kume.some((c) => alanlar.every((a) => c.includes(a))))
      return { metin, gun, durum: "bag yok", eksik: "-" };
    if (gun > saklama) return { metin, gun, durum: "pencere", eksik: "-" };
    return { metin, gun, durum: "cevaplanir", eksik: "-" };
  });
}

export const gunlukBayt = (k) =>
  k.reduce((t, s) => t + GUN_OLAY * s.pay * s.bayt, 0);
export const saklamaGun = (k) => Math.floor(BUTCE_B / gunlukBayt(k));

export const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  const gb = gunlukBayt(KAYNAK) / 1e9, saklama = saklamaGun(KAYNAK);
  console.log(`model: ${KAYNAK.length} kaynak, ${SORU.length} soru, gunluk ` +
    `${gb.toFixed(2)} GB, ${BUTCE_B / 1e9} GB butce -> ${saklama} gun saklama`);
  console.log(`eslenebilir alan kumeleri: ` +
    kumeler(KAYNAK).map((c) => c.length).join(" ve ") + " alan");
  const y = gen([44, 6, 13, 13]);
  console.log("\n" + y(["soru", "gun", "durum", "eksik alan"]));
  for (const s of esle(KAYNAK, saklama)) console.log(y([s.metin, s.gun, s.durum, s.eksik]));
  const d = esle(KAYNAK, saklama);
  const say = (t) => d.filter((s) => s.durum === t).length;
  console.log(`\ncevaplanir ${say("cevaplanir")}, cevaplanamaz ` +
    `${SORU.length - say("cevaplanir")}: alan yok ${say("alan yok")}, ` +
    `bag yok ${say("bag yok")}, pencere ${say("pencere")}`);
}
```

```
model: 3 kaynak, 16 soru, gunluk 9.19 GB, 600 GB butce -> 65 gun saklama
eslenebilir alan kumeleri: 9 ve 4 alan

soru                                           gun        durum   eksik alan
hangi hesap hangi abone kaydini okudu           30      bag yok            -
okuma kabul mu edildi ret mi                    30   cevaplanir            -
istek hangi istemci adresinden geldi             7   cevaplanir            -
hangi hesap hangi tabloyu degistirdi            30      bag yok            -
degisiklik oncesi deger neydi                   30     alan yok   once_deger
hangi uygulama surumu calisiyordu               30     alan yok        surum
ayni oturumda baska ne yapildi                   7     alan yok       oturum
yetki karari neydi ve neye dayandi              30     alan yok yetki_karari
donem basindaki ilk ret ne zaman                60   cevaplanir            -
donem boyunca kac abone kaydi okundu            60      bag yok            -
hangi uc noktalar cagrildi                      30   cevaplanir            -
hangi istek hangi satiri degistirdi             60      bag yok            -
ayni adresten kac hesap denendi                 30   cevaplanir            -
olaydan onceki ceyrekte ayni hesap ne yapti     90      pencere            -
disari yazilan kayit kumesi neydi               60      bag yok            -
donem boyunca kac satir degisti                 60   cevaplanir            -

cevaplanir 6, cevaplanamaz 10: alan yok 4, bag yok 5, pencere 1
```

Üç kaynak da düzenli yazılıyor, hiçbiri kapalı değil, günde 9,19 GB kayıt üretiliyor. Buna
rağmen on altı sorunun onu cevapsız. Bu tablonun asıl bilgisi cevaplanamayan sayısı değil,
üçüncü sütundaki **nedenlerin dağılımıdır**; çünkü üç neden üç ayrı işle çözülür ve bedelleri
farklıdır.

En büyük yığın **bağ yok** satırlarındadır: beş soru. Bu sorularda gereken alanların hepsi
yazılıyor. "Hangi hesap hangi tabloyu değiştirdi" sorusunun ihtiyacı olan `aktor` uygulama
denetim kaydında, `tablo` ve `islem` veritabanı değişiklik kaydında duruyor. İki kayıt aynı
saniyede yazılmış olabilir, ama veritabanı kaydında `iz` alanı olmadığı için hangi isteğin hangi
satır değişikliğini doğurduğu gösterilemez. Yoğun bir dönemde aynı saniyede yüzlerce istek ve
yüzlerce satır değişikliği vardır; zaman damgasına dayanan bir eşleme iddia üretir, kanıt
üretmez. **Bağ alanı olmayan iki kayıt kaynağı, toplamı kadar değil, ayrı ayrı topladıkları
kadar soru cevaplar.**

İkinci yığın **alan yok**: dört soru. Bunlar tasarım eksiğidir ve yeni alan yazmakla kapanır.
Üçüncüsü tek satırdır ama en sinsisidir: `pencere`. "Olaydan önceki çeyrekte aynı hesap ne yaptı"
sorusunun bütün alanları var, bağı da var; 90 gün geriye uzandığı için cevapsız kalıyor. Bu soru
şemaya bakılarak asla bulunamaz. Şema doğru, alanlar tam, bağ kurulmuş görünür — cevaplanamama
saklama aritmetiğinden gelir ve ancak soru kümesi pencereyle birlikte modellendiğinde ortaya
çıkar.

#### Cevaplanabilir Kılmanın Bedeli

Dört eksik alan ile bir bağ alanı yazılabilir. Her ek alan her kayda girer ve günlük hacmi
büyütür; bütçe sabit olduğu için hacim doğrudan saklama gününe dönüşür.

```js
// ekleme.mjs — her ek alan cevaplanan soruyu artirir ama gunluk hacmi buyutur;
// sabit butcede hacim saklama gunune, saklama gunu de cevaba geri doner. MODELDIR.
import { KAYNAK, SORU, esle, gunlukBayt, saklamaGun, gen } from "./kayit-esleme.mjs";

// Her ekleme: hangi kaynaklara hangi alan, kayit basina kac bayt, kisisel veri mi.
const EKLEME = [
  { alan: "iz", hedef: ["veritabani degisiklik kaydi"], bayt: 18, kisisel: false },
  { alan: "yetki_karari", hedef: ["uygulama denetim kaydi"], bayt: 16, kisisel: false },
  { alan: "surum", hedef: ["uygulama denetim kaydi"], bayt: 12, kisisel: false },
  { alan: "oturum", hedef: ["uygulama denetim kaydi", "ag gecidi erisim kaydi"],
    bayt: 26, kisisel: true },
  { alan: "once_deger", hedef: ["veritabani degisiklik kaydi"], bayt: 340, kisisel: true },
];

const uygula = (k, e) => k.map((s) => e.hedef.includes(s.ad)
  ? { ...s, bayt: s.bayt + e.bayt, alan: [...s.alan, e.alan] } : { ...s });

const TABAN_GB = gunlukBayt(KAYNAK) / 1e9;
const y = gen([16, 10, 6, 9, 12, 14, 9]);
console.log(y(["eklenen alan", "gunluk GB", "kat", "saklama", "cevaplanir", "cevaplanamaz",
  "kisisel"]));
let k = KAYNAK.map((s) => ({ ...s })), kisisel = 1;   // istemci_ip zaten kisisel
const satir = (ad) => {
  const gb = gunlukBayt(k) / 1e9, sak = saklamaGun(k);
  const c = esle(k, sak).filter((s) => s.durum === "cevaplanir").length;
  console.log(y([ad, gb.toFixed(2), (gb / TABAN_GB).toFixed(2), sak, c, SORU.length - c,
    kisisel]));
  return { sak, c };
};
const iz = [satir("(taban sema)")];
for (const e of EKLEME) {
  k = uygula(k, e);
  if (e.kisisel) kisisel++;
  iz.push(satir(e.alan));
}
const enIyi = iz.reduce((a, b) => (b.c > a.c ? b : a)), son = iz.at(-1);
console.log(`\nen cok cevap veren sema ${enIyi.sak} gun saklamali olan: ${enIyi.c} soru`);
console.log(`son sema ${enIyi.c - son.c} soru daha az cevapliyor, cunku saklama ` +
  `${enIyi.sak} gunden ${son.sak} gune indi ve denetim donemi 60 gun`);
console.log(`taban semadan son semaya: cevaplanan ${iz[0].c} -> ${son.c}, ` +
  `hacim ${(gunlukBayt(k) / 1e9 / TABAN_GB).toFixed(2)} kat, kisisel veri 1 -> ${kisisel} kalem`);
```

```
eklenen alan     gunluk GB   kat  saklama  cevaplanir  cevaplanamaz  kisisel
(taban sema)          9.19  1.00       65           6            10        1
iz                    9.34  1.02       64          11             5        1
yetki_karari          9.46  1.03       63          12             4        1
surum                 9.55  1.04       62          13             3        1
oturum               10.43  1.13       57           9             7        2
once_deger           13.28  1.45       45          10             6        3

en cok cevap veren sema 62 gun saklamali olan: 13 soru
son sema 3 soru daha az cevapliyor, cunku saklama 62 gunden 45 gune indi ve denetim donemi 60 gun
taban semadan son semaya: cevaplanan 6 -> 10, hacim 1.45 kat, kisisel veri 1 -> 3 kalem
```

İlk ekleme tabloda en ucuz olanıdır ve en çok kazandırandır: veritabanı kaydına 18 baytlık bir
`iz` alanı, günlük hacmi yüzde iki büyütüp cevaplanan soruyu 6'dan 11'e çıkarıyor. Tek başına
hiçbir yeni olgu kaydetmez; yalnız zaten yazılan iki kaydı birbirine bağlar. **Bir kayıt
tasarımında en yüksek getirili alan, çoğu zaman yeni bir olguyu değil, var olan iki olgunun aynı
işe ait olduğunu yazan alandır.**

Sonraki iki ekleme doğrusal ilerliyor: `yetki_karari` ve `surum`, hacmi yüzde dört büyütüp cevabı
13'e çıkarıyor. Bu satır tablonun en iyi noktasıdır ve tabloya bakmadan bulunamaz. Ek alanların
**sırası** da rastgele değildir: listedeki her alan, kayıt başına baytının o kaynağın günlük
payıyla çarpımı kadar hacim getirir. `surum` alanı 12 baytlıktır ama yalnız olayların yüzde
18'ini taşıyan kaynağa girer; `oturum` 26 baytlıktır ve yüzde 80'ine girer. İkincisi birincinin
iki katından biraz fazla yer kaplar gibi görünür, gerçekte dokuz katından fazlasını kaplar.
**Bir alanın bedeli baytıyla değil, baytının yazıldığı kayıt sayısıyla ölçülür.**

Dördüncü satır kırılmayı gösteriyor. `oturum` alanı iki yüksek hacimli kaynağa girer ve günlük
hacim 10,43 GB'ye çıkar; sabit bütçede saklama 62 günden 57 güne iner. Bu ekleme bir soruyu
cevaplanır kılar ve **60 güne uzanan beş soruyu birden cevapsız bırakır**: cevaplanan 13'ten
9'a düşer. Beşinci satırda değişiklik öncesi değerin yazılması hacmi 1,45 kata çıkarır, saklamayı
45 güne indirir ve tablo 10'da kapanır — taban şemadan yalnız dört soru daha iyi, en iyi
şemadan üç soru daha kötü.

Bu, tabloda tek bir eğri olarak duran şeyin adıdır: **daha çok kayıt, sabit bütçede daha az
cevap.** Kırılma kayıt hacmi arttığı için değil, saklama penceresi soru kümesinin uzandığı
sürenin altına indiği için olur. Denetim dönemi 60 gündür; 57 günlük saklama, kaydın kendisi
kusursuz olsa bile dönemin ilk üç gününü cevapsız bırakır.

Bedelin üçüncü sütunu tabloda tek haneli görünür ama en uzun ömürlüsüdür. Kişisel veri kalemi
1'den 3'e çıkar: oturum tanımlayıcısı ile değişiklik öncesi alan değeri, abonenin doğrudan
kimliğine bağlanabilen kalemlerdir. Bu iki alan yalnız hacim getirmez; kayda erişimi kısıtlar,
saklamaya ayrı bir üst sınır koyar ve dışarı verilen her kanıt kopyasında ayıklanmasını
gerektirir. Bir alanı "her ihtimale karşı" yazmanın bedeli bu üç sütunda birden okunur.

#### Özet

- Bir kayıt tasarımı nitelemeyle değil, önüne konan soru kümesiyle ölçülür; ölçü birimi
  cevaplanamayan sorudur. Modelde 16 sorunun 10'u taban şemayla cevapsızdır.
- Cevaplanamama üç ayrı nedene ayrılır ve üçü ayrı işle çözülür: alan yok (4 soru), bağ yok
  (5 soru), saklama penceresi yetmiyor (1 soru).
- En yüksek getirili alan yeni bir olguyu değil, iki kaydın aynı işe ait olduğunu yazan bağ
  alanıdır: 18 bayt hacim karşılığında cevaplanan soru 6'dan 11'e çıkar.
- Sabit saklama bütçesinde her ek alan saklama gününe dönüşür: beş alan hacmi 1,45 kata çıkarır,
  saklamayı 65 günden 45 güne indirir.
- Daha çok kayıt daha az cevap verebilir: en iyi şema 62 günlük saklamayla 13 soru cevaplarken,
  iki alan daha eklenmiş şema 45 günle 10 soruda kalır, çünkü denetim dönemi 60 gündür.
- Bedelin kalıcı sütunu kişisel veri kalemidir: 1'den 3'e çıkan bu sayı erişim kısıtı, ayrı
  saklama sınırı ve her kanıt kopyasında ayıklama yükü doğurur.

#### Sonraki Adım

Bu dersin bütün ölçümü olaydan **sonra** yapıldı: soru zaten sorulmuştu ve kayıtta cevabı olup
olmadığına bakıldı. Aynı kayıtların ikinci bir işi daha vardır — soruyu doğuran olayı, olay
sürerken haber vermek. Ama uygulama düzeyinde bir kötüye kullanım, protokol düzeyinde bir
saldırıya benzemez: istekler geçerli, oturum açık, yetki kararı çoğu zaman olumludur ve tek
anormallik iş kuralının ölçtüğü bir sayıdadır. Sonraki ders bu sayılar üzerine kurulan tespit
senaryolarını olay akışında koşturur ve eşik seçiminin iki bedelini birlikte ölçer: kaç kötüye
kullanım oturumu kaçıyor ve kaç kez boşuna uyandırılıyor.

### Uygulamaya Özgü Tespit Senaryoları

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/uygulamaya-ozgu-tespit-senaryolari

900 oturumluk bir olay akışında 18 kötüye kullanım oturumu dört tespit senaryosuyla aranıyor. Tek tek eşik taraması her ölçüde aynı takası veriyor: reddedilen yetki eşiği 3'te 364 yanlış uyarı ve 211 mesai dışı uyandırma, 25'te sıfır yanlış ama sıfır yakalama. Dört senaryo birlikte seçildiğinde 25 yanlış uyarı bütçesi 18 oturumun 8'ini, 180 bütçesi 18'ini yakalıyor — ikincisi 30 günde 101 gece uyandırması demek. Bölge dışı okuma alanı yazılmadığında aynı bütçede yakalanan 15'ten 13'e iniyor.

Önceki ders kaydı olaydan sonra sorgulayan tarafı ölçtü: on altı sorunun kaçının cevabı şemada
vardı. Aynı kayıtların ikinci bir işi daha var — soruyu doğuran olayı, olay sürerken haber
vermek. Uygulama düzeyinde bu iş, ağ düzeyindekine benzemez. Kötüye kullanan taraf geçerli bir
oturumla, geçerli uç noktalara, çoğu zaman olumlu yetki kararı alarak istek yapar; anormal olan
protokol değil, iş kuralının ölçtüğü bir sayıdır.

Bu ders o sayıların üzerine kurulan **tespit senaryolarını** kurgu bir olay akışında koşturur.
Tespit hattının mimarisi, olayların normalleştirilmesi ve bağıntı kuralı Güvenlik Operasyonları
ve Olay Müdahalesi kursunda ölçülmüştü; burada tekrarlanmaz, girdi olur. Ölçülen tek şey eşik
seçiminin iki bedelidir: kaç kötüye kullanım oturumu kaçıyor ve kaç kez boşuna uyandırılıyor.

- **UM7.** Olay akışı **kurgudur**: abone portalında 30 günde 900 oturum, dört rol ve dört
  kötüye kullanım sınıfı. Sayılar tohumu görünen bir üreteçten gelir.
- **UM8.** **Tespit senaryosu**, tek bir uygulama ölçüsü üzerine kurulan eşik kuralıdır. Ölçüler
  iş mantığından okunur: oturumda okunan farklı abone kaydı, reddedilen yetki kararı sayısı, aynı
  istemci adresinden denenen farklı hesap ve hesabın yetkili bölgesi dışında okunan kayıt.
- **UM9.** Bir uyarı **gerçek** sayılır ancak oturum kötüye kullanım oturumuysa; değilse **yanlış
  uyarıdır**. Mesai saatleri 08–18 kabul edilir; bu aralığın dışındaki yanlış uyarı bir
  **uyandırmadır** ve ayrı sayılır.
- **UM10.** Normal oturumların yüzde sekizi "gün sonu toplu işi" gibi ağır kuyruk üretir.
  Bu kuyruk hiçbir kuralın kaldıramadığı örtüşmenin kaynağıdır.
- **UM11.** Bölge dışı okuma ölçüsü, önceki dersin şemasında **olmayan** bir alana dayanır.
  Alan yazılmazsa senaryo kurulamaz; bu, kayıt tasarımının tespit tarafındaki karşılığıdır.

#### Tek Ölçüde Eşik Taraması

```js
// akis.mjs — uygulama olay akisi uretilir ve is mantigina dayali tespit senaryolari
// esik esik kosturulur. MODELDIR: oturumlar da kotuye kullanim da kurgudur.
export const TOHUM = 20260418, OTURUM = 900, GUN = 30;
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);
// v < 0.08 olan oturum "gun sonu toplu isi" gibi normal ama agir bir kuyruk uretir.
const say = (ort, u, v = 1) => Math.round(ort * (0.35 + 1.3 * u) * (v < 0.08 ? 3.5 : 1));

// Rol = hesabin normal is hacmi. Entegrasyon hesabi normalde de yuksek hacimlidir.
const ROL = [
  { ad: "abone temsilcisi", pay: 0.42, okuma: 12, ret: 2.4, adres: 1.4, bolge: 0.3 },
  { ad: "saha teknisyeni", pay: 0.28, okuma: 6, ret: 3.0, adres: 1.2, bolge: 0.5 },
  { ad: "entegrasyon hesabi", pay: 0.12, okuma: 140, ret: 1.0, adres: 2.2, bolge: 2.5 },
  { ad: "abone", pay: 0.18, okuma: 1, ret: 1.6, adres: 1.6, bolge: 0.0 },
];
const rolSec = (u) => { let t = 0;
  for (const x of ROL) { t += x.pay; if (u < t) return x; } return ROL.at(-1); };

// Kotuye kullanim sinifi = oturumun hangi olcusunu normalin disina tasidigi.
export const KOTU = [
  { ad: "toplu okuma", adet: 6, uygula: (o, u) => { o.okuma = say(300, u); } },
  { ad: "yetki tarama", adet: 4, uygula: (o, u) => { o.ret = say(18, u); } },
  { ad: "bolge disi sizinti", adet: 5, uygula: (o, u) => { o.bolge = say(12, u); } },
  { ad: "hesap devralma", adet: 3, uygula: (o, u) => { o.adres = say(6, u); } },
];

export const OTURUMLAR = Array.from({ length: OTURUM }, (_, i) => {
  const rol = rolSec(r()), saat = Math.floor(r() * 24), kuyruk = r();
  return { i, rol: rol.ad, saat, kotu: null, okuma: say(rol.okuma, r(), kuyruk),
    ret: say(rol.ret, r(), kuyruk), adres: say(rol.adres, r(), kuyruk),
    bolge: say(rol.bolge, r(), kuyruk) };
});
for (const k of KOTU) for (let n = 0; n < k.adet; n++) {
  const o = OTURUMLAR[Math.floor(r() * OTURUM)];
  o.kotu = k.ad; k.uygula(o, r());
}
export const KOTU_TOPLAM = OTURUMLAR.filter((o) => o.kotu).length;

// Senaryo = tek bir uygulama olcusu uzerine kurulan esik kurali.
export const SENARYO = [
  { ad: "farkli kayit okuma", olcu: "okuma", hedef: "toplu okuma", esik: [40, 80, 150, 260] },
  { ad: "reddedilen yetki", olcu: "ret", hedef: "yetki tarama", esik: [3, 6, 12, 25] },
  { ad: "adres basina hesap", olcu: "adres", hedef: "hesap devralma", esik: [2, 3, 5, 7] },
  { ad: "bolge disi okuma", olcu: "bolge", hedef: "bolge disi sizinti", esik: [2, 4, 8, 12] },
];
const mesaiDisi = (o) => o.saat < 8 || o.saat >= 18;

export function kosuf(s, t) {
  const uyari = OTURUMLAR.filter((o) => o[s.olcu] >= t);
  const yanlis = uyari.filter((o) => !o.kotu);
  return { esik: t, uyari: uyari.length, gercek: uyari.filter((o) => o.kotu).length,
    hedefYakalanan: uyari.filter((o) => o.kotu === s.hedef).length,
    hedefToplam: KOTU.find((k) => k.ad === s.hedef).adet,
    yanlis: yanlis.length, uyandirma: yanlis.filter(mesaiDisi).length };
}

export const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`model (tohum ${TOHUM}): ${OTURUM} oturum, ${GUN} gun, ` +
    `${KOTU_TOPLAM} kotuye kullanim oturumu`);
  console.log("rol dagilimi: " + ROL.map((x) =>
    `${x.ad} ${OTURUMLAR.filter((o) => o.rol === x.ad).length}`).join(", "));
  const y = gen([20, 7, 7, 10, 8, 11, 12]);
  console.log("\n" + y(["senaryo", "esik", "uyari", "kacirilan", "gercek", "yanlis+",
    "uyandirma"]));
  for (const s of SENARYO) for (const t of s.esik) {
    const o = kosuf(s, t);
    console.log(y([s.ad, t, o.uyari, o.hedefToplam - o.hedefYakalanan, o.gercek, o.yanlis,
      o.uyandirma]));
  }
}
```

```
model (tohum 20260418): 900 oturum, 30 gun, 18 kotuye kullanim oturumu
rol dagilimi: abone temsilcisi 388, saha teknisyeni 229, entegrasyon hesabi 120, abone 163

senaryo                esik  uyari kacirilan  gercek    yanlis+   uyandirma
farkli kayit okuma       40    149         0       7        142          83
farkli kayit okuma       80    110         0       7        103          60
farkli kayit okuma      150     58         1       6         52          29
farkli kayit okuma      260     10         2       4          6           5
reddedilen yetki          3    377         0      13        364         211
reddedilen yetki          6     49         0       5         44          28
reddedilen yetki         12     17         0       4         13           6
reddedilen yetki         25      0         4       0          0           0
adres basina hesap        2    467         0      12        455         261
adres basina hesap        3    115         0       6        109          65
adres basina hesap        5     43         1       4         39          25
adres basina hesap        7     20         2       2         18          14
bolge disi okuma          2    127         0       5        122          68
bolge disi okuma          4     41         0       5         36          21
bolge disi okuma          8      7         2       3          4           3
bolge disi okuma         12      3         4       1          2           1
```

Dört senaryo da aynı biçimi çiziyor: eşik yükseldikçe kaçırılan artıyor, yanlış uyarı düşüyor.
İlginç olan bu eğrinin **nerede** durduğudur. Reddedilen yetki senaryosunun 3 eşiği 377 uyarı
üretiyor ve bunların 364'ü yanlış; 211'i mesai dışında geliyor, yani 30 günde 211 gece
uyandırması. Aynı senaryonun 25 eşiği sıfır yanlış uyarı verir ve dört kötüye kullanım
oturumunun dördünü birden kaçırır. **Bir ucunda kimsenin okumadığı bir uyarı akışı, öbür ucunda
hiç uyarı vermeyen bir kural var; ikisi de aynı kuralın iki ayarıdır.**

Farklı kayıt okuma senaryosu, örtüşmenin neden ayar hatasından gelmediğini gösteriyor.
Entegrasyon hesapları normal işlerinde ortalama 140 farklı kayıt okur; toplu okuma yapan kötüye
kullanım oturumu ortalama 300 okur. İki dağılım örtüşür. Eşik 260'a çekildiğinde yanlış uyarı
6'ya iner ama altı toplu okuma oturumunun ikisi kaçar. Örtüşmeyi doğuran şey aracın kalitesi
değil, **normalin kendisidir**: aynı ölçüde meşru olarak yüksek çalışan bir rol vardır ve o rolü
kuraldan çıkarmak, kötüye kullanımın en kolay saklanacağı yeri kuralın dışında bırakmak demektir.

Bölge dışı okuma senaryosu bu tabloda ayrı durur. Ölçüsü bir hacim değil bir **kural ihlalidir**:
hesabın yetkili bölgesi dışındaki kayda dokunması. Bu yüzden 8 eşiğinde yalnız 4 yanlış uyarıyla
üç sızıntı oturumu yakalar; aynı akışta adres başına hesap ölçüsü dört gerçek uyarı için 39
yanlış uyarı öder. Ayrım kuralın sıkılığından değil ölçünün seçiminden gelir: bir iş kuralına dayanan
ölçü, normal ile anormali dağılımın kuyruğunda değil tanımında ayırır. Kuyruğa hâlâ bağımlıdır —
12 eşiğinde beş oturumun dördü kaçar — ama aynı ayrım gücünü çok daha ucuza verir.

Ağır kuyruk aynı olguyu bütün rollere yayar. Oturumların yüzde sekizi normal ama üç buçuk kat
yoğun bir gün sonu işi yapar. Adres başına hesap senaryosunun 2 eşiğinde 467 oturum uyarı
üretiyor — akışın yarısından fazlası. Bu eşik "duyarlı" değildir; ölçünün ayrım gücünün
bulunmadığı bir noktada durur ve kuralın çıktısını rastgele bir nüfus örneklemine çevirir.

#### Eşikleri Birlikte Seçmek

Senaryolar tek tek ayarlanmaz. Nöbetteki kişiye dört kuralın çıktısı birlikte gider; bedel de
birlikte doğar.

```js
// esik.mjs — dort senaryonun esikleri birlikte secilir: yanlis uyari butcesi altinda
// en cok kotuye kullanim oturumu yakalayan esik takimi aranir. MODELDIR.
import { OTURUMLAR, SENARYO, KOTU, KOTU_TOPLAM, gen } from "./akis.mjs";

const mesaiDisi = (o) => o.saat < 8 || o.saat >= 18;
function takim(esikler, senaryolar = SENARYO) {
  const uyari = OTURUMLAR.filter((o) => senaryolar.some((s, j) => o[s.olcu] >= esikler[j]));
  const yanlis = uyari.filter((o) => !o.kotu);
  return { uyari: uyari.length, yakalanan: uyari.filter((o) => o.kotu).length,
    yanlis: yanlis.length, uyandirma: yanlis.filter(mesaiDisi).length,
    sinif: KOTU.map((k) => uyari.filter((o) => o.kotu === k.ad).length) };
}
function enIyi(butce, senaryolar = SENARYO) {
  const listeler = senaryolar.map((s) => s.esik);
  let en = null;
  const gez = (j, secim) => {
    if (j === listeler.length) {
      const o = takim(secim, senaryolar);
      if (o.yanlis > butce) return;
      if (!en || o.yakalanan > en.o.yakalanan ||
        (o.yakalanan === en.o.yakalanan && o.yanlis < en.o.yanlis)) en = { secim: [...secim], o };
      return;
    }
    for (const t of listeler[j]) gez(j + 1, [...secim, t]);
  };
  gez(0, []);
  return en;
}

const y = gen([9, 18, 8, 12, 12, 10, 12, 15]);
console.log(y(["butce", "secilen esikler", "uyari", "yakalanan", "kacirilan", "yanlis+",
  "uyandirma", "yanlis/gercek"]));
for (const b of [25, 50, 100, 180, 400]) {
  const e = enIyi(b);
  console.log(y([b, e.secim.join(" "), e.o.uyari, `${e.o.yakalanan}/${KOTU_TOPLAM}`,
    KOTU_TOPLAM - e.o.yakalanan, e.o.yanlis, e.o.uyandirma,
    (e.o.yanlis / e.o.yakalanan).toFixed(1)]));
}
const tam = enIyi(100), sinif = KOTU.map((k, i) => `${k.ad} ${tam.o.sinif[i]}/${k.adet}`);
console.log(`\nbutce 100'deki takimin sinif dagilimi: ${sinif.join(", ")}`);

// bolge alani yazilmiyorsa dorduncu senaryo hic kurulamaz.
const uc = SENARYO.slice(0, 3), uce = enIyi(100, uc);
console.log(`bolge alani olmadan ayni butcede: yakalanan ${uce.o.yakalanan}/${KOTU_TOPLAM}, ` +
  `bolge disi sizintidan ${uce.o.sinif[2]}/${KOTU[2].adet}`);

// Alanin bedeli onceki dersin modelinden: 42e6 olay/gun, uygulama denetim kaydi payi 0.18,
// gunluk 9.55 GB ve 600 GB butce (surum alani eklenmis sema).
const GUN_OLAY = 42e6, PAY = 0.18, TABAN = 9.55248e9, BUTCE = 600e9, BOLGE_BAYT = 14;
const yeni = TABAN + GUN_OLAY * PAY * BOLGE_BAYT;
console.log(`bolge alani ${BOLGE_BAYT} bayt: gunluk ${(TABAN / 1e9).toFixed(2)} GB -> ` +
  `${(yeni / 1e9).toFixed(2)} GB (yuzde ${((yeni / TABAN - 1) * 100).toFixed(1)}), ` +
  `saklama ${Math.floor(BUTCE / TABAN)} -> ${Math.floor(BUTCE / yeni)} gun`);
```

```
butce       secilen esikler   uyari   yakalanan   kacirilan   yanlis+   uyandirma  yanlis/gercek
25               260 25 7 8      29        8/18          10        21          17            2.6
50               260 12 5 8      56       13/18           5        43          27            3.3
100              260 12 5 4      87       15/18           3        72          43            4.8
180               80 12 3 4     191       18/18           0       173         101            9.6
400               80 12 3 4     191       18/18           0       173         101            9.6

butce 100'deki takimin sinif dagilimi: toplu okuma 4/6, yetki tarama 4/4, bolge disi sizinti 5/5, hesap devralma 2/3
bolge alani olmadan ayni butcede: yakalanan 13/18, bolge disi sizintidan 2/5
bolge alani 14 bayt: gunluk 9.55 GB -> 9.66 GB (yuzde 1.1), saklama 62 -> 62 gun
```

Tablo eşik seçiminin bir ayar değil bir **satın alma** olduğunu yazıyor. On sekiz oturumun
tamamını yakalayan bir takım vardır ve fiyatı bellidir: 173 yanlış uyarı ve 30 günde 101 gece
uyandırması, yani her gece ortalama 3,4 kez. Yakalanan oturum başına 9,6 yanlış uyarı düşer. Aynı
akışta 100 bütçeli takım 18'in 15'ini yakalar ve uyandırmayı 43'e indirir; üç oturum kaçar.
Hangisinin doğru olduğu bu tablodan okunmaz — okunacak olan, **her iki kararın da bir sayı
karşılığında verildiğidir**. Bütçe 180'den 400'e çıkarıldığında satır değişmez; ölçünün ayrım
gücü tükenmiştir ve daha çok yanlış uyarıya razı olmak artık hiçbir şey yakalatmaz.

Sınıf dağılımı ikinci bir ayrım getiriyor. Bütçe 100'deki takım yetki taramanın dördünü de,
bölge dışı sızıntının beşini de yakalar; kaçırdığı üç oturum toplu okuma ve hesap devralma
sınıflarındandır — yani **normalin en geniş olduğu ölçülerde**. Kaçırılan oturum sayısı bir
toplamdır; hangi sınıftan kaçtığı ayrı bilgidir ve karar ancak o ayrıntıyla verilir.

Son iki satır bu dersi öncekine bağlıyor. Bölge dışı okuma senaryosu, önceki dersin şemasında
bulunmayan bir alana dayanır. Alan yazılmadığında senaryo hiçbir eşikte kurulamaz: aynı bütçede
yakalanan 15'ten 13'e iner ve beş sızıntı oturumunun yalnız ikisi, başka ölçülerde tesadüfen
yüksek çıktığı için görülür. **Kayıtta olmayan bir alan, bir tespit senaryosunun eşiğini değil
varlığını ortadan kaldırır.** Alanın kayıt bedeli küçüktür — günlük hacimde yüzde 1,1 artış,
saklamada bir günün altında bir kayıp. Asıl bedeli başka yerdedir: kural, hesabın yetkili bölge
listesini gerektirir; bu liste bir personel atama verisidir ve kayıt kümesine dördüncü bir
kişisel veri kalemi olarak girer.

#### Özet

- Uygulamaya özgü tespit, protokol anormalliğine değil iş kuralının ölçtüğü bir sayıya bakar:
  okunan farklı kayıt, reddedilen yetki, adres başına hesap, bölge dışı okuma.
- Her eşik aynı takası verir ve iki uç da işlevsizdir: reddedilen yetki eşiği 3'te 364 yanlış
  uyarı ve 211 uyandırma, 25'te sıfır yanlış ve dört oturumun dördü birden kaçırılmış.
- Örtüşmenin kaynağı aracın kalitesi değil normalin kendisidir: entegrasyon hesapları meşru
  olarak yüksek hacimlidir ve oturumların yüzde sekizi ağır kuyruk üretir.
- Eşikler birlikte seçilir ve fiyat birlikte doğar: 18 oturumun tamamı 173 yanlış uyarı ve 30
  günde 101 uyandırmayla, 15'i 72 yanlış uyarı ve 43 uyandırmayla yakalanır.
- Kaçırılan oturumun sayısı kadar sınıfı da bilgidir: kaçan üç oturum normalin en geniş olduğu
  iki ölçüdendir.
- Kayıtta olmayan alan senaryonun eşiğini değil varlığını kaldırır: bölge alanı yazılmadığında
  yakalanan 15'ten 13'e iner, bedeli ise yüzde 1,1 hacim ve dördüncü bir kişisel veri kalemidir.

#### Sonraki Adım

Bu dersin sonunda elde bir uyarı vardır ve uyarı doğrudur: bir oturum abone kayıtlarını yetkisiz
okumuştur. Uyarının ilk dakikasında sorulacak sorular öncekilerden farklıdır, çünkü artık cevap
bir raporu değil bir kararı besler — hesap kapatılacak mı, hangi abonelerin verisi görülmüştür,
sızma nereden başlamıştır. Sonraki ders bu uygulama ihlali senaryosunda müdahale adımlarını
koşturur ve tek bir şeyi ölçer: hangi adım hangi kayda ihtiyaç duyuyor, o kayıt yoksa adım kaç
dakika uzuyor ve hangi adım hiç tamamlanamıyor.

### Uygulama İhlali Müdahalesi

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/uygulama-ihlali-mudahalesi

Bir yetkisiz erişim ihlalinde on iki müdahale adımı dört kayıt şemasıyla koşturuluyor. Taban şemada yedi adım kayıtsız kalıyor, toplam 630 dakika sürüyor ve iki adım hiç tamamlanamıyor; en geniş şemada aynı müdahale 151 dakika, 4,17 kat kısa. Kayıt yokluğu adımları 4 ile 8,3 kat arasında uzatıyor. Kapsama kararı her şemada 10. dakikada veriliyor — fark kapsamada değil kapsam çıkarmada: etkilenen abone kümesi çıkarılamadığında bildirim 380 aboneden 41 200 abonelik üst sınıra genişliyor.

Önceki dersin sonunda elde doğru bir uyarı var: bir oturum, yetkili olmadığı abone kayıtlarını
okumuş. Uyarının doğrulanmasıyla birlikte iş, saymaktan yapmaya döner ve sorular değişir — hangi
hesap, nereden, hangi uç noktalardan, kaç abone kaydı, veri değişti mi, aynı desende başka hesap
var mı. Olay müdahale yaşam döngüsünün aşamaları ve nöbet düzeni Güvenlik Operasyonları ve Olay
Müdahalesi kursunda ölçülmüştü; burada tekrarlanmaz.

Bu ders yalnız bir şeyi ölçer: **hangi adım hangi kayda ihtiyaç duyuyor ve o kayıt yoksa adım kaç
dakika uzuyor.** İhlal senaryosu kayıt olarak girer; hiçbir istismar yöntemi ya da yük anlatılmaz,
çünkü ölçülen şey saldırının nasıl yapıldığı değil, yapıldıktan sonra nasıl anlaşıldığıdır.

- **UM12.** Olay **kurgudur**: abone portalında bir hesap üzerinden yetkisiz okuma; kiracıda
  41 200 abone kaydı var, gerçekte dokunulan küme 380 kayıt.
- **UM13.** **Olay müdahale kılavuzu**, adımların veri yapısı olarak modellenmiş hâlidir. Her
  adımın üç niteliği vardır: gereken kayıt alanları, kayıtla süren dakika, kayıtsız süren dakika.
- **UM14.** Bir adımın gereken alanları **tek bir eşlenebilir kümede** bulunmalıdır; önceki
  dersteki bağ kuralı burada da geçerlidir.
- **UM15.** Kayıtsız süresi tanımsız olan adım **hiç tamamlanamaz**: en iyi çabayla dört katı
  süre harcanır ve kesin sonuç yerine bir üst sınır bildirilir.
- **UM16.** Süreler **veridir**, bu sayfada yapılmış bir ölçüm değildir. Dört şema önceki
  derslerin şemalarıdır: taban, bağ alanı eklenmiş, yetki kararı ile sürüm eklenmiş, oturum ile
  değişiklik öncesi değer de eklenmiş.

#### Adım–Kayıt Bağımlılığı

```js
// mudahale.mjs — uygulama ihlali senaryosunda mudahale adimlari kosturulur; her adim
// bir kayit kumesine bagimlidir. MODELDIR: olay da sureler de kurgudur.
export const KIRACI_ABONE = 41200;   // kesin kume cikarilamazsa bildirilecek ust sinir

// Sema = onceki dersin kayit tasarimlari. Alanlar eslenebilir kumeler halinde tutulur:
// ayni kume icindeki alanlar birlestirilebilir, ayri kumelerdekiler birlestirilemez.
export const SEMA = [
  { ad: "taban", kume: [["zaman", "iz", "aktor", "eylem", "sonuc", "yol", "yontem", "durum",
    "istemci_ip"], ["zaman", "tablo", "nesne", "islem"]] },
  { ad: "+iz", kume: [["zaman", "iz", "aktor", "eylem", "sonuc", "yol", "yontem", "durum",
    "istemci_ip", "tablo", "nesne", "islem"]] },
  { ad: "+karar+surum", kume: [["zaman", "iz", "aktor", "eylem", "sonuc", "yol", "yontem",
    "durum", "istemci_ip", "tablo", "nesne", "islem", "yetki_karari", "surum"]] },
  { ad: "+oturum+deger", kume: [["zaman", "iz", "aktor", "eylem", "sonuc", "yol", "yontem",
    "durum", "istemci_ip", "tablo", "nesne", "islem", "yetki_karari", "surum", "oturum",
    "once_deger"]] },
];

// Adim = [ad, gereken alanlar, kayitla dakika, kayitsiz dakika]. Kayitsiz dakika null ise
// adim hic tamamlanamaz; en iyi cabayla dort kati sure gider, sonuc ust sinir olur.
export const ADIM = [
  ["uyariyi dogrula", ["aktor", "eylem", "sonuc"], 6, 40],
  ["hesabi ve oturumu kes", ["aktor"], 4, 25],
  ["giris yolunu bul", ["istemci_ip", "iz"], 12, 70],
  ["cagrilan uc noktalari cikar", ["yol", "yontem", "iz"], 10, 60],
  ["yetki karari neden olumlu", ["aktor", "eylem", "yetki_karari"], 14, 100],
  ["etkilenen abone kumesi", ["aktor", "eylem", "nesne"], 25, null],
  ["veri degisti mi", ["iz", "tablo", "islem"], 15, 120],
  ["degisen degerleri geri al", ["tablo", "once_deger"], 20, null],
  ["ayni desende baska hesap", ["istemci_ip", "aktor"], 18, 90],
  ["surum ve yama durumu", ["aktor", "surum"], 8, 45],
  ["ayni oturumdaki diger isler", ["oturum", "eylem"], 9, 75],
  ["bildirilecek kapsami yaz", ["aktor", "nesne", "zaman"], 10, 60],
];
export const KAPSAMA_ADIM = 2;   // ilk iki adim kapsama kararini besler

export const varMi = (sema, alanlar) =>
  sema.kume.some((c) => alanlar.every((a) => c.includes(a)));

export function kosuf(sema) {
  let toplam = 0, kapsama = 0, eksik = 0, tamamlanamayan = 0, kesinKume = true;
  const satir = ADIM.map(([ad, alanlar, ile, siz], i) => {
    const var_ = varMi(sema, alanlar);
    const dk = var_ ? ile : (siz ?? ile * 4);
    if (!var_) { eksik++; if (siz === null) { tamamlanamayan++;
      if (ad === "etkilenen abone kumesi") kesinKume = false; } }
    toplam += dk;
    if (i < KAPSAMA_ADIM) kapsama += dk;
    return { ad, dk, durum: var_ ? "kayittan" : (siz === null ? "tamamlanamaz" : "elle") };
  });
  return { satir, toplam, kapsama, eksik, tamamlanamayan,
    bildirim: kesinKume ? 380 : KIRACI_ABONE };
}

export const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  const s = SEMA[0], o = kosuf(s);
  console.log(`sema "${s.ad}": ${ADIM.length} mudahale adimi, ` +
    `${s.kume.length} eslenebilir alan kumesi`);
  const y = gen([30, 34, 10, 15]);
  console.log("\n" + y(["adim", "gereken alanlar", "dakika", "kaynak"]));
  ADIM.forEach(([ad, alanlar], i) =>
    console.log(y([ad, alanlar.join(","), o.satir[i].dk, o.satir[i].durum])));
  console.log(`\ntoplam ${o.toplam} dakika, kayitsiz adim ${o.eksik}/${ADIM.length}, ` +
    `hic tamamlanamayan ${o.tamamlanamayan}, kapsama karari ${o.kapsama}. dakikada`);
  console.log(`etkilenen abone kumesi cikarilamadi: bildirim kapsami ${o.bildirim} abone`);
}
```

```
sema "taban": 12 mudahale adimi, 2 eslenebilir alan kumesi

adim                                             gereken alanlar    dakika         kaynak
uyariyi dogrula                                aktor,eylem,sonuc         6       kayittan
hesabi ve oturumu kes                                      aktor         4       kayittan
giris yolunu bul                                   istemci_ip,iz        12       kayittan
cagrilan uc noktalari cikar                        yol,yontem,iz        10       kayittan
yetki karari neden olumlu               aktor,eylem,yetki_karari       100           elle
etkilenen abone kumesi                         aktor,eylem,nesne       100   tamamlanamaz
veri degisti mi                                   iz,tablo,islem       120           elle
degisen degerleri geri al                       tablo,once_deger        80   tamamlanamaz
ayni desende baska hesap                        istemci_ip,aktor        18       kayittan
surum ve yama durumu                                 aktor,surum        45           elle
ayni oturumdaki diger isler                         oturum,eylem        75           elle
bildirilecek kapsami yaz                       aktor,nesne,zaman        60           elle

toplam 630 dakika, kayitsiz adim 7/12, hic tamamlanamayan 2, kapsama karari 10. dakikada
etkilenen abone kumesi cikarilamadi: bildirim kapsami 41200 abone
```

Tablonun ilk dört satırı hızlıdır ve hepsi tek bir eşlenebilir kümeden okunur: kim, nereden,
hangi uç noktalardan. Bu dört adım 32 dakika sürer ve müdahalenin en görünür kısmıdır. Kalan sekiz
satırın yedisi kayıtsızdır ve toplam sürenin 598 dakikasını üretir. **Bir müdahalenin süresini
belirleyen şey ilk adımların hızı değil, ortadaki adımların hangi kaydı bulamadığıdır.**

En pahalı iki satır aynı nedenden pahalıdır. "Veri değişti mi" adımı `iz`, `tablo` ve `islem`
alanlarını birlikte ister; üç alan da yazılıyor, ama veritabanı değişiklik kaydında bağ alanı
olmadığı için hangi isteğin hangi satırı değiştirdiği gösterilemez. Aynı şey "etkilenen abone
kümesi" adımında olur: `aktor` bir kümede, `nesne` ötekinde. İkisi de eksik alan değil, kurulmamış
bağ yüzünden uzar. **Bağ eksikliğinin bedeli ölçüm defterinde bir satır, müdahale defterinde iki
yüz yirmi dakikadır.**

Tablonun okunmayan bir satırı da vardır ve o satır bir yanılgıyı önler: "aynı desende başka
hesap" adımı taban şemada bile kayıttan okunur, çünkü `istemci_ip` ile `aktor` aynı kümededir. Bu
adım müdahalenin en geniş kapsamlı sorusunu sorar — olay tek hesapla mı sınırlı — ve on sekiz
dakikada cevaplanır. **Bir kayıt tasarımının değeri adım sayısına göre değil, hangi adımların
kayıttan okunabildiğine göre dağılır; en ucuz alan en geniş soruyu cevaplayan alan olabilir.**

Son iki satır kayıt tasarımının müdahale dışına taşan bedelini yazar. Etkilenen abone kümesi
kesin olarak çıkarılamadığında yerine bir üst sınır bildirilir: kiracıdaki 41 200 abonenin
tamamı. Gerçekte dokunulan küme 380 kayıttır. Aradaki fark bir raporlama ayrıntısı değildir;
bildirim yükümlülüğünü, çağrı merkezi yükünü ve kurumun dışarıya söylediği cümleyi belirler.
Benzer biçimde "değişen değerleri geri al" adımı, değişiklik öncesi değer yazılmadığı için hiç
tamamlanamaz — veri geri alınamaz, yalnız hangi satırların değiştiği söylenebilir. İki adım da
harcanan zamanı geri vermez: model bu adımlara sırasıyla 100 ve 80 dakika yazar ve o sürenin
sonunda elde kesin bir küme değil, bir aralık kalır. **Tamamlanamayan adım, atlanan adım
değildir; bedeli hem dakikada hem cevabın kesinliğinde iki kez ödenir.**

#### Aynı Müdahale, Dört Kayıt Şeması

```js
// karsilastir.mjs — ayni mudahale dort kayit semasiyla kosturulur; kayit tasarimindaki
// fark dakikaya ve bildirim kapsamina cevrilir. MODELDIR.
import { SEMA, ADIM, kosuf, varMi, gen } from "./mudahale.mjs";

const y = gen([16, 10, 11, 12, 15, 12]);
console.log(y(["sema", "toplam dk", "kapsama dk", "kayitsiz", "tamamlanamaz", "bildirim"]));
const sonuc = SEMA.map((s) => {
  const o = kosuf(s);
  console.log(y([s.ad, o.toplam, o.kapsama, `${o.eksik}/${ADIM.length}`, o.tamamlanamayan,
    o.bildirim]));
  return o;
});

// Adim basina uzama: ayni adim taban semada ve en genis semada kac dakika suruyor.
const taban = SEMA[0];
const uzama = ADIM.map(([ad, alanlar, ile, siz]) => ({ ad, ile,
  siz: varMi(taban, alanlar) ? ile : (siz ?? ile * 4),
  kesin: siz !== null || varMi(taban, alanlar) }))
  .filter((u) => u.siz !== u.ile).sort((a, b) => (b.siz - b.ile) - (a.siz - a.ile));
const z = gen([30, 10, 10, 8, 10]);
console.log("\ntaban semada uzayan adimlar (en genis semayla karsilastirma)");
console.log(z(["adim", "kayitla", "kayitsiz", "kat", "sonuc"]));
for (const u of uzama)
  console.log(z([u.ad, u.ile, u.siz, (u.siz / u.ile).toFixed(1), u.kesin ? "kesin" : "ust sinir"]));

const t = sonuc[0], g = sonuc.at(-1);
console.log(`\ntaban sema ${t.toplam} dakika, en genis sema ${g.toplam} dakika: ` +
  `${t.toplam - g.toplam} dakika fark, ${(t.toplam / g.toplam).toFixed(2)} kat`);
console.log(`kapsama karari her semada ${g.kapsama}. dakikada verilebiliyor; ` +
  `fark kapsamada degil kapsam cikarmada`);
console.log(`bildirim kapsami ${t.bildirim} abonelik ust sinirdan ${g.bildirim} abonelik ` +
  `kesin kumeye iniyor: ${(t.bildirim / g.bildirim).toFixed(0)} kat dar`);
console.log(`ikinci sema (+iz) tek alanla ${t.toplam - sonuc[1].toplam} dakika kazandiriyor ` +
  `ve tamamlanamayan adimi ${t.tamamlanamayan}'den ${sonuc[1].tamamlanamayan}'e indiriyor`);
```

```
sema             toplam dk kapsama dk    kayitsiz   tamamlanamaz    bildirim
taban                  630         10        7/12              2       41200
+iz                    400         10        4/12              1         380
+karar+surum           277         10        2/12              1         380
+oturum+deger          151         10        0/12              0         380

taban semada uzayan adimlar (en genis semayla karsilastirma)
adim                             kayitla  kayitsiz     kat     sonuc
veri degisti mi                       15       120     8.0     kesin
yetki karari neden olumlu             14       100     7.1     kesin
etkilenen abone kumesi                25       100     4.0 ust sinir
ayni oturumdaki diger isler            9        75     8.3     kesin
degisen degerleri geri al             20        80     4.0 ust sinir
bildirilecek kapsami yaz              10        60     6.0     kesin
surum ve yama durumu                   8        45     5.6     kesin

taban sema 630 dakika, en genis sema 151 dakika: 479 dakika fark, 4.17 kat
kapsama karari her semada 10. dakikada verilebiliyor; fark kapsamada degil kapsam cikarmada
bildirim kapsami 41200 abonelik ust sinirdan 380 abonelik kesin kumeye iniyor: 108 kat dar
ikinci sema (+iz) tek alanla 230 dakika kazandiriyor ve tamamlanamayan adimi 2'den 1'e indiriyor
```

İlk sütun kayıt tasarımının müdahale süresine çevrilmiş hâlidir: aynı olay, aynı adımlar, aynı
kişiler; 630 dakika ile 151 dakika arasında 4,17 kat fark. İkinci satır bu farkın nereden
geldiğini gösteriyor. Tek bir bağ alanı — veritabanı kaydına eklenen 18 baytlık `iz` — müdahaleyi
230 dakika kısaltır ve tamamlanamayan adımı ikiden bire indirir. Önceki derste aynı alan cevaplanan
soruyu altıdan on bire çıkarmıştı; burada aynı alanın ikinci faturası ödenmiş olur.

İkinci sütun bir yanılgıyı kesiyor. Kapsama kararı — hesabın askıya alınması ve oturumun
kesilmesi — dört şemada da 10. dakikada verilebilir, çünkü o adım yalnız `aktor` alanını ister ve
o alan her şemada vardır. **Kayıt tasarımı saldırıyı durdurma hızını değiştirmez; değiştirdiği
şey ne olduğunu söyleme hızıdır.** İhlal müdahalelerinin uzun sürmesinin nedeni çoğu zaman
kapsama değil, kapsam çıkarmadır: kimin verisine dokunulduğu, neyin değiştiği ve aynı desende
başka hesap olup olmadığı.

Şemaların sırası da bir bilgi taşır. Birinci adımdan ikinciye geçiş bir alan karşılığında 230
dakika kazandırır; ikinciden üçüncüye iki alan karşılığında 123 dakika; üçüncüden dördüncüye iki
alan karşılığında 126 dakika. Alan başına kazanç 230, 62 ve 63 dakikadır. Bağ alanı diğerlerinden
üç kattan fazla kazandırır ve bunu hiçbir yeni olgu kaydetmeden yapar. Aynı sıra hacim tarafında
tersine döner: bağ alanı günlük hacmi yüzde iki, son iki alan yüzde otuz dokuz büyütür. **Kayıt
alanları eşit fiyatlı değildir; hem kazançları hem bedelleri arasında kat farkı vardır ve iki
sıralama birbirinin tersidir.**

Uzama tablosu bedeli adım adım yazıyor. Kat sütunu 4,0 ile 8,3 arasında değişir ve en yüksek
katlar en küçük adımlardadır: dokuz dakikalık "aynı oturumdaki diğer işler" adımı kayıtsız 75
dakika sürer. Sonuç sütunu daha keskin bir ayrım getirir. Beş adım kayıtsız da olsa **kesin**
sonuç verir — yalnız daha uzun sürer. İki adım kayıtsız kaldığında kesin sonuç veremez; harcanan
100 ve 80 dakikanın karşılığı bir üst sınırdır. **Bir adımın kayıt bağımlılığı iki türlüdür:
biri süreyi, öteki cevabın kesinliğini belirler; ikincisi hiçbir insan saatiyle kapatılamaz.**

Modelin sınırı da yazılmalıdır: toplam dakika tek kişilik bir hesaptır. Adımların çoğu birbirini
beklemez ve üç kişi çalıştığında geçen süre toplam dakikadan küçük olur. Ama bölünme yalnız
**süreyi** böler, kesinliği bölmez: üç kişi de "etkilenen abone kümesi" adımını kayıtsız
koşturduğunda sonuç yine üst sınırdır. Aynı biçimde kayıtsız adımların uzaması insan sayısıyla
kapatılabilirken, iki tamamlanamayan adım hiçbir kadroyla kapatılamaz. **İnsan ekleyerek
kısaltılabilen şey ile kısaltılamayan şey ayrı sütunlardır; müdahale planı ikisini karıştırdığında
kadro artırarak çözülemeyecek bir işi kadroya havale eder.**

Bedelin öteki yüzü önceki derste sayılmıştı ve burada tekrar okunmalıdır. En geniş şema 151
dakikalık müdahaleyi mümkün kılar, ama günlük hacmi 1,45 kata çıkarır, saklamayı 65 günden 45
güne indirir ve kişisel veri kalemini üçe çıkarır. 45 günlük saklama, 60 günlük denetim döneminin
başındaki bir olayda bu 151 dakikayı hiç kullandırmaz — kayıt orada yoktur. **Müdahale hızı için
alınan alan, olayın penceresi kaçtığında hiçbir şey kazandırmaz.**

#### Özet

- Bir müdahale kılavuzu adım listesi olarak değil, adım–kayıt bağımlılığı olarak ölçülür: her
  adımın gereken alanları, kayıtla süresi ve kayıtsız süresi ayrı yazılır.
- Taban şemada 12 adımın 7'si kayıtsız kalır, müdahale 630 dakika sürer; en geniş şemada aynı
  müdahale 151 dakikadır, arada 4,17 kat vardır.
- Uzamanın büyük bölümü eksik alandan değil kurulmamış bağdan gelir; tek bir bağ alanı 230
  dakika kazandırır ve tamamlanamayan adımı ikiden bire indirir.
- Kayıt tasarımı kapsama kararının hızını değiştirmez — her şemada 10. dakika — yalnız kapsam
  çıkarmanın hızını değiştirir.
- Kayıt bağımlılığı iki türlüdür: beş adım kayıtsız da kesin sonuç verir ama 5,6 ile 8,3 kat uzar;
  iki adım kesin sonuç veremez ve bildirim 380 aboneden 41 200 abonelik üst sınıra genişler.
- Hızlı müdahalenin bedeli önceki dersin defterinde yazılıdır: 1,45 kat hacim, 65 günden 45 güne
  inen saklama ve üç kişisel veri kalemi.

#### Sonraki Adım

Bu dersin bütün hesabı bir varsayıma dayanıyordu: kayıt alanı yazıldıysa müdahale anında elde
duruyor. Kalıcı bir hizmette bu doğrudur. Kısa ömürlü iş yüklerinde değildir — bir görev
konteyneri kırk saniye yaşayıp sonlandığında, ürettiği kayıt kalemlerinin ancak dışarı
yazılabilmiş olanı sorgulanabilir; gerisi süreçle birlikte gider. Sonraki ders bu pencereyi
ölçer: iş yükü ölmeden hangi uygulama kalemi dışarı çıkabiliyor, ayrıntı düzeyi arttıkça
toplanabilen kalemin oranı ne oluyor ve elde kalan kalemler önceki derslerin sorularından kaçını
cevaplıyor.

### Kısa Ömürlü İş Yüklerinde İz

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/kisa-omurlu-is-yuklerinde-iz

2 000 kısa ömürlü iş yükü 671 501 kayıt kalemi üretiyor, 642 504'ü dışarı yazılıyor: kayıp yalnızca yüzde 4,3. Aynı veride iş yükünün son kalemi 2 000 iş yükünün ancak 115'inde toplanabiliyor, hatalı çıkış sınıfının 92 iş yükünden hiçbir kalem çıkmıyor. Ayrıntı düzeyi sekiz kat artırıldığında dışarı yazılan kalem 4 272 000'e çıkıyor ama yetki kararı sorusunu cevaplayan iş yükü 1 218'den sıfıra iniyor. Bütün kalemleri toplayan ayarın bedeli 91 084 ek gönderim isteği ve 33 çekirdek-dakika ek yaşam süresi.

Önceki dersin bütün hesabı bir varsayıma dayanıyordu: bir kayıt alanı yazıldıysa müdahale anında
elde durur. Kalıcı bir hizmette bu doğrudur. Kısa ömürlü iş yüklerinde değildir. Bir görev
konteyneri kırk saniye yaşayıp sonlandığında, ürettiği kalemlerin yalnız **dışarı yazılabilmiş**
olanı sorgulanabilir; gerisi süreçle birlikte gider. Bulut ortamında kanıt toplamanın kalıcı
sistemlerden farkı Bulut ve Sanallaştırma Güvenliği kursunda ölçülmüştü; burada tekrarlanmaz,
girdi olur.

Bu ders yalnız **uygulama izini** ölçer: iş yükü ölmeden hangi uygulama kalemi dışarı yazılmış
oluyor. Ölçünün adı **toplanabilen kalem penceresidir** ve tek bir sayıya indirgenemez, çünkü
kaybolan kalemler akış içinde rastgele dağılmaz — hepsi sondadır.

- **UM17.** İş yükü kümesi **kurgudur**: 2 000 çalıştırma, dört ömür bandı. Ömürler tohumu
  görünen bir üreteçten gelir.
- **UM18.** Kalemler iş yükü içinde sabit hızda üretilir ve yerel bir **tampona** yazılır.
  Gönderici her `aralik` saniyede bir, en çok `yigin` kadar kalemi dışarı yazar.
- **UM19.** İş yükü sonlandığında tamponda kalan her şey **kaybolur**. Son bir gönderim ancak
  kapanış süresi gönderim süresini karşılıyorsa yapılabilir; modelde gönderim 1,2 saniye,
  varsayılan kapanış 0,5 saniyedir.
- **UM20.** **Soru**, iş yükünün ömründeki göreli bir konumda üretilen kaleme bağlıdır. Kalem
  dışarı yazılmadıysa o soru o iş yükü için cevapsızdır; ölçü birimi yine cevaplanamayan sorudur.
- **UM21.** Süreler ve hızlar **veridir**, bu sayfada yapılmış bir ölçüm değildir.

#### Toplanabilen Kalem Penceresi

```js
// iz.mjs — kisa omurlu is yuklerinde disari yazilabilen kalem penceresi olculur.
// MODELDIR: is yukleri, omurler ve kalem hizlari kurgudur.
export const TOHUM = 20260502, IS_YUKU = 2000;
export const HIZ = 6, ARALIK = 5, YIGIN = 200, GONDERIM = 1.2, KAPANIS = 0.5;
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);

// Sinif = is yukunun omur bandi. Hatali cikis en kisa yasayan ve en cok kaybedendir.
export const SINIF = [
  { ad: "kisa gorev", pay: 0.55, alt: 3, ust: 20 },
  { ad: "toplu is", pay: 0.25, alt: 20, ust: 120 },
  { ad: "istek isleyici", pay: 0.15, alt: 60, ust: 400 },
  { ad: "hatali cikis", pay: 0.05, alt: 1, ust: 4 },
];
const sinifSec = (u) => { let t = 0;
  for (const s of SINIF) { t += s.pay; if (u < t) return s; } return SINIF.at(-1); };
export const YUKLER = Array.from({ length: IS_YUKU }, () => {
  const s = sinifSec(r());
  return { sinif: s.ad, omur: s.alt + r() * (s.ust - s.alt) };
});

// Tampon FIFO'dur: her gonderim en cok YIGIN kalem tasir. Is yuku olurken tamponda
// kalan her sey gider; son gonderim ancak kapanis suresi gonderim suresini karsilarsa olur.
export function kos(omur, hiz = HIZ, aralik = ARALIK, kapanis = KAPANIS) {
  const kalem = Math.max(1, Math.floor(omur * hiz));
  let gonderilen = 0, istek = 0;
  const gonder = (t) => {
    const uretilen = Math.min(kalem, Math.floor(t * hiz) + 1);
    const g = Math.min(YIGIN, uretilen - gonderilen);
    if (g > 0) { gonderilen += g; istek++; }
  };
  for (let t = aralik; t <= omur; t += aralik) gonder(t);
  if (kapanis >= GONDERIM) gonder(omur);
  return { kalem, gonderilen, kayip: kalem - gonderilen, istek };
}

// Soru = [metin, kalemin is yuku omrundeki goreli konumu]. Kalem disari yazilmadiysa
// o is yuku icin soru cevapsizdir.
export const SORU = [
  ["istek hangi hesaptan geldi", 0.00],
  ["hangi uc nokta cagrildi", 0.10],
  ["hangi bagimlilik cagrildi", 0.45],
  ["yetki karari neydi", 0.85],
  ["is yuku hangi hatayla sonlandi", 1.00],
];

export function toplu(hiz = HIZ, aralik = ARALIK, kapanis = KAPANIS) {
  let kalem = 0, gonderilen = 0, istek = 0;
  const soruSay = SORU.map(() => 0);
  for (const y of YUKLER) {
    const o = kos(y.omur, hiz, aralik, kapanis);
    kalem += o.kalem; gonderilen += o.gonderilen; istek += o.istek;
    SORU.forEach(([, p], j) => {
      if (Math.floor(p * (o.kalem - 1)) < o.gonderilen) soruSay[j]++;
    });
  }
  return { kalem, gonderilen, kayip: kalem - gonderilen, istek, soruSay };
}

export const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`model (tohum ${TOHUM}): ${IS_YUKU} is yuku, ${HIZ} kalem/s, gonderim ` +
    `araligi ${ARALIK} s, yigin ${YIGIN} kalem, kapanis suresi ${KAPANIS} s, ` +
    `gonderim suresi ${GONDERIM} s`);
  const y = gen([18, 8, 11, 12, 12, 11, 9]);
  console.log("\n" + y(["is yuku sinifi", "adet", "ort. omur", "uretilen", "gonderilen",
    "kayip", "oran"]));
  for (const s of SINIF) {
    const l = YUKLER.filter((w) => w.sinif === s.ad).map((w) => kos(w.omur));
    const ku = l.reduce((t, o) => t + o.kalem, 0), g = l.reduce((t, o) => t + o.gonderilen, 0);
    const om = YUKLER.filter((w) => w.sinif === s.ad).reduce((t, w) => t + w.omur, 0);
    console.log(y([s.ad, l.length, (om / l.length).toFixed(1), ku, g, ku - g,
      (g / ku).toFixed(2)]));
  }
  const t = toplu();
  console.log(`\ntoplam ${t.kalem} kalem uretildi, ${t.gonderilen} disari yazildi, ` +
    `${t.kayip} kayip (yuzde ${((t.kayip / t.kalem) * 100).toFixed(1)})`);
  const z = gen([32, 8, 14, 8]);
  console.log("\n" + z(["soru", "konum", "cevaplanan", "oran"]));
  SORU.forEach(([m, p], j) => console.log(z([m, p.toFixed(2),
    `${t.soruSay[j]}/${IS_YUKU}`, (t.soruSay[j] / IS_YUKU).toFixed(2)])));
}
```

```
model (tohum 20260502): 2000 is yuku, 6 kalem/s, gonderim araligi 5 s, yigin 200 kalem, kapanis suresi 0.5 s, gonderim suresi 1.2 s

is yuku sinifi        adet  ort. omur    uretilen  gonderilen      kayip     oran
kisa gorev            1091       11.5       74404       57738      16666     0.78
toplu is               536       71.2      228687      221405       7282     0.97
istek isleyici         281      217.8      367056      363361       3695     0.99
hatali cikis            92        2.5        1354           0       1354     0.00

toplam 671501 kalem uretildi, 642504 disari yazildi, 28997 kayip (yuzde 4.3)

soru                               konum    cevaplanan    oran
istek hangi hesaptan geldi          0.00     1757/2000    0.88
hangi uc nokta cagrildi             0.10     1757/2000    0.88
hangi bagimlilik cagrildi           0.45     1757/2000    0.88
yetki karari neydi                  0.85     1218/2000    0.61
is yuku hangi hatayla sonlandi      1.00      115/2000    0.06
```

İki tablo aynı koşumun iki farklı okumasıdır ve birbirine hiç benzemez. Üstteki tabloda toplam
kayıp yüzde 4,3'tür. Bu sayı bir gösterge panosunda "kayıt toplama sağlıklı" diye okunur;
gerçekten de üretilen 671 501 kalemin 642 504'ü dışarı yazılmıştır. Kayıt hattında hiçbir arıza
yoktur; gönderici çalışmakta, ağ ayakta, hedef yazılabilir durumdadır.

Alttaki tablo aynı veriyi soru başına okuyor ve başka bir şey söylüyor. İş yükünün ilk yarısında
üretilen kalemler 2 000 iş yükünün 1 757'sinde toplanabiliyor. Yetki kararının yazıldığı kalem
1 218'inde, iş yükünün nasıl sonlandığını yazan son kalem yalnız **115'inde**. Yani "iş yükü
hangi hatayla sonlandı" sorusu iş yüklerinin yüzde 94'ünde cevapsızdır — kayıt yazıldığı hâlde.
**Kayıp kalem oranı ile cevaplanabilirlik oranı aynı şey değildir, çünkü kaybolan kalemler akış
içinde rastgele dağılmaz; hepsi sondadır ve müdahalede en çok istenen kalemler de sondakilerdir.**

Sınıf tablosu kaybın nerede yoğunlaştığını yazıyor. İstek işleyici sınıfı ortalama 218 saniye
yaşar ve kalemlerinin yüzde 99'unu dışarı yazar. Hatalı çıkış sınıfı ortalama 2,5 saniye yaşar
ve **hiçbir kalemi dışarı çıkmaz**: 92 iş yükü, 1 354 kalem, sıfır. Gönderim aralığı beş
saniyedir; iki buçuk saniye yaşayan bir iş yükü ilk periyodik gönderime hiç ulaşmaz, kapanış
süresi de gönderim süresini karşılamadığı için son gönderim yapılamaz. Bu sınıf toplam kalemin
yalnız binde ikisidir, ama müdahalede en çok bakılan sınıftır: bir iş yükünün beklenmedik biçimde
ve hızla sonlanması zaten incelemenin başlangıç nedenidir.

Toplam kayıp oranının yanıltmasının nedeni de bu tablodadır. Toplam, kalem sayısıyla
ağırlıklandırılmış bir ortalamadır ve kalemlerin büyük bölümünü uzun yaşayan iş yükleri üretir:
281 istek işleyici tek başına 367 056 kalem yazar, 1 091 kısa görev ise 74 404. Uzun yaşayanın
yüzde 99'luk oranı toplamı yukarı çeker, kısa yaşayanın yüzde 78'i ve hatalı çıkışın sıfırı
toplamda kaybolur. **İş yükü başına ölçülmeyen bir toplama oranı, en çok kalem üreten sınıfın
oranını bütün ortamın oranı diye rapor eder.** Aynı veri iş yükü başına okunduğunda 92 iş yükünün
tamamen sessiz olduğu görülür ve bu sayı toplam oranın hiçbir yerinde yazmaz.

#### Ayrıntı Düzeyi ve Toplama Ayarları

```js
// ayar.mjs — iki ayar ekseni kosturulur: ayrinti duzeyi (kalem/s) ve gonderim duzeni
// (aralik, kapanis suresi). Olculen sey kalem sayisi degil cevaplanan sorudur. MODELDIR.
import { HIZ, ARALIK, KAPANIS, IS_YUKU, SORU, toplu, gen } from "./iz.mjs";

const y = gen([10, 11, 12, 8, 14, 12, 17]);
console.log(y(["ayrinti", "uretilen", "gonderilen", "kayip", "yetki (0.85)", "son (1.00)",
  "cevaplanan cift"]));
for (const kat of [1, 2, 4, 8]) {
  const t = toplu(HIZ * kat);
  const cift = t.soruSay.reduce((a, b) => a + b, 0);
  console.log(y([`${kat}x`, t.kalem, t.gonderilen, ((t.kayip / t.kalem) * 100).toFixed(1) + "%",
    (t.soruSay[3] / IS_YUKU).toFixed(2), (t.soruSay[4] / IS_YUKU).toFixed(2),
    `${cift}/${SORU.length * IS_YUKU}`]));
}

const z = gen([9, 10, 12, 14, 12, 12, 16]);
console.log("\n" + z(["aralik", "kapanis", "gonderilen", "yetki (0.85)", "son (1.00)",
  "istek", "ek cekirdek-sn"]));
for (const kapanis of [KAPANIS, 1.5]) for (const aralik of [5, 2, 1]) {
  const t = toplu(HIZ, aralik, kapanis);
  console.log(z([aralik, kapanis, t.gonderilen, (t.soruSay[3] / IS_YUKU).toFixed(2),
    (t.soruSay[4] / IS_YUKU).toFixed(2), t.istek,
    (IS_YUKU * (kapanis - KAPANIS)).toFixed(0)]));
}

const taban = toplu(), yogun = toplu(HIZ * 8), genis = toplu(HIZ, 1, 1.5);
console.log(`\nayrinti 8 kat artinca disari yazilan kalem ${taban.gonderilen}'den ` +
  `${yogun.gonderilen}'e cikiyor ama yetki karari sorusu ` +
  `${taban.soruSay[3]} is yukunden ${yogun.soruSay[3]} is yukune iniyor`);
console.log(`en genis ayar (aralik 1 s, kapanis 1.5 s) ayni ayrintida son kalemi ` +
  `${taban.soruSay[4]} yerine ${genis.soruSay[4]} is yukunde disari yaziyor; ` +
  `bedeli ${genis.istek - taban.istek} ek gonderim istegi ve ` +
  `${(IS_YUKU * (1.5 - KAPANIS) / 60).toFixed(0)} cekirdek-dakika ek yasam suresi`);
```

```
ayrinti      uretilen  gonderilen   kayip  yetki (0.85)  son (1.00)  cevaplanan cift
1x             671501      642504    4.3%          0.61        0.06       6604/10000
2x            1344000     1283327    4.5%          0.59        0.03       6500/10000
4x            2688990     2564937    4.6%          0.58        0.01       6454/10000
8x            5378988     4272000   20.6%          0.00        0.00       5221/10000

aralik      kapanis  gonderilen  yetki (0.85)  son (1.00)       istek  ek cekirdek-sn
5               0.5      642504          0.61        0.06       21360               0
2               0.5      662111          0.89        0.15       55024               0
1               0.5      668090          1.00        0.31      111065               0
5               1.5      671501          1.00        1.00       23245            2000
2               1.5      671501          1.00        1.00       56715            2000
1               1.5      671501          1.00        1.00      112444            2000

ayrinti 8 kat artinca disari yazilan kalem 642504'den 4272000'e cikiyor ama yetki karari sorusu 1218 is yukunden 0 is yukune iniyor
en genis ayar (aralik 1 s, kapanis 1.5 s) ayni ayrintida son kalemi 115 yerine 2000 is yukunde disari yaziyor; bedeli 91084 ek gonderim istegi ve 33 cekirdek-dakika ek yasam suresi
```

İlk tablo bu kursun ikinci kez gösterdiği olguyu veriyor. Ayrıntı düzeyi sekiz kat artırıldığında
dışarı yazılan kalem 642 504'ten 4 272 000'e çıkar — altı buçuk kat daha çok kayıt. Aynı hareket
yetki kararı sorusunu cevaplayan iş yükünü 1 218'den sıfıra indirir. Mekanizma son sütunda değil
kayıp sütununda görünür: sekiz kat ayrıntıda üretim hızı saniyede 48 kaleme çıkar, oysa gönderici
beş saniyede en çok 200 kalem taşır, yani saniyede 40. Üretim taşıma kapasitesini geçtiğinde
tampon **birikmeye başlar** ve akışın sonu hiçbir zaman sıraya gelmez. **Daha çok kayıt yazmak,
taşıma kapasitesi sabitken en son yazılan kalemi kuyrukta daha da geriye iter; toplam kalem artar,
cevaplanan soru azalır.**

Bu kırılmanın altındaki üç satır aynı olgunun yumuşak hâlidir. Ayrıntı iki ve dört kat
artırıldığında kapasite henüz aşılmaz; yine de cevaplanan soru–iş yükü çifti 6 604'ten 6 454'e
iner. Kazanç yoktur, çünkü eklenen kalemler zaten toplanabilen pencerenin içine düşer; kaybedilen
ise yine sondaki kalemdir.

İkinci tablo iki ayarın ne satın aldığını yazıyor. Gönderim aralığını beş saniyeden bir saniyeye
indirmek yetki kararı sorusunu 0,61'den 1,00'e çıkarır, ama son kalem yine iş yüklerinin ancak
yüzde 31'inde toplanır — çünkü sorun aralık değil, kapanış anındaki gönderimin hiç
yapılamamasıdır. Kapanış süresi gönderim süresini karşılayacak kadar uzatıldığında beş saniyelik
aralıkla bile bütün sorular her iş yükünde cevaplanır. **Toplanabilen kalem penceresini belirleyen
şey gönderim sıklığı değil, iş yükünün ölmeden önce bir gönderim tamamlayabilmesidir.**

Bedel iki sütunda yazılıdır. Aralığı bire indirmek gönderim isteğini 21 360'tan 111 065'e çıkarır:
beş kattan fazla ağ isteği, iş yükü başına elli beş istek. Kapanış süresini bir saniye uzatmak
2 000 çekirdek-saniye, yani 33 çekirdek-dakika ek yaşam süresi getirir ve her iş yükünün
sonlanmasını geciktirir. İkisi birlikte 91 084 ek istek eder. Üçüncü bir bedel de tabloda
görünmez ama önceki derslerin defterindedir: dışarı yazılan her kalem, bir önceki dersteki sabit
saklama bütçesinin içine düşer ve saklama gününü kısaltır.

#### Özet

- Kısa ömürlü iş yüklerinde ölçü, yazılan kalem değil **dışarı yazılabilen** kalemdir; iş yükü
  ölürken tamponda kalan her şey kaybolur.
- Kayıp oranı ile cevaplanabilirlik oranı ayrı sayılardır: modelde kayıp yüzde 4,3 iken, iş
  yükünün son kalemi 2 000 iş yükünün yalnız 115'inde toplanabilir.
- Kayıp sınıflara eşit dağılmaz: ortalama 2,5 saniye yaşayan hatalı çıkış sınıfının 92 iş
  yükünden hiçbir kalem çıkmaz, oysa incelemenin başlangıç nedeni çoğu zaman bu sınıftır.
- Ayrıntı düzeyini artırmak cevabı düşürebilir: sekiz kat ayrıntıda dışarı yazılan kalem altı
  buçuk kat artarken yetki kararı sorusunu cevaplayan iş yükü 1 218'den sıfıra iner, çünkü üretim
  hızı taşıma kapasitesini aşar ve akışın sonu sıraya hiç gelmez.
- Pencereyi belirleyen şey gönderim sıklığı değil, iş yükünün ölmeden bir gönderim
  tamamlayabilmesidir: kapanış süresi uzatıldığında beş saniyelik aralık bile yeterlidir.
- Bedel ölçülür: 91 084 ek gönderim isteği, 33 çekirdek-dakika ek yaşam süresi ve dışarı yazılan
  her kalemin sabit saklama bütçesinden aldığı pay.

#### Sonraki Adım

Buraya kadar bütün kayıtlar, uyarılar ve kalemler kurumun kendi içinden geldi. Bir uygulamanın
açığı çoğu zaman başka bir yerden duyulur: dışarıdan bakan biri onu bulur ve bildirir. Bu akış bir
tespit hattı değildir, bir iş kuyruğudur; girdisi insan tarafından yazılmış bildirimler, çıktısı
düzeltilmiş ya da reddedilmiş kalemlerdir ve ölçüsü kalem sayısı değil **süredir**. Sonraki ders
dış bildirim kanalını ve ödül programını bu eksende ölçer: bildirimden doğrulamaya ve doğrulamadan
düzeltmeye kaç gün geçiyor, gelen bildirimlerin kaçı yineleniyor ve kanalın açılması kuyruğu hangi
noktada tıkıyor.

### Dış Bildirim Kanalı

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/dis-bildirim-kanali

180 günde gelen 340 bildirimin 91'i benzersiz; 190'ı yinelenen, 59'u kapsam dışı, yani kuyruğun yüzde 73'ü yeni açık taşımıyor. Günde iki kalemlik ilk bakış kapasitesinde kuyruk 104 kaleme çıkıyor ve ortalama bekleme 31,2 gün oluyor. Dört kayıt şemasıyla koşturulduğunda doğrulama 28,6 günden 25,8 güne iniyor ama bildirimden düzeltmeye 85,7 günden 89,9 güne çıkıyor. İstismar sorusuna kesin cevap 15'ten 20'ye çıkıp en geniş şemada 13'e iniyor; aynı sayıyı 24'e çıkaran şey ek alan değil, ilk bakış kapasitesinin 2'den 5'e çıkarılması.

Buraya kadar bütün kayıtlar ve uyarılar kurumun kendi içinden geldi. Bir uygulamanın açığı çoğu
zaman başka bir yerden duyulur: dışarıdan bakan biri onu bulur ve bildirir. **Dış bildirim kanalı
ve ödül programı**, bu bildirimlerin girdiği yapıdır. Bildiren tarafın süreci Güvenlik Araçları ve
Sızma Testi kursunda ölçülmüştü; burada tekrarlanmaz, girdi olur. Bu ders akışı **işleten** tarafı
ölçer ve birimi gündür: bildirimden doğrulamaya kaç gün, doğrulamadan düzeltmeye kaç gün, gelen
bildirimin kaçı yinelenen.

- **UM22.** Bildirim akışı **kurgudur**: 180 günde 340 bildirim, 120 açık, beş bulgu sınıfı.
  Sayılar tohumu görünen bir üreteçten gelir.
- **UM23.** Aynı açık birden çok kez bildirilir. Bir açığın ilk bildirimi **benzersiz**,
  sonrakiler **yinelenendir**; hiçbir açığa düşmeyen bildirim **kapsam dışıdır**.
- **UM24.** **İlk bakış kuyruğu** geliş sırasıyla işler; kapasiteyi bildirimin türü değil
  **sayısı** tüketir.
- **UM25.** Doğrulama iki yoldan yapılır: gereken alanlar tek bir eşlenebilir kümedeyse
  **kayıttan** bir günde, değilse **elle yeniden üretimle** sınıfa göre üç ile dokuz gün arasında.
- **UM26.** Her bildirim ikinci bir soru doğurur: **bu açık daha önce kullanıldı mı.** Kayıt
  doğrulama gününden `saklama` gün geriye uzanır ve kuyrukta geçen süre bu pencereden düşer.
  Üç sonuç vardır: **kesin**, **kısmi** (yalnız pencere kadar geriye bakılabilmiştir) ve
  **cevapsız** (alan yoktur).
- **UM27.** Şemalar ve saklama günleri önceki derslerin modelinden **veri** olarak gelir. Ödül
  **kurgu birimdir**; süreler bu sayfada yapılmış bir ölçüm değildir.

#### Gelen Bildirim, Yinelenen ve İlk Bakış Kuyruğu

```js
// bildirim.mjs — dis bildirim kanali ve odul programi, akisi isleten taraftan olculur:
// kac bildirim geliyor, kaci yinelenen, ilk bakisa kadar kac gun geciyor. MODELDIR.
export const TOHUM = 20260611, ACIK = 120, BILDIRIM = 340, DONEM = 180, TRIAJ = 2;
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);

// gorunurluk: acigin kac kez bildirilecegi. alan: istismar sorusunun istedigi kayit alani.
export const SINIF = [
  { ad: "yapilandirma", pay: 0.26, gorunurluk: 3.4, elle: 3, duzelt: 2, odul: 8,
    alan: ["yol", "durum"] },
  { ad: "girdi dogrulama", pay: 0.21, gorunurluk: 2.2, elle: 5, duzelt: 3, odul: 15,
    alan: ["iz", "yol", "yontem"] },
  { ad: "yetki atlama", pay: 0.20, gorunurluk: 1.0, elle: 8, duzelt: 6, odul: 40,
    alan: ["aktor", "eylem", "yetki_karari"] },
  { ad: "veri sizintisi", pay: 0.18, gorunurluk: 1.4, elle: 9, duzelt: 8, odul: 55,
    alan: ["aktor", "eylem", "nesne"] },
  { ad: "oturum yonetimi", pay: 0.15, gorunurluk: 0.8, elle: 7, duzelt: 5, odul: 30,
    alan: ["oturum", "eylem"] },
];
const sinifSec = (u) => { let t = 0;
  for (const s of SINIF) { t += s.pay; if (u < t) return s; } return SINIF.at(-1); };

// Acik = bildirimin arkasindaki gercek kalem; ayni acik gorunurlugu oraninda cok bildirilir.
export const ACIKLAR = Array.from({ length: ACIK }, () => {
  const s = sinifSec(r());
  return { sinif: s.ad, agirlik: s.gorunurluk * (0.3 + 1.4 * r()),
    yas: Math.round(8 + 340 * r() ** 1.6) };
});
const TOP = ACIKLAR.reduce((t, a) => t + a.agirlik, 0);
const acikSec = (u) => { let t = 0;
  for (let i = 0; i < ACIK; i++) { t += ACIKLAR[i].agirlik / TOP; if (u < t) return i; }
  return ACIK - 1; };

// Kanal acilinca hacim one yigilir: gelis gunu DONEM * u^2.2. Yuzde 18 kapsam disidir.
export const BILDIRIMLER = Array.from({ length: BILDIRIM }, (_, i) => ({
  i, gun: Math.floor(DONEM * r() ** 2.2), acik: r() < 0.18 ? null : acikSec(r()),
})).sort((a, b) => a.gun - b.gun);
const gorulen = new Set();
for (const b of BILDIRIMLER) {
  b.tur = b.acik === null ? "kapsam disi" : gorulen.has(b.acik) ? "yinelenen" : "benzersiz";
  gorulen.add(b.acik);
}
export const say = (x) => BILDIRIMLER.filter((b) => b.tur === x).length;

// Ilk bakis kuyrugu: gunde `hiz` kalem, gelis sirasiyla; kapasiteyi tur degil sayi tuketir.
export function triaj(hiz = TRIAJ, yaz = false) {
  const kuyruk = [], bakis = new Array(BILDIRIM);
  let zirve = 0, j = 0;
  for (let g = 0; j < BILDIRIM || kuyruk.length; g++) {
    while (j < BILDIRIM && BILDIRIMLER[j].gun === g) kuyruk.push(BILDIRIMLER[j++]);
    zirve = Math.max(zirve, kuyruk.length);
    for (let k = 0; k < hiz && kuyruk.length; k++) {
      const b = kuyruk.shift();
      bakis[b.i] = g;
      if (yaz) b.bakis = g;
    }
  }
  return { zirve, son: Math.max(...bakis),
    bekleme: BILDIRIMLER.reduce((t, b) => t + (bakis[b.i] - b.gun), 0) / BILDIRIM };
}

export const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  const bos = say("yinelenen") + say("kapsam disi");
  console.log(`model (tohum ${TOHUM}): ${DONEM} gunde ${BILDIRIM} bildirim, ${ACIK} acik, ` +
    `ilk 30 gunde ${BILDIRIMLER.filter((b) => b.gun < 30).length} bildirim`);
  console.log(`benzersiz ${say("benzersiz")}, yinelenen ${say("yinelenen")}, kapsam disi ` +
    `${say("kapsam disi")}: yuzde ${((bos / BILDIRIM) * 100).toFixed(0)}'i yeni acik degil`);
  const y = gen([18, 10, 11, 11, 10]);
  console.log("\n" + y(["sinif", "bildirim", "benzersiz", "yinelenen", "ort. yas"]));
  for (const s of SINIF) {
    const l = BILDIRIMLER.filter((b) => b.acik !== null && ACIKLAR[b.acik].sinif === s.ad);
    const be = l.filter((b) => b.tur === "benzersiz");
    console.log(y([s.ad, l.length, be.length, l.length - be.length,
      (be.reduce((a, b) => a + ACIKLAR[b.acik].yas, 0) / be.length).toFixed(0)]));
  }
  const z = gen([10, 9, 15, 12]);
  console.log("\n" + z(["kapasite", "zirve", "ort. bekleme", "son bakis"]));
  for (const hiz of [1, 2, 3, 5]) {
    const t = triaj(hiz);
    console.log(z([`${hiz}/gun`, t.zirve, t.bekleme.toFixed(1), t.son]));
  }
}
```

```
model (tohum 20260611): 180 gunde 340 bildirim, 120 acik, ilk 30 gunde 149 bildirim
benzersiz 91, yinelenen 190, kapsam disi 59: yuzde 73'i yeni acik degil

sinif               bildirim  benzersiz  yinelenen  ort. yas
yapilandirma             163         35        128       151
girdi dogrulama           44         20         24       120
yetki atlama              35         17         18       153
veri sizintisi            24         11         13       136
oturum yonetimi           15          8          7       108

kapasite      zirve   ort. bekleme   son bakis
1/gun           174          116.1         339
2/gun           104           31.2         177
3/gun            70           10.4         177
5/gun            49            2.3         177
```

Üç yüz kırk bildirimin doksan biri yeni bir açık taşıyor. Kalan 249 kalem — 190 yinelenen ve 59
kapsam dışı — kuyruğun yüzde 73'üdür. Bu oran kanalın kalitesizliğinden değil **yapısından**
gelir: kanal herkese açıktır, aynı açığı gören herkes bildirir ve kimin daha önce bildirdiği
dışarıdan görünmez.

Sınıf tablosu yığılmanın nerede olduğunu yazıyor. Yapılandırma sınıfı 163 bildirim üretir ve
bunların ancak 35'i yeni bir açıktır; oturum yönetimi sınıfında 15 bildirim, 8 benzersiz açık
vardır. **Bir bulgu sınıfının kanaldaki payı, o sınıfın kurumda kaç açık bıraktığını değil,
dışarıdan ne kadar kolay görüldüğünü ölçer.** Kuyruğun bileşimi kurumun açık dağılımının değil,
dış görünürlük dağılımının fotoğrafıdır.

Son sütun bu dersin ikinci yarısını hazırlıyor. Bildirilen açıkların ortalama yaşı 108 ile 153
gün arasındadır: bir açık bildirildiğinde çoktan aylardır oradadır. "Bu açık daha önce kullanıldı
mı" sorusu yüz günden uzun bir geçmişe bakmayı gerektirir; önceki derslerin saklama penceresi ise
45 ile 65 gün arasındaydı.

Kuyruk tablosu üçüncü sayıyı veriyor. Günde iki kalemlik ilk bakış kapasitesinde kuyruk 104
kaleme çıkar ve bir bildirim ortalama 31,2 gün bekler. Kapasite bire indiğinde son bildirime 339.
günde bakılır: dönem 180 gündür, yani kanal kendi dönemine yetişemez. Yığılmanın nedeni ortalama
hacim değildir; ilk 30 günde 149 bildirim gelir, dönem toplamının yüzde 44'ü ilk altıda birlik
dilimdedir. **Kanalın açılması bir yük eğrisi doğurur; kapasite ortalama gelişe göre seçildiğinde
zirvede tıkanır ve tıkanma tek seferlik değil kalıcıdır.**

#### Doğrulama, İstismar Sorusu ve Düzeltme Kuyruğu

```js
// dogrulama.mjs — benzersiz bildirimler dort kayit semasiyla kosturulur: dogrulama
// kayittan mi elle mi, istismar sorusu cevaplaniyor mu, duzeltme ne zaman. MODELDIR.
import { BILDIRIMLER, ACIKLAR, SINIF, triaj, say, gen, BILDIRIM } from "./bildirim.mjs";

const K1 = ["zaman", "iz", "aktor", "eylem", "sonuc", "yol", "yontem", "durum", "istemci_ip"];
const K2 = ["zaman", "tablo", "nesne", "islem"];
const EK = ["yetki_karari", "surum", "oturum", "once_deger"];
export const SEMA = [
  { ad: "taban", saklama: 65, kat: 1.00, ek: 0, kume: [K1, K2] },
  { ad: "+iz", saklama: 64, kat: 1.02, ek: 1, kume: [[...K1, ...K2]] },
  { ad: "+karar+surum", saklama: 62, kat: 1.04, ek: 3,
    kume: [[...K1, ...K2, ...EK.slice(0, 2)]] },
  { ad: "+oturum+deger", saklama: 45, kat: 1.45, ek: 5, kume: [[...K1, ...K2, ...EK]] },
];
export const KAPASITE = 2;   // duzeltme icin gunde ayrilan gun-is
const varMi = (sema, a) => sema.kume.some((c) => a.every((x) => c.includes(x)));

// Dogrulama kayittan 1 gun, kayitsiz sinifin elle yeniden uretim gunudur. Istismar
// sorusunda kayit `saklama` gun geriye uzanir; kuyrukta gecen `sure` pencereden duser.
export function kos(sema, hiz = 2) {
  triaj(hiz, true);
  const kalem = BILDIRIMLER.filter((b) => b.tur === "benzersiz").map((b) => {
    const a = ACIKLAR[b.acik], s = SINIF.find((x) => x.ad === a.sinif);
    const kayittan = varMi(sema, s.alan);
    const sure = b.bakis - b.gun + (kayittan ? 1 : s.elle);
    return { b, s, kayittan, sure, dogrulama: b.gun + sure,
      istismar: !kayittan ? "cevapsiz" : a.yas <= sema.saklama - sure ? "kesin" : "kismi" };
  }).sort((x, y) => x.dogrulama - y.dogrulama);

  // Duzeltme kuyrugu: gunde KAPASITE gun-is havuza eklenir, sirayi odulu yuksek alir.
  const bekleyen = [];
  let j = 0, havuz = 0;
  for (let g = kalem[0].dogrulama; j < kalem.length || bekleyen.length; g++) {
    while (j < kalem.length && kalem[j].dogrulama <= g) bekleyen.push(kalem[j++]);
    havuz = bekleyen.length ? havuz + KAPASITE : KAPASITE;
    bekleyen.sort((x, y) => y.s.odul - x.s.odul);
    while (bekleyen.length && havuz >= bekleyen[0].s.duzelt)
      { const k = bekleyen.shift(); havuz -= k.s.duzelt; k.duzeltme = g; }
  }
  const n = kalem.length, top = (f) => kalem.reduce((t, k) => t + f(k), 0);
  const sayi = (x) => kalem.filter((k) => k.istismar === x).length;
  return { n, kalem, kayittan: kalem.filter((k) => k.kayittan).length,
    dogrulamaGun: top((k) => k.sure) / n, toplamGun: top((k) => k.duzeltme - k.b.gun) / n,
    duzeltmeGun: top((k) => k.duzeltme - k.dogrulama) / n, odul: top((k) => k.s.odul),
    kesin: sayi("kesin"), kismi: sayi("kismi"), cevapsiz: sayi("cevapsiz") };
}

if (import.meta.url === `file://${process.argv[1]}`) {
  const y = gen([16, 9, 10, 12, 12, 8, 8, 10]);
  console.log(y(["sema", "saklama", "kayittan", "dogrulama", "duzeltme", "kesin", "kismi",
    "cevapsiz"]));
  const sonuc = SEMA.map((s) => {
    const o = kos(s);
    console.log(y([s.ad, `${s.saklama} gun`, `${o.kayittan}/${o.n}`,
      `${o.dogrulamaGun.toFixed(1)} gun`, `${o.duzeltmeGun.toFixed(1)} gun`,
      o.kesin, o.kismi, o.cevapsiz]));
    return o;
  });
  const [a, , c, d] = sonuc, h5 = SEMA.map((s) => kos(s, 5));
  const el = a.kalem.filter((k) => !k.kayittan), o = (l) => l.reduce((t, k) => t + k.s.odul, 0);
  console.log(`\nbildirimden duzeltmeye ${a.toplamGun.toFixed(1)} gunden ` +
    `${d.toplamGun.toFixed(1)} gune cikiyor; kesin cevap ${SEMA[2].ad} semasinda ` +
    `${c.kesin} ile en yuksek, ${SEMA[3].ad} semasinda ${d.kesin}`);
  console.log(`kapasite 2'den 5'e cikinca kesin cevap ${sonuc.map((x) => x.kesin).join("/")} ` +
    `yerine ${h5.map((x) => x.kesin).join("/")}: alan eklenmeden ` +
    `${h5[3].kesin - d.kesin} bildirim daha kesin cevap aliyor`);
  console.log(`elle dogrulanan ${el.length} bildirimin odulu ${o(el)} kurgu birim, ` +
    `kayittan dogrulanan ${a.n - el.length} bildirimin ${a.odul - o(el)}`);
}
```

```
sema              saklama  kayittan   dogrulama    duzeltme   kesin   kismi  cevapsiz
taban              65 gun     55/91    28.6 gun    57.1 gun      15      40        36
+iz                64 gun     66/91    27.6 gun    60.8 gun      18      48        25
+karar+surum       62 gun     83/91    26.3 gun    63.6 gun      20      63         8
+oturum+deger      45 gun     91/91    25.8 gun    64.2 gun      13      78         0

bildirimden duzeltmeye 85.7 gunden 89.9 gune cikiyor; kesin cevap +karar+surum semasinda 20 ile en yuksek, +oturum+deger semasinda 13
kapasite 2'den 5'e cikinca kesin cevap 15/18/20/13 yerine 18/21/24/24: alan eklenmeden 11 bildirim daha kesin cevap aliyor
elle dogrulanan 36 bildirimin odulu 1525 kurgu birim, kayittan dogrulanan 55 bildirimin 580
```

Doğrulama sütunu kayıt tasarımının zaferi gibi durur: kayıttan doğrulanan bildirim 55'ten 91'e
çıkar, ortalama doğrulama 28,6 günden 25,8 güne iner. Kazanç 2,8 gündür. Aynı şemalar önceki
derste müdahaleyi 4,17 kat kısaltmıştı; burada oran 1,11'dir, çünkü sürenin baskın terimi
doğrulama işi değil **kuyruk beklemesidir**. **Bir işin süresini kısaltan kayıt alanı, o iş bir
kuyruğun arkasındaysa toplam süreyi ancak kuyruğun bıraktığı kadar kısaltır.**

Düzeltme sütunu ters yöne gider: 57,1 günden 64,2 güne çıkar, bildirimden düzeltmeye geçen toplam
süre de 85,7'den 89,9 güne. Doğrulama hızlandıkça kalemler düzeltme kuyruğuna daha erken girer,
kuyruk kapasitesi ise sabittir; **kazanılan gün bir sonraki kuyruğa taşınır ve orada beklenir.**
Darboğaz kayıt tasarımı değil, günde iki gün-işlik düzeltme kapasitesidir.

Son üç sütun bu kursun ölçü birimini yazıyor. Cevapsız soru şema genişledikçe 36'dan sıfıra iner:
en geniş şemada 91 bildirimin hepsi için istismar sorusu **sorulabilir**. Ama kesin cevap 15'ten
20'ye çıktıktan sonra 13'e, taban şemanın da altına düşer. En geniş şema hiçbir soruyu cevapsız
bırakmaz ve en az kesin cevap verir.

Mekanizma UM26'dadır: kesin cevabın koşulu, açığın yaşının **saklama eksi geçen süre** kadar
pencereye sığmasıdır. En geniş şemada saklama 45, ortalama süre 25,8 gündür; geriye yaklaşık 19
günlük bir pencere kalır, oysa bildirilen açıkların ortalama yaşı 108 ile 153 gün arasındadır.
**Kuyrukta geçen her gün saklama penceresinden düşer.** Hacimle saklamayı takas eden tasarımın dış
bildirim akışındaki faturası budur: 5 ek alan, 1,45 kat günlük hacim ve 20 gün daha kısa saklama
karşılığında kesin cevap iki birim **azalır**.

Üçüncü çıktı satırı aynı sayıyı ikinci bir kolla oynatıyor. İlk bakış kapasitesi ikiden beşe
çıkarıldığında kesin cevap dizisi 15/18/20/13 yerine 18/21/24/24 olur; en geniş şemadaki bu artış
**hiçbir kayıt alanı eklenmeden, hiçbir hacim ödenmeden** kazanılır. **İlk bakış kapasitesi bir
hizmet düzeyi kararı gibi görünür; ölçüldüğünde bir kayıt kararı olduğu çıkar.**

Ödül tarafı bedelin son sütununu yazıyor. Taban şemada elle doğrulanan 36 bildirimin ödül toplamı
1 525 kurgu birim, kayıttan doğrulanan 55 bildiriminki 580 birimdir. Ödülü yüksek sınıflar kayıttan
doğrulanamayanlardır; ucuz ve çok bildirilen yapılandırma sınıfı bir günde kapanır. **Doğrulama
yükü ile ödül bütçesi aynı yöne gider: en pahalı bulgular en yavaş doğrulananlardır.** Ödül almayan
249 kalem ise ilk bakış kapasitesinin yüzde 73'ünü tüketir; ödül programının asıl maliyeti ödenen
birimde değil, ödenmeyen kalemlerin tuttuğu sıradadır.

#### Özet

- Dış bildirim kanalı bir tespit hattı değil bir kuyruktur: modelde 340 bildirimin 91'i yeni bir
  açık taşır, 190'ı yinelenen, 59'u kapsam dışıdır.
- Kuyruğun bileşimi kurumun açık dağılımını değil dış görünürlük dağılımını yansıtır: yapılandırma
  sınıfı 163 bildirimle kanalın yarısını doldurur, arkasında yalnız 35 açık vardır.
- Kapasite ortalama gelişe göre seçilemez: ilk 30 günde 149 bildirim gelir, günde iki kalemlik
  kapasitede kuyruk 104 kaleme çıkar ve ortalama bekleme 31,2 gün olur.
- Kayıt alanı eklemek doğrulamayı 28,6 günden 25,8 güne indirir, ama bildirimden düzeltmeye geçen
  süre 85,7 günden 89,9 güne çıkar: kazanılan gün sabit kapasiteli düzeltme kuyruğuna taşınır.
- Kuyrukta geçen gün saklama penceresinden düşer; en geniş şema cevapsız soruyu sıfıra indirirken
  kesin cevabı 20'den 13'e, taban şemanın 15'inin de altına düşürür.
- Bedel iki kolda ölçülür: 5 ek alan, 1,45 kat hacim ve 20 gün kısa saklama kesin cevabı
  azaltırken, ilk bakış kapasitesinin ikiden beşe çıkması aynı sayıyı alan eklemeden 24'e taşır.

#### Sonraki Adım

Bu konu boyunca kayıt tasarlandı, uyarı eşiği seçildi, bir ihlal müdahale edildi, kısa ömürlü iş
yüklerinin izi ölçüldü ve dış bildirim akışı kuruldu. Her ders aynı soruyu sordu: olaydan sonra
sorulacak soruların kaçı cevaplanabiliyor ve cevaplanabilir kılmak neye mal oluyor. Geriye bir
soru kalıyor ve onu kurumun kendisi sormuyor: bütün bu pratiğin **yapıldığını** dışarıdan bakan
birine ne gösterecek. Sonraki konu bunu ölçer — bir denetim kontrol maddesinin mühendislik
karşılığı kaç pratiğe düşüyor, kaçının kanıtı hatta otomatik üretiliyor ve kaçı olaydan sonra elle
toplanıyor.

## Uygulama Uyumluluğu

Denetim maddesinin mühendislik karşılığının sayılması: yirmi altı kontrolün kaçının ekipte gerçekten koşan bir pratiğe düştüğü ve kaçının hiçbir pratiğe düşmediği, bir kontrolün cevabının sorgudan mı belgeden mi kişi beyanından mı geldiği, kanıt üretiminin hatta yerleştirilmesiyle elle toplanan kalemin kaça indiği ve otomatik kanıtın hacim, saklama ve kişisel veri olarak doğurduğu bedel, ortalama düzeltme süresi ile açık yaşının aynı veriden ters yönde okunması ve ölçütün hesaplanabilmesi için kayıtta bulunması gereken zaman damgasının kaç kalemde eksik olduğu.

### Kontrollerin Mühendislik Karşılığı

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/kontrolun-muhendislik-karsiligi

Yirmi altı denetim maddesi bir uygulama ekibinin on sekiz pratiğiyle eşleştirilir: 25 bağın ardından 17 kontrolün karşılığı çıkar, 9 kontrolün hiçbir mühendislik karşılığı yoktur ve bunların beşi tek bir uyumluluk yapısında toplanır. Karşılığı olan kontrol ortalama 1,47 pratiğe düşer, 10 kontrol tek pratiğe dayanır, 2 pratik hiçbir kontrole düşmez ve 26 sorunun yalnız 11'i kayıttan sorgulanarak cevaplanır.

Önceki konu olayın kendisini ölçtü: kayıt tasarlandı, uygulamaya özgü tespit senaryoları
koşturuldu, müdahale adımlarının hangi kayda ihtiyaç duyduğu sayıldı ve dış bildirim akışı süreyle
ölçüldü. Bütün bu pratiğin ortak bir açığı kaldı — yapıldığını kuruma dışarıdan bakan birine
gösterecek kanıt, dönem sonunda elle toplanıyor. Bu konunun dört dersi o boşluğu ölçer.

İlk adım eşlemenin kendisidir. Yönetişim, Risk ve Uyumluluk kursunda kontrol ile gereksinim
arasındaki matris koşturulmuş, kanıtsız kalan gereksinim ve birden çok gereksinimi karşılayan
kontrol sayılmıştı; o ölçüm burada girdidir ve tekrarlanmaz. Buradaki matrisin uçları farklıdır:
bir ucunda denetim maddesi, öteki ucunda **bir uygulama ekibinin gerçekten koşan işi** vardır.
Sorulan şey de farklıdır — bir denetim maddesi ekibin hangi işine düşüyor, kaç işine düşüyor ve
**kaç madde hiçbir işine düşmüyor.**

#### Kontrol Kümesi ve Pratik Kümesi

**UY1.** Kontrol kümesi 26 maddedir ve dört uyumluluk yapısından toplanmıştır: işlev tabanlı
çerçeve, belgelendirilebilir yönetim sistemi standardı, denetim kontrol kümesi ve sektörel
uyumluluk gereksinimi. Küme **kurgudur**; hiçbir yapının, düzenlemenin ya da kurumun adı geçmez,
maddeler yalnız **sordukları şeyle** yazılır. **UY2.** Pratik kümesi 18 kalemdir ve kurgu bölgesel
ölçüm ağının abone portalı ekibinin koşan işlerinden oluşur. **UY3.** Her pratiğin bir **yeri**
vardır — hat, depo, koşum ya da elle — ve bir **izi**: makinece okunabilir kayıt ya da belge.
**UY4.** Eşleme bir **iddiadır**: bir kontrolün bir pratiğe düşmesi o pratiğin kontrolü yürüttüğünü
söyler, kanıt ürettiğini söylemez; kanıt üçüncü bölümde ayrılır. **UY5.** Matris yalnız **ekibin
kendi** yürüttüğü işi görür; platformun ya da başka bir ekibin yaptığı iş burada görünmez ve bu,
karşılığı olmayan kontrol sayısını olduğundan yüksek gösterir.

```js
// uyum/kume.mjs — denetim kontrolleri ve ekip pratikleri MODELDIR: kurgu bolgesel olcum agi.
// Kontroller dort uyumluluk yapisindan gelir, pratikler bir uygulama ekibinin isleridir.
export const ayir = (s) => s.trim().split("\n").map((l) => l.trim().split("|"));
export const gen = (B) => (...h) => h.map((v, j) =>
  (j ? String(v).padStart(B[j]) : String(v).padEnd(B[0]))).join("");

// kod | uyumluluk yapisi | kontrolun sordugu sey
export const KONTROL = ayir(`
  IC-01|islev-cerceve|bilesen envanteri guncel tutulur
  IC-02|islev-cerceve|erisim en az ayricalikla verilir
  IC-03|islev-cerceve|tasinan ve duran veri sifrelenir
  IC-04|islev-cerceve|guvenlik olaylari merkezi toplanir
  IC-05|islev-cerceve|anormal davranis uyari uretir
  IC-06|islev-cerceve|olay mudahale rolleri tanimlidir
  IC-07|islev-cerceve|kurtarma hedefi sinanir
  IC-08|islev-cerceve|tedarikci bileseni degerlendirilir
  YS-01|yonetim-sistemi|kapsam bildirimi guncellenir
  YS-02|yonetim-sistemi|uygulanabilirlik bildirimi gerekcelidir
  YS-03|yonetim-sistemi|ic denetim donemsel kosar
  YS-04|yonetim-sistemi|duzeltici eylem kapatilir
  YS-05|yonetim-sistemi|yonetim gozden gecirmesi kayitlidir
  YS-06|yonetim-sistemi|personel yetkinligi kayitlidir
  DK-01|denetim-kumesi|degisiklik onaydan gecer
  DK-02|denetim-kumesi|uretim erisimi ikinci gozle verilir
  DK-03|denetim-kumesi|yedegin geri yuklenmesi sinanir
  DK-04|denetim-kumesi|ayricalikli erisim gozden gecirilir
  DK-05|denetim-kumesi|kod degisikligi ikinci goz gorur
  DK-06|denetim-kumesi|acik tanimli sure icinde kapatilir
  DK-07|denetim-kumesi|sistem saatleri esitlenir
  SG-01|sektorel|odeme verisi ayri bolutte islenir
  SG-02|sektorel|kisisel veri kalemi siniflandirilir
  SG-03|sektorel|veri saklama suresi uygulanir
  SG-04|sektorel|veri sahibi talebi izlenebilir
  SG-05|sektorel|ucuncu tarafa aktarim kaydedilir
`).map(([kod, yapi, metin]) => ({ kod, yapi, metin }));

// kod | pratigin kostugu yer | biraktigi iz | pratigin adi
export const PRATIK = Object.fromEntries(ayir(`
  P01|hat|makine|bagimlilik bilesen analizi
  P02|hat|makine|statik cozumleme
  P03|hat|makine|yapi ciktisi imzalama
  P04|hat|makine|koken bilgisi uretimi
  P05|hat|makine|imaj taramasi
  P06|depo|makine|birlestirme isteginde ikinci goz
  P07|depo|makine|dal koruma kurali
  P08|kosum|makine|sir deposundan kisa omurlu kimlik
  P09|kosum|makine|anahtar dondurme isi
  P10|kosum|makine|ag bolutleme kurali
  P11|kosum|makine|kabul denetleyicisi
  P12|kosum|makine|uygulama denetim kaydi
  P13|kosum|makine|uyari kurali kumesi
  P14|elle|belge|yedek geri yukleme tatbikati
  P15|elle|belge|erisim gozden gecirme toplantisi
  P16|elle|belge|olay mudahale tatbikati
  P17|elle|belge|veri siniflandirma calismasi
  P18|elle|belge|yonetim gozden gecirme toplantisi
`).map(([kod, yer, iz, ad]) => [kod, { kod, yer, iz, ad }]));

// kontrol | onu gercekten yuruten pratikler; bos hucre: muhendislik karsiligi yok
export const ESLEM = Object.fromEntries(ayir(`
  IC-01|P01,P04
  IC-02|P08,P15
  IC-03|
  IC-04|P12
  IC-05|P13
  IC-06|P16
  IC-07|P14
  IC-08|P01,P05
  YS-01|
  YS-02|
  YS-03|
  YS-04|
  YS-05|P18
  YS-06|
  DK-01|P06,P07
  DK-02|P08
  DK-03|P14
  DK-04|P15
  DK-05|P06,P07
  DK-06|P01,P02,P05
  DK-07|
  SG-01|P10,P11
  SG-02|P17
  SG-03|
  SG-04|P12
  SG-05|
`).map(([k, p]) => [k, p ? p.split(",") : []]));

export const YAPI = ["islev-cerceve", "yonetim-sistemi", "denetim-kumesi", "sektorel"];

if (import.meta.url === `file://${process.argv[1]}`) {
  const pratik = Object.values(PRATIK);
  const bag = Object.values(ESLEM).reduce((t, p) => t + p.length, 0);
  console.log(`model: ${KONTROL.length} kontrol, ${pratik.length} pratik, ${bag} bag`);
  const y = gen([20, 10]);
  console.log("\n" + y("uyumluluk yapisi", "kontrol"));
  for (const u of YAPI) console.log(y(u, KONTROL.filter((c) => c.yapi === u).length));
  const z = gen([20, 10, 16]);
  console.log("\n" + z("pratigin yeri", "pratik", "biraktigi iz"));
  for (const yer of ["hat", "depo", "kosum", "elle"]) {
    const p = pratik.filter((x) => x.yer === yer);
    console.log(z(yer, p.length, p[0].iz));
  }
}
```

```
model: 26 kontrol, 18 pratik, 25 bag

uyumluluk yapisi       kontrol
islev-cerceve                8
yonetim-sistemi              6
denetim-kumesi               7
sektorel                     5

pratigin yeri           pratik    biraktigi iz
hat                          5          makine
depo                         2          makine
kosum                        6          makine
elle                         5           belge
```

Model iki listeden ve aralarındaki 25 bağdan oluşuyor. Kontrol tarafı dengeli dağılmış: en büyük
yapı sekiz, en küçüğü beş madde getiriyor. Pratik tarafındaki dağılım ise dengeli değil ve asıl
bilgi orada: on sekiz pratiğin **on üçü** hatta, depoda ya da koşumda çalışıyor ve makinece
okunabilir bir iz bırakıyor; **beşi** bir toplantı ya da tatbikat olarak yürüyor ve geriye yalnız
bir belge bırakıyor. Bu iki iz türü aynı matriste eşit görünür, denetimde eşit değildir.

#### Matrisi Koşturmak

Eşleme tablosundaki boş hücre bu dersin ölçü birimidir: bir kontrolün karşısında hiçbir pratik
yoksa o madde ekibin hiçbir işine düşmüyor demektir. İkinci sayı bunun tersidir — bir madde kaç
işe düşüyor.

Matris iki yönde okunabilir ve iki okuma iki ayrı soruya karşılık gelir. Kontrolden pratiğe
bakıldığında sorulan şey **kapsamadır**: madde yürüyor mu, yürüyorsa kaç işle. Pratikten kontrole
bakıldığında sorulan şey **kaldıraçtır**: bu iş kaç maddeye birden yetiyor. İki okuma aynı 25 bağ
üzerinde koşar ve farklı kalemleri öne çıkarır; bu yüzden ikisi de yazılır. Üçüncü bir okuma da
vardır ve çoğunlukla atlanır: hiçbir kontrole düşmeyen pratik. O sütun kontrol kümesinin
görmediği işi sayar.

```js
// uyum/matris.mjs — kontrol-pratik matrisi kosturulur, karsiligi olmayan kontrol sayilir.
import { KONTROL, PRATIK, ESLEM, YAPI, gen } from "./kume.mjs";

const y = gen([18, 9, 15, 15, 16]);
console.log(y("uyumluluk yapisi", "kontrol", "karsiligi var", "karsiligi yok", "pratik/kontrol"));
const oran = (k) => {
  const v = k.filter((c) => ESLEM[c.kod].length > 0);
  const b = v.reduce((t, c) => t + ESLEM[c.kod].length, 0);
  return [v.length, k.length - v.length, v.length ? (b / v.length).toFixed(2) : "-"];
};
for (const u of YAPI) {
  const k = KONTROL.filter((c) => c.yapi === u);
  console.log(y(u, k.length, ...oran(k)));
}
console.log(y("TOPLAM", KONTROL.length, ...oran(KONTROL)));

const yok = KONTROL.filter((c) => ESLEM[c.kod].length === 0);
console.log(`\nmuhendislik karsiligi olmayan ${yok.length} kontrol:`);
for (const c of yok) console.log(`  ${c.kod}  ${c.metin}`);

const kacKontrol = (p) => Object.values(ESLEM).filter((l) => l.includes(p)).length;
const sirali = Object.values(PRATIK).map((p) => ({ ...p, n: kacKontrol(p.kod) }))
  .sort((a, b) => b.n - a.n);
const tek = KONTROL.filter((c) => ESLEM[c.kod].length === 1).length;
const enCok = KONTROL.filter((c) => ESLEM[c.kod].length > 2).map((c) => c.kod);
console.log(`\nbirden cok kontrole dusen pratik ${sirali.filter((p) => p.n > 1).length}: ` +
  sirali.filter((p) => p.n > 1).map((p) => `${p.kod} (${p.n})`).join(", "));
console.log(`tek pratige dayanan kontrol ${tek}; ikiden cok pratige dusen ${enCok.join(", ")}`);
console.log(`hicbir kontrole dusmeyen pratik ${sirali.filter((p) => p.n === 0).length}: ` +
  sirali.filter((p) => p.n === 0).map((p) => `${p.kod} ${p.ad}`).join(", "));
```

```
uyumluluk yapisi    kontrol  karsiligi var  karsiligi yok  pratik/kontrol
islev-cerceve             8              7              1            1.43
yonetim-sistemi           6              1              5            1.00
denetim-kumesi            7              6              1            1.67
sektorel                  5              3              2            1.33
TOPLAM                   26             17              9            1.47

muhendislik karsiligi olmayan 9 kontrol:
  IC-03  tasinan ve duran veri sifrelenir
  YS-01  kapsam bildirimi guncellenir
  YS-02  uygulanabilirlik bildirimi gerekcelidir
  YS-03  ic denetim donemsel kosar
  YS-04  duzeltici eylem kapatilir
  YS-06  personel yetkinligi kayitlidir
  DK-07  sistem saatleri esitlenir
  SG-03  veri saklama suresi uygulanir
  SG-05  ucuncu tarafa aktarim kaydedilir

birden cok kontrole dusen pratik 8: P01 (3), P05 (2), P06 (2), P07 (2), P08 (2), P12 (2), P14 (2), P15 (2)
tek pratige dayanan kontrol 10; ikiden cok pratige dusen DK-06
hicbir kontrole dusmeyen pratik 2: P03 yapi ciktisi imzalama, P09 anahtar dondurme isi
```

Yirmi altı kontrolün **on yedisinin** karşılığı vardır, **dokuzunun** yoktur. Dokuz sayısı tek
başına bir kusur değil; kusur olup olmadığı **nerede toplandığına** bakılarak anlaşılır. Beşi tek
bir uyumluluk yapısında, belgelendirilebilir yönetim sistemi standardında toplanmıştır — kapsam
bildirimi, uygulanabilirlik bildirimi, iç denetim, düzeltici eylem ve personel yetkinliği. Bu
maddelerin hiçbiri bir uygulama ekibinin işi değildir ve olmaması da bir eksiklik sayılmaz;
karşılığı ekipte değil, kurumun yönetim katmanındadır. Matris bunu söylemez, yalnız boş hücre
gösterir. **Boş hücrenin okunması, kimin işi olduğunun ayrı yazılmasını gerektirir.**

Kalan dördü bambaşka bir sınıftandır. IC-03, DK-07, SG-03 ve SG-05 doğrudan bu uygulamanın
çalıştığı yere aittir: veri şifreleme, saat eşitleme, saklama süresi ve üçüncü tarafa aktarım.
Dördü de ekibin sorumluluğundadır ve dördünün de karşılığında hiçbir pratik koşmuyor. DK-07 bu
dördü içinde en sinsi olanıdır: sistem saatleri eşitlenmiyorsa önceki konunun ürettiği bütün
kayıtlar birbiriyle sıralanamaz — yani kontrolün karşılığının yokluğu, karşılığı olan başka
kontrollerin kanıtını da bozar.

Kontrol başına düşen pratik sayısı **1,47**'dir ve on kontrol tek bir pratiğe dayanır. Tek pratiğe
dayanan bir kontrol, o pratik durduğu anda karşılıksız kalır; matris bunu ancak yeniden
koşturulduğunda gösterir. Ters yönde okunduğunda sekiz pratik birden çok kontrolü karşılıyor —
bağımlılık bileşen analizi tek başına üç maddeye yetiyor. Son satır ise matrisin en az konuşulan
kutusudur: iki pratik hiçbir kontrole düşmüyor. Yapı çıktısı imzalama ve anahtar döndürme işi
ekipte koşuyor, kaynak harcıyor ve bu kontrol kümesinde karşılığı yok. **Bu, pratiğin gereksiz
olduğunu göstermez; kontrol kümesinin onu sormadığını gösterir** — kontrol kümesi bir mühendislik
önceliği listesi değildir.

#### Cevabı Ne Üretiyor

**UY6.** Bir kontrolün cevabı üç kaynaktan gelebilir: makinece okunabilir kayıttan **sorgu** ile,
dönem sonunda toplanan belgeden **elle derleme** ile, ya da hiçbir kayda dayanmayan **kişi beyanı**
ile. Kaynağın ikinci bir özelliği vardır: sorgu dönemin tamamını kapsar, belge yalnızca üretildiği
günü kapsar.

```js
// uyum/iz.mjs — pratigin biraktigi ize bakilir: kontrolun sorusu neyle cevaplaniyor.
import { KONTROL, PRATIK, ESLEM, YAPI, gen } from "./kume.mjs";

// Uc obek: pratigi makine-okunur iz birakiyorsa "makine izli"; yalniz toplanti ya da
// tatbikat belgesi birakiyorsa "yalniz belge"; hic pratigi yoksa "izsiz".
const obek = (c) => {
  const p = ESLEM[c.kod].map((x) => PRATIK[x]);
  return !p.length ? "izsiz" : p.some((x) => x.iz === "makine") ? "makine izli" : "yalniz belge";
};
const OBEK = ["makine izli", "yalniz belge", "izsiz"];
const y = gen([18, 14, 14, 9]);
console.log(y("uyumluluk yapisi", ...OBEK));
for (const u of YAPI) {
  const k = KONTROL.filter((c) => c.yapi === u);
  console.log(y(u, ...OBEK.map((o) => k.filter((c) => obek(c) === o).length)));
}
console.log(y("TOPLAM", ...OBEK.map((o) => KONTROL.filter((c) => obek(c) === o).length)));

// Cevabin kapsami: makine iz donem boyunca yazilir, belge yalnizca uretildigi gune aittir.
const KAPSAM = { "makine izli": "donem boyu", "yalniz belge": "tek gun", izsiz: "yok" };
const KAYNAK = { "makine izli": "sorgu", "yalniz belge": "elle derleme", izsiz: "kisi beyani" };
const z = gen([16, 10, 18, 16]);
console.log("\n" + z("obek", "kontrol", "cevabin kapsami", "cevabi ureten"));
for (const o of OBEK) {
  const k = KONTROL.filter((c) => obek(c) === o);
  console.log(z(o, k.length, KAPSAM[o], KAYNAK[o]));
}
const belge = KONTROL.filter((c) => obek(c) === "yalniz belge");
console.log(`\nyalniz belge obegi: ${belge.map((c) => c.kod).join(", ")}`);
const makine = KONTROL.filter((c) => obek(c) === "makine izli").length;
console.log(`26 denetim sorusunun ${makine}'i kayittan sorgulanarak, ` +
  `${belge.length}'si donem sonunda elle derlenerek cevaplaniyor; ` +
  `${KONTROL.length - makine - belge.length}'u hic cevaplanmiyor`);
```

```
uyumluluk yapisi     makine izli  yalniz belge    izsiz
islev-cerceve                  5             2        1
yonetim-sistemi                0             1        5
denetim-kumesi                 4             2        1
sektorel                       2             1        2
TOPLAM                        11             6        9

obek               kontrol   cevabin kapsami   cevabi ureten
makine izli             11        donem boyu           sorgu
yalniz belge             6           tek gun    elle derleme
izsiz                    9               yok     kisi beyani

yalniz belge obegi: IC-06, IC-07, YS-05, DK-03, DK-04, SG-02
26 denetim sorusunun 11'i kayittan sorgulanarak, 6'si donem sonunda elle derlenerek cevaplaniyor; 9'u hic cevaplanmiyor
```

Matrisin doluluk oranı yüzde 65'ti; cevabın kaynağına bakıldığında sayı **11/26**'ya, yüzde 42'ye
iner. Aradaki altı kontrol matriste dolu görünür, denetimde bir belgeyle karşılanır ve o belge
**tek bir günü** anlatır. Yedek geri yükleme tatbikatı bir gün koşmuştur, erişim gözden geçirme
toplantısı bir gün yapılmıştır, veri sınıflandırma çalışması bir kez bitirilmiştir. Kontrolün
sorusu ise dönemin tamamı hakkındadır: ayrıcalıklı erişim **dönem boyunca** gözden geçirildi mi.
Tek günlük bir belge bu soruyu tam olarak cevaplamaz; onu bir örnekleme çevirir.

Üç obek, üç ayrı iş türüne karşılık gelir. İzsiz dokuz kontrol için yapılacak iş **pratik
kurmaktır** — dördü ekibin kendi alanında, beşi başka bir katmanda. Yalnız belgeli altı kontrol için
yapılacak iş pratik kurmak değildir; pratik zaten koşuyor, ondan **makinece okunabilir iz
çıkarmaktır**. Makine izli on bir kontrol için ise yapılacak iş yalnızca izi denetimin sorduğu
biçimde derlemektir. Bu üç iş birbirinden çok farklı bedeller taşır ve bir uyumluluk çalışmasını
"yüzde 65 hazır" diye özetleyen bir tablo üçünü de aynı hücreye yazar.

#### Özet

- Yirmi altı denetim maddesi ile bir uygulama ekibinin on sekiz pratiği arasında 25 bağ vardır;
  17 kontrolün mühendislik karşılığı çıkar, 9'unun hiç çıkmaz.
- Karşılığı olmayan dokuzun beşi tek bir uyumluluk yapısında toplanır ve karşılığı ekipte değil
  kurumun yönetim katmanındadır; kalan dördü doğrudan ekibin alanındadır. Boş hücreyi okumak,
  kimin işi olduğunun ayrı yazılmasını gerektirir.
- Karşılığı olan kontrol ortalama 1,47 pratiğe düşer ve 10 kontrol tek bir pratiğe dayanır; sekiz
  pratik birden çok kontrolü karşılar, en kaldıraçlısı üç maddeye yeter.
- İki pratik hiçbir kontrole düşmez. Bu, pratiğin gereksiz olduğunu değil, kontrol kümesinin bir
  mühendislik önceliği listesi olmadığını gösterir.
- Cevabın kaynağına bakıldığında oran yüzde 65'ten yüzde 42'ye iner: 11 kontrol kayıttan sorguyla,
  6'sı tek günü anlatan bir belgeyle cevaplanır, 9'u hiç cevaplanmaz.

#### Sonraki Adım

Matris koştu ve üç ayrı iş türü ayrıldı. Bunlardan ikisi bu dersin dışında kalıyor: izsiz
kontroller için pratik kurmak bir mühendislik planı işidir, karşılığı başka katmanda olanlar ise
ekibin listesinde bile değildir. Geriye ölçülebilir olan kalıyor — **altı belgeli kontrol** ve
zaten makine izi bırakan **on bir kontrol**.

Sonraki ders bu on yedi kalemi kanıt üretimi ekseninde yeniden ele alır ve tek bir sayıyı izler:
dönem sonunda elle toplanan kalem kaça iniyor. Kanıtın hatta üretilmesi elle derlemeyi bitirir mi,
hangi kalem hiçbir koşulda otomatikleşmez ve otomatik üretilen kanıt kaç kat hacim, kaç kişisel
veri kalemi ve hangi saklama kısıtını beraberinde getirir?

### Kanıt Otomasyonu

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/kanit-otomasyonu

Yirmi dört denetim kanıtı kalemi hatta yerleştirilir: elle dokunulan kalem 24'ten 9'a, yıllık derleme yükü 213 saatten 96,2 saate iner, 170 saatlik kurulum 1,46 yılda karşılanır ve altı kalem hiçbir koşulda otomatikleşmez. Bedel karşı sütunda çıkar: dönem başına kanıt kaydı 24'ten 72.401'e, 3.017 kata yükselir, incelenen oran yüzde 100'den yüzde 0,63'e düşer ve kişisel veri türü taşıyan altı kalem 90 günlük saklama penceresi yüzünden dönemin yalnız yüzde 24,7'sini cevaplar.

Önceki ders yirmi altı denetim maddesini ekibin on sekiz pratiğiyle eşleştirdi ve üç iş türü
ayırdı. Bunlardan ikisi ölçülemedi: dokuz kontrolün karşılığında hiçbir pratik yok, beşinin
karşılığı da başka bir katmanda. Geriye ölçülebilir olan on yedi kontrol kaldı — on biri makinece
okunabilir iz bırakıyor, altısı yalnız bir belge bırakıyor.

Bu ders o on yedi kontrolün kanıtını izler. Sorulan şey pratiğin var olup olmadığı değil,
**kanıtın nerede üretildiğidir.** Bir pratiğin koşması ile o pratiğin koştuğunun kanıtlanabilmesi
iki ayrı iştir ve ikincisi çoğunlukla dönem sonunda, elle yapılır. Ölçü birimi de buradan çıkar:
**elle dokunulan kalem sayısı** ve o kalemlerin yıllık derleme yükü.

#### Kanıt Kalemi Kümesi

**UY7.** Kanıt kalemi kümesi 24'tür ve önceki dersin karşılığı çıkan 17 kontrolüne bağlanır;
küme kurgu bölgesel ölçüm ağına aittir ve **modeldir**. **UY8.** Her kalemin bir **türü** vardır:
**iz** bir sistemde kendiliğinden oluşan kayıttır, **karar** bir kişinin gerekçesidir, **toplantı**
bir tatbikat ya da toplantı tutanağıdır. **UY9.** Elle derlenen kanıt derleme günü üretilir ve
hangi aralığı kapsadığı kaydın üstünde yazmaz; hatta üretilen kanıt bir dönem damgası taşır — bu
ayrım modelin varsayımıdır. **UY10.** Dakikalar dönem başına **veri olarak** verilmiştir,
ölçülmemiştir; derleme yılda üç kez yapılır ve bu da kurgudur.

```js
// kanit/kalem.mjs — denetim kaniti kalemleri MODELDIR: kurgu bolgesel olcum agi, bir donem.
// Kalemler onceki dersin karsiligi cikan 17 kontroluna baglanir; sayilar kurgudur.
export const gen = (B) => (...h) => h.map((v, j) =>
  (j ? String(v).padStart(B[j]) : String(v).padEnd(B[0]))).join("");

// kod|kontrol|tur|kaynak|elle dakika|donemde uretilen kayit|kisisel veri
export const KALEM = `
  K01|IC-01|iz|hat|120|312|yok|bagimlilik envanteri
  K02|IC-01|iz|hat|90|312|yok|koken bilgisi
  K03|IC-02|iz|kosum|150|8640|var|kisa omurlu kimlik verilisi
  K04|IC-02|karar|kosum|240|24|var|erisim gozden gecirme karari
  K05|IC-04|iz|kosum|180|54000|var|uygulama denetim kaydi
  K06|IC-05|iz|kosum|100|960|yok|uyari kurali tetiklenmesi
  K07|IC-06|toplanti|elle|300|2|yok|olay mudahale tatbikat raporu
  K08|IC-06|karar|elle|120|6|yok|rol atama karari
  K09|IC-07|toplanti|elle|360|2|yok|kurtarma hedefi olcum raporu
  K10|IC-08|iz|hat|110|312|yok|imaj tarama raporu
  K11|YS-05|toplanti|elle|180|4|yok|yonetim gozden gecirme tutanagi
  K12|DK-01|iz|depo|130|486|yok|degisiklik onay kaydi
  K13|DK-01|karar|depo|90|18|yok|acil degisiklik gerekcesi
  K14|DK-02|iz|kosum|140|420|var|uretim erisimi verilisi
  K15|DK-03|toplanti|elle|300|2|yok|geri yukleme tatbikat raporu
  K16|DK-04|karar|kosum|280|24|var|ayricalikli erisim gozden gecirmesi
  K17|DK-05|iz|depo|120|486|yok|kod incelemesi onayi
  K18|DK-05|iz|depo|80|486|yok|dal koruma kural durumu
  K19|DK-06|iz|hat|160|312|yok|acik tarama sonucu
  K20|DK-06|iz|hat|140|312|yok|statik cozumleme sonucu
  K21|SG-01|iz|kosum|150|1440|yok|bolut kurali durumu
  K22|SG-01|iz|kosum|130|1440|yok|kabul denetleyicisi red kaydi
  K23|SG-02|karar|elle|420|1|var|veri siniflandirma tablosu
  K24|SG-04|iz|kosum|170|2400|var|veri sahibi talebi izi
`.trim().split("\n").map((l) => {
  const [kod, kontrol, tur, kaynak, dk, kayit, kisisel, ad] = l.trim().split("|");
  return { kod, kontrol, tur, kaynak, dk: +dk, kayit: +kayit, kisisel, ad };
});

export const TUR = ["iz", "karar", "toplanti"];
export const DERLEME = 3;                 // yilda uc kez kanit derlemesi (kurgu)
export const KURULUM = { hat: 6, depo: 8, kosum: 12, elle: 0 };   // kalem basina kisi-saat

if (import.meta.url === `file://${process.argv[1]}`) {
  const y = gen([12, 8, 10, 12, 14, 16]);
  console.log(y("kalem turu", "kalem", "sistemde", "elle", "donem dakika", "donem kaydi"));
  for (const t of TUR) {
    const k = KALEM.filter((x) => x.tur === t);
    console.log(y(t, k.length, k.filter((x) => x.kaynak !== "elle").length,
      k.filter((x) => x.kaynak === "elle").length,
      k.reduce((a, x) => a + x.dk, 0), k.reduce((a, x) => a + x.kayit, 0)));
  }
  const dk = KALEM.reduce((a, x) => a + x.dk, 0);
  console.log(y("TOPLAM", KALEM.length, KALEM.filter((x) => x.kaynak !== "elle").length,
    KALEM.filter((x) => x.kaynak === "elle").length, dk,
    KALEM.reduce((a, x) => a + x.kayit, 0)));
  console.log(`\nbaslangic durumu: ${KALEM.length} kalemin ${KALEM.length}'u elle derleniyor`);
  console.log(`derleme basina ${(dk / 60).toFixed(1)} saat, yilda ${DERLEME} derleme -> ` +
    `${(DERLEME * dk / 60).toFixed(1)} saat`);
  console.log(`kisisel veri turu tasiyan kalem ` +
    `${KALEM.filter((x) => x.kisisel === "var").length}/${KALEM.length}`);
}
```

```
kalem turu     kalem  sistemde        elle  donem dakika     donem kaydi
iz                15        15           0          1970           72318
karar              5         3           2          1150              73
toplanti           4         0           4          1140              10
TOPLAM            24        18           6          4260           72401

baslangic durumu: 24 kalemin 24'u elle derleniyor
derleme basina 71.0 saat, yilda 3 derleme -> 213.0 saat
kisisel veri turu tasiyan kalem 7/24
```

Tablonun ikinci ve üçüncü sütunu bu dersin asıl gerilimini kuruyor. Yirmi dört kalemin **on
sekizi** zaten bir sistemde oluşuyor — hatta, depoda ya da koşumda. Buna karşın başlangıç
durumunda **yirmi dördünün de** kanıtı elle derleniyor. Kayıt sistemde vardır ve dönem sonunda bir
kişi onu dışa aktarır, bir dizine koyar, bir tabloya işler. Aradaki fark bir mühendislik açığı
değil, bir bağlantı açığıdır: kaydın var olması, denetimin sorduğu biçimde durduğu anlamına gelmez.

Kalem sayısının kontrol sayısından fazla olması da bir bilgidir: on yedi kontrol yirmi dört kalem
istiyor. Bazı maddeler tek kalemle karşılanmaz — kod değişikliğinin ikinci gözden geçtiğini
göstermek hem inceleme onayını hem dal koruma kuralının durumunu ister, çünkü ilki olayın
gerçekleştiğini, ikincisi gerçekleşmemesinin engellendiğini söyler. Kanıt kalemi sayısı kontrol
sayısıyla değil, **kontrolün sorusunun kaç parçadan oluştuğuyla** belirlenir.

Üçüncü satır bunun sınırını da veriyor. Dört toplantı kaleminin hiçbiri bir sistemde oluşmuyor ve
bu, araç eksikliğinden değil, kalemin **doğasından** kaynaklanıyor: bir tatbikatın sonucu bir kişi
tarafından yazılır. Dakika sütunu ise dağılımın dengesiz olduğunu söylüyor — dört toplantı kalemi
1.140 dakika, yani toplam yükün dörtte birinden fazlası; oysa kalem sayısının tam altıda biri.

#### Üretimi Hatta Yerleştirmek

**UY11.** Karar türü bir kalemin **kaydı** otomatikleşir — kararın verildiği, veren kişi ve zaman
damgası bir sistemden okunur; **gerekçe metni** elle kalır. Kalan elle iş, kalemin dakikasının
0,4 katı sayıldı ve bu oran modelin varsayımıdır. **UY12.** Kurulum bedeli kalem başına kişi-saat
olarak verilmiştir (hat 6, depo 8, koşum 12) ve **veridir**; bakım bedeli modellenmedi, bu da
amorti süresini olduğundan kısa gösterir.

```js
// kanit/otomasyon.mjs — kanit uretimi hatta yerlestirilir: elle toplanan kalem kaca iniyor.
import { KALEM, DERLEME, KURULUM, gen } from "./kalem.mjs";

// Iz turu kalem bir sistemde kendiliginden olusur: hatta uretilir. Karar turunun kaydi
// otomatiklesir, gerekcesi elle kalir (kalemin dakikasinin 0,4 kati). Toplanti otomatiklesmez.
const durum = (k) => k.kaynak === "elle" ? "elle kalir"
  : k.tur === "iz" ? "hatta uretilir"
  : k.tur === "karar" ? "yari otomatik" : "elle kalir";
const kalan = (k) => durum(k) === "hatta uretilir" ? 0
  : durum(k) === "yari otomatik" ? Math.round(0.4 * k.dk) : k.dk;

const DURUM = ["hatta uretilir", "yari otomatik", "elle kalir"];
const y = gen([18, 8, 20, 16]);
console.log(y("otomasyon sonucu", "kalem", "kalan elle dakika", "kurulum saat"));
for (const d of DURUM) {
  const k = KALEM.filter((x) => durum(x) === d);
  console.log(y(d, k.length, k.reduce((a, x) => a + kalan(x), 0),
    k.reduce((a, x) => a + KURULUM[x.kaynak], 0)));
}
const kalanDk = KALEM.reduce((a, x) => a + kalan(x), 0);
const kurulum = KALEM.reduce((a, x) => a + (durum(x) === "elle kalir" ? 0 : KURULUM[x.kaynak]), 0);
console.log(y("TOPLAM", KALEM.length, kalanDk, kurulum));

const oncesi = DERLEME * KALEM.reduce((a, x) => a + x.dk, 0) / 60;
const sonrasi = DERLEME * kalanDk / 60;
const elleKalem = KALEM.filter((x) => durum(x) !== "hatta uretilir");
console.log(`\nelle dokunulan kalem ${KALEM.length} -> ${elleKalem.length} ` +
  `(${KALEM.filter((x) => durum(x) === "elle kalir").length} tam, ` +
  `${KALEM.filter((x) => durum(x) === "yari otomatik").length} kismi)`);
console.log(`yillik derleme yuku ${oncesi.toFixed(1)} -> ${sonrasi.toFixed(1)} saat; ` +
  `kazanc ${(oncesi - sonrasi).toFixed(1)} saat/yil`);
console.log(`kurulum ${kurulum} saat -> amorti ${(kurulum / (oncesi - sonrasi)).toFixed(2)} yil`);
console.log(`hicbir kosulda otomatiklesmeyen kalem: ` +
  KALEM.filter((x) => durum(x) === "elle kalir").map((x) => `${x.kod} ${x.tur}`).join(", "));
```

```
otomasyon sonucu     kalem   kalan elle dakika    kurulum saat
hatta uretilir          15                   0             138
yari otomatik            3                 244              32
elle kalir               6                1680               0
TOPLAM                  24                1924             170

elle dokunulan kalem 24 -> 9 (6 tam, 3 kismi)
yillik derleme yuku 213.0 -> 96.2 saat; kazanc 116.8 saat/yil
kurulum 170 saat -> amorti 1.46 yil
hicbir kosulda otomatiklesmeyen kalem: K07 toplanti, K08 karar, K09 toplanti, K11 toplanti, K15 toplanti, K23 karar
```

Elle dokunulan kalem **24'ten 9'a** iniyor: altısı tam elle, üçü kısmi. Yıllık derleme yükü 213
saatten 96,2 saate düşüyor ve kazanç yılda 116,8 saat. Kurulum 170 saat tutuyor, yani yatırım
**1,46 yılda** karşılanıyor. Bu üç sayı birlikte okunmalıdır: tek başına "otomasyon yükü yarıdan
fazla düşürdü" cümlesi doğrudur ama ilk yılın net bakiyesi eksidir.

Son satır otomasyonun tavanını veriyor. Altı kalem hiçbir koşulda otomatikleşmez ve ikisi karar,
dördü toplantı türündedir. Bu altı kalem kalan elle yükün **1.680 dakikasını**, yani 1.924
dakikanın yüzde 87'sini taşır. Otomasyon yükün büyük kısmını değil, **kalem sayısının** büyük
kısmını aldı; kalan dokuz kalem sayıca az, dakikaca ağırdır. Sıradaki iyileştirmenin nereye
bakacağı bu sütunda yazıyor ve orası bir hat değil, bir toplantı düzenidir.

Kısmi otomatikleşen üç kalem ayrı bir sınıftır ve en çok yanlış anlaşılanıdır. Erişim gözden
geçirme kararı bir sistemde işaretlenir, ama **neden** o erişimin sürdürüldüğü bir cümledir ve o
cümleyi bir hat yazamaz. Kaydın otomatikleşmesi, kararın otomatikleştiği anlamına gelmez;
otomatikleşen şey kararın **var olduğunun** kanıtıdır, içeriğinin değil.

#### Otomatik Kanıtın Bedeli

**UY13.** Denetçi bir kalemden en çok 25 kayıt inceler; denetim dönemi 365 gün, kişisel veri türü
taşıyan kanıt kaleminin saklama penceresi 90 gündür. Üçü de **kurgu veridir** ve pencere kararı
kalemin taşıdığı veri türünden gelir.

```js
// kanit/bedel.mjs — otomatik kanitin bedeli: hacim, ornekleme orani ve saklama penceresi.
import { KALEM, gen } from "./kalem.mjs";

const ORNEK = 25, DONEM_GUN = 365, SAKLAMA_GUN = 90;   // ucu de kurgu veridir
const otomatik = (k) => k.kaynak !== "elle" && k.tur !== "toplanti";
const kayit = KALEM.reduce((a, k) => a + k.kayit, 0);
const incelenen = KALEM.reduce((a, k) => a + Math.min(k.kayit, ORNEK), 0);

const y = gen([26, 18, 20]);
console.log(y("kanit hacmi", "derleme oncesi", "hatta uretilirken"));
console.log(y("donem basina kanit kaydi", KALEM.length, kayit));
console.log(y("denetcinin inceledigi", KALEM.length, incelenen));
console.log(y("incelenen oran", "%100", `%${(100 * incelenen / kayit).toFixed(2)}`));

// Kisisel veri turu tasiyan kanit kalemi saklama penceresine tabidir; pencere donemden kisa
// oldugunda kalem donemin yalnizca bir bolumunu cevaplar.
const kisisel = KALEM.filter((k) => otomatik(k) && k.kisisel === "var");
const tam = KALEM.filter((k) => otomatik(k) && k.kisisel === "yok");
const elle = KALEM.filter((k) => !otomatik(k));
const pay = (100 * SAKLAMA_GUN / DONEM_GUN).toFixed(1);
const z = gen([28, 10, 16]);
console.log("\n" + z("kanitin kapsadigi ara", "kalem", "donem payi"));
console.log(z(`donem boyu (${DONEM_GUN} gun)`, tam.length, "%100"));
console.log(z(`son ${SAKLAMA_GUN} gun (saklama kisiti)`, kisisel.length, `%${pay}`));
console.log(z("tek gun (elle derleme)", elle.length, "-"));

console.log(`\nkisisel veri turu tasiyan otomatik kalem: ` +
  kisisel.map((k) => k.kod).join(", "));
console.log(`${KALEM.length} kanit kaleminden ${tam.length} kalem donemin tamamini, ` +
  `${kisisel.length} kalem son ${SAKLAMA_GUN} gunu, ${elle.length} kalem tek gunu cevapliyor`);
console.log(`kanit kaydi ${KALEM.length} -> ${kayit} (${Math.round(kayit / KALEM.length)} kat); ` +
  `incelenen kayit ${incelenen}`);
```

```
kanit hacmi                   derleme oncesi   hatta uretilirken
donem basina kanit kaydi                  24               72401
denetcinin inceledigi                     24                 458
incelenen oran                          %100               %0.63

kanitin kapsadigi ara            kalem      donem payi
donem boyu (365 gun)                12            %100
son 90 gun (saklama kisiti)          6           %24.7
tek gun (elle derleme)               6               -

kisisel veri turu tasiyan otomatik kalem: K03, K04, K05, K14, K16, K24
24 kanit kaleminden 12 kalem donemin tamamini, 6 kalem son 90 gunu, 6 kalem tek gunu cevapliyor
kanit kaydi 24 -> 72401 (3017 kat); incelenen kayit 458
```

İlk tablo ilk bakışta otomasyonun aleyhine okunur: kanıt kaydı 24'ten 72.401'e, **3.017 kata**
çıkıyor ve incelenen oran yüzde 100'den yüzde 0,63'e düşüyor. Bu okuma yanlıştır ve yanlış olma
nedeni kursun ölçüsündedir. Derleme öncesindeki yüzde 100, yirmi dört belgenin tamamının
okunduğunu söyler; o yirmi dört belgenin **hangi aralığı** anlattığını söylemez. Sonraki durumda
incelenen 458 kayıt bir örneklemdir, ama arkasındaki 72.401 kaydın tamamı sorgulanabilir
durumdadır — denetçinin bir sonraki sorusu örneklemi büyütmeyi değil, sorguyu değiştirmeyi
gerektirir. **Daha çok kayıt daha az inceleme demektir; daha az cevap demek zorunda değildir.**

Bu koşullu cümlenin koşulu ikinci tabloda görünüyor. Kişisel veri türü taşıyan altı kalem —
kimlik verilişi, denetim kaydı, üretim erişimi, veri sahibi talebi ve iki gözden geçirme kararı —
90 günlük bir saklama penceresine tabidir. Denetim dönemi 365 gündür. Bu altı kalem dönemin
**yüzde 24,7'sini** cevaplar; dönemin ilk dokuz ayı hakkındaki her soru cevapsızdır ve cevapsız
olduğu ancak soru sorulduğunda anlaşılır. Otomasyon bu kalemleri kanıtsız yapmadı; **kanıtın ömrünü
kanıt üretiminden ayrı bir kısıt haline getirdi.**

Sorgulanabilirlik koşulu da bedava değildir. Hatta üretilen bir kanıt kaydının denetimde işe
yaraması için üç alan taşıması gerekir: hangi kontrole ait olduğu, hangi ana ait olduğu ve
üretildikten sonra değiştirilmediğinin gösterilebilmesi. Bu üç alan kurulum saatinin içindedir ve
üçü de eksik olabilir. Alanları eksik bir otomatik kanıt yığını, elle derlenmiş yirmi dört
belgeden daha az cevap verir — sayısı büyüktür, sorgulanamaz ve hangi dönemi anlattığı yazmaz.
Otomasyonun kazancı hacimden değil, **bu üç alandan** gelir.

Üç satır birlikte okunduğunda tablo şudur: yirmi dört kalemin **on ikisi** dönemin tamamını,
**altısı** son doksan günü, **altısı** tek bir günü cevaplıyor. Otomasyondan önce bu üç sınıf
birbirinden ayırt edilemiyordu, çünkü hepsi aynı biçimde — dönem sonunda derlenmiş bir belge
olarak — duruyordu. Ölçmenin ilk kazancı sayının kendisi değil, **üç sınıfın ayrılmış olmasıdır.**

#### Özet

- Yirmi dört kanıt kaleminin on sekizi zaten bir sistemde oluşuyordu, buna karşın yirmi dördünün
  de kanıtı dönem sonunda elle derleniyordu; açık mühendislik değil, bağlantı açığıdır.
- Üretim hatta yerleştirildiğinde elle dokunulan kalem 24'ten 9'a, yıllık derleme yükü 213
  saatten 96,2 saate iner; 170 saatlik kurulum 1,46 yılda karşılanır ve ilk yılın bakiyesi eksidir.
- Altı kalem hiçbir koşulda otomatikleşmez ve kalan elle yükün yüzde 87'sini taşır: otomasyon
  yükün değil, kalem sayısının büyük kısmını aldı.
- Kararın kaydı otomatikleşir, gerekçesi elle kalır; otomatikleşen şey kararın var olduğunun
  kanıtıdır, içeriğinin değil.
- Bedel karşı sütunda çıkar: kanıt kaydı 3.017 kat artar, incelenen oran yüzde 0,63'e iner ve
  kişisel veri türü taşıyan altı kalem 90 günlük saklama penceresi yüzünden dönemin yüzde
  24,7'sini cevaplar.

#### Sonraki Adım

Kanıt üretimi hatta yerleşti ve üç sınıf ayrıldı: dönemin tamamını, son doksan günü ve tek günü
cevaplayan kalemler. Bu ölçümlerin hepsi **kanıtın var olup olmadığı** üzerineydi. 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ılmayanlar ne kadar süredir açık.

Sonraki ders bu iki sayıyı bir uygulama ekibinin ölçeğinde hesaplar — ortalama düzeltme süresi ve
açık yaşı. İkisi aynı bulgu kümesinden çıkar, aynı dönemde ters yönlere gider ve ikisinin de
hesaplanabilmesi kayıtta belirli zaman damgalarının bulunmasına bağlıdır. Damga eksikse kalem
hesaba hiç girmez; girmeyen kalemler rastgele mi seçilir, yoksa hep aynı sınıftan mıdır?

### Uygulama Güvenlik Ölçütleri

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/uygulama-guvenlik-olcutleri

Yüz kırk iki bulgunun kapanan 121'inde 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.

Ö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.

```js
// 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.

```js
// 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.

```js
// 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ı.

### Güvenlik Borcu

Source: https://academia.sh/tr/kurslar/uygulama-tespit-ve-uyumluluk/guvenlik-borcu

Otuz dört kalemlik bir borç defterinin 21'i açık, 13'ü kabul edilmiş risktir; kabullerin yalnız 5'inde geçerlilik süresi, 2'sinde yeniden değerlendirme noktası yazılıdır. Altı sorunun biri tam, dördü kısmi cevaplanır, biri cevapsızdır; kısmi cevapları tam yapmak 26 alan yazmayı gerektirir. Dört dönemlik kuyruk 48 kişi-günü kapasiteyle 209 kişi-günlük defterin 11 kalemini kapatır ve kalan kuyruğun ortalama yaşı 91 günden 360 güne çıkar. Süresi hiç yazılmamış 8 kabul kalemi hiçbir dönemde yeniden sorulmaz; süresi dolmuş 3 kabulden yalnız biri yeniden değerlendirme noktası taşır.

Önceki ders iki ölçütü hesapladı ve ikisinin de ölçülen şeye dokunulmadan iyileştirilebildiğini
gösterdi. En ucuz iyileştirme yaşlı kalemi kabul edilmiş riske çevirmekti: açık yaşı 59,8 günden
23,4 güne indi, düzeltilen kalem sayısı sıfır kaldı. O yedi kalem bir yere gitti ve gittiği yer bu
dersin konusudur.

Kabul edilmiş risk ile açık borç birlikte **güvenlik borcunu** oluşturur. Yazılım Mimarlığı
müfredatında teknik borç ölçülmüştü; o ölçüm burada tekrarlanmaz ve güvenlik borcunu ondan ayıran
tek bir alan vardır: **kabulün bir süresi olur.** Teknik borç kendiliğinden ödenmez ama süresi de
dolmaz; kabul edilmiş bir risk, süresi yazılmadığında borç olmaktan çıkıp kayıt olur.

#### Borç Defteri

**UY21.** Borç defteri 34 kalemdir: önceki dersin kapanmamış 21 açık kalemi ve daha önce kabule
çevrilmiş 13 kalem. Küme kurgu bölgesel ölçüm ağının abone portalı ekibine ait bir **modeldir**;
üreteç bu blokta yazılıdır, tohum görünürdür. **UY22.** Her kalemin bir **çabası** (kişi-günü) ve
bir **risk puanı** vardır; ikisi de kurgu veridir. **UY23.** Bir kabul kaleminde üç alan bulunabilir:
adı geçen **sahip**, **geçerlilik süresi** ve **yeniden değerlendirme noktası**. **UY24.** Alanların
dağılımı **veri olarak** verilmiştir: ilk beş kabulde süre, ilk ikisinde yeniden değerlendirme
noktası, ilk altısında sahip yazılıdır.

```js
// borc/defter.mjs — guvenlik borcu defteri MODELDIR: kurgu bolgesel olcum agi, planlama ani.
// Uretec kendi yazilmistir, tohum gorunurdur; defter 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 TOHUM = 41100, N_ACIK = 21, N_KABUL = 13;
let s = TOHUM;
const rnd = () => (s = (Math.imul(s, 1664525) + 1013904223) >>> 0) / 4294967296;

// Kabul kalemlerinin ilk besinde gecerlilik suresi, ilk ikisinde yeniden degerlendirme
// noktasi, ilk altisinda adi gecen sahip yazilidir; kalanlarda alan bostur. Bu dagilim veridir.
const SURE = [90, 120, 180, 180, 365];

export const DEFTER = [];
for (let i = 0; i < N_ACIK + N_KABUL; i++) {
  const kabul = i >= N_ACIK, k = i - N_ACIK;
  DEFTER.push({
    kod: `D${String(i + 1).padStart(2, "0")}`,
    sinif: kabul ? "kabul" : "acik",
    kaynak: rnd() < (kabul ? .75 : .70) ? "hat disi" : "hat",
    risk: 4 + Math.floor(rnd() * 21),                  // 4-24 arasi kurgu risk puani
    caba: 1 + Math.floor(rnd() * 13),                  // kisi-gunu
    yas: kabul ? 40 + Math.floor(rnd() * 380) : 20 + Math.floor(rnd() * 160),
    sure: kabul && k < SURE.length ? SURE[k] : null,
    yeniden: kabul && k < 2,
    sahip: kabul ? k < 6 : true,
  });
}
export const acik = DEFTER.filter((d) => d.sinif === "acik");
export const kabuller = DEFTER.filter((d) => d.sinif === "kabul");
export const doldu = (d) => d.sure !== null && d.yas > d.sure;

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`model: ${DEFTER.length} borc kalemi, ${acik.length} acik + ${kabuller.length} kabul edilmis risk`);
  const y = gen([16, 8, 10, 12, 12, 14]);
  console.log("\n" + y("sinif", "kalem", "kisi-gunu", "risk toplam", "suresi var", "suresi dolmus"));
  for (const [ad, k] of [["acik borc", acik], ["kabul edilmis", kabuller]])
    console.log(y(ad, k.length, k.reduce((a, d) => a + d.caba, 0), k.reduce((a, d) => a + d.risk, 0),
      k.filter((d) => d.sure !== null).length, k.filter(doldu).length));

  // Bir borc kalemine sorulacak sorular ve her birinin istedigi alan.
  const SORU = [["kalem acik mi kabul mu", "sinif", DEFTER.length, DEFTER.length],
    ["kabulu kim verdi", "sahip", N_KABUL, kabuller.filter((d) => d.sahip).length],
    ["kabul kac gun gecerli", "sure", N_KABUL, kabuller.filter((d) => d.sure !== null).length],
    ["kabulun suresi doldu mu", "sure+yas", N_KABUL, kabuller.filter((d) => d.sure !== null).length],
    ["yeniden degerlendirme ne zaman", "yeniden nokta", N_KABUL, kabuller.filter((d) => d.yeniden).length],
    ["kalem hangi donemde kapanacak", "kuyruk sirasi", DEFTER.length, 0]];
  const cevap = (t, b) => t === 0 ? "yok" : t === b ? "tam" : "kismi";
  const z = gen([32, 16, 8, 10, 8]);
  console.log("\n" + z("soru", "gereken alan", "taban", "tasiyan", "cevap"));
  for (const [m, a, b, t] of SORU) console.log(z(m, a, b, t, cevap(t, b)));
  const n = (c) => SORU.filter(([, , b, t]) => cevap(t, b) === c).length;
  const yok = (f) => N_KABUL - kabuller.filter(f).length;
  const eksik = yok((d) => d.sahip) + yok((d) => d.sure !== null) + yok((d) => d.yeniden);
  console.log(`\n${SORU.length} sorunun ${n("tam")}'i tam, ${n("kismi")}'i kismi cevaplaniyor, ` +
    `${n("yok")}'i cevapsiz`);
  console.log(`kismi cevaplari tam yapmak icin ${eksik} alan yazilir; suresi dolmus ` +
    `${kabuller.filter(doldu).length} kalemin ${kabuller.filter((d) => doldu(d) && d.yeniden).length}'i ` +
    `yeniden degerlendirme noktasi tasiyor`);
}
```

```
model: 34 borc kalemi, 21 acik + 13 kabul edilmis risk

sinif              kalem kisi-gunu risk toplam  suresi var suresi dolmus
acik borc             21       141         274           0             0
kabul edilmis         13        68         185           5             3

soru                                gereken alan   taban   tasiyan   cevap
kalem acik mi kabul mu                     sinif      34        34     tam
kabulu kim verdi                           sahip      13         6   kismi
kabul kac gun gecerli                       sure      13         5   kismi
kabulun suresi doldu mu                 sure+yas      13         5   kismi
yeniden degerlendirme ne zaman     yeniden nokta      13         2   kismi
kalem hangi donemde kapanacak      kuyruk sirasi      34         0     yok

6 sorunun 1'i tam, 4'i kismi cevaplaniyor, 1'i cevapsiz
kismi cevaplari tam yapmak icin 26 alan yazilir; suresi dolmus 3 kalemin 1'i yeniden degerlendirme noktasi tasiyor
```

İlk tablo defterin iki sınıfını yan yana koyuyor ve asıl bilgi son iki sütunda. Kabul edilmiş 13
kalemin yalnız **beşinde** geçerlilik süresi yazılı; kalan sekizde kabul, sonu olmayan bir karardır.
Süresi yazılı beşin **üçünün** süresi planlama anında zaten dolmuş durumda ve bunu kimse sormadığı
için üçü de defterde kabul olarak duruyor. Risk toplamı sütunu ölçeği veriyor: kabul edilmiş
kalemler defterin risk toplamının **185'ini** taşıyor, açık borç 274'ünü. Kabul, riski kaldırmaz;
yalnız onu ölçütlerin baktığı sütundan çıkarır.

Soru tablosunda altı sorunun **biri** tam cevaplanıyor. Kalan beşin dördü yalnız kabul kalemlerini
ilgilendiriyor, biri bütün defteri; dördü kısmi, biri hiç cevaplanmıyor. Kısmi olanları tam yapmak
**26 alan** yazmayı gerektiriyor — yedi sahip, sekiz süre, on bir yeniden değerlendirme noktası.
Bu, kurstaki en ucuz bedeldir ve bir hat kurulumu ya da ek hacim gerektirmez; yazılacak şey
kararın kendisidir. Son satır bunun karşılığını veriyor: süresi
dolmuş üç kabulden **yalnız biri** kendisini yeniden gündeme getirecek bir nokta taşıyor.

#### Kuyruğu Koşturmak

**UY25.** Kapasite dönem başına 12 kişi-günü, dönem 90 gün ve planlama ufku dört dönemdir; üçü de
**kurgu veridir**. Sıralama kuralı birim çabaya düşen risktir ve kapasiteye sığmayan kalem sonraki
döneme kalır. **UY26.** İki koşum karşılaştırılır: kabul edilmiş kalemin hiç geri gelmediği defter
ve süresi dolan kabulün — yeniden değerlendirme noktası varsa — kuyruğa geri girdiği defter.

```js
// borc/kuyruk.mjs — borc sabit kapasiteli bir kuyruk olarak dort donem kosturulur.
import { DEFTER, acik, kabuller, doldu, gen } from "./defter.mjs";

const KAPASITE = 12, DONEM = 4, DONEM_GUN = 90;   // kisi-gunu, donem sayisi, donem uzunlugu

// Siralama birim cabaya dusen risktir; kapasiteye sigmayan kalem sonraki doneme kalir.
// geriDonus acikken: suresi dolan ve yeniden degerlendirme noktasi olan kabul kuyruga girer.
const kosuf = (geriDonus) => {
  const kuyruk = acik.map((d) => ({ ...d })), bekleyen = kabuller.map((d) => ({ ...d }));
  const satir = [];
  for (let t = 1; t <= DONEM; t++) {
    let geri = 0;
    if (geriDonus) for (const d of bekleyen)
      if (!d.donuk && d.yeniden && doldu(d)) { d.donuk = true; kuyruk.push(d); geri++; }
    kuyruk.sort((a, b) => b.risk / b.caba - a.risk / a.caba);
    let kalan = KAPASITE;
    for (const d of kuyruk) if (!d.kapali && d.caba <= kalan) { d.kapali = true; kalan -= d.caba; }
    const acikta = kuyruk.filter((d) => !d.kapali);
    satir.push([t, geri, kuyruk.filter((d) => d.kapali).length, KAPASITE - kalan, acikta.length,
      acikta.reduce((a, d) => a + d.caba, 0),
      Math.round(acikta.reduce((a, d) => a + d.yas, 0) / acikta.length)]);
    for (const d of [...acikta, ...bekleyen.filter((x) => !x.donuk)]) d.yas += DONEM_GUN;
  }
  return { satir, acikta: kuyruk.filter((d) => !d.kapali), bekleyen,
    geri: satir.reduce((a, s) => a + s[1], 0) };
};

const y = gen([8, 10, 10, 12, 10, 14, 10]);
const KOSUM = [["A: kabul geri gelmez", false], ["B: suresi dolan geri gelir", true]];
KOSUM.forEach(([ad, geriDonus], i) => {
  const r = kosuf(geriDonus);
  console.log((i ? "\n" : "") + ad);
  console.log(y("donem", "geri gelen", "kapanan", "harcanan", "kalan", "kalan kisi-gunu", "ort yas"));
  for (const s of r.satir) console.log(y(...s));
  const gizli = r.bekleyen.filter((d) => !d.donuk);
  console.log(`defterde gorunen borc ${r.acikta.length} kalem / ` +
    `${r.acikta.reduce((a, d) => a + d.caba, 0)} kisi-gunu; ` +
    `kuyruga hic girmeyen kabul ${gizli.length} kalem / ` +
    `${gizli.reduce((a, d) => a + d.caba, 0)} kisi-gunu, risk toplami ` +
    `${gizli.reduce((a, d) => a + d.risk, 0)}`);
});

console.log(`\ndort donemde toplam kapasite ${KAPASITE * DONEM} kisi-gunu; defterin tamami ` +
  `${DEFTER.reduce((a, d) => a + d.caba, 0)} kisi-gunu`);
console.log(`planlama aninda suresi dolmus ${kabuller.filter(doldu).length} kabulun ` +
  `${kabuller.filter((d) => doldu(d) && d.yeniden).length} tanesi yeniden degerlendirme noktasi ` +
  `tasiyor; dort donem boyunca kuyruga geri donen kabul ${kosuf(true).geri}`);
console.log(`suresi hic yazilmamis ${kabuller.filter((d) => d.sure === null).length} kalem ` +
  `hicbir donemde yeniden sorulmuyor`);
```

```
A: kabul geri gelmez
donem   geri gelen   kapanan    harcanan     kalankalan kisi-gunu   ort yas
1                0         4          12        17           129        91
2                0         7          12        14           117       175
3                0         9          10        12           107       259
4                0        11          12        10            95       360
defterde gorunen borc 10 kalem / 95 kisi-gunu; kuyruga hic girmeyen kabul 13 kalem / 68 kisi-gunu, risk toplami 185

B: suresi dolan geri gelir
donem   geri gelen   kapanan    harcanan     kalankalan kisi-gunu   ort yas
1                1         4          11        18           133        87
2                1         7          11        16           130       175
3                0         9          12        14           118       260
4                0        11          11        12           107       349
defterde gorunen borc 12 kalem / 107 kisi-gunu; kuyruga hic girmeyen kabul 11 kalem / 57 kisi-gunu, risk toplami 150

dort donemde toplam kapasite 48 kisi-gunu; defterin tamami 209 kisi-gunu
planlama aninda suresi dolmus 3 kabulun 1 tanesi yeniden degerlendirme noktasi tasiyor; dort donem boyunca kuyruga geri donen kabul 2
suresi hic yazilmamis 8 kalem hicbir donemde yeniden sorulmuyor
```

Kuyruk dört dönemde **11 kalem** kapatıyor ve iki koşumda da aynı sayıyı kapatıyor. Kapasite
sabittir: dört dönemde 48 kişi-günü, defterin tamamı ise **209 kişi-günü**. Bu oran planın
sınırını yazıyor — bu kapasiteyle defter kapanmaz, yalnız sıralanır. Üçüncü dönemde harcanan
kapasite 10 kişi-gününde kalıyor, çünkü sıradaki kalem kalan iki güne sığmıyor; **sabit kapasiteli
bir kuyruk kapasitesini tam kullanamaz** ve bu kayıp sıralama kuralının değil kalem boyutunun
sonucudur.

Asıl bilgi son iki sütunda. Kalan kalem sayısı 17'den 10'a düşerken ortalama yaş **91 günden 360
güne** çıkıyor. Kuyruk kısalıyor ve yaşlanıyor: birim çabaya düşen risk kuralı ucuz ve riskli
kalemleri öne alıyor, pahalı kalemler her dönem bir sonrakine devrediyor. Bir borç planının
başarısı kapanan kalem sayısıyla değil, **hiç sıraya gelmeyen kalemin yaşıyla** okunur.

İki koşum arasındaki fark tek satırdır ve dersin cevabıdır. A koşumunda dört dönem sonunda defter
10 kalem ve 95 kişi-günü gösteriyor; kuyruğa hiç girmeyen 13 kabul kalemi 68 kişi-günü ve 185 risk
puanı taşıyor ve hiçbir dönemde sorulmuyor. B koşumunda süresi dolan iki kabul geri geliyor, defter
12 kaleme çıkıyor ve gizli kalan yük 185'ten 150'ye iniyor. **Defterin büyümesi kötüleşme değil,
ölçümün genişlemesidir.** Geri dönen kalem sayısının ikide kalmasının nedeni de bellidir: sekiz
kabulde süre hiç yazılmamıştır ve süresi olmayan bir kabul, hiçbir kuralın geri getiremeyeceği
tek kalem türüdür.

#### Özet

- Güvenlik borcu iki sınıftan oluşur ve teknik borçtan tek bir alanla ayrılır: kabulün bir süresi
  vardır. Defterin 34 kaleminin 21'i açık borç, 13'ü kabul edilmiş risktir.
- Kabullerin yalnız 5'inde süre, 2'sinde yeniden değerlendirme noktası, 6'sında adı geçen sahip
  yazılıdır; süresi yazılı beşin üçünün süresi planlama anında zaten dolmuştur.
- Altı sorunun biri tam, dördü kısmi cevaplanır, biri cevapsızdır; kısmi olanları tam yapmanın
  bedeli 26 alandır ve bu bedel hiçbir hat kurulumu ya da ek hacim gerektirmez.
- Dört dönemde 48 kişi-günü kapasite 209 kişi-günlük defterin 11 kalemini kapatır; kalan kuyruk
  17 kalemden 10'a inerken ortalama yaşı 91 günden 360 güne çıkar.
- Süresi ve yeniden değerlendirme noktası yazılmayan kabul defterden kalıcı olarak düşer: 13
  kabulden 11'i hiçbir dönemde yeniden sorulmaz ve 150 risk puanı ölçüm dışında kalır.

#### Kurs Kapanışı

Dokuz ders boyunca tek bir soru soruldu: olaydan sonra sorulacak soruların kaçı cevaplanabiliyor ve
cevaplanabilir kılmak neye mal oluyor. Her dersin kendi kalem kümesi, kendi soru kümesi ve kendi
bedel sütunu vardı.

| Ders | Kaç soru | Cevaplanabilen | Cevaplanabilir kılmanın bedeli |
|---|---|---|---|
| Denetim Kaydı Tasarımı | 16 soru | 6 → 13 | 1,45 kat hacim, 65→45 gün saklama, 3 kişisel veri kalemi |
| Uygulamaya Özgü Tespit Senaryoları | 18 kötüye kullanım | 15 → 18 | 173 yanlış uyarı, 30 günde 101 uyandırma |
| Uygulama İhlali Müdahalesi | 12 adım | 5 → 12 kayıttan | 630→151 dakika; kayıtsızken 41 200 abonelik bildirim |
| Kısa Ömürlü İş Yüklerinde İz | 5 soru × 2 000 iş yükü | 6 604 / 10 000 çift | 91 084 ek gönderim, 33 çekirdek-dakika |
| Dış Bildirim Kanalı | 91 benzersiz bildirim | cevapsız 36 → 0, kesin 15 → 20 | 5 alan, 1,45 kat hacim, 20 gün kısa saklama |
| Kontrollerin Mühendislik Karşılığı | 26 kontrol | 11 sorgu, 6 belge | 9 kontrole pratik, 6 belgeye makine izi kurmak |
| Kanıt Otomasyonu | 24 kanıt kalemi | 12 dönem boyu, 6 son 90 gün | 170 saat kurulum, 3 017 kat hacim, yüzde 0,63 inceleme |
| Uygulama Güvenlik Ölçütleri | 8 soru | 5 tam, 1 kısmi | 568 ek durum geçişi kaydı |
| Güvenlik Borcu | 6 soru | 1 tam, 4 kısmi | 26 alan; 209 kişi-günlük borca 48 kişi-günü kapasite |

Bu kurs M25 Uygulama Güvenliği ve DevSecOps müfredatının beşinci ve son kursudur. Beş kursun her
biri aynı kalemi başka bir aşamada yakaladı ve her biri kendi birimiyle saydı.

| Kurs | Ölçü ekseni | Birim |
|---|---|---|
| K01 Güvenli Geliştirme Yaşam Döngüsü | yakalama aşaması ve kat | aşama |
| K02 Güvenli Kodlama | kapsama | dışarıda kalan nokta |
| K03 Güvenlik Otomasyonu ve Tedarik Zinciri | denetimin bulduğu, kaçırdığı ve hattan aldığı süre | bulgu ve dakika |
| K04 Çalışma Zamanı Güvenliği ve Sır Yönetimi | en pahalı aşamada tutmak | kaçırılan ve yanlış kesilen |
| K05 Tespit, Müdahale ve Uyumluluk | sorunun cevaplanabilirliği | cevaplanamayan soru |

Beş kurs boyunca sorulan tek soru şuydu: **bir kalem hangi aşamada yakalandı ve o aşamada kaça mal
oldu.** Güvenlik bir aşama değil, her aşamada farklı fiyatı olan bir karardır; ve en pahalı aşama
her zaman sonuncusudur. Bu kursun defteri bunun son biçimidir — kabul edilmiş bir risk, kalemin
hiçbir aşamada yakalanmamasının kayda geçmiş hâlidir ve süresi yazılmadığında yakalanma ihtimali
de kayıttan düşer.

Müfredatın kuralı bir kez daha yazılır: **bedeli yazılmayan denetim ölçülmemiş sayılır.** Bir
kaydın, bir uyarının, bir kanıt kaleminin ya da bir ölçütün yanına hacmi, dakikası, kişisel veri
kalemi ve kişi-günü yazılmıyorsa o denetim hakkında bilinen tek şey yapıldığıdır — kaça mal olduğu
ve neyi kaçırdığı değil.

