---
title: 'Sola Kaydırma'
source: 'https://academia.sh/tr/kurslar/guvenli-yasam-dongusu/sola-kaydirma'
course: 'Güvenli Geliştirme Yaşam Döngüsü'
language: tr
updated: '2026-08-17T18:06:43+00:00'
license: 'CC BY-SA 4.0'
---

# Sola Kaydırma

Düzeltme maliyeti aşama başına geri alınan işten türetilir ve aynı 23 kalemlik küme iki akışta koşturulur: ortak 18 kalemde geç akış 318 saat, erken akış 68 saat, kat 4,68 ve önlenen 250 saatten denetim yükü düşünce net kazanç 217,5 saat kalır. Kat tek bir sayı değildir, gereksinimde doğan kalemde 22,5, dağıtımda doğanda 13'tür; erken akış bedelinin yarısı sola kaydırmanın hiç dokunamadığı tek kalemden gelir.

Önceki ders denetimin yerini değiştirdi: tek kapı yerine altı aşamaya dağıtılmış denetimle
yakalanan kalem 18'den 23'e çıktı, toplam gecikme 35 aşamadan 3 aşamaya indi. Gecikme bir sayıydı,
ama **aşama** bir para birimi değildir. Bir kalemi tasarım aşamasında düzeltmek bir toplantı
kararıdır; aynı kalemi çalışan bir sistemden geri almak veri göçü, sürüm planı ve kesinti
penceresidir. İki iş aynı birimle ölçülemez.

Bu ders o birimi kurar. Denetimin akışta öne alınmasına **sola kaydırma** (shift left) denir ve
tek başına bu ifade bir karar taşımaz — ne kadar sola, hangi kalem için ve ne pahasına sorusunun
yanıtı yoktur. Burada aşama başına düzeltme maliyeti modele girer, aynı kalem kümesi geç ve erken
denetimli iki akışta koşar, toplam kat hesaplanır. Dersin ikinci yarısı ters yöne bakar: kaydırmanın
hiçbir şey kazandırmadığı kalem sınıfı ayrılır ve o sınıfın bedeldeki payı sayılır.

- **DY7.** Kalem kümesi önceki dersle aynıdır ve değişmez; eklenen tek şey maliyettir.
- **DY8.** Düzeltme maliyeti verilmiş bir çarpan değildir, **geri alınan işten türetilir**: kalem
  doğduğu aşamadan sonra kaç aşama geçtiyse, o aşamalarda üretilmiş iş de yeniden yapılır.
- **DY9.** Aşama başına geri alma bedelleri ve temel düzeltme emeği model değerleridir; birim
  **kurgu geliştirici-saattir**. Gerçek bir kurumda bu sayılar geçmiş düzeltme kayıtlarından
  çıkarılır.
- **DY10.** Karşılaştırma yalnız **iki akışta da yakalanan** kalemler üzerinde yapılır. Geç akışın
  hiç görmediği kalemin bedeli sıfır değildir, **ödenmemiştir**; ayrı yazılır.
- **DY11.** Erken denetimlerin koşum yükü önceki dersten alınır ve tek kalemde net kazançtan
  düşülür. Kurulum, eğitim ve bakım yükü modelde yoktur; hepsi net kazancı düşürür.

## Aşama Başına Düzeltme Maliyeti

Maliyet bir çarpan olarak verilmez, kurulur. Her aşama bir iş üretir; kalem o aşamayı geçtikten
sonra düzeltilirse üretilen iş de geri alınır. Toplam bedel, temel düzeltme emeği artı geçilen
aşamaların geri alma bedelidir.

