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 |
|---|---------|--------|------------------------------------------|---------|
| 65 | **🔴 Device Validation Pending — Safe Offline Change Detection Handler (W5-3c-1)** — Deep Scan offline pass için İLK gerçek değer üreten handler eklendi: `createOfflineChangeDetectionHandler()` (fabrika; bağımlılıklar closure ile ENJEKTE). Handler ÖNCEDEN-VAROLAN iki baseline'ın ECU kümesi FARKINI hesaplar → `changedEcu`. PRIOR baseline = son TAM taramanın diske yazılı çıktısı (`deepScanPersistence.load` ile beslenecek — AYRI PR); CURRENT baseline = pasif öğrenilmiş gözlem (`vehicleKnowledgeBase.get` ile beslenecek — AYRI PR). **AKTİF SORGU YOK:** iki küme de zaten elde olan veri; araca tek CAN frame / OBD isteği / ECU-PID-DID sorgusu GÖNDERİLMEZ. **SAF + İZOLE:** handler `deepScanPersistence`/`vehicleKnowledgeBase`/runtime/native/HAL/EventBus'i DOĞRUDAN import ETMEZ (yalnız `PhaseContext`/`PhaseResult` tip import'u); `PhaseHandler` sözleşmesi ve `PhaseContext` DEĞİŞMEZ. **FAIL-CLOSED:** parmak izi yok / baseline eksik (null) / baseline BOŞ → değişim İDDİA EDİLMEZ (`changedEcu=false`, kategori reason). Persistence ECU listesi opsiyonel → boş baseline OLAĞAN; bunu "değişti" saymak sahte pozitif olurdu, o yüzden `baseline_incomplete` döner. **FIRMWARE DEĞERLENDİRİLMEZ:** `changedFirmware` DAİMA `false` (dürüst — pasif firmware kaynağı yok; ayrı PR). **BOUNDED + IMMUTABLE ÇIKTI:** yalnız `{status, changedEcu, changedFirmware, reason(kategori)}` — ham ECU/PID/DID listesi, firmware sürümü, VIN, GPS, secret, parmak izi hash'i TAŞIMAZ. **KORUMA BANDI (uçtan uca kanıtlı):** `completeScan`/`_finalize`/`_applyResult` aktif-kayıt yolu / runtime aktif-kayıt API'leri (`recordEcuDiscovery` vb.) / `saveSnapshot` ÇAĞRILMAZ → `hasCompletedFullScan`/`completedScanCount`/`changeCheckCount` DEĞİŞMEZ; `runtime.reset()` davranışı korunur (gerçek `runOfflinePass` ile koşturulan uçtan uca testte doğrulandı). Trigger/wiring DEĞİŞMEDİ; Event Bus/Capability/Assistant/Driver DNA/Prediction/Diagnostic section/SQL/Native/OBD/CAN/HAL'e DOKUNULMADI. **HOST-DOĞRULANDI:** 21 yeni test (changedEcu diff/normalizasyon, boş+null baseline fail-closed, firmware daima false, immutable+privacy, input immutable, fail-soft, cancel, kaynak-kilidi, uçtan uca guard band); tam suite **3841 yeşil (211 dosya)**, tsc `-b --noEmit` temiz, lint 0 error, production build OK. **AÇIKÇA:** (a) bu PR yalnız handler ekler; (b) trigger değiştirilmedi; (c) wiring değiştirilmedi; (d) aktif discovery yapılmıyor; (e) hiçbir ECU/PID/DID sorgusu gönderilmiyor; (f) handler henüz pass'e BAĞLI DEĞİL (W5-3c-2 adapter + W5-3c-3 bağlama ayrı PR). | `platform/deepScan/offlineChangeDetectionHandler.ts` (yeni — saf handler + `ChangeBaseline`/`ChangeDetectionReason`/`OfflineChangeDetectionDeps`), `platform/deepScan/index.ts` (barrel export), `__tests__/deepScanOfflineChangeDetection.test.ts` (yeni, 21 test) | Gerçek cihazda (Xiaomi 23090RA98I + en az bir low-tier K24/Mali-400/T507) — handler pass'e bağlandıktan SONRA (W5-3c-3): (1) gerçek araçta prior (son tam tarama) + current (pasif öğrenilmiş) baseline'lar dolu iken ECU seti değiştiğinde `changedEcu=true`, değişmediğinde `false`; (2) araç OBD/CAN trafiğinde bu handler kaynaklı ECU/PID/DID/Firmware isteği YOK (aktif sorgu üretmiyor); (3) pass sonrası `hasCompletedFullScan`/counter'lar değişmedi, runtime `idle`; (4) boş/eksik baseline'da sahte `changedEcu=true` ÜRETİLMİYOR (fail-closed); (5) low-tier'da ek CPU/RAM yükü ölçüm gürültüsü seviyesinde (saf set-diff, O(n)). Cihaz kanıtı olmadan 🟢 YAPMA. ⚠️ **Mali-400 cihaz doğrulaması bekliyor.** | 2026-07-13 |
| 64 | **🔴 Device Validation Pending — Deep Scan Offline Pass Trigger + Runtime Wiring + Minimal Diagnostics (W5-3b)** — W5-3a'daki `runOfflinePass()` İLK kez üretim wiring'ine bağlandı. `platformCoreDeepScanWiring`'e tek deterministik giriş noktası `triggerDeepScanOfflinePass()` (hash/dedup guard + single-flight) + iptal (`cancelDeepScanOfflinePass`) + bounded teşhis (`getDeepScanOfflinePassStatus`) eklendi; SystemBoot **Wave 3**'te (Wave 2 ownership KURULDUKTAN SONRA) fire-and-forget çağrılır (`void ... .catch`; boot BLOKLANMAZ). **GUARD:** aynı guard anahtarı (varsayılan `deepscan.offline.boot`) EN FAZLA bir kez pass başlatır (duplicate YOK); yürüyen pass varken ikinci tetik reddedilir (single-flight); wiring restart'ında guard doğal sıfırlanır (durum wiring örneğine bağlı). **DAVRANIŞ DEĞİŞMEZ:** handler GEÇİLMEZ → tüm offline fazlar `skipped` → GERÇEK İŞ YAPILMAZ; change detection / knowledge / fingerprint / evidence / report ÇALIŞMAZ; aktif ECU/PID/DID/Firmware sorgusu YOK (runtime aktif-kayıt API'leri hiç çağrılmaz — gerçek zincir testiyle kanıtlı); runtime `idle → running → idle` döner (pass sonunda `runtime.reset()` W5-3a garantisi). **OWNERSHIP KORUNUR:** `OwnedOrchestrator` yüzeyi offline `runOfflinePass`/`cancelOfflinePass`'i gösterir ama AKTİF tarama API'lerini (`start`/`run`/`runNextPhase`) ASLA göstermez (compile-time; W5-3a kilidi bu davranışa GÜNCELLENDİ, kaldırılmadı). **TEŞHİS (bounded + immutable):** present/started/running/active/cancelled/triggerCount/lastRun/lastDuration/lastResult/lastReason/lastError/phaseCount/summaryAvailable — hepsi primitive/enum/sayı; VIN/GPS/secret/ham CAN-OBD/guard-anahtarı TAŞIMAZ. Event Bus / Capability Registry / HAL / Assistant / Driver DNA / Prediction / SQL / Supabase / Native / CAN / OBD DEĞİŞMEDİ (wiring bunları import ETMEZ). **HOST-DOĞRULANDI:** yeni trigger-wiring testleri (25+ senaryo: trigger/duplicate/hash-guard/tek-pass/single-flight/idle→running→idle/reset/summary/immutable/bounded/dispose/restart/cancel/timeout-iletimi/handler-yok/aktif-discovery-yok/privacy/input-immutable/Wave-sırası/EventBus-Capability değişmedi); W5-1 wiring fake'i + W5-3a 2 kilit yeni davranışa güncellendi; tam suite **3820 yeşil (210 dosya)**, tsc `-b --noEmit` temiz, lint 0 error, production build OK. **AÇIKÇA:** (a) gerçek handler YOK; (b) gerçek discovery YOK; (c) **W5-3c değer üreten (offline handler) PR'dır**; (d) aktif ECU sorgusu YOK (tip + faz + aktif-kayıt kapısı + handler-yok ile garanti); (e) Mali-400 doğrulaması bekliyor. | `platform/system/platformCoreDeepScanWiring.ts` (OwnedOrchestrator offline yüzey + `triggerDeepScanOfflinePass`/`cancelDeepScanOfflinePass`/`getDeepScanOfflinePassStatus` + bounded status), `platform/system/SystemBoot.ts` (Wave 3 trigger, fire-and-forget), `__tests__/deepScanOfflineTriggerWiring.test.ts` (yeni), `__tests__/platformCoreDeepScanWiring.test.ts` (fake offline yüzey), `__tests__/deepScanOfflinePass.test.ts` (2 kapsam kilidi güncellendi) | Gerçek cihazda (Xiaomi 23090RA98I + en az bir low-tier K24/Mali-400/T507): (1) boot'ta trigger TEK kez çalışır (`getDeepScanOfflinePassStatus().triggerCount=1`, duplicate boot/HMR çoğaltmıyor); (2) `runOfflinePass` çağrıldı ama araç OBD/CAN trafiğinde deep-scan kaynaklı ECU/PID/DID/Firmware isteği YOK (handler yok → aktif sorgu üretilmiyor); (3) pass sonrası runtime `idle` (`summaryAvailable=true`, `lastResult='ran'`); gerçek tarama sonradan başlayabiliyor; (4) boot süresi regresyonu yok (fire-and-forget → boot bloklanmıyor; hedef boot delta <10ms); (5) **Mali-400/K24 steady-state ek yük ölçüm gürültüsü seviyesinde** (pass tek-atış; timer/polling yok → ≈0); (6) background/foreground / restart'ta çift-pass veya leak yok; (7) teşhis raporunda offline pass status okunabilir (ADB'siz) — ⚠️ Not: `getDeepScanOfflinePassStatus` henüz `diagnosticSections`'a EKLENMEDİ (ayrı küçük teşhis PR'ı gerekir). Cihaz kanıtı olmadan 🟢 YAPMA. ⚠️ **Mali-400 doğrulaması bekliyor.** | 2026-07-13 |
| 63 | **🔴 Device Validation Pending — Tanı Raporu Sanitize Sertleştirme (Diagnostics PR-2)** — PR-1'in (#80) açtığı denetimde ortaya çıkan ÜÇ sanitize boşluğu kapatıldı. **(1) `selfTest` bölümü sanitize'ı TAMAMEN atlıyordu:** `reportSelfTestSnapshot` raporu ham spread ediyordu (`{...base, selfTest}`) → deny-list, VIN/MAC/koordinat/api_key maskeleri ve derinlik tavanı bu bölüme UYGULANMIYORDU. Prob `detail` alanları SERBEST METİN taşır: ham `Error.message` (`selfTestEngine` runProbe catch), ham fetch hata metni (probeBackend) ve stack karesi/dosya yolu (probeIdleRenderLoop) → **maskesiz kanal**. Artık inspector ile AYNI kapıdan geçer: yeni `_sanitizeSection()` (tek kapı — yeni bölüm eklenince sanitize'ı atlamak imkânsız). Teşhis değeri KAYBOLMAZ: stack karesi (`FullMapView.tsx:814`) okunur kalır, yalnız VIN/MAC/koordinat/anahtar maskelenir. **(2) `DENY_KEYS` camelCase'e KÖRDÜ:** eşleşme `key.toLowerCase()` idi, set'te `'api_key'` vardı → `apiKey`.toLowerCase() = `'apikey'` ≠ `'api_key'` → **SIZIYORDU**. Anahtar artık NORMALİZE edilir (küçült + alfanümerik olmayanı at) ve **TAM EŞLEŞME** yapılır. Liste genişledi: `apikey · accesstoken · refreshtoken · authorization · bearer · secret · password · jwt · token · email` (+ mevcut konum/VIN/MAC/telefon). **⚠️ TAM eşleşme ZORUNLU — substring/prefix YASAK:** `lat` substring olsaydı `platform` (W4E runtime teşhis bölümünün TAMAMI) ve `detectedPlatform` düşerdi; `vin` prefix olsaydı `vinMasked` (VIN sızıntısını ÖNLEMEK için üretilen maskeli türev) silinirdi → koruma raporu boşaltırdı. False-positive taraması: 14 üretici dosyada 326 benzersiz anahtar tarandı, **meşru alan düşmüyor**. **(3) Cycle guard YOKTU:** özyinelemeyi sınırlayan tek şey MAX_DEPTH'ti. Eklenen guard **ANCESTOR-PATH** desenidir (girerken ekle, `finally` ile çıkarken sil) — naif "görülen nesneler" seti PAYLAŞILAN REFERANSI (aynı nesne iki KARDEŞ dalda = DAG) cycle sanıp ikinci dalı sessizce boşaltırdı (DTC `[null,null]` ile aynı sınıf sessiz kayıp). Cycle → `[CYCLE]` işareti (sessiz kayıp DEĞİL, görünür); dizi elemanıysa ELENMEZ (uzunluk korunur). **Public API artık THROW ETMEZ:** getter/Proxy patlarsa yalnız o DÜĞÜM `[UNREADABLE]` olur, kardeş alanlar akar (`_safeSection`'ın düğüm-bazlı karşılığı) → tek zehirli alan TÜM tanı raporunu öldüremez. **DEĞİŞMEYEN (bilinçli):** MAX_DEPTH=6 · MAX_ARRAY_LEN=20 · MAX_STR_LEN=2048 · mevcut MASKS (VIN/MAC/COORD/api_key=/token=) · UI · RPC · DB/migration · rıza · teslimat modeli (`'sent'` yalanı AYRI PR). **HOST-DOĞRULANDI:** 17 yeni davranış kilidi + 4 kaynak-metin kilidi (regresyon kasası; PR-1'in dizi kilidi kaldırılmadı, yeni doğru davranışa GÜNCELLENDİ), tam suite **3711 yeşil (206 dosya)**, tsc temiz, lint 0 error, build OK. **BYTE ÖLÇÜMÜ (en zengin fixture, aynı test, önce/sonra):** `self_test` **5157 B → 5119 B (−38 B)** — sanitize maskeleme sonrası hafif KÜÇÜLDÜ, şişme YOK; `dev_inspector` **5479 B → 5479 B (0)** — inspector zaten aynı kapıdan geçiyordu. | `platform/remoteLogService.ts` (`_normalizeKey` + genişletilmiş DENY_KEYS + ancestor-path cycle guard + düğüm-bazlı fail-soft + `_sanitizeSection` tek kapı; `reportSelfTestSnapshot` + `reportDiagnosticSnapshot` onu kullanır), `__tests__/diagnosticSanitizeHardening.test.ts` (yeni, 17 test), `__tests__/regression.guards.test.ts` (4 kilit; dizi kilidi güncellendi) | Gerçek cihazda: (1) **"Tanı Robotu" (self-test) raporu gönderiliyor** ve gövdesinde `selfTest.results[].detail` alanları MEVCUT (bölüm kaybolmadı, sanitize onu boşaltmadı); (2) `selfTest.summary`/`worst`/`env` dolu ve `results.length` = summary toplamı (MAX_ARRAY_LEN=20 kırpması YOK — bugün 14 prob, 6 pay var); (3) gerçek self-test raporunda **ham `Error.message`/fetch hata metni içinde VIN/MAC/koordinat/anahtar İZİ YOK**, maskeler (`[VIN]`/`[MAC]`/`[COORD]`/`api_key=[MASKED]`) görünüyorsa doğru çalışıyor; (4) `platform` (Event Bus/HAL sayaçları) ve `vidMirror.vehicle.vinMasked` bölümleri raporda **HÂLÂ VAR** (yeni deny listesi meşru alanları düşürmedi — TAM eşleşme kanıtı); (5) `triage` mevcut ve `ruleErrors=0`; (6) DTC varken `obdDeep.dtc.codes[0].code` dolu (PR-1 kazanımı bozulmadı); (7) raporda `[CYCLE]`/`[UNREADABLE]` işareti **görünmüyor** (üretimde dairesel/zehirli düğüm yok — görünürse üretici tarafta bug var demektir, teşhis edilir); (8) rapor gövdesinde `truncated` alanı YOK ve `octet_length` < 45 KB; (9) low-tier cihazda (K24/Mali-400 veya T507) self-test raporu gönderimi başarılı, ANR/donma yok; (10) Xiaomi'de CPU/RAM/boot regresyonu yok. **Gerçek cihazda self-test raporu görülmeden 🟢 YAPMA** — host testleri kodu kanıtlar, sahadaki gerçek `detail` metinlerini kanıtlamaz. | 2026-07-13 |
| 62 | **🔴 Device Validation Pending — Tanı Raporu DTC Derinliği + Triyaj Null-Guard (Diagnostics PR-1)** — Denetimin (2026-07-12) KANITLI iki P0'ı kapatıldı. **(1) DTC kodları kabloda `null` gidiyordu:** `remoteLogService._deepSanitize` derinlik ≥ `MAX_DEPTH` olan KABI düşürür; gövde `depth=0` ile çağrıldığı için zincir `root(0)→obdDeep(1)→dtc(2)→codes[](3)→kod nesnesi(4)` **derinlik 4'te ölüyordu** → `codes:[null,null]`. Aynı derinlikteki `obdDeep.extended.samples[]` (katalog-dışı PID keşfi), `uiActivity.recent[].reasons[]`, `inspector.timeline[].signals/env` ve `inspector.runtime.workers[]` de düşüyordu. **`MAX_DEPTH` 4 → 6 (ÖLÇÜLMÜŞ, keyfi değil):** payload gövdesinin tüm bölümleri tarandı, en derin **kap** derinlik 4'te → 5 = minimum yeterli; 6 seçildi çünkü `sanitizeForRemote` ve inspector girişleri `depth=1`'den başlıyor (bir seviye pay) ve ölçülen payload'da derinlik ≥5'te KAP OLMADIĞI için **bugün 0 ek bayt** akıtır. Sanitize dizi dalı artık düşen elemanı **ELER** (`.map` ile yerinde bırakılan `undefined` JSON'da `null` oluyordu — sessiz "kod var ama boş" yalanı). **(2) DTC varken TRİYAJ TAMAMEN kayboluyordu:** `ruleObdDtc` null-guard'sız `c.code` okuyordu → TypeError → `buildTriageSnapshot` döngüsü kırılıyor → `_attachTriage`'ın yutucu catch'i `payload.triage`'ı HİÇ yazmıyor → admin **arızanın olduğu tam anda** "kritik bulgu yok" görüyordu (13 kuralın HEPSİ birden susuyordu: termal/bellek/güç/GPS/self-test dahil). Kural null-guard'landı (`dtc.count` "arıza var" kanıtıdır; kod METNİ yalnız zenginleştirme → liste boş/bozuk olsa da bulgu ÜRETİLİR) **+ motor seviyesinde KURAL İZOLASYONU** (bir kural patlarsa yalnız o kural düşer, diğerleri çalışır) **+ `ruleErrors` sayacı** (izolasyon sessiz olmasın — triyaj eksik çalıştıysa raporda görünür). **DEĞİŞMEYEN (bilinçli):** redaction/allowlist/deny-list/maskeler · `MAX_ARRAY_LEN`/`MAX_STR_LEN` · UI · RPC · DB/migration · rıza/önizleme · teslimat modeli (`'sent'` yalanı **PR-2'ye** bırakıldı). **HOST-DOĞRULANDI:** 13 yeni kilit yeşil (9 davranış + 4 kaynak-metin regresyon kasası), tam suite **3690 yeşil (205 dosya)**, tsc temiz, lint 0 error, build OK. **BYTE ÖLÇÜMÜ (en zengin fixture, aynı test, önce/sonra):** `support_snapshot` **3163 B → 4045 B (+882 B, +%27,9)** · `dev_inspector` **3747 B → 5480 B (+1733 B, +%46,3)** → ikisi de canlı sunucu tavanının (**64 KB**, migration 027) çok altında. | `platform/remoteLogService.ts` (MAX_DEPTH 4→6 + dizi dalı undefined filtresi), `platform/diagnosticTriage.ts` (ruleObdDtc null-guard + kural izolasyonu + `ruleErrors`), `__tests__/diagnosticDtcDepthTriage.test.ts` (yeni, 9 test), `__tests__/regression.guards.test.ts` (4 kaynak-metin kilidi) | **Gerçek araçta, DTC VARKEN** (arıza lambası yanan / kasıtlı DTC üretilmiş araç) gönderilen `support_snapshot` gövdesinde: (1) `obdDeep.dtc.codes[0].code` **dolu string** (`null` DEĞİL) ve `severity`/`system` dolu; (2) `codes` dizisinde **hiç `null` eleman yok**; (3) `payload.triage` **MEVCUT** ve `findings` içinde **`OBD_DTC_PRESENT`** bulgusu var (kritik DTC varsa `severity:'critical'`); (4) `triage.ruleErrors = 0`; (5) DTC varken diğer triyaj bulguları (termal/güç/GPS) **da** üretilmeye devam ediyor; (6) `obdDeep.extended.samples[0].pid` dolu (katalog-dışı PID keşfi artık sunucuya ulaşıyor); (7) Dev Inspector raporunda `inspector.timeline[0].signals.spd/rpm` **dolu**; (8) raporda VIN/MAC/koordinat/secret **YOK** (maskeler delinmedi); (9) gerçek rapor gövdesi **`truncated` alanı taşımıyor** ve `octet_length` < 45 KB (64 KB tavanı aşılırsa sunucu gövdeyi `{truncated:true}` kabuğuyla DEĞİŞTİRİR = %100 sessiz kayıp, üstelik UI yine "gönderildi" der — PR-2 konusu); (10) low-tier cihazda (K24/Mali-400 veya T507) rapor gönderimi başarılı, ANR/donma yok. **Araç + DTC olmadan 🟢 YAPMA** — host testleri kodu kanıtlar, gerçek DTC akışını kanıtlamaz. | 2026-07-13 |
Expand Down
Loading
Loading