---
title: 'Yapılandırma ve Sır Ayrımı'
source: 'https://academia.sh/tr/kurslar/devops-temelleri/yapilandirma-ve-sir-ayrimi'
course: 'DevOps Kültürü ve Temelleri'
language: tr
updated: '2026-08-17T18:09:05+00:00'
license: 'CC BY-SA 4.0'
---

# Yapılandırma ve Sır Ayrımı

Üç ortamın yapılandırma dosyaları diske yazılır ve çalışan bir denetleyici kaç anahtarın gerçekten değiştiğini, kaçının değişmediği hâlde yapılandırmada durduğunu ve kaçının bir ortamda tanımsız olduğunu sayar; sırrın sızabileceği dört yüzey bir tarayıcıyla taranır ve yakalanan, kaçan, yanlış alarm ayrı ayrı yazılır.

Aynı yazılımın üç ortamda aynı yazılım olmasını sağlayan şey kodun aynı olması değildir; kodun
okuduğu değerlerin nerede durduğudur. Bir uygulamanın yapılandırmayı ortamdan okuması, gizli
değerleri kaynaktan ayrı tutması **Sunucu Tarafı Temelleri** kursunda kurulmuştu. Bu ders o
kurulumu tekrarlamaz. Buradaki birim tek uygulama değil, **ortamlar arasındaki fark**tır: kaç
değer ortamdan ortama gerçekten değişiyor, kaçı değişmediği hâlde yapılandırmada duruyor, kaçı
bir ortamda hiç tanımlı değil, ve sır sayılan değerler kaç ayrı yoldan dışarı sızıyor.

Ölçüm **bölgesel ölçüm ağı** üzerinde yapılır: su sayaçlarından okuma toplayan, okumaları
doğrulayan, faturaya çeviren ve saha ekiplerine iş emri açan **kurgu** bir yazılım. Üç ortamı
ve gecelik bir toplu işi vardır. Aşağıdaki dosyalar gerçekten diske yazılır, denetleyiciler
gerçekten koşar; içerdikleri değerlerin tamamı kurgudur ve hiçbiri gerçek bir gizli değer
değildir.

**DK19.** Ortamlar arasındaki tek ayrım yapılandırma dosyalarıdır; kod, yapı çıktısı ve işletim
adımları üç ortamda aynıdır.
**DK20.** Yapılandırma `ANAHTAR=deger` biçiminde düz dosyalarda durur; sır sayılan anahtarlar ad
kalıbıyla belirlenir, ayrı bir sır deposu yoktur.
**DK21.** Sırrın sızabileceği yüzey dörttür ve dördü de diskteki birer dosyayla temsil edilir:
yapı çıktısı, günlük, hata iletisi, sürüm deposuna işlenmiş dosya dizini.
**DK22.** Sızıntılar taramadan önce bilerek yerleştirilir ve sayıları bilinir; kaçanın
sayılabilmesi buna bağlıdır.

## Üç Ortamın Dosyaları