```js
// maliyet.mjs — ayni kalem kumesi, artik asama basina duzeltme maliyetiyle (model)
export const ASAMA = ['gereksinim', 'tasarim', 'kod', 'yapi', 'dagitim', 'calisma-zamani'];
// Bir asamayi gecmenin geri alinma bedeli (kurgu gelistirici-saat): kalem o asamayi
// gectiyse, duzeltme o asamada uretilmis isi de yeniden yaptirir.
export const YENIDEN = [0, 3, 8, 2, 6, 24];
export const TEMEL = 2; // kalemin kendi duzeltme emegi, asamadan bagimsiz
// Maliyet: temel emek arti dogus ile yakalama arasinda gecilen her asamanin geri alinmasi.
export const bedel = (dogus, yakalanan) =>
  TEMEL + YENIDEN.slice(dogus + 1, yakalanan + 1).reduce((s, x) => s + x, 0);
export const KALEM = `
  veri-siniflandirmasi-yok      0 100000
  saklama-suresi-tanimsiz       0 100001
  kisisel-veri-kapsami-belirsiz 0 100010
  kimlik-dogrulamasiz-ic-cagri  1 011110
  zayif-oturum-modeli           1 010011
  guven-sinirsiz-veri-akisi     1 010000
  yetki-modelinde-eksik-rol     1 011001
  eksik-yetki-denetimi          2 001101
  gomulu-gizli-anahtar          2 001110
  dogrulanmamis-girdi           2 001001
  gunluge-yazilan-kisisel-veri  2 001001
  yarim-kalan-hata-yolu         2 001000
  zayif-rastgelelik             2 001000
  sinirsiz-sorgu-boyu           2 000001
  guncel-olmayan-bagimlilik     3 000110
  imzasiz-yapi-ciktisi          3 000110
  gereksiz-yapi-araci           3 000100
  varsayilan-parola             4 000011
  asiri-genis-ag-kurali         4 000011
  sifresiz-yedek                4 000010
  acik-yonetim-ucu              4 000011
  olcek-altinda-yaris           5 000001
  ucuncu-tarafta-aciklanan-acik 5 000001`
  .trim().split('\n').map((r) => {
    const [ad, d, g] = r.trim().split(/\s+/);
    return { ad, dogus: +d, g };
  });
export const ilkGorulen = (k, asamalar) =>
  asamalar.find((i) => i >= k.dogus && k.g[i] === '1') ?? null;
```

```js
// kosum1.mjs — kat, tek bir sayi degildir: dogdugu asamaya gore degisir
import { ASAMA, YENIDEN, bedel, KALEM } from './maliyet.mjs';

console.log('dogus asamasi   yeniden yapma  en erken bedel  en gec bedel  kat   kalem');
for (const [i, a] of ASAMA.entries()) {
  const erken = bedel(i, i), gec = bedel(i, ASAMA.length - 1);
  console.log(a.padEnd(16) + String(YENIDEN[i]).padEnd(15) + String(erken).padEnd(16) +
    String(gec).padEnd(14) + (gec / erken).toFixed(1).padEnd(6) +
    KALEM.filter((k) => k.dogus === i).length);
}
console.log('\nayni kalem, asama asama gecikirse (tasarimda dogan bir kalem)');
console.log('yakalandigi asama  bedel  bir onceki asamaya gore artis');
let onceki = null;
for (let j = 1; j < ASAMA.length; j++) {
  const b = bedel(1, j);
  console.log(ASAMA[j].padEnd(19) + String(b).padEnd(7) +
    (onceki === null ? '-' : `${b - onceki} saat, ${(b / onceki).toFixed(2)} kat`));
  onceki = b;
}
```

```
dogus asamasi   yeniden yapma  en erken bedel  en gec bedel  kat   kalem
gereksinim      0              2               45            22.5  3
tasarim         3              2               42            21.0  4
kod             8              2               34            17.0  7
yapi            2              2               32            16.0  3
dagitim         6              2               26            13.0  4
calisma-zamani  24             2               2             1.0   2

ayni kalem, asama asama gecikirse (tasarimda dogan bir kalem)
yakalandigi asama  bedel  bir onceki asamaya gore artis
tasarim            2      -
kod                10     8 saat, 5.00 kat
yapi               12     2 saat, 1.20 kat
dagitim            18     6 saat, 1.50 kat
calisma-zamani     42     24 saat, 2.33 kat
```

Birinci tablo kat sütununu tek bir sayıya indirmenin neden yanlış olduğunu gösteriyor. Gereksinim
aşamasında doğan bir kalem en geç yakalandığında 22,5 kat pahalıya düzeltilir; dağıtımda doğan bir
kalem için aynı sayı 13'tür. Aradaki fark kalemin ciddiyetinden değil, **doğduğu noktadan sonra
kaç aşamalık iş üretildiğinden** gelir. "Geç bulunan açık kat kat pahalıdır" cümlesi doğru, ama
hangi kat olduğu kalemin nereden geldiğine bağlıdır ve ikisi arasında 1,7 katlık bir fark vardır.

