# `.fikocad` Asenkron Kaydet/Yükle + İlerleme + Küçük Boyut — Tasarım

Salt tasarım (kod yok). Amaç: dosya kaydet/yükle uzun sürerken **UI donmasın**,
**gerçek ilerleme** gösterilsin ve **dosya boyutu küçülsün** (taşınabilir aygıt dostu).

## 0. Mevcut durum tespiti (ne var, ne eksik)

| Parça | Konum | Durum |
|-------|-------|-------|
| Saf format çekirdeği | `motor/io/src/fiko_format.cpp:157` `fikoYaz` / `:231` `fikoOku` | ✅ Sahne/Vulkan'sız, test edilebilir, `std::string` tampon üstünde |
| Sahne düzeyi kaydet | `fiko_format.cpp:341` `fikoKaydet` | ⚠️ **SENKRON** — snapshot + BinTools serialize + deflate + disk yazma hepsi ana-thread'te bloklar |
| Sahne düzeyi yükle | `fiko_format.cpp:439` `fikoYukle` | ⚠️ **SENKRON** — read + inflate + parse + **BinTools deserialize + `ucgenle` (ağır)** + GPU yükleme hepsi ana-thread'te bloklar |
| Sıkıştırma | `fiko_format.cpp:83` `sikistir` / `:95` `coz` | ⚠️ miniz `mz_compress2(... , 6)` — **seviye 6** (orta), zstd yok |
| B-rep serileştirme | `motor/geometri/src/brep_io.cpp:272` `govdeBaytYaz` | ⚠️ `BinTools::Write(sekil, akis)` — **2 argümanlı overload → `WithTriangles=true, WithNormals=true`** (üçgenleme + normaller dosyaya gömülüyor; yüklemede zaten `ucgenle` ile yeniden üretiliyor → **gereksiz şişme**) |
| Uygulama teli (kaydet) | `uygulama/fikocad/dosya_islemleri.cpp:408` `fikoKaydetKomut` | ⚠️ senkron çağırıyor |
| Uygulama teli (aç) | `dosya_islemleri.cpp:392` `fikoYol` / `:404` `fikoAc` | ⚠️ senkron çağırıyor |
| Menü / kısayol | `main.cpp:868-869` (Dosya menü), `main.cpp:1692-1693` (Ctrl+S/Ctrl+O) | ✅ bağlı, sadece hedef fonksiyon async olacak |
| **İş sistemi (worker havuzu)** | `motor/cekirdek/src/gorev.cpp` — `GorevSistemi` | ✅ **HAZIR**: worker havuzu + atomik ilerleme + iptal + **ana-thread finalize** (`pompala`) + olay (`GorevBasladi`/`GorevBitti`) |
| **İlerleme UI** | `main.cpp:3555-3594` "İşlemler" paneli | ✅ **HAZIR**: `gorevler().anlik()` okur, `ProgressBar` + `%` + adım metni + `✕` iptal düğmesi çizer, yeni iş gelince otomatik açılır |
| STEP async referans deseni | `dosya_islemleri.cpp:73` `stepYol` | ✅ **BİRE BİR ÖRNEK**: `kuyrukla(baslik, worker, finalize)` + `b.ilerlet(oran, mesaj)` + `b.iptalIstendi()` + `.fkcache` |

**Ana bulgu:** Async altyapı ve ilerleme UI'ı **zaten mevcut ve STEP import bunu kullanıyor.**
Yeni sistem yazılmayacak — `.fikocad` kaydet/yükle **aynı `GorevSistemi` desenine** taşınacak
(`stepYol` kalıbının ikizi). Mükerrer iş yok.

---

## 1. Asenkron iş modeli

### 1.1 Thread güvenliği ilkesi (değişmez)

