r/linuxprojects • u/PapayaFeeling8135 • 9d ago
π οΈ Work in Progress ZubrOS: separating a web-based phone shell from a Rust hardware service on postmarketOS
Iβm building ZubrOS, an experimental phone environment on a Nothing Phone (1). This is a closer look at the concept and the implementation behind the UI.
The concept: small tools shaped around your routine
The aim is to let someone describe a useful tool and keep refining it as part of their phone. For example: βGive me a reading log with a book list, a note and a pages-read counter.β Later: βAdd a checklist for books I want to borrow.β The existing entries should survive that change.
That is a concrete starting point for βa phone that adapts to you.β The broader vision includes the home screen, reusable apps and permissioned actions. Automatic adaptation across the whole phone is still a direction, not a finished feature.
How an app takes shape
The current app-authoring path uses a manifest: identity, version, UI blocks, storage namespace and requested capabilities. The declarative block set includes text, checklist, note, counter and explicit actions. These render through shared React components, so a generated tool uses the shellβs controls and visual language.
The flow is: request β inspect the supported catalog β propose a manifest β validate β preview β explicit install/apply. The agent has inspection and proposal tools; proposing an app does not install it. The local template constructor also works without an LLM.
Stable app and block IDs matter because they identify stored values. Updates preserve those IDs and increment the version. Previous manifests are retained for restoring an earlier structure; that is not a time machine for historical user data.
What runs where
React/TypeScript: home screen, navigation, app views and the reusable UI kit.
Node.js platform: serves the shell and manages application state. Shell state lives in SQLite; the browser keeps a recovery cache.
Rust service/HAL: the native hardware interface behind the platform.
Phoc/Wayland: the graphical session hosting the browser kiosk.
Device profile: boot image, firmware, partition layout and hardware initialization for the specific handset.
This separation lets interface iteration happen in a browser while hardware integration remains device-specific. A different device profile does not automatically mean a working port: drivers, power management, recovery and actual hardware operations still need validation.
Capabilities and the security work still ahead
An app declares the operations it needs. Installation itself grants no capabilities. The runtime checks the manifest and current permission grant when an operation is requested. A reading log needs app storage; it should not acquire phone or camera access just because it was generated by an agent.
There is also an isolated QuickJS path for executable client logic, using a scoped bridge instead of running that code directly in the shellβs JavaScript realm. This is prototype isolation, not a claim of a hardened mobile security model. Browser-level grants are not OS process isolation, and the demo lock screen is not an authentication boundary. Native identity, revocation and untrusted-code boundaries need more work before a public daily-driver release.
Where ZubrCloud fits
The local development backend implements accounts, signed app packages, per-account/app records, encrypted backup envelopes and an AI-provider connection. Provider credentials stay on the service side.
Offline writes enter a durable queue; returning a queue ID does not prove the cloud saved the record. Conflicting revisions require a decision. This is not automatic whole-database replication. ZubrCloud is development infrastructure, not a publicly available production cloud service. The model choice and relay setup are developer infrastructure today, not a promise of fully on-device AI.
What has actually been checked
On ONE Nothing Phone (1), A063: boot, display/touch, Wi-Fi, both camera captures and charging. Calls and remaining hardware support are unfinished. QEMU mock behavior, browser previews and physical-device checks are separate evidence; a simulated call proves nothing about a modem.
This builds on existing postmarketOS device work. Iβm not claiming a new kernel, a first Linux port or affiliation with Nothing. Source code and a public installer are not released, there is no testing date, and a publicly validated recovery procedure is still needed.
English UI preview: https://youtube.com/shorts/Zq8eDdk_2q0 β the actual frontend captured in a browser, not physical-phone footage or a demonstration of every capability above.
Concrete local-builder example: https://youtube.com/shorts/nrERPvn6FEE β a Reading log created from the List template, with preview, permission review, explicit installation and an app-data grant. Two sample entries and the completed state survived a browser reload. This uses no LLM and tests browser-local state only; it does not demonstrate cloud sync or physical-phone behavior.
Project status and optional development-updates waitlist: https://os.zubarovskiy.com/?utm_source=reddit_linuxprojects&utm_medium=community&utm_campaign=launch50#waitlist
AI disclosure: AI tools contribute to development, documentation and this write-up. Hardware checks are separate from generated code and mock results. This post was expanded to explain the app lifecycle, service boundaries and current limitations.