İkinci tablo daha keskin bir şey söylüyor: artış düzgün değildir. Tasarımda doğan bir kalem kod
aşamasına sarktığında bedel beş katına çıkar; oradan yapı aşamasına geçtiğinde yalnız 1,2 katına.
Artışın yoğunlaştığı iki sınır vardır — kodun yazıldığı aşama ve sistemin çalışır hâle geldiği
aşama. Aralarındaki yapı ve dağıtım sınırları ucuzdur. Bu, kaydırmanın nereye yapılacağını doğrudan
belirler: bir denetimi dağıtımdan yapıya çekmek 6 saat kazandırır, koddan tasarıma çekmek 8 saat.
Aynı çabayla farklı sınırlar geçilir ve hepsi eşit değildir.

## İki Akış, Toplam Kat

Aynı kalem kümesi iki akışta koşuyor: denetimin yalnız dağıtım ve çalışma zamanında bulunduğu geç
akış ile altı aşamanın hepsinde bulunduğu erken akış.

```js
// kosum2.mjs — ayni kalem kumesi iki akista: gec denetimli ve erken denetimli
import { ASAMA, bedel, KALEM, ilkGorulen } from './maliyet.mjs';

const GEC = [4, 5], ERKEN = [0, 1, 2, 3, 4, 5];
const DENETIM_YUKU = 32.5; // erken denetimlerin kosum yuku (onceki dersten, saat)
const satir = KALEM.map((k) => {
  const g = ilkGorulen(k, GEC), e = ilkGorulen(k, ERKEN);
  return { k, g, e, gb: g === null ? null : bedel(k.dogus, g), eb: bedel(k.dogus, e) };
});
const ortak = satir.filter((s) => s.g !== null);
const yalnizErken = satir.filter((s) => s.g === null);
const kazanmayan = ortak.filter((s) => s.g === s.e);
const top = (l, f) => l.reduce((a, s) => a + f(s), 0);

console.log(`${KALEM.length} kalem; ikisinde de yakalanan ${ortak.length}, ` +
  `gec akisin hic gormedigi ${yalnizErken.length}`);
const gt = top(ortak, (s) => s.gb), et = top(ortak, (s) => s.eb);
console.log(`gec akis ${gt} saat, erken akis ${et} saat, kat ${(gt / et).toFixed(2)}, ` +
  `onlenen ${gt - et} saat`);
console.log(`net kazanc: ${gt - et} - ${DENETIM_YUKU} = ${(gt - et - DENETIM_YUKU).toFixed(1)} saat`);
console.log(`gec akisin hic gormedigi ${yalnizErken.length} kalem erken akista ` +
  `${top(yalnizErken, (s) => s.eb)} saate kapaniyor; gec akista bedeli hic odenmez`);

console.log('\nkazanc nerede yogunlasiyor');
console.log('dogus asamasi   kalem  gec bedel  erken bedel  onlenen  pay %');
for (const [i, a] of ASAMA.entries()) {
  const l = ortak.filter((s) => s.k.dogus === i);
  if (l.length === 0) { console.log(a.padEnd(16) + '0'); continue; }
  const g = top(l, (s) => s.gb), e = top(l, (s) => s.eb);
  console.log(a.padEnd(16) + String(l.length).padEnd(7) + String(g).padEnd(11) +
    String(e).padEnd(13) + String(g - e).padEnd(9) + (((g - e) / (gt - et)) * 100).toFixed(1));
}

// Kazandirmayan kalemler iki ayri sinif: gec dogduklari icin erisilemeyenler ile
// erken dogup yalnizca gec gorunebilenler.
const gecDogan = kazanmayan.filter((s) => s.k.dogus >= 4);
const gecGorunen = kazanmayan.filter((s) => s.k.dogus < 4);
console.log(`\nerken denetimin kazandirmadigi ${kazanmayan.length} kalem, iki sinif`);
console.log('sinif                     kalem  erken akistaki bedel  erken akis bedelinin %');
for (const [ad, l] of [['erken dogup gec gorunen', gecGorunen], ['gec dogan', gecDogan]])
  console.log(ad.padEnd(26) + String(l.length).padEnd(7) + String(top(l, (s) => s.eb)).padEnd(22) +
    ((top(l, (s) => s.eb) / et) * 100).toFixed(1));
for (const s of gecGorunen)
  console.log(`  ${s.k.ad}: ${ASAMA[s.k.dogus]} asamasinda dogar, ${ASAMA[s.e]} ` +
    `asamasinda gorunur, iki akista da ${s.eb} saat`);
```

