0f9280bd00
Delay competing Rime work, add extension memory telemetry and stress coverage, and refresh the 1.8 release assets and metadata for build 79.
82 lines
3.6 KiB
Markdown
82 lines
3.6 KiB
Markdown
# Keyboard memory budget — acceptance (OSGDiag)
|
||
|
||
Phase 0 / 2 memory work is validated on a **physical iPhone** with Console
|
||
filtering for `OSGDiag`. Unit tests and `xcodebuild` cover compile-time
|
||
wiring; jetsam behavior is device-only.
|
||
|
||
## Hybrid Flow (product default)
|
||
|
||
- Foreground host is **light by default**: orphan Live Activity cleanup only —
|
||
**no** auto `startSession` / continuous capture on appear.
|
||
- Capture starts only on explicit Start / `osgkeyboard://startflow` / mic press.
|
||
- Idle background capture is stopped so a parked host does not jetsam the keyboard.
|
||
- **Do not** stack CLM + Rime + ASR in the same second after onboarding.
|
||
- ASR warmup runs on **first mic press** (`beginUtterance`), gated by
|
||
`HostMemoryBudget` (~260 MB RSS). `hostHeavy` is set only while heavy work
|
||
actually runs, then cleared. A sticky `hostHeavy` (host died mid-work)
|
||
expires after `hostHeavyMaxAge` (~120 s) and is cleared on
|
||
`clearFlowState` / host-launch reconciliation so typing 中文/EN is not
|
||
permanently blocked.
|
||
|
||
## Console checklist
|
||
|
||
Filter Console by process separately: host `OSGKeyboard` vs extension
|
||
`com.osgkeyboard.ios.keyboard`. Host-only filter will never show `KVC.*`.
|
||
|
||
| Scenario | Expect |
|
||
|----------|--------|
|
||
| **Force-quit host**, open Notes, switch to OSG | First `dyld.constructor`, then `KVC.init` → `viewDidLoad` → `viewDidAppear` |
|
||
| Host foreground right after launch | `skip capture` + `postOnboardingWarmup scheduled … delay=45s` (no immediate Rime/CLM) |
|
||
| ~45 s later, host still active | Serial `rime.installIfNeeded` then `clm.prepare` |
|
||
| First mic press | `scheduleASRWarmup`; `hostHeavy` only while work runs |
|
||
| Switch to typing | Single `rime.prepare` / `englishPrepare` |
|
||
|
||
If neither `dyld.constructor` nor `KVC.init` appears after force-quitting the host,
|
||
the extension is dying in dyld (Shared≈9.4 MB + librime) — next lever is splitting
|
||
Rime out of Shared.
|
||
|
||
## RSS comparison (optional)
|
||
|
||
Record `OSGDiag` `rss=` tags for:
|
||
|
||
1. Cold voice surface only
|
||
2. Cold typing after prepare
|
||
3. Host foreground + extension
|
||
|
||
Target: typing peak below the old “voice + eager Librime construct” baseline.
|
||
|
||
## Extension physical-footprint budget
|
||
|
||
`phys_footprint` is the primary extension metric because device jetsam follows
|
||
it more closely than RSS. `KeyboardExtensionMemoryTelemetry` records structured
|
||
`[OSGDiag/memory] extMemory` lines at lifecycle and heavy-resource milestones,
|
||
plus 50 ms samples during the first four seconds:
|
||
|
||
- **Normal:** below 36 MiB
|
||
- **Warning:** 36–40 MiB
|
||
- **High:** 40–48 MiB; 40 MiB is the internal safe peak
|
||
- **Critical:** 48 MiB or above
|
||
|
||
The approximate 60 MiB device boundary is not a public Apple contract. The
|
||
40 MiB target deliberately reserves room for transient SwiftUI, Rime, and
|
||
system-framework pages. Telemetry is observation-only: crossing a band logs
|
||
`crossed=1` but does not change the selected surface or unload resources.
|
||
|
||
Each record includes the current and peak footprint, delta from process start,
|
||
elapsed startup time, surface/language, Full Access, clipboard state, and
|
||
operation-specific context. Filter Console by `OSGDiag/memory` and compare:
|
||
|
||
1. `KVC.viewDidLoad.afterInstallServices`
|
||
2. `KVC.viewDidLoad.afterInstallSwiftUI`
|
||
3. `typing.englishPrepare.done`
|
||
4. `typing.rimePrepare.done`
|
||
5. `clipboard.reload.done`
|
||
6. `KVC.viewDidAppear.done`
|
||
|
||
## Structural split
|
||
|
||
- Extension links **OSGKeyboardShared** only (no Charts / StoreKit / Speech / HostSupport).
|
||
- Host embeds **OSGKeyboardHostSupport** (ASR, CLM, CloudASR, tip/charts UI).
|
||
- Heavy assets (`osg_pinyin.dict.yaml`, CLM bin, licenses, local-asr catalog)
|
||
ship in the **host app** bundle; extension reads Rime from App Group after deploy.
|