```bash
#!/usr/bin/env bash
# Kurgu bolgesel olcum aginin uc ortam yapilandirmasini diske yazar.
set -e
mkdir -p yapilandirma kaynak

cat > yapilandirma/gelistirme.env <<'SON'
ORTAM_ETIKETI=gelistirme
OLCUM_VERI_ADRESI=127.0.0.1:5432
OLCUM_VERI_HAVUZ=4
OLCUM_VERI_PAROLA=kurgu-gel-p4t9
SAYAC_OKUMA_ZAMAN_ASIMI_MS=2000
DOGRULAMA_ESIK_YUZDE=12
TOPLU_IS_BASLANGIC=02:30
TOPLU_IS_ES_ZAMAN=2
SAHA_IS_EMRI_ADRESI=127.0.0.1:8081
FATURA_PARA_BIRIMI=TRY
KUTUK_DUZEYI=ayrinti
AZAMI_DENEME=3
SON

cat > yapilandirma/sinama.env <<'SON'
ORTAM_ETIKETI=sinama
OLCUM_VERI_ADRESI=olcum-sinama.ic:5432
OLCUM_VERI_HAVUZ=8
OLCUM_VERI_PAROLA=kurgu-sin-r7w2
SAYAC_OKUMA_ZAMAN_ASIMI_MS=2000
DOGRULAMA_ESIK_YUZDE=12
TOPLU_IS_BASLANGIC=02:30
TOPLU_IS_ES_ZAMAN=4
SAHA_IS_EMRI_ADRESI=is-emri-sinama.ic:8081
FATURA_PARA_BIRIMI=TRY
KUTUK_DUZEYI=ayrinti
AZAMI_DENEME=3
SINAMA_TOHUMU=4471
SON

cat > yapilandirma/uretim.env <<'SON'
ORTAM_ETIKETI=uretim
OLCUM_VERI_ADRESI=olcum-uretim.ic:5432
OLCUM_VERI_HAVUZ=32
OLCUM_VERI_PAROLA=kurgu-ure-h3m8
SAYAC_OKUMA_ZAMAN_ASIMI_MS=2000
DOGRULAMA_ESIK_YUZDE=12
TOPLU_IS_BASLANGIC=02:30
TOPLU_IS_ES_ZAMAN=16
FATURA_PARA_BIRIMI=TRY
KUTUK_DUZEYI=ozet
AZAMI_DENEME=3
FATURA_IMZA_ANAHTARI=kurgu-imza-9c1e
SON
```

Uygulamanın okuma noktası tektir ve ortam adına bakan hiçbir dallanma içermez.

```js
// kaynak/ayar.mjs — kurgu uygulamanin tek ayar noktasi: her deger ortamdan okunur.
export const ayar = {
  ortam:         process.env.ORTAM_ETIKETI,
  veriAdresi:    process.env.OLCUM_VERI_ADRESI,
  parola:        process.env.OLCUM_VERI_PAROLA,
  isEmriAdresi:  process.env.SAHA_IS_EMRI_ADRESI,
  imzaAnahtari:  process.env.FATURA_IMZA_ANAHTARI,
  havuz:         Number(process.env.OLCUM_VERI_HAVUZ),
  zamanAsimiMs:  Number(process.env.SAYAC_OKUMA_ZAMAN_ASIMI_MS ?? 2000),
  esikYuzde:     Number(process.env.DOGRULAMA_ESIK_YUZDE ?? 12),
  topluBaslangic: process.env.TOPLU_IS_BASLANGIC ?? "02:30",
  esZaman:       Number(process.env.TOPLU_IS_ES_ZAMAN ?? 2),
  paraBirimi:    process.env.FATURA_PARA_BIRIMI ?? "TRY",
  kutukDuzeyi:   process.env.KUTUK_DUZEYI ?? "ozet",
  azamiDeneme:   Number(process.env.AZAMI_DENEME ?? 3),
  yenidenOkumaGun: Number(process.env.YENIDEN_OKUMA_GUN ?? 30),
};
```

## Farkın Sayımı

Denetleyici üç dosyayı ve kaynağın okuma noktalarını ayrı ayrı okur, sonra ikisini karşılaştırır.