```
23 kalem; ikisinde de yakalanan 18, gec akisin hic gormedigi 5
gec akis 318 saat, erken akis 68 saat, kat 4.68, onlenen 250 saat
net kazanc: 250 - 32.5 = 217.5 saat
gec akisin hic gormedigi 5 kalem erken akista 10 saate kapaniyor; gec akista bedeli hic odenmez

kazanc nerede yogunlasiyor
dogus asamasi   kalem  gec bedel  erken bedel  onlenen  pay %
gereksinim      2      66         4            62       24.8
tasarim         3      78         6            72       28.8
kod             5      146        42           104      41.6
yapi            2      16         4            12       4.8
dagitim         4      8          8            0        0.0
calisma-zamani  2      4          4            0        0.0

erken denetimin kazandirmadigi 7 kalem, iki sinif
sinif                     kalem  erken akistaki bedel  erken akis bedelinin %
erken dogup gec gorunen   1      34                    50.0
gec dogan                 6      12                    17.6
  sinirsiz-sorgu-boyu: kod asamasinda dogar, calisma-zamani asamasinda gorunur, iki akista da 34 saat
```

Ortak on sekiz kalem üzerinde geç akış **318 saat**, erken akış **68 saat** harcıyor; toplam kat
**4,68**. Bu, tek kalem üzerinden okunan 13–22,5 aralığından epey düşüktür ve düşük olması
gerekir: kat, kalemlerin doğuş dağılımına göre ağırlıklanır ve kümenin dörtte biri zaten dağıtım
ya da çalışma zamanında doğduğu için kazanç üretmez. Bir programın gerçek katı, tek bir kalemin
katından her zaman küçüktür.

Önlenen 250 saatten erken denetimlerin koşum yükü düşüldüğünde **net kazanç 217,5 saat** kalır.
Sayının kendisi kadar biçimi önemlidir: sola kaydırma bir ilke olarak değil, iki kalemli bir
çıkarma olarak yazılabilir hâle gelmiştir. Modelde bulunmayan kurulum, eğitim ve bakım yükleri bu
sayıyı düşürür; bir kurumda karar, önlenen saatin bu üç kalemi de karşılayıp karşılamadığına bakar.

Aynı çıkarma bir başabaş noktası da verir. Önlenen 250 saat, koşum yükünün üstüne en çok 217,5
saatlik kurulum, eğitim ve bakım kaldırabilir; bu eşiğin üstündeki her saat kaydırmayı zarara
çevirir. Altı denetimin kurulumu bu bütçeye sığmıyorsa doğru karar hepsini kurmak değil, kazanç
payı en yüksek olan aşamalardan başlamaktır — ve o sıra bu tablodaki pay sütununda yazılıdır.

Modelin sessiz bir varsayımı burada söylenmelidir: **yakalanan her kalem düzeltiliyor sayıldı.**
Gerçekte yakalanan kalemlerin bir bölümü bilerek ertelenir. Ertelenen kalem, yakalanmamış kalemle
aynı yolu izler ve sonunda geç akıştaki bedeli öder; erken denetim yalnız ödemeyi **görünür**
kılmıştır. Bu yüzden 250 saatlik önleme bir kazanç değil, bir **üst sınırdır**: gerçekleşmesi
yakalanan kalemleri düzeltecek kapasitenin bulunmasına bağlıdır.

Geç akışın hiç görmediği beş kalem karşılaştırmanın dışında tutuldu. Erken akış onları 10 saate
kapatıyor; geç akışta bedelleri **sıfır değil, ödenmemiştir**. Bir düzeltme maliyeti tablosunun en
yanıltıcı satırı budur: hiç bulunmayan kalem, tabloda en ucuz kalem gibi görünür.

Kazanç dağılımı kaydırmanın nereye yapılacağını söylüyor. Önlenen 250 saatin **%41,6'sı** kod
aşamasında doğan kalemlerden, %28,8'i tasarımda, %24,8'i gereksinimde doğanlardan gelir. Yapı
aşamasında doğan kalemler toplamın yalnız %4,8'ini üretir; dağıtım ve çalışma zamanında doğanlar
sıfır üretir. İlk üç aşamaya konan denetim kazancın %95'ini taşır.

## Kaydırmanın Kazandırmadığı Kalem

Son tablo bu dersin asıl bulgusudur. On sekiz kalemin **yedisi** erken denetimden hiçbir şey
kazanmıyor ve bu yedi kalem iki ayrı sınıftır.