`GorevBaglam` sözleşmesi (`motor/cekirdek/include/fiko/cekirdek/gorev.hpp:22-24`):
worker thread **yalnız saf CPU** yapar — **Sahne / ECS / OlayGunlugu / Vulkan'a ASLA
dokunmaz**. Sahne mutasyonu + GPU yükleme + olay yayını yalnız `finalize` (ana-thread,
`pompala()` içinde) güvenlidir. Vulkan tek-thread'dir; tampon üretimi/submit ana-thread'te kalır.

### 1.2 YÜKLE (aç) akışı — 3 faz

STEP import'un (`dosya_islemleri.cpp:73` `stepYol`) birebir kalıbı:

```
fikoYolAsync(b, yol):
  cekirdek.gorevler().kuyrukla("Belge Açılıyor",
    WORKER (saf CPU):                              // UI bloklamaz
      1. disk oku          → ilerlet(0.05, "Dosya okunuyor")
      2. fikoOku(veri,belge) (inflate + POD parse) → ilerlet(0.15, "Çözülüyor")
      3. her düğüm için (n/toplam ile oranla):
           govdeBaytOku(brep)  (BinTools deserialize)
           yuzRenkleriAta      (varsa)
           ucgenle / kenarMesh / noktaMesh  (AĞIR)  → ilerlet(0.15..0.95, "Ağ üretiliyor")
         → sonuç: shared_ptr<vector<HazirDugum>> (mesh + IthalGovde, GPU'suz)
         → iptalIstendi() her düğümde kontrol; erken dön
    FINALIZE (ana-thread):                          // GPU + Sahne + kamera
      vulkan().bekle(); topluYuklemeBasla();
      grupları kur + eski→yeni kimlik haritası + üst bağlar
      her HazirDugum → ithalEkleHazir(mesh,kenar,nokta)  (TEK submit)
      topluYuklemeBitir();
      kamera.durumAta(...) + hassasiyetler
      bilgiVer("Belge açıldı")
  )
```

**Kritik ayrım:** Bugün `fikoYukle` (`fiko_format.cpp:439`) içinde `ucgenle`/`kenarMesh`/
`noktaMesh` (satır 486-488) **ana-thread'te** çalışıyor — asıl donma kaynağı bu. Bunlar
**tamamen saf CPU** (Vulkan yok) → **worker'a taşınır**. Sadece `ithalEkleHazir` + GPU
tampon yüklemesi (satır 499, `topluYukleme*`) finalize'de kalır.

**Paralel tessellation (opsiyonel, Dalga 2b):** STEP import FAZ2'deki (`dosya_islemleri.cpp:264-299`)
gövdeler-arası paralel mesh deseni aynen uygulanabilir — ama önce **seri derin kopya**
(`govdeDerinKopya`, `dosya_islemleri.cpp:273`) ile paylaşımlı OCCT geometri koparılmalı
(data-race guard). Tek gövdeli/küçük belgede gereksiz; büyük montajda 5-20×.

### 1.3 KAYDET akışı — snapshot ana-thread, ağır iş worker

Kaydette ters yön: Sahne/ECS okuması ana-thread'te, ağır serileştirme+sıkıştırma worker'da.

```
fikoKaydetAsync(b, yol):
  // ADIM A — SNAPSHOT (ana-thread, HIZLI, kuyruklamadan ÖNCE):
  //   fikoKaydet'in ilk yarısı (fiko_format.cpp:341-414): ECS gez, FikoBelge doldur.
  //   B-rep için İKİ seçenek (bkz. §1.4):
  //     (v1) govdeBaytYaz'ı burada çağır → FikoBelge.brep string dolu (ana-thread OCCT)
  //     (v2) brep shared_ptr / derin-kopya kilitle → serileştirme worker'a taşınır
  //   → shared_ptr<FikoBelge> üret (kopya, worker'a taşınır)
  cekirdek.gorevler().kuyrukla("Belge Kaydediliyor",
    WORKER (saf CPU):
      1. (v2 ise) her düğüm govdeBaytYaz → ilerlet(0.0..0.5, "Geometri yazılıyor")
      2. fikoYaz(belge, veri)  (POD pack + chunk deflate/zstd) → ilerlet(0.5..0.9, "Sıkıştırılıyor")
      3. atomik yaz: yol+".tmp" → fsync → rename (fiko_format.cpp:419-433 mantığı)
                                                → ilerlet(1.0, "Yazıldı")
    FINALIZE (ana-thread):
      MRU ekle (sonDosyaEkle) + bilgiVer("Belge kaydedildi")
  )
```

