On-device semantic search over the user's own data
Semantic search on a phone is not a vector-database problem at user scale — it is an index-freshness problem, invisible until someone searches.
We use Google Analytics to see which pages help people. No ads, no profiles. Privacy Policy
98 posts
Semantic search on a phone is not a vector-database problem at user scale — it is an index-freshness problem, invisible until someone searches.
On-device inference has no per-call bill, and that hides six real costs — eligibility, size, battery, thermal, capability ceiling and operations.
Routing between a local and a hosted model needs a decision you can audit. Route before attempting, record the path on every result, and watch the proportion.
Reading offline is the easy half. The write path is where it breaks: stale cold starts, unresolved conflicts, unorchestrated retries and torn pages.
Comparing a local model to an API is not a race between two averages — it is tail latency, failure rates, and how often one task crosses the boundary.
Before and after on a real module migration: what proved the change was inert, what the agent got wrong, and the receipt that made it safe to run at all.
A protected-path list was typed by hand and had drifted nine entries behind reality. Derive the list instead of copying it, and gate the copies you keep.
Compose has two kinds of state holder: plain classes that live in the composition, and ViewModels that outlive it. Knowing which to reach for is what keeps UiState classes from growing to twenty fields.
Compose's recommended architecture is three layers with one-directional dependencies. The split inside the UI layer — elements and state holders — is the one that decides whether a screen can be tested without a device.
CompositionLocal passes values down the composition without parameters. That invisibility is the feature and the danger: three tests for when it is the right tool, and what to use instead when it isn't.
Correct hoisting can still produce an unmaintainable codebase. The four failure modes that show up once a screen grows past a few components, and the fixes for each.
Hoisting to a ViewModel is a different decision from hoisting to a parent composable. The dividing question is lifetime, and getting it wrong in either direction has a specific cost.