feat(assistant): Unified Assistant Context Store (OfflineAssistantContext)#43
Merged
Conversation
…text) Voice Assistant · Companion AI · Safety Kernel · Offline Conversation · Vehicle Learning · Diagnostic AI · Maintenance AI katmanlarının BUGÜN ayrı ayrı okuduğu kaynakları TEK merkezde toplayan, periyodik + dondurulmuş snapshot yayınlayan store. useAssistantContextStore (yeni, tek dosya): - buildSnapshot(): SAF kurucu — enjekte kaynaklar, throw ETMEZ, girdiyi mutate ETMEZ, çıktı Object.freeze'li (kök + 10 bölüm). Whitelist: girdiye fazladan alan eklense bile snapshot'a SIZAMAZ. - readLiveSources(): canlı adaptör — her kaynak İZOLE try/catch (fail-soft); biri düşse diğer bölümler üretilmeye devam eder. - Lifecycle: abonelikler start'ta BİR KEZ kurulur, dispose'ta BİR KEZ kapatılır → snapshot başına subscribe/unsubscribe döngüsü YOK. start/stop idempotent, dangling görev guard'lı (zero-leak). Performans bütçesi: periyot 5 sn · DeviceTier=low → 10 sn. Görev runtimeManager.scheduleTask üstünde criticality:'NORMAL' + deferIdle:true → hot-path'e (3Hz hız/RPM) GİRMEZ. Dirty-flag ile park hâlinde tik sıfır ayırma yapar (60 sn bayatlama tavanı). Ağır soğuk-yol bölümleri (identity/learning) 30 sn (low: 60 sn) aralıkla okunur, arada önbellek döner; learning okuması zaten memoized + bounded(512) + tier-farkında entegrasyon servisinden gelir. Gizlilik: VIN · MAC · GPS koordinatı · ham PID/DID/CAN snapshot'a ASLA girmez. Navigasyon hedefi yalnız görünen ad (koordinatsız, ≤64 karakter). Kaynağı OLMAYAN alanlar uydurulmadı, dürüstçe null: deepScan.* (projede genel bir Deep Scan servisi YOK — yalnız DTCPanel'de lokal isDeepScanning UI state'i), driver.fatigueScore, status.ignition, media.ducking, network.wifi/mobile (yalnız navigator.connection.type kesinse dolar). Additive: hiçbir servise YAZMAZ, severity/driveSafe/diagnostic kararını DEĞİŞTİRMEZ (yalnız okur), henüz hiçbir tüketiciye ve SystemBoot'a bağlı DEĞİL → bu PR'da çalışma zamanı davranışı değişmez. Test: 25 test (snapshot · tier periyodu · freeze/immutability · fail-soft · null servis · dispose · zero-leak · gizlilik · dirty flag · manuel refresh · bellek büyümesi · hot-path). tsc -b temiz, lint temiz, tam suite 2628 yeşil (regresyon yok). Ledger #28 (cihazda test bekliyor). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q74z6tXWP39iBSXZYnLQW1
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…t-store # Conflicts: # docs/DEVICE_VALIDATION_LEDGER.md
This was referenced Jul 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Amaç
Voice Assistant · Companion AI · Safety Kernel · Offline Conversation · Deep Scan · Vehicle Learning · Diagnostic AI · Maintenance AI katmanlarının bugün ayrı ayrı okuduğu kaynakları tek merkezde toplayan, periyodik ve dondurulmuş (immutable) snapshot yayınlayan birleşik bağlam store'u.
Additive: hiçbir servise yazmaz, hiçbir tüketiciye ve SystemBoot'a bağlı değil → bu PR'da çalışma zamanı davranışı değişmez.
Yeni dosyalar
src/store/useAssistantContextStore.tssrc/__tests__/assistantContextStore.test.ts(25 test)Değişen dosyalar
docs/DEVICE_VALIDATION_LEDGER.md— kayıt feat(vehicle): Araç Bilgi Tabanı Temeli (PR-28) #28 🔴 (CLAUDE.md zorunluluğu)Başka hiçbir dosyaya dokunulmadı.
Tasarım —
assistantSafetyKerneldesenibuildSnapshot(sources, now, revision)Object.freeze'lireadLiveSources(now, coldRefreshMs)try/catch→ biri düşse diğer bölümler üretilmeye devam ederstartAssistantContext/stopAssistantContextBu ayrım sayesinde karar/şekillendirme mantığı cihazsız, mock'suz, deterministik test edilir.
Snapshot bölümleri
identity(fingerprintHash, manufacturer, profileHint, protocol) ·health(healthScore, severity, driveSafe, maintenance) ·learning(evidenceCount, patternCount, strongestConfidence, learnedVehicleCount) ·deepScan·status(speed, rpm, coolantTemp, fuelLevel, batteryVoltage, ignition) ·driver(fatigueScore, tripDuration, cognitiveMode) ·navigation(isNavigating, destination, remainingKm, remainingTime) ·media(playing, volume, ducking) ·network(online, wifi, mobile) ·device(tier, thermalStatus, powerSaver)Kök nesne ve 10 bölümün hepsi ayrı ayrı
Object.freeze'li.Repo denetiminde şu alanları besleyen bir servis bulunamadı. Değer üretmek yerine dürüstçe
nullbırakıldı ve şemada yer tutuyor:deepScan.*(5 alan)DTCPanel.tsxiçinde lokalisDeepScanningUI state'i vardriver.fatigueScorestatus.ignitionmedia.duckingaudioServiceduck durumunu dışa açmıyor (_duckCountprivate)network.wifi/mobilenavigator.connection.typekesin söylüyorsa dolar;connectivityServicesync okuma API'si sunmuyorKaynakları eklendiğinde yalnız adaptör doldurulacak; şema ve tüketiciler değişmeyecek.
Performans bütçesi
DeviceTier === 'low'→ 10 sn.runtimeManager.scheduleTasküstünde:criticality: 'NORMAL'(güvenlik kararı üretmez → düşük tier'da mod çarpanıyla yavaşlaması istenir) +deferIdle: true(requestIdleCallback) → hot-path'e (3Hz hız/RPM) girmez.identity,learning) her tikte değil, 30 sn (low: 60 sn) aralıkla okunur; arada önbellek döner.learningokuması zaten memoized + bounded(512) + tier-farkındavehicleLearningIntegrationServiceüstünden gelir (low tier'da ağır pattern detayı kapalı).Gizlilik
VIN · MAC · GPS koordinatı · ham PID/DID/CAN snapshot'a asla girmez. Kurucu whitelist çalışır: girdiye fazladan alan eklense bile snapshot'a sızamaz (yapısal garanti, testle kilitli). Navigasyon hedefi yalnız görünen ad (koordinatsız, ≤64 karakter).
Zero-leak
Snapshot başına subscribe/unsubscribe döngüsü yok (abonelikler start'ta bir kez).
start/stopidempotent. Dispose: scheduler görevi kaldırılır, tüm abonelikler kapatılır, önbellekler ve yayınlanan snapshot temizlenir (eski referans tutulmaz). Dispose sonrası elde kalmış bir görev referansı tetiklense biletick()sessizce çıkar (dangling görev guard'ı).Dokunulmayanlar
assistantSafetyKernel.ts·companionContext.ts·vehicleLearningDecay.ts·vehicleLearningPatternEngine.ts·diagnosticKnowledgeEngine.ts· Fingerprint algoritması · Vehicle Learning algoritması · Discovery Pipeline · OBD polling · Native Android · SQL/Supabase · PR #11 / PR #20Testler — 25 test
Snapshot oluşturma (3) · tier periyodu low=10s / mid+high=5s (2) · freeze + immutability + girdi mutasyonsuzluğu (3) · fail-soft (2) · null servis / throw eden kaynak (2) · dispose + start/stop idempotency + dangling görev (4) · gizlilik (2) · dirty flag (3) · manuel refresh (1) · bellek büyümesi yok (1) · hot-path koruması (2).
CI beklentisi
Yerel:
tsc -btemiz ·eslinttemiz · 170 dosya / 2628 test yeşil (baseline 2603 + 25 yeni; regresyon yok).Risk
Düşük. Yeni, izole bir dosya; hiçbir mevcut çağrı yolu değişmedi. Store başlatılmadığı sürece (
startAssistantContextçağrılmadıkça) tek etkisi modül import'u. Başlatıldığında dahi: yalnız okur, yazmaz; güvenlik/tanı kararlarını değiştirmez; görev NORMAL + idle → hot-path ve BASIC_JS bütçesi korunur. Asıl risk tüketici bağlama (wiring) PR'ında doğar — orada snapshot'ın bayatlığı venullalanların tüketicilerce doğru ele alınması doğrulanmalıdır.Ledger
Kayıt #28 — 🔴 cihazda test edilmedi. Numara 28 seçildi çünkü 26 ve 27 açık PR'larda (#41, #42) rezerve.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Q74z6tXWP39iBSXZYnLQW1