Birinci sınıf altı kalemdir ve tanım gereği erişilemez: dağıtımda ya da çalışma zamanında doğarlar.
Bir yapılandırma kalemi ya da sonradan açıklanan bir bağımlılık açığı, tasarım oturumunda
konuşulamaz çünkü o oturum yapıldığında henüz yoktur. Bu sınıfın bedeli düşüktür — erken akış
bedelinin %17,6'sı — çünkü zaten doğdukları aşamada yakalanırlar.

İkinci sınıf tek bir kalemdir ve dersin sert bulgusu odur. `sinirsiz-sorgu-boyu` kod aşamasında
doğar, ancak çalışma zamanında görünür ve iki akışta da **34 saate** mal olur. Erken akışın toplam
68 saatlik bedelinin **tam yarısı** bu tek kalemden gelir. Denetimi ne kadar sola alırsanız alın bu
sayı düşmez, çünkü kodda görülecek bir şey yoktur: yanlış yazılmış bir satır değil, konulmamış bir
sınır vardır ve sınırın gerekli olduğu ancak veri büyüdüğünde ortaya çıkar.

Bu sınıfın ortak yanı, kalemin **varlığının bir ölçeğe, bir veri dağılımına ya da bir dış olaya
bağlı olmasıdır**. Yük altında ortaya çıkan yarışlar, belirli veri hacminden sonra anlam kazanan
sınır yoklukları ve ancak bir dış duyuruyla bilinir hâle gelen bağımlılık açıkları buraya girer.
Bu kalemler için doğru karar kaydırmak değil, çalışma zamanında **görmeyi ucuzlatmaktır** — ölçüm,
sınır denetimi ve geri alma hazırlığı. Sola kaydırmanın kapsamını yazmayan bir program, bu sınıfın
maliyetini de kaydırmanın başarısızlığı olarak okur ve yanlış yere daha çok denetim koyar. Ayrımın
ölçülebilir karşılığı şudur: bir kalemin geç yakalanması denetimin eksikliğinden geliyorsa erken
akış onu ucuzlatır; kalemin kendisi geç görünüyorsa erken akışın bedeli geç akışınkiyle **birebir
aynı** kalır. Tablodaki son sütun tam olarak bu eşitliği arar.

## Özet

- Düzeltme maliyeti çarpan olarak verilmez, geri alınan işten türetilir: temel emek artı doğuştan
  yakalamaya kadar geçilen her aşamanın geri alma bedeli.
- Kat tek bir sayı değildir: gereksinimde doğan kalemde 22,5, dağıtımda doğanda 13. Artış da düzgün
  değildir — tasarımdan koda geçmek 5 kat, koddan yapıya geçmek 1,2 kattır.
- Ortak 18 kalemde geç akış 318 saat, erken akış 68 saat harcar; toplam kat 4,68, önlenen 250 saat.
  Denetim yükü düşüldüğünde net kazanç 217,5 saattir.
- Geç akışın hiç görmediği 5 kalem karşılaştırmanın dışındadır: bedelleri sıfır değil ödenmemiştir,
  erken akış onları 10 saate kapatır.
- Önlenen saatin %95'i ilk üç aşamada doğan kalemlerden gelir; yapıda doğanlar %4,8, dağıtım ve
  çalışma zamanında doğanlar %0 üretir.
- 18 kalemin 7'si erken denetimden hiçbir şey kazanmaz. Altısı geç doğduğu için erişilemez;
  yedincisi kodda doğup yalnız çalışma zamanında görünür ve tek başına erken akış bedelinin
  yarısını taşır.

## Sonraki Adım

Bu ders kaydırmanın kazancını ve sınırını sayıya bağladı, ama kazancın en büyük payını taşıyan
aşamayı kutu içinde bıraktı. Önlenen saatin dörtte biri gereksinim aşamasında doğan kalemlerden
geliyor ve o kalemleri yakalayan denetim tabloda tek satırla geçti: on sekiz gereksinim
incelemesi, beş uyarı, üç gerçek kalem. Bir gereksinim incelemesinin bir kalemi nasıl yakaladığı
hiç açılmadı. Yakalayabilmesi için gereksinimin **sınanabilir** yazılmış olması gerekir; "sistem
güvenli olmalıdır" biçiminde yazılmış bir satır hiçbir incelemede hiçbir kalem üretmez. Sonraki
ders güvenlik gereksinimlerini sınanabilirlik ekseninde sınıflandırır: kaç gereksinim otomatik
sınanabiliyor, kaçı yalnız gözle denetlenebiliyor, kaçı hiç sınanamıyor ve kötüye kullanım
senaryosu yazıldığında listeye kaç yeni gereksinim giriyor.
