Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/DEVICE_VALIDATION_LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

| # | Özellik | Nerede | Kabul ölçütü (cihazda ne gözlemlenmeli) | Eklendi |
|---|---------|--------|------------------------------------------|---------|
| 48 | **🔴 Device Validation Pending — Platform Kernel / Service Lifecycle Foundation** — Platform servislerinin (Vehicle HAL · Capability Registry · Event Bus · Deep Scan · Navigation · AI · Fleet · Remote · Health · Vision) yaşam döngüsünü, bağımlılıklarını, başlatma/durdurma SIRASINI, sağlık durumunu ve HATA İZOLASYONUNU yöneten merkezi çekirdek. ⚠️ **KOD GERÇEĞİ (salt-okunur analiz):** lifecycle ≥3 desende parçalı — SystemBoot "Wave 1-4"+LIFO cleanup+named restart (MAX_RESTARTS=2, BACKOFF_BASE 5s, COOLOFF 5dk); modül-düzeyi startX/stopX; servis-içi _listeners/_reg. ORTAK descriptor/bağımlılık/health/circuit modeli YOK → Kernel doldurur (gerçek servisleri BAĞLAMADAN, yalnız DI). **Model:** 11 state (registered→initializing→ready→starting→running/degraded/paused→stopping→stopped/failed/disposed) · 6 criticality · 6 startPolicy · 4 restartPolicy · 4 health. **Descriptor:** id/version/criticality/dependencies/optionalDependencies/requiredCapabilities/minimumDeviceTier/startPolicy/restartPolicy/init·start·stopTimeoutMs/owner/experimental. **Service contract:** init/start/pause/resume/stop/health/dispose HEPSİ opsiyonel (eksik→no-op). **API:** register/unregister/has/getServiceStatus/list/resolveStartOrder/initialize/start/startAll/pause/resume/stop/stopAll/restart/markDegraded/runHealthCheck/getKernelSnapshot/subscribe/reset/dispose. **Dependency:** directed-acyclic; **cycle kayıt anında reddedilir**; topolojik başlatma (tie-break=id), **ters topolojik durdurma**; eksik required→başlamaz; eksik optional→degraded başlar; dependency failed→dependent bloke. **Gate (DI):** Capability Registry DOĞRUDAN import EDİLMEZ (isAvailable/getStatus/subscribe contract); required unknown/unavailable→başlamaz; degraded→degraded başlar; **minimumDeviceTier sağlanmazsa başlamaz** (Mali-400/low'da optional ağır servis GATE). **Timeout:** proje 5s konvansiyonundan türetildi (magic yok); timer YALNIZ aktif lifecycle çağrısı boyunca (settle'da temizlenir); **steady-state timer/polling YOK**. **Restart/circuit:** never/manual/on_failure/bounded_auto; bounded (safety=1, diğer=2); max aşımında **circuit-open**; **retry timer döngüsü YOK** (backoff yalnız saf `computeKernelBackoffMs` contract). **Health:** service.health() varsa çağrılır (fail-soft), yoksa state'ten türetilir; result state'i MUTATE ETMEZ. **Event (DI opsiyonel):** publishName ile platform.runtime.started/stopped/degraded · platform.service.started/stopped/failed; **Event Bus yoksa lifecycle sürer**, publish hatası izole. **Fail-soft:** servis exception izole, bir servis düşse bağımsızlar sürer, public API throw etmez, unknown servis güvenli, dispose sonrası no-op, partial-start+stopAll güvenli. **Immutable** snapshot/status (nested dahil), descriptor girdi mutate edilmez, iç Map/graph dışa verilmez. **Privacy:** degradedReasons/lastErrorCode sanitize (VIN/MAC/koordinat/secret sızmaz). **YALIN:** SystemBoot'a BAĞLANMAZ · gerçek servisleri auto-start ETMEZ · HAL/Registry/Bus'ı KENDİSİ YARATMAZ (DI) · persistence/SQL/cloud YOK · global singleton YOK · yeni bağımlılık YOK · import yan etkisiz (yalnız DeviceTier TYPE). Kernel servis iş mantığını BİLMEZ. Bounded (servis 128 · listener 32). **Gerçek servis wiring · SystemBoot wiring AYRI PR.** | `platform/kernel/platformKernel.ts` (yeni), `platform/kernel/index.ts` (yeni), `__tests__/platformKernel.test.ts` (yeni, ~53 test) | Gerçek cihazda (gerçek servis wiring PR'ı bağlandıktan SONRA): (1) servisler dependency SIRASIYLA başlıyor; (2) stop sırasında TERS sırayla kapanıyor; (3) bir servis çökünce bağımsız servisler çalışmaya devam ediyor; (4) capability/DeviceTier olmayan servis başlatılmıyor; (5) Mali-400 cihazda ağır optional servisler gate ediliyor; (6) lifecycle timeout ve cleanup sonrası timer/listener sızıntısı yok; (7) kernel snapshot servis durumlarını doğru gösteriyor; (8) BASIC_JS/Mali-400'de sürekli CPU/RAM yükü yok (steady-state timer yok, pasifken sıfır yük). ⚠️ **Gerçek servis + SystemBoot wiring AYRI PR.** Test edilmeden 🟢 yapma. | 2026-07-11 |
| 45 | **🟢 FullMapView Idle Render Optimization (device-verified 2026-07-12, +WAKE-tarafı park tutucusu)** — Cihaz QA'sının FAIL sebebini kapatır: tam ekran harita **boşta, kullanıcı dokunmadan** 1.5–2.1 CPU çekirdeği yakıyordu (+30sn %64 · +60sn %96 · +2dk %106 · **+3dk %210** · +6dk %167; harita kapanınca 45sn'de %20). **KÖK NEDEN (iki katman):** (1) idle kapısı **GPS gürültüsünü hareket sanıyordu** — park hâlinde ±3 m doğrulukla gelen fix'ler "3 m yer değiştirme ≈ 10 km/h" üretip `isIdleNow`'u sürekli false yapıyor, rAF döngüsü **hiç uyumuyordu**; (2) döngü uyanıkken tick **değişiklik olmasa da** `updateUserMarker()` çağırıyor, o da **koşulsuz `source.setData()`** yapıyordu (`MapLayerManager.ts:371`) → her 60 ms'de bir MapLibre repaint + kamera 150–500 ms'de yeniden hesap → sürekli GPU/compositor yükü (`mali-event-hand` %24 + `Chrome_InProcGp` %17). **ÇÖZÜM (yalnız FullMapView.tsx):** (a) **yapılan-iş kapısı** — marker/kamera `NO_WORK_IDLE_MS=2500` boyunca hiç güncellenmediyse harita gerçekten sabittir → döngü uyur (gürültüye dayalı hız/yer-değiştirme sezgilerinin yerine **ground truth**); (b) **marker + kamera dedup** (eşikler: 0.3 m / 0.5° / 0.5 km/h; kamera 0.5 m / 0.5°) → değişmeyen kare repaint üretmez; (c) **park gürültü tutucusu** — hız < 1.5 km/h ve nav/sürüş yokken fix'in kendi doğruluk yarıçapı (≥5 m) altındaki kayma hareket sayılmaz; (d) **force kapıları** — kullanıcı pan'inden sonra kamera MUTLAKA geri merkezler, stil/katman düşerse marker MUTLAKA yeniden çizilir (self-healing korunur); (e) DR yolu ve tek-nokta dalı (her karede setData ediyordu) da dedup'a bağlandı. **Wake tetikleyicileri ve hareket semantiği DEĞİŞMEDİ** → nav/sürüş/takip davranışı aynı. | `components/map/FullMapView.tsx` (tek dosya), `__tests__/fullMapViewIdleRender.test.ts` (yeni, 25 test) | **🔴 Xiaomi zircon (bekliyor):** (1) tam ekran harita açık + dokunulmadan 3 dk → process CPU **%210 → tek haneli/düşük onlu** seviyeye insin (önceki QA baseline: `docs-local/qa-runs/2026-07-11T15-52-52Z-deep-device-analysis/`); (2) `dumpsys gfxinfo` boşta kare üretimi ~56 fps'ten **~0–2 fps**'e insin; (3) harita **kapatılınca** timer/rAF tamamen dursun; (4) 30 dk soak: PSS/Graphics düz, crash/ANR 0; (5) **navigasyon davranışı DEĞİŞMESİN** — rota başlat/reroute/takip/marker/pan-sonrası-recenter aynı; (6) pan/zoom/rotate akıcılığı bozulmasın. **🔴 Mali-400 (K24) — bekliyor:** aynı ölçümler; asıl kazanç orada kanıtlanmalı. Cihazda görülmeden 🟢 YAPILMAZ. **✅ DOĞRULAMA (2026-07-12, gerçek Xiaomi 23090RA98I, main+#64+#61, tam ekran harita idle/park, dokunma yok, 12s settle, CDP rAF-attribution + `/proc` jiffies — screencap YOK):** İLK ÖLÇÜM #61'i **DÜŞÜRDÜ** — idle CPU 108% (main+#64 106% ile aynı), rAF 137/sn, idle-gate döngüsü `L` 278/3sn (HİÇ uyumuyor). **KÖK NEDEN (cihaz CDP tanısı, geçici `window.__ib`/`__wc` instrumentation):** `isIdleNow` %100 `hysteresis(wake <2500ms)` bloğunda takılıyordu; wake **2.8/sn spam** — `onGPSLocation` displacement-wake (satır ~318) **accuracy-BLIND**'dı → park GPS gürültüsü (accuracy 3m, ~3m zıplama) "≥3m/≥5km/h" eşiğini geçip wake tetikliyordu. #61'in park tutucusu yalnız `isIdleNow` (döngü ÇIKIŞI) tarafındaydı, wake GİRİŞİ korunmamıştı → **yarım fix**. **DÜZELTME (wake-tarafı park tutucusu, `isIdleNow` ile tutarlı semantik):** park (nav/sürüş yok + hız<STANDSTILL_KMH) hâlinde fix'in kendi doğruluk yarıçapı (`Math.max(STANDSTILL_HOLD_M, accuracy)`) altındaki kayma wake ETMEZ; gerçek hareket (hız≥1.5 **veya** yarıçap-üstü displacement) wake eder → takip/fail-soft korunur. **DÜZELTME SONRASI (aynı cihaz/yöntem):** idle CPU **108%→21%** (~5x, Ayarlar tabanı ~19% seviyesine), toplam rAF **137→3.3/sn** (%97.6↓), idle-gate `L` **278→0** (döngü uyudu), MapLibre native repaint **114→0**, VisionOverlay(#64) 0. Ölçütler (1)(2)(3) KARŞILANDI (following AÇIK'ken uyudu → gerçek ardışık-fix jitter < CAM_EPS). **Testler:** `fullMapViewIdleRender.test.ts` 25→**30** (yeni `feedGps` modeli GPS-wake yolunu simüle eder — eski 25 test wake'i yalnız manuel çağırdığından bu bug'ı KAÇIRMIŞTI; R1-R5 wake-tarafı tutucuyu kilitler). ⚠️ Test edilmeyen: gerçek araçta hareket/nav-başlat/reroute/pan-recenter (ofis testi, araç yok); 30dk soak; **Mali-400 (K24) hâlâ 🔴**; olası kamera-tarafı park tutucusu (cihazda gerekmedi — jitter<CAM_EPS). | 2026-07-12 |
| 47 | **🟢 Device-Verified (2026-07-12, CDP rAF-attribution) — VisionOverlay AR-kapalı idle loop gate** — ✅ Xiaomi 23090RA98I, tam ekran harita idle: renderAR 3sn'de 1 çağrı = ~0.3fps (fix'siz ~60fps, %99.4↓); #61 wake-fix build'inde de 0 rAF. Restart mekanizması sağlam. Araçta AR/HYBRID çizim geri-gelme testi + Mali-400 hâlâ bekliyor. — GÖREV 2 kök-neden araştırmasının (docs-local/device-runs/20260712T000500-map-idle-root-cause) bulduğu **birincil** idle-CPU kaynağını kapatır. `VisionOverlay.renderAR` (AR kamera/şerit katmanı) 60 fps rAF döngüsü, **AR/kamera KAPALIYKEN bile** (`!frame \|\| !isHybrid \|\| confidenceLevel==='off'`) `requestAnimationFrame(renderAR)` ile KOŞULSUZ yeniden planlanıyordu → VisionOverlay FullMapView'de koşulsuz mount olduğundan, harita açıkken (çizim yapmasa da) her kare `getContext('2d',{willReadFrequently:true})` (CPU-backed canvas) + `getBoundingClientRect` (layout) + `clearRect` yapıp ana thread'i ve compositor'ı boşa yüküyordu. **KANIT (gerçek cihaz, DevTools + /proc, A/B):** rAF çağrılarının %84'ü VisionOverlay (~138/sn); VisionOverlay rAF canlı düşürülünce (settled idle harita) **process 35%→20%, main-thread 11%→6%, gfx 5.2→0.3 fps** — Ayarlar tabanına + ~0-2fps hedefine ulaştı. FullMapView tick (PR #61) zaten settled'da 0/sn (idle-gate çalışıyor); sorun ayrı bileşendeydi. **FIX (tek dosya, 1 satır davranış):** off-branch'te `requestAnimationFrame(renderAR)` yerine `rafRef.current = null` → döngü DURUR. Yeniden başlatma OTOMATİK: renderAR deps'i (isHybrid/confidenceLevel/vision.frame/currentLat/currentLon) değişince renderAR yeniden yaratılır → mevcut `useEffect([renderAR])` döngüyü tekrar başlatır. **Aktif AR çizim yolu (satır 623 reschedule) DEĞİŞMEZ** → AR/navigasyon işlevi korunur. Aynı "reschedule etmeden dur" deseni satır ~550 (`if(!canvas) return;`) zaten kullanıyor. Zero-leak: unmount cleanup + rafRef=null. YENİ timer/rAF/bağımlılık YOK. Kapsam-dışı dokunulmadı: FullMapView PR #61, GPS PR #62, native OBD/CAN, SQL, Platform Kernel #55. | `components/map/VisionOverlay.tsx` (renderAR off-branch), `__tests__/visionOverlayIdleLoopGate.test.ts` (yeni, 5 kaynak-kilidi test — bu repo SSR render kullandığından rAF davranışsal testi mümkün değil, kilit off-branch'e requestAnimationFrame geri konmasını engeller) | Gerçek Xiaomi cihazda (önce/sonra, tam ekran harita idle, park, dokunma yok, `/proc` + DevTools rAF attribution — **screencap ölçüm penceresinde YOK**): (1) VisionOverlay rAF idle'da **~0/sn** (önce ~60-138/sn); (2) idle harita process CPU **≤ ~20-22%** (Ayarlar tabanına yakın, önce ~35%); (3) gfx idle kare **≤ ~2 fps** (önce ~5.2); (4) **AR/HYBRID navigasyon açılınca** şerit/ok/tabela çizimi ÇALIŞIYOR (döngü yeniden başlıyor); (5) background/cold-warm start/30dk soak regresyonsuz, crash/ANR 0; (6) **Mali-400 (K24)**: CPU-canvas maliyeti orada oransal daha ağır → kazanç muhtemelen daha büyük ama ölçümsüz "çalışır" denmez. Test edilmeden 🟢 yapma. | 2026-07-12 |
| 43 | **🔴 Device Validation Pending — Compass Foreground Demand Gating** — PR #42'nin (Ledger #42) bilinçli bıraktığı "Compass Settings ekranında KAPATILMADI" sınırlamasını KAPATIR. Önce `gpsService._startCompassListener()` `startGPSTracking()` ile KOŞULSUZ açılıyor, uygulama ön plandayken (Ayarlar/profil/medya/haritasız ekran dahil) HİÇ kapanmıyordu → cihaz QA'sında boşta ana ekranda `rot_vec`+`game_rotvec` 60 Hz açık. **BU PR:** küçük, ref-count'lu, owner-bazlı **compass demand contract** (`compassDemand.ts`) — `acquireCompassDemand/releaseCompassDemand/hasCompassDemand/getCompassDemandCount` + `subscribeCompassDemand` (0↔1 geçişlerinde bildirir). gpsService bu talebi dinler: **ilk acquire → gate compass aboneliği AÇILIR; son release → KAPANIR** (yalnız GPS tracking açıkken). **Tüketiciler:** `FullMapView` mount'ta `map:full` acquire / unmount'ta release (heading-up harita gerçekten heading kullanır); `MiniMapWidget` YALNIZ kendi mevcut `isDriving` histerezisinde (giriş >5 km/h, çıkış <3 km/h) `map:mini` acquire — park/kuzey-yukarı statikte talep YOK (yeni eşik eklenmedi). **KORUNAN:** GPS konum takibi (talep yokken watch aynen sürer, yalnız compass kapanır), blend/smoothing (`computeBlendedHeading`/`applyCompassSmoothing`/`COMPASS_THROTTLE_MS`), izin ve fallback yolu, background/foreground gate (visibility) davranışı — HİÇBİRİ değişmez. **YALIN:** owner bounded(32), duplicate acquire yok, release idempotent, timer/polling YOK, import yan etkisiz, gate'in sahibi değil, zero-leak (stopGPSTracking demand unsub'ı bırakır; MiniMap unmount cleanup'ı release eder). ⚠️ **Native samplingPeriod düşüşü İDDİA EDİLMEZ** (Chromium DeviceOrientation 60 Hz sabit); Generic Sensor API EKLENMEZ. Kapsam-dışı dokunulmadı: blackBox, smartDriving, FullMapView PR #61, GPS PR #62, Platform Kernel PR #55, SystemBoot, OBD/CAN, SQL. | `platform/gps/compassDemand.ts` (yeni), `platform/gpsService.ts` (compass talep-güdümlü), `components/map/FullMapView.tsx` (acquire/release), `components/map/MiniMapWidget.tsx` (isDriving'e bağlı acquire/release), `__tests__/compassForegroundDemand.test.ts` (yeni, 29 test), `__tests__/orientationDemandGating.test.ts` (PR #58 1/3/5/6/7 kilitleri yeni talep-güdümlü davranışa güncellendi) | Gerçek Xiaomi cihazda (önce/sonra, `dumpsys sensorservice` + idle CPU/`SensorsHandlerThread`): (1) **Ayarlar/haritasız ekranda** uygulama adına `rot_vec`/`game_rotvec` (rotation-vector/game-rotation) sensörleri AÇIK OLMAMASI; (2) harita/navigasyon açılınca compass sensörlerinin GERİ GELMESİ; (3) heading/pusula yönünün DOĞRU olması; (4) harita kapanınca compass sensörlerinin SÖKÜLMESİ; (5) background davranışının BOZULMAMASI; (6) duplicate listener OLMAMASI; (7) Xiaomi'de idle CPU ve `SensorsHandlerThread`'in önce/sonra ölçülmesi (düşüş beklenir); (8) Mali-400'de regresyon yok. ⚠️ **Mali-400 cihaz doğrulaması bekliyor.** Test edilmeden 🟢 yapma. | 2026-07-11 |
Expand Down
Loading
Loading