# Review — Omurga Chunk 4 (EGT-49) — r4 — teyit turu r2 (blocker kapanışı) — 2026-07-26

> **Review type:** impl-review (dar kapsam — heyet 139'un dört kaleminin teyidi; onaylı gövde kapsam dışı)
> **Previous review:** `review-omurga-chunk4-impl-2026-07-26-r3.md` (heyet 139 — ❌ REJECTED, dar kapsam: F-r3-1 blocker + F-r3-1b + F-r3-2 + tarama kaçağı notu)
> **Upstream document(s) read:** `docs/plans/omurga-plan_chunk5.md` §5.9 D-7, `docs/plans/omurga-plan_chunk9.md` §9.5 S-17
> **Stage locks in effect:** Spec v1.10 + Plan v2.5 locked (pin değişmedi)

**Bağımsız kanıt (bu makinede):** 279/279 test (855 assertion) — CI #731 yeniden üretildi; Pint temiz. Ayrıca canlı e2e (aşağıda).

---

## Kapanış matrisi

| Kalem | Durum | Kanıt |
|---|---|---|
| **F-r3-1** (blocker) — `varchar(255)` taşması | ✅ Kapalı | Kolon `text` (migration:234, ölçümlü yorum :231-233); canlı dev DB şeması da `text` (information_schema'dan doğrulandı — elle DDL değil, migration yoluyla yenilenmiş). Test `stores a long filename without truncating or overflowing` (:373-392): 100+ karakterlik `SGK_hizmet_dokumu_…_12345678901_2026.pdf`, yazılıp aynen geri okunuyor. **Canlı doğrulama:** aynı adın ciphertext'i **424 karakter** — r3'te 256 karakter `varchar(255)`'te patlıyordu, şimdi `INSERT OK` |
| **F-r3-1b** — chunk5 kuralı | ✅ Kapalı | D-7'ye eklendi (`omurga-plan_chunk5.md:168`): *"şifreli kolonun tipi her zaman `text`'tir, `string` değil"* + ölçüm + "TCKN'nin bugün sığması tesadüftür, kural değil" gerekçesi — istenenin birebir kendisi |
| **F-r3-2** — maske değeri | ✅ Kapalı | `anon-rules.sql:71-77`: `MASKED WITH VALUE NULL` + gerekçe (ciphertext kolonu, düz metin maskeli kopyayı `DecryptException` ile düşürürdü, K-2; katmanın neden kaldığı da yazılı). **Canlı e2e:** ciphertext'li probe satırı → dump → maskele → maskeli dump'ta ciphertext **0**, `original_filename` **`\N` (NULL)** |
| **Tarama kaçağı** — `disk(…)->url(` | ✅ Kapalı | S-17 tarifine üçüncü kalıp gerekçesiyle eklendi (`omurga-plan_chunk9.md:96`); arch test needle listesinde `')->url('` (`tests/Arch/SensitiveDataTest.php:175`), çıplak `->url(`'in neden taranmadığı yorumda (:171) — sınır bilinçli ve yazılı |

**Sorulara verilen cevapların uygulanması da teyitli:** `config/crypto.php` konmadı ✓ (dosya yok — doğru karar), N-2'ye ek yapılmadı ✓. **Açık bırakılan kalem doğru sınıflandırılmış:** S-16 senkron bacağı plan değişikliğidir, Sets kararı beklemesi doğru — kayıt bu turun tutanağında ve chunk5 turundan önce karara bağlanmalı ki tarife girecekse chunk9 tek seferde yazılsın.

## Verdict: ✅ APPROVED

Dördü de kapalı ve blocker'ın kapanışı yeterli: kolon tipi + canlı DB şeması + uzun-ad testi + 424 karakterlik ciphertext'in canlıda kabulü — kusurun r3'teki kanıt yöntemiyle birebir aynı yöntemle artık üretilemediği gösterildi. Maske değeri e2e ile NULL doğrulandı; D-7 kuralı chunk5'i aynı tuzaktan koruyor; S-17 kalıbı kaçağı kapatıyor. Chunk 4 bu turla temiz — bekleyen tek karar S-16 senkron bacağıdır (Sets). Son karar Sets'indir.