```js
// denetle.mjs — uc ortam dosyasi ile kaynaktaki okuma noktalarini karsilastirir.
import { readFileSync } from "node:fs";

const ORTAMLAR = ["gelistirme", "sinama", "uretim"];
const oku = (a) => Object.fromEntries(readFileSync(`yapilandirma/${a}.env`, "utf8")
  .split("\n").filter(Boolean).map((s) => [s.slice(0, s.indexOf("=")), s.slice(s.indexOf("=") + 1)]));

const dosya = Object.fromEntries(ORTAMLAR.map((a) => [a, oku(a)]));
const anahtarlar = [...new Set(ORTAMLAR.flatMap((a) => Object.keys(dosya[a])))].sort();

const kaynak = readFileSync("kaynak/ayar.mjs", "utf8");     // hangi anahtar okunuyor,
const okunan = new Map();                                   // kacinin gomulu varsayilani var
for (const [, ad, vars] of kaynak.matchAll(/process\.env\.([A-Z_]+)(\s*\?\?)?/g))
  okunan.set(ad, Boolean(vars));

const say = { degisen: [], sabit: [], eksik: [] };
for (const k of anahtarlar) {
  const v = ORTAMLAR.map((a) => dosya[a][k]);
  if (v.some((x) => x === undefined)) say.eksik.push(k);
  else if (new Set(v).size === 1) say.sabit.push(k);
  else say.degisen.push(k);
}
const gizliVarsayilan = [...okunan].filter(([k]) => !anahtarlar.includes(k)).map(([k]) => k);
const zorunlu = [...okunan].filter(([, v]) => !v).map(([k]) => k);

const yaz = (etiket, liste) => {                            // sayiyi bas, adlari ucerli sar
  console.log(`${etiket.padEnd(30)}: ${liste.length}`);
  for (let i = 0; i < liste.length; i += 3) console.log("    " + liste.slice(i, i + 3).join(" "));
};
console.log(`toplam anahtar (uc dosyada)   : ${anahtarlar.length}`);
yaz("  ucunde var, degeri farkli", say.degisen);
yaz("  ucunde var, degeri ayni", say.sabit);
yaz("  en az bir ortamda eksik", say.eksik);
console.log(`kaynagin okudugu anahtar      : ${okunan.size}, varsayilansiz: ${zorunlu.length}`);
yaz("  hicbir ortam dosyasinda yok", gizliVarsayilan);
yaz("  dosyada var, kaynak okumuyor", anahtarlar.filter((k) => !okunan.has(k)));
for (const a of ORTAMLAR)
  yaz(`kosumda patlar / ${a}`, zorunlu.filter((k) => dosya[a][k] === undefined));
```

```
toplam anahtar (uc dosyada)   : 14
  ucunde var, degeri farkli   : 6
    KUTUK_DUZEYI OLCUM_VERI_ADRESI OLCUM_VERI_HAVUZ
    OLCUM_VERI_PAROLA ORTAM_ETIKETI TOPLU_IS_ES_ZAMAN
  ucunde var, degeri ayni     : 5
    AZAMI_DENEME DOGRULAMA_ESIK_YUZDE FATURA_PARA_BIRIMI
    SAYAC_OKUMA_ZAMAN_ASIMI_MS TOPLU_IS_BASLANGIC
  en az bir ortamda eksik     : 3
    FATURA_IMZA_ANAHTARI SAHA_IS_EMRI_ADRESI SINAMA_TOHUMU
kaynagin okudugu anahtar      : 14, varsayilansiz: 6
  hicbir ortam dosyasinda yok : 1
    YENIDEN_OKUMA_GUN
  dosyada var, kaynak okumuyor: 1
    SINAMA_TOHUMU
kosumda patlar / gelistirme   : 1
    FATURA_IMZA_ANAHTARI
kosumda patlar / sinama       : 1
    FATURA_IMZA_ANAHTARI
kosumda patlar / uretim       : 1
    SAHA_IS_EMRI_ADRESI
```

On dört anahtarın yalnız altısı üç ortamda tanımlı ve değeri gerçekten farklı. **Farkın
saklandığı yer bu altı satırdır.** Geri kalan sekiz anahtar farkı değil, farkın görüntüsünü
taşır.

Beş anahtar üç ortamda da aynı değeri taşıyor. Bunlar yapılandırma değil, sabittir; yapılandırma
dosyasında durmalarının bir bedeli vardır: tek bir ortamda elle değiştirilebilirler.
`DOGRULAMA_ESIK_YUZDE` üretimde on ikiden on beşe çekildiğinde doğrulama davranışı sessizce
ayrışır ve bu değişiklik hiçbir kod incelemesine düşmez, çünkü kod değişmemiştir.