### 1.4 Snapshot'ta B-rep — thread güvenliği kararı

OCCT `TopoDS_Shape` **paylaşımlı, thread-güvensiz** (kardeş gövdeler alt Geom'ları paylaşır).
Kullanıcı kaydet sırasında 3D'de çalışmaya devam edince gövde mutasyona uğrayabilir.

- **Dalga 2 (basit, güvenli):** `govdeBaytYaz` (BinTools serialize) **ana-thread snapshot'ta**
  kalır; worker sadece `fikoYaz` POD-pack + deflate/zstd + disk yazar (saf `std::string` işi).
  Snapshot birkaç yüz ms sürebilir ama **atomik** (tutarlı görüntü). Küçük/orta belgede yeterli.
- **Dalga 2b (büyük belge, isteğe bağlı):** Snapshot'ta gövdelerin `govdeDerinKopya`'sı
  (`brep_io.cpp` mevcut) alınır → paylaşım kopar → **serileştirme worker'a taşınır** (paralel).
  Böylece BinTools maliyeti de UI dışına çıkar. Derin kopya ucuz, serialize pahalı.

### 1.5 İptal

- Zaten hazır: `GorevBaglam::iptalIstendi()` (`gorev.cpp:34`) + UI'daki `✕` düğmesi
  (`main.cpp:3584` → `gorevler().iptalEt`).
- Worker döngüleri her düğümde `iptalIstendi()` kontrol edip erken döner (STEP: `dosya_islemleri.cpp:272,285`).
- İptal/hata → `finalize` **çağrılmaz** (`gorev.cpp:124`) → yarım sahne kurulmaz, GPU'ya hiçbir şey yüklenmez.
- Kaydet iptali: `.tmp` dosyası silinir (finalize yok; worker erken dönerken temizler) →
  hedef dosya **hiç dokunulmaz** (atomik rename yapılmadığından eski dosya bozulmaz).

### 1.6 Eşzamanlılık koruması

- Aynı belge iki kez kuyruklanmasın: `main.cpp` komut tarafında basit bir "kaydet/yükle iş
  aktif mi" bayrağı (`GorevSistemi::anlik()` başlıklarına bakarak ya da `UygulamaBaglam`'da
  `atomic<bool> dosyaIsiAktif`) → aktifken tekrar Ctrl+S yut + `bilgiVer("Kayıt sürüyor...")`.
- Kaydet worker'ı çalışırken kullanıcı 3D'de düzenleme yaparsa: Dalga 2 snapshot'u zaten
  kopya olduğundan sonuç tutarlı; ama "kaydettikten sonraki değişiklik kaydedilmedi" doğal.

---

## 2. İlerleme (progress) göstergesi

**Yeni UI yazılmayacak.** `main.cpp:3555-3594` "İşlemler" paneli her kare `gorevler().anlik()`'ı
okuyup `ProgressBar` + `%` + adım metni + `✕` çiziyor; yeni iş gelince otomatik açılıyor
(FikoUi "Koyu" tema, sis yok). `.fikocad` işleri `kuyrukla` ile girer girmez **bedavaya** görünür.

Gerçek ilerleme için worker'da `b.ilerlet(oran, "adım")` çağrıları (chunk/düğüm bazlı):

