Explanation
System design overview
How a request travels from your keyboard to a verified result.
OOMU is a native macOS application. Not a website in a wrapper, not a thin client over an API. That single decision explains most of what follows.
The shape of it
| Layer | What it is |
|---|---|
| Interface | Next.js 16 and React 19, rendered in the application's own webview. |
| Bridge | 183 Tauri commands. The only path from interface to engine. |
| Engine | Rust. Routing, execution, storage, credentials, scheduling. |
| Models | llama.cpp on Apple Silicon, plus whichever cloud providers you have connected. |
| Storage | One SQLCipher-encrypted SQLite database, keyed from the macOS Keychain. |
The interface has no filesystem access, no network access, and no database access. Everything it does, it asks for. That constraint is what makes the rest of the design possible: there is exactly one place to enforce anything.
A turn, end to end
1. The snapshot
Before any model runs, the engine assembles a turn snapshot: your prompt, recent conversation, attachment metadata, the capability manifest version, which models are configured, whether the project is local-only, whether the network is available, which providers are reachable, which Apple permissions macOS has granted, and a source label for every segment of context.
Source labels are the quiet load-bearing detail. Text you typed and text that arrived from a web page carry different labels, and the distinction survives the whole turn.
2. The decision
The snapshot goes to the understanding model: a 0.6-billion-parameter Qwen3 that OOMU fine-tuned to do one thing: decide. It runs locally with a 4,608-token context, a 96-token output ceiling, and thinking disabled.
It returns a turn decision: a route (local, cloud, deterministic, or clarify), a mode, normalized goals bound to spans of your text, proposed capabilities bound to goals, whether fresh information is needed, ambiguities, risk signals, and the digests of the router and the capability manifest it decided against.
The decision is validated before use. An internally inconsistent decision is rejected rather than executed. Accepted decisions are recorded with their digest.
The router never writes your answer.
3. Execution
If the decision proposes capabilities, each one goes through the same sequence:
Resolve → describe the effect → execute → verify the postcondition → write a receipt.
Resolve turns model-supplied arguments into canonical, checked ones: a real path with its device, inode, and modification time; a real element from a real observation; a real bundle identifier.
Describe produces an effect descriptor (reversibility, externality, privilege level, blast radius, data classes, and an idempotency key) and digests it.
Execute runs the native executor. Nothing generic; each capability has its own.
Verify runs a postcondition verifier that looks at the world and reports what it observed.
Receipt records all of it, including whether the postcondition actually held.
An autonomous turn may take at most eight tool steps before it must produce an answer.
4. Synthesis
Only then does a language model write prose (locally on Gemma 4, or on your connected cloud model) with the verified results as its material.
5. Commit
The turn is written with its request digest, result, and result digest. The activity record is completed with a receipt count and an evidence digest, or failed with a category. The usage ledger records whether it ran locally or in the cloud, and the token counts.
Where policy is enforced
Three gates, all in the engine, all before anything leaves the machine.
| Gate | Enforced by |
|---|---|
| Air-Gap Mode | A process-wide egress permit. Every outbound operation must acquire one. Initializes to blocked, before the setting is read. |
| Project cloud access | Present in the turn snapshot. A local-only project means the router is not offered a cloud route. |
| macOS TCC | The operating system. OOMU cannot override it, and does not try. |
Note which axis each one sits on. Access to your machine is macOS's decision. Data leaving your machine is OOMU's, and OOMU gates it in the engine.
Why device permissions belong to macOS
Beta 1 built a second permission system on top of the operating system: a file sandbox, a permission broker, trust policies with resource budgets, a capability gatekeeper. It was more machinery, and it was worse.
It was worse because it created a second, unfamiliar security surface. Users had to reason about OOMU's permissions and macOS's. Two systems can disagree, and when they do, the more permissive one wins. And an in-app dialog in front of every action produces exactly one behavior: people click through.
So for device access, Beta 2 defers to the operating system, and every native macOS permission is enforced: one prompt, in macOS's voice, at the moment the feature needs it, managed afterwards in System Settings alongside every other application, and revoked there the same way. Settings → Mac access reports what macOS has granted across ten categories; it does not grant anything itself.
That is a division of labour, not an absence of gating. OOMU governs the axis macOS does not cover, which is what leaves: Air-Gap Mode and each project's cloud access policy are both evaluated in the engine before a route is chosen. Finer-grained gating over private information leaving the machine is in development for the Beta 2 release; this page describes what is in the build today.
And OOMU keeps the parts macOS does not do at all: identity binding on every resolved resource, postcondition verification on every action, and a receipt for each one.
The pieces
Storage
One database, encrypted with SQLCipher, keyed from the Keychain, verified as encrypted at open. Constraints in the schema make illegal states unrepresentable: a completed activity record without evidence is refused by the database itself.
Secrets are not in the database. They are in the Keychain, referenced opaquely.
Concurrency
Worker threads park in blocking receivers rather than polling, so an idle OOMU consumes no background CPU. Scheduled work sleeps until an exact deadline.
Recovery
On startup, the engine reconciles. Expired routine leases are released. Reserved workflow steps are reset. Steps that were mid-execution are quarantined as Check required, because their outcome cannot be verified. All of it is logged.
Nothing unverifiable is reported as done or as failed.
Extension
Three narrow doors, each with a different trust model:
| Door | Trust |
|---|---|
| Mods | Content only. Three capabilities. No code executes. |
| Local MCP tools | Executables you pick from a system dialog, with per-tool read-only marking. |
| Connectors | OAuth to services you sign into, with tokens in the Keychain. |
None of them can widen the capability manifest.
Identity
Beta 2 is fully namespaced away from Beta 1: bundle ai.eldris.oomu.gpd.beta2, its own Keychain service, its own model cache, its own single-instance lock, its own update channel. Installing it cannot disturb a Beta 1 installation, and it cannot read Beta 1's data.
Design commitments
| Commitment | How it shows up |
|---|---|
| Local by default | The router and assistant run on your Mac. Cloud is opt-in and per-project. |
| Verified, not assumed | Every action has a postcondition verifier and a receipt. |
| The OS owns device permissions | Every native macOS permission is enforced, and OOMU cannot override one. |
| OOMU owns egress | Air-Gap Mode and project cloud policy are evaluated in the engine before a route is chosen. |
| Idempotent everywhere | Operation IDs on mutations, idempotency keys on effects, unique occurrence keys on schedules. |
| Honest about limits | Unavailable connectors say so; unmeasured speed says so; unsupported Mod features are listed by name. |
| Twelve languages, at parity | Enforced by a test that fails on a single missing key. |
Related
- Evidence & receipts: the verification model in detail.
- Privacy & security: where your data lives.
- Application Bridge API: the boundary layer.
- How OOMU picks a model: the router in detail.