Bildirilmiş fark ile yalnız koşumda görünen fark burada ayrışır. Bildirilmiş olan, dosyalardaki
altı satırdır: yazılıdır, okunabilir, karşılaştırılabilir. Yalnız koşumda görünen ise ikiye
ayrılır. `YENIDEN_OKUMA_GUN` hiçbir ortam dosyasında yok; kaynakta varsayılanı otuz. Yani
**dördüncü bir ortam tanımı kaynağın içinde duruyor** ve üç ortamın hepsi onu kullanıyor.
Değerini değiştirmek için yapılandırma değil kod değiştirmek gerekir; yapılandırmanın ortamda
durması ilkesi tam burada kırılır ve kırıldığı hiçbir dosyadan okunmaz. `SINAMA_TOHUMU` bunun
aynası: sınama dosyasında yazılı ama kaynak onu hiç okumuyor. Bildirilmiş bir farkın etkili
olduğu varsayılamaz; sınamanın sabit tohumla koştuğunu sanan biri, tohumsuz koşan bir sınamaya
bakıyor.

Farkın gizlediği hata sınıfı, eksik anahtarların dağılımında görülür. `SAHA_IS_EMRI_ADRESI`
yalnız üretimde eksik: iş emri açma yolu geliştirme ve sınamada sorunsuz koşar, üretimde ilk iş
emrinde tanımsız bir adrese gider. Bu hata sınıfının adı **yalnız üretimde görünen yol**dur ve
sınama onu göremez, çünkü sınamada eksik olan şey yoktur. `FATURA_IMZA_ANAHTARI` bunun tersidir:
yalnız üretimde tanımlı olduğu için imzalama yolu üretim dışında hiç koşmamıştır. İki eksiklik
aynı sayıya sahiptir — her ortamda bir tane — ama biri üretimde patlar, öteki üretimde ilk kez
denenir.

## Farkın Ne Zaman Göründüğü

Sayım her ortamda bir eksik zorunlu anahtar bildirdi; eksikliğin **ne zaman** görüneceğini
bildirmedi. Aynı sayı iki ayrı hata sınıfına karşılık gelir ve aradaki farkı belirleyen şey,
uygulamanın o anahtarı açılışta mı yoksa ilk kullanımda mı okuduğudur.

```js
// baslat.mjs — acilista zorunlu anahtarlari dogrular; imza yolu ise is aninda calisir.
import { ayar } from "./kaynak/ayar.mjs";

const ACILIS_ZORUNLU = ["ortam", "veriAdresi", "parola", "isEmriAdresi"];
const eksik = ACILIS_ZORUNLU.filter((k) => ayar[k] === undefined);
if (eksik.length) {
  console.log(`  acilis reddedildi -> eksik: ${eksik.join(", ")}`);
  process.exit(1);
}
console.log(`  acildi -> havuz=${ayar.havuz} esZaman=${ayar.esZaman} kutuk=${ayar.kutukDuzeyi}`);
try {                                                  // gecelik toplu isin imzalama adimi
  if (!ayar.imzaAnahtari) throw new Error("imza anahtari tanimsiz");
  console.log(`  03:00 toplu is -> imzalandi`);
} catch (h) {
  console.log(`  03:00 toplu is -> basarisiz: ${h.message}`);
}
```

```bash
#!/usr/bin/env bash
# Her ortamin dosyasini yukleyip uygulamayi ayri ayri baslatir.
for o in gelistirme sinama uretim; do
  echo "$o:"
  ( set -a; . "yapilandirma/$o.env"; set +a; node baslat.mjs ) || true
done
```

```
gelistirme:
  acildi -> havuz=4 esZaman=2 kutuk=ayrinti
  03:00 toplu is -> basarisiz: imza anahtari tanimsiz
sinama:
  acildi -> havuz=8 esZaman=4 kutuk=ayrinti
  03:00 toplu is -> basarisiz: imza anahtari tanimsiz
uretim:
  acilis reddedildi -> eksik: isEmriAdresi
```

Üç ortamın üçünde de bir zorunlu anahtar eksikti ve sayı üçünde de birdi. Koşum üç ayrı sonuç
verdi. Üretim açılışta reddedildi: bu, eksikliğin en ucuz biçimidir, çünkü hata dağıtımı yapan
kişinin gözü ekrandayken görünür. Geliştirme ve sınama açıldı ve hata gece üçte, gecelik toplu
işin ortasında çıktı. Eksiklik aynı, bedeli değil — **farkı yaratan tek şey açılış denetimi
listesinin uzunluğudur.** `imzaAnahtari` o listede olmadığı için üç ortamda da geç patlar.