| İş | Oran aralığı | Adım metni |
|----|-------------|-----------|
| Yükle | 0.05 | "Dosya okunuyor" |
| Yükle | 0.15 | "Çözülüyor" (inflate) |
| Yükle | 0.15→0.95 | "Ağ üretiliyor (%d/%d)" (düğüm bazlı, `n/toplam`) |
| Kaydet | 0.0→0.5 | "Geometri yazılıyor" (v2: düğüm bazlı) |
| Kaydet | 0.5→0.9 | "Sıkıştırılıyor" |
| Kaydet | 1.0 | "Yazıldı" |

- **Büyük dosya:** panel belirgin, çubuk ilerler, iptal edilebilir.
- **Küçük dosya:** iş milisaniyede biter → panel bir kare görünür ya da hiç görünmez (doğal, spam yok).
- **Açılış splash'ı (`acilis_splash.hpp`) KULLANILMAZ** — o yalnız uygulama başlangıcı için
  (Vulkan/ImGui context'ten önce GDI). Dosya işlemleri ImGui yaşarken olur → "İşlemler" paneli doğru araç.

**Not — ilerleme granülerliği:** `fikoOku`/`fikoYaz` saf çekirdek (`fiko_format.cpp`) şu an
tek çağrı. Düğüm-bazlı ilerleme için ya (a) worker döngüsü `fikoOku` yerine chunk'ları kendi
gezip düğüm başına `ilerlet` çağırır, ya da (b) çekirdeğe **opsiyonel progress callback**
parametresi eklenir (bkz. §4). (b) daha temiz ve test edilebilir kalır.

---

## 3. Daha küçük dosya boyutu (taşınabilir aygıt dostu)

### 3.1 EN BÜYÜK KAZANÇ — üçgenlemeyi B-rep'ten çıkar

**Bulgu:** `brep_io.cpp:276` `BinTools::Write(sekil(g), akis)` — 2 argümanlı overload OCCT'de
`WithTriangles=true, WithNormals=true` varsayar. Gövde `ucgenle` ile mesh'lendiğinden (her zaman),
**üçgenleme + düğüm normalleri TopoDS içinde tutulur ve dosyaya gömülür.** Oysa `.fikocad` yüklemede
`ucgenle`'yi **zaten yeniden çağırıyor** (`fiko_format.cpp:486`) → gömülü mesh **tamamen gereksiz**.

**Çözüm:** `govdeBaytYaz`'a `bool ucgenlerDahil = false` parametresi (varsayılan: çıkar) →
`BinTools::Write(sekil(g), akis, /*triangles*/false, /*normals*/false)`. Karmaşık modellerde
dosya boyutunu **önemli oranda** düşürür (mesh, B-rep'ten sık sık büyüktür). Yükleme davranışı
değişmez (mesh yeniden üretilir). Risk: yok — `.fikocad` ve `.fkcache`'in ikisi de re-tessellate
ediyor (`.fkcache` mesh'i ayrıca ham POD saklıyor, `dosya_islemleri.cpp:127-137`).

> Uygulama: `govdeBaytYaz` tek merkez → değişiklik hem `.fikocad` (`fiko_format.cpp:382`) hem
> `.fkcache` (`dosya_islemleri.cpp:138`) yolunu birden iyileştirir. `.fkcache` mesh'i zaten POD
> tuttuğundan brep'in mesh'siz olması orada da doğru.

### 3.2 Sıkıştırma — miniz seviye ↑ veya zstd

Mevcut: `mz_compress2(..., 6)` (`fiko_format.cpp:89`) — orta seviye.

**Aşama 1 (sıfır bağımlılık, hemen):** seviye **6 → 9** (miniz max, `MZ_BEST_COMPRESSION`).
Deflate'te oran artışı ölçülü, ama bedava. Kaydet worker'da olduğundan ekstra CPU UI'yı etkilemez.

**Aşama 2 (zstd değerlendirmesi):**
- **Kazanım:** zstd deflate'e göre hem daha iyi oran hem çok daha hızlı (özellikle çözme).
  B-rep gibi ikili blokta belirgin fark → daha küçük dosya + daha hızlı yükle (mobil dostu).
- **Lisans:** BSD-3-Clause (ticari-temiz, projedeki miniz MIT / diğer OSS ile uyumlu).
- **Entegrasyon maliyeti:** `ucuncu_taraf/zstd/` (şu an **yok**, `ls ucuncu_taraf` → miniz var,
  zstd yok). zstd'nin **tek-dosya amalgam** dağıtımı var (`zstd/build/single_file_libs` →
  `zstd.c` + `zstd.h`) → miniz kalıbında minik `CMakeLists.txt` (`ucuncu_taraf/miniz/CMakeLists.txt`
  ikizi) + `fiko::zstd` alias. `motor/io/CMakeLists.txt`'e `PRIVATE fiko::zstd` eklenir.
- **Karar:** Aşama 1 (miniz 9) hemen; zstd **Dalga 3** (amalgam vendor + chunk başlığında yeni
  sıkıştırma kodu). Format zaten ileri-uyumlu.

**Format uyumu:** Chunk başlığındaki `sikistirma` alanı (`u8`, `fiko_format.cpp:107` / spec
`docs/dosya_format_spec.md` §2.2) şu an `0=ham, 1=deflate`. **`2=zstd`** eklenir. Okuyucu
tanımadığı kodu görürse hata verir (sürüm koruması); yeni sürümlü dosya eski uygulamada açılmaz
→ `surumKucuk` artırılır (`fiko_format.cpp:29`). Eski `.fikocad` (deflate=1) sonsuza dek okunur.

### 3.3 Chunk-bazlı sıkıştırma politikası (zaten kısmen var)

`fiko_format.cpp`: META/CMRA **ham** (`chunkYaz(..., false)`, satır 172/186), TREE/NODE **sıkıştırılmış**
(satır 198/225). Doğru zaten. `chunkYaz` (satır 106) ayrıca "sıkışınca büyürse ham bırak" koruması
yapıyor (satır 111). Eklenecek: büyük NODE bloğuna **zstd yüksek seviye**, küçük metadata ham.

### 3.4 Opsiyonel "kompakt" mod

Kaydet-dialog'a (gelecekte) bir "kompakt" seçeneği: (a) üçgensiz B-rep (§3.1, zaten varsayılan
olacak), (b) zstd max seviye, (c) precision kırpma (aşağıda). Şimdilik varsayılan ayarlar zaten
kompakt hedefli; ayrı UI Dalga 4.

### 3.5 İleri boyut düşürme (sonraki dalga, opsiyonel)

- **Precision:** BinTools f64 koordinat saklar. Custom quantize (f32 / birim-ölçekli sabit nokta)
  yalnız kendi B-rep formatımızda mümkün; OCCT BinTools'ta değil → **ertelenir** (kayıp riskli).
- **Dedup:** Aynı geometrinin tekrar eden gövdeleri (pattern/mirror) tek B-rep + örnek referansı.
  Feature/parametrik dalgayla birlikte (spec `docs/dosya_format_spec.md` §5 "ertelenen").
- Bu ikisi **taşınabilir hedef için gerekli değil** — §3.1 + §3.2 asıl kazancı verir.

---

## 4. Mimari — async sarmalayıcı + progress callback

Mevcut `fikoKaydet`/`fikoYukle` (`fiko_format.cpp`) **silinmez** — saf çekirdek ve senkron API
(test + fallback) korunur. Üstüne **ince async katman** eklenir:

### 4.1 Çekirdeğe opsiyonel progress callback (test edilebilir kalır)

`motor/io/include/fiko/io/fiko_format.hpp` — saf çekirdek imzaları genişler (varsayılan boş → geri uyumlu):

```
using Ilerleme = std::function<void(float oran, std::string_view adim)>;

bool fikoYaz(const FikoBelge&, std::string& cikti, std::string& hata, const Ilerleme& = {});
bool fikoOku(const std::string& veri, FikoBelge&, std::string& hata, const Ilerleme& = {});
```

Böylece worker `b.ilerlet`'i doğrudan callback olarak geçer; çekirdek Sahne/GorevSistemi'ne
**bağımlı olmadan** düğüm-bazlı ilerleme raporlar (birim testi callback'i sayaçla doğrular).

### 4.2 Sahne düzeyinde async giriş noktaları

İki yol mümkün — **B tercih edilir** (mükerrer azaltır):

- **A:** `fiko_format.cpp`'e `fikoKaydetAsync(Sahne&, Kamera&, yol, GorevSistemi&)` /
  `fikoYukleAsync(...)` ekle. io modülü cekirdek'e bağımlı olur.
- **B (tercih):** Async **orkestrasyon `dosya_islemleri.cpp`'de kalır** (STEP `stepYol` zaten
  orada, aynı yer). `fikoKaydetKomut`/`fikoYol` içi, `stepYol` kalıbında `kuyrukla(...)`'ya
  dönüştürülür. Snapshot için `fiko_format.cpp`'ten saf yardımcılar ayrılır:
  - `belgeCikar(const Sahne&, const OrbitKamera&) -> FikoBelge` (ana-thread, `fikoKaydet`'in
    satır 343-414'ü buraya) — Sahne okur, FikoBelge döner.
  - `belgeUygula(Sahne&, OrbitKamera&, HazirYukleme&&)` (ana-thread finalize, `fikoYukle`'nin
    GPU/sahne kurulum yarısı, satır 456-528) — worker'ın ürettiği mesh'li ara sonucu sahneye kurar.
  - Worker `belgeCikar` çıktısını serialize eder / diskten okuyup `HazirYukleme` (mesh dahil) üretir.
  Bu bölme io modülünü cekirdek'e bağımlı yapmaz; `dosya_islemleri.cpp` zaten her ikisini de linkler.

### 4.3 Ara veri tipi (yükle)

STEP'in `HazirDugum`'una (`dosya_islemleri.cpp:85`) benzer `HazirYukleme` struct'ı: gruplar +
mesh'li düğümler (`IthalGovde` + `MeshVeri`/`KenarVeri`/`NoktaVeri`) + kamera. Worker doldurur,
finalize `ithalEkleHazir` ile GPU'ya yükler. Böylece **GPU teması yalnız finalize'de**.

---

## 5. Atomik yazma (yarım dosya koruması)

Zaten var (`fiko_format.cpp:419-433`): `yol+".tmp"`'e yaz → hedefi sil → `rename`. Async'te
**worker thread'te korunur** (saf disk işi, thread-safe). Eklenecek sağlamlaştırma:

- `rename`'den önce `ofstream` flush + (mümkünse) fsync → güç kesintisinde bütünlük.
- İptal/hata → `.tmp` silinir, hedef **dokunulmaz** (eski sürüm bozulmaz).
- `.fkcache` (`dosya_islemleri.cpp:305-322`) zaten aynı temp+rename desenini kullanıyor → tutarlı.

---

## 6. Dalga planı

| Dalga | İçerik | Dosya:satır | Risk |
|-------|--------|-------------|------|
| **1** | **Boyut hızlı kazanç:** `govdeBaytYaz`'a `ucgenlerDahil=false` → BinTools üçgen/normal çıkar + miniz seviye 6→9. UI/thread değişmez. | `brep_io.cpp:272,276`; `fiko_format.cpp:89` | Çok düşük (yükleme re-tessellate zaten var) |
| **1b** | Progress callback: `fikoYaz`/`fikoOku`'ya opsiyonel `Ilerleme` param (senkron test). | `fiko_format.hpp:72-75`; `fiko_format.cpp:157,231` | Düşük |
| **2** | **Async yükle:** `fikoYol` → `kuyrukla` (worker: read+inflate+parse+tessellate; finalize: GPU+sahne+kamera). `belgeUygula` ayrımı. İptal. "İşlemler" paneli bedava. | `dosya_islemleri.cpp:392`; `fiko_format.cpp:439-528` | Orta (finalize sınırı doğru çizilmeli) |
| **2** | **Async kaydet:** `fikoKaydetKomut` → snapshot ana-thread (`belgeCikar`) + worker serialize/deflate/atomik-yaz + finalize MRU/bilgi. Çift-iş guard. | `dosya_islemleri.cpp:408`; `fiko_format.cpp:341-414` | Orta |
| **2b** | Büyük belge: paralel tessellation (yükle) + derin-kopya-sonra-worker-serialize (kaydet). STEP FAZ2 kalıbı. | `dosya_islemleri.cpp:264-299,273` | Orta (OCCT paylaşım/data-race) |
| **3** | **zstd:** `ucuncu_taraf/zstd/` amalgam vendor + `fiko::zstd` + chunk `sikistirma=2` + `surumKucuk` artır. Eski dosya geri-uyumlu. | yeni `ucuncu_taraf/zstd/CMakeLists.txt`; `motor/io/CMakeLists.txt`; `fiko_format.cpp:83-125,29` | Orta (yeni bağımlılık) |
| **4** | Kompakt mod UI + (opsiyonel) precision/dedup araştırması. | kaydet-dialog `dosya_islemleri.cpp:372` | Düşük (opsiyonel) |

**Öncelik gerekçesi:** Dalga 1 tek satırlık değişikle en büyük boyut kazancını verir (mesh
gömme kaldırma) ve async'ten bağımsız. Dalga 2 asıl donma sorununu çözer. zstd (Dalga 3) ek
kazanç ama yeni bağımlılık gerektirdiğinden sonra.

---

## 7. Somut dokunulacak konumlar (özet)

**Boyut:**
- `motor/geometri/src/brep_io.cpp:272-282` `govdeBaytYaz` → `BinTools::Write(..., false, false)` + param
- `motor/io/src/fiko_format.cpp:83-93` `sikistir` → seviye 9; `:106-125` `chunkYaz` → (Dalga 3) zstd seçimi; `:29` `SURUM_KUCUK` artır
- `ucuncu_taraf/zstd/` (yeni, Dalga 3) + `motor/io/CMakeLists.txt` link

**Async + progress:**
- `motor/io/include/fiko/io/fiko_format.hpp:72-84` → `Ilerleme` callback param + (opsiyonel) `belgeCikar`/`belgeUygula` ayrımı
- `motor/io/src/fiko_format.cpp:341-437` `fikoKaydet` → `belgeCikar` (snapshot) ayrıştır; `:439-533` `fikoYukle` → worker mesh üretimi + `belgeUygula` finalize ayrıştır
- `uygulama/fikocad/dosya_islemleri.cpp:392-416` `fikoYol`/`fikoKaydetKomut` → `stepYol` (`:73`) kalıbında `cekirdek.gorevler().kuyrukla(...)`
- `uygulama/fikocad/main.cpp` — değişiklik **gerekmez**: menü (`:868-869`) + kısayol (`:1692-1693`) aynı fonksiyonları çağırır; `pompala` (`:2040`) finalize'i sürer; "İşlemler" paneli (`:3555-3594`) ilerlemeyi otomatik gösterir

**Değişmeyen (yeniden kullanılan) altyapı:**
- `motor/cekirdek/{include/fiko/cekirdek/gorev.hpp, src/gorev.cpp}` — `GorevSistemi` (worker+ilerleme+iptal+finalize)
- `uygulama/fikocad/main.cpp:3555-3594` — "İşlemler" ilerleme paneli
- `fiko_format.cpp:419-433` — atomik temp+rename yazma