Çıktıda ölçümün konusu olmayan iki fark daha yazılı. Kütük düzeyi iki ortamda ayrıntı, üretimde
özettir. Yalnız üretimde görünen bir yolun kaydı, yalnız üretimde kısılmış bir kütükle tutuluyor:
fark, ürettiği hatayı görecek sinyali de aynı ortamda kısar. Gecelik toplu işin eş zamanlılığı
ise iki, dört ve on altıdır. Sınamada dört koşucuyla geçen bir yarış durumu üretimde on altı
koşucuyla ilk gecede görünür. Bu bildirilmiş bir farktır, dosyada yazılıdır — ama bildirilmiş
olması sınandığı anlamına gelmez.

Bu üç değeri kimin değiştirdiği de ayrı bir sorudur. Havuz büyüklüğü, eş zamanlılık ve kütük
düzeyi işleten ekibin elindedir ve genellikle bir olaydan sonra değişir; doğrulama eşiği ile
ödeme biçimi yazan ekibin kararıdır. İkisi aynı dosyada durduğu için değişiklikler aynı görünür
ve hangi farkın hangi ekipten geldiği ancak dosya geçmişine bakılarak ayrılır.

## Sırrın Dört Çıkış Yolu

Sır da ortamdan ortama değişen bir değerdir ve buraya kadarki sayıma dahildir. Ayrı sayılmasının
nedeni tek bir asimetridir: yanlış bir bağlantı noktası düzeltilir, sızmış bir sır düzeltilemez;
yalnız değiştirilebilir ve değiştirilene kadar geçerli kalır. Sızabileceği dört yüzey aşağıda
kurgu içerikle diske yazılır.

```bash
#!/usr/bin/env bash
# Dort yuzey: yapi ciktisi, gunluk, hata iletisi, surum deposuna islenmis dosya dizini.
set -e
mkdir -p yapi kutuk hata

cat > yapi/paket.mjs <<'SON'
// Yapi cikti dosyasi (kurgu): kaynak, uretim degerleriyle birlikte tek dosyaya toplandi.
const ayar = {
  adres: "olcum-uretim.ic:5432",
  OLCUM_VERI_PAROLA: "kurgu-ure-h3m8",
  imza: "kurgu-imza-" + "9c1e",
};
export const baglan = () => ayar;
SON

cat > kutuk/gecelik.jsonl <<'SON'
{"an":"03:12:04","olay":"toplu_is_basladi","ortam":"uretim","sayac":48210}
{"an":"03:12:04","olay":"veri_baglantisi","baglanti":"olcum:kurgu-ure-h3m8@olcum-uretim.ic:5432"}
{"an":"03:12:05","olay":"ayar_ozeti","OLCUM_VERI_PAROLA":"****","KUTUK_DUZEYI":"ozet"}
{"an":"04:41:19","olay":"fatura_imzalandi","imzaB64":"a3VyZ3UtaW16YS05YzFl","adet":48210}
SON

cat > hata/son-hata.txt <<'SON'
Yakalanmayan hata: fatura imzasi dogrulanamadi (gecelik toplu is, uretim)
  istek : POST /fatura/imzala?imza=kurgu-imza-9c1e
  ayar  : { ortam: 'uretim', OLCUM_VERI_PAROLA: 'kurgu-ure-h3m8', havuz: 32 }
  yigin : toplu-is.mjs:118 -> imzala.mjs:42
SON

cat > depo-dizini.txt <<'SON'
kaynak/ayar.mjs
yapilandirma/ornek.env
yapilandirma/uretim.env
paket.json
SON
```

Tarayıcının iki kuralı vardır: sır değerinin birebir eşleşmesi ve sır anahtarı ad kalıbı.

```js
// tarayici.mjs — dort yuzeyde sir arar; kural=deger birebir esleme, kural=ad ad kalibi.
import { readFileSync } from "node:fs";

const YUZEY = { yapi: "yapi/paket.mjs", kutuk: "kutuk/gecelik.jsonl",
                hata: "hata/son-hata.txt", depo: "depo-dizini.txt" };
const AD_KALIBI = /PAROLA|ANAHTAR|\.env$/;

const degerler = ["gelistirme", "sinama", "uretim"]              // uc dosyadaki sir degerleri
  .flatMap((a) => readFileSync(`yapilandirma/${a}.env`, "utf8").split("\n").filter(Boolean))
  .filter((s) => AD_KALIBI.test(s.slice(0, s.indexOf("="))))
  .map((s) => s.slice(s.indexOf("=") + 1));

const bulgu = [];
for (const [ad, yol] of Object.entries(YUZEY))
  readFileSync(yol, "utf8").split("\n").filter(Boolean).forEach((satir, i) => {
    const kural = [degerler.some((d) => satir.includes(d)) && "deger",
                   AD_KALIBI.test(satir.trim()) && "ad"].filter(Boolean);
    if (kural.length) bulgu.push({ ad, satirNo: i + 1, satir, kural: kural.join("+") });
  });

// Yerlestirilmis sizintilar: yuzey adi + o satirin ayirt edici izi.
const YERLESIK = [["yapi", "OLCUM_VERI_PAROLA:"], ["yapi", 'imza: "kurgu-imza-'],
  ["kutuk", '"baglanti"'], ["kutuk", '"imzaB64"'], ["hata", "OLCUM_VERI_PAROLA:"],
  ["hata", "imza=kurgu"], ["depo", "uretim.env"]];

const eslesen = (b) => YERLESIK.some(([y, iz]) => y === b.ad && b.satir.includes(iz));
const kacan = YERLESIK.filter(([y, iz]) => !bulgu.some((b) => b.ad === y && b.satir.includes(iz)));

console.log(`sir degeri: ${degerler.length}   yuzey: ${Object.keys(YUZEY).length}   ` +
  `yerlestirilen sizinti: ${YERLESIK.length}   bildirilen satir: ${bulgu.length}`);
console.log(`yakalanan: ${YERLESIK.length - kacan.length}   kacan: ${kacan.length}   ` +
  `yanlis alarm: ${bulgu.filter((b) => !eslesen(b)).length}`);
for (const b of bulgu)
  console.log(`  [${eslesen(b) ? "gercek" : "YANLIS"}] ${b.ad}:${b.satirNo}  kural=${b.kural}`);
for (const [y, iz] of kacan) console.log(`  [KACAN ] ${y}  iz=${iz}`);
```

```
sir degeri: 4   yuzey: 4   yerlestirilen sizinti: 7   bildirilen satir: 7
yakalanan: 5   kacan: 2   yanlis alarm: 2
  [gercek] yapi:4  kural=deger+ad
  [gercek] kutuk:2  kural=deger
  [YANLIS] kutuk:3  kural=ad
  [gercek] hata:2  kural=deger
  [gercek] hata:3  kural=deger+ad
  [YANLIS] depo:2  kural=ad
  [gercek] depo:3  kural=ad
  [KACAN ] yapi  iz=imza: "kurgu-imza-
  [KACAN ] kutuk  iz="imzaB64"
```

## Yakalanan, Kaçan, Yanlış Alarm

Tarayıcı yedi satır bildirdi, yerleştirilmiş sızıntı da yedi. **Sayılar eşit, kümeler değil.**
Bu eşitlik, bir tarama raporunun toplamına bakarak kapsama karar veren her okuma için uyarıdır.

Kaçan iki sızıntının ortak yanı, sır değerinin aranan biçimde durmamasıdır. Biri birleştirmeyle
ikiye bölünmüş (`"kurgu-imza-" + "9c1e"`), öteki taban altmış dörde çevrilmiş
(`a3VyZ3UtaW16YS05YzFl`). İkisi de aynı sırrı taşır, ikisi de değer eşleme kuralının dışında
kalır. Bunun genel biçimi şudur: **birebir değer araması, değeri dönüştüren her adımın gerisinde
kalır** — yapı aracının satır birleştirmesi, günlük yazıcısının kodlaması, ileti biçimlendiricinin
kısaltması. Yakalanan beş sızıntının hepsi değerin olduğu gibi durduğu satırlardır.

Yakalama oranını yükseltmenin yolu bellidir: aranan değerin dönüşmüş biçimleri de üretilir —
kodlanmış hâli, kısaltılmış hâli, parçalarının her biri — ve hepsi ayrı ayrı aranır. Bunun
bedeli doğrudan yanlış alarma yazılır: değer kısaldıkça rastgele eşleşme olasılığı büyür ve
`9c1e` gibi dört karakterlik bir parça normal metinde de bulunur. İki kural arasındaki ilişki
budur; kaçanı azaltan her genişletme yanlış alarmı artırır, ve iki sayı ayrı ayrı yazılmadıkça
hangisinin arttığı görünmez.

Yanlış alarmların ikisi de ad kuralından gelir ve ikisi de **doğru davranışın kendisidir**:
maskelenmiş kütük satırı sırrı gizlemek için yazılmıştır, örnek yapılandırma dosyası ise
sürüm deposunda bulunması gereken şeydir. Bedeli sayısal değil davranışsaldır. İki yanlış alarm
listeye girdiğinde listeyi okuyan kişi bir sonraki taramada satırlara tek tek bakmaz; kaçan iki
sızıntının bulunma olasılığı, yanlış alarmların sayısıyla birlikte düşer.

Dört yüzeyin sahipleri de ayrıdır: yapı çıktısı derleme adımının, günlük işletimin, hata iletisi
uygulama kodunun, depo dizini sürüm kontrolünün alanındadır. Bir yüzeyde sızıntı kapatıldığında
ötekiler açık kalır, çünkü kapatan kişi yalnız kendi yüzeyini görür. Sayının burada verdiği karar
şudur: sır ayrımı tek bir yerde alınan bir karar değil, dört ayrı yüzeyde ayrı ayrı korunan bir
sınırdır.

## Özet

- Üç ortam dosyasındaki on dört anahtarın altısı gerçekten değişiyor; farkın saklandığı yer bu
  altı satırdır. Beş anahtar üç ortamda da aynı değeri taşıyor, yani yapılandırma değil sabit.
- Üç anahtar en az bir ortamda eksik; zorunlu altı anahtardan biri her ortamda tanımsız kalıyor.
  Üretimde eksik olan iş emri adresi yalnız üretimde patlar, yalnız üretimde tanımlı imza anahtarı
  ise imzalama yolunu üretim dışında hiç koşturmaz.
- Koşumda aynı sayı üç ayrı sonuç verdi: üretim açılışta reddedildi, öteki iki ortam açıldı ve
  gece üçte toplu işin ortasında düştü. Farkı yaratan şey açılış denetimi listesinin uzunluğudur.
- Bildirilmiş fark dosyalardaki altı satırdır; yalnız koşumda görünen fark, kaynağa gömülü
  varsayılanla tanımlanan dördüncü ortam (`YENIDEN_OKUMA_GUN`) ve hiçbir kodun okumadığı ölü
  anahtardır (`SINAMA_TOHUMU`).
- Dört yüzeye yerleştirilen yedi sızıntıdan beşi yakalandı, ikisi kaçtı; kaçanların ikisi de
  değerin dönüştürülmüş hâliydi (birleştirme ve taban altmış dört).
- Tarayıcı yedi satır bildirdi, sızıntı da yedi taneydi; ikisi yanlış alarmdı ve ikisi de doğru
  davranışı işaretliyordu. Toplam sayının eşitliği kapsama kanıtı değildir.

## Sonraki Adım

Yapılandırmanın ortamda durması tek başına duran bir kural değil, birbirine bağlı bir kümenin
üyesidir; bu ders o kümenin bir üyesini ölçtü ve ölçerken kuralın kaynağa gömülü varsayılanla
sessizce kırıldığını gördü. Kümenin tamamı **Sunucu Tarafı Temelleri** kursunda adlarıyla
kurulmuştu. Sonraki ders o adları tekrarlamak yerine tek bir soru sorar: her ilke, diskteki
dosyalar üzerinde koşan bir denetime çevrilebiliyor mu? Çevrilebilenler kurgu uygulamanın gerçek
dosyaları üzerinde koşturulur, yakalananla kaçan ayrı sayılır; çevrilemeyenler için de yerine ne
konduğu yazılır.
