-
Notifications
You must be signed in to change notification settings - Fork 4
Resource Engine
A desktop shell that understands the machine it runs on, and arbitrates between the workloads competing for it. No other Linux desktop shell does this. Every other thing Aphotic does (themes, bars, a launcher, a plugin platform, agent tracking) has an analogue somewhere else. Resource arbitration between desktop workloads does not. See Why Aphotic for the problem this exists to solve.
When two workloads want the same finite resource, Aphotic detects the contention and asks which one wins. It never decides for you, and it never kills anything.
Workload -> Resource Claim -> Contention -> Negotiation -> Apply -> Monitor -> Restore
The canonical case, live-verified: a local model holding 8226 MB of VRAM, a game registering 13386 MB through GameMode, 22376 MB against a 22108 MB safety budget. A real negotiation gets raised. You answer it. Choose Suspend and Ollama unloads through its own API in about 10 ms: the model steps aside, the game keeps every megabyte it asked for, nothing crashes.
The implementation enforces these; they aren't just stated intent.
-
Nothing gets terminated. The only stop path is a
suspendRequestedsignal to the owning profile's own graceful-stop hook. A claim stays registered until its owner releases it, so the claim table keeps telling the truth even when a stop is slow or declined. -
The engine never touches the kernel or
sysctl, and never probes hardware directly. Capacity is declared by whichever domain knows how to measure it (declareResource()). An undeclared resource gets tracked but never arbitrated. Core declares nothing at rest: CPU and system-memory capacity are declared only while something claims against them (reference counted inSystemCapacity), so a base install with nothing running can never raise a negotiation on its own. -
The engine never resolves a conflict on its own. Contention produces a negotiation; you answer it. Three choices cover every case regardless of which two domains collided:
[Suspend <workload>],[Keep Running],[Ignore]. Negotiations queue instead of stacking, so two conflicts can't produce two modal prompts at once.
Two filters keep the prompt from asking questions with only one answer. Only a workload that belongs to a registered profile asks for arbitration: the catch-all per-process claims (the compositor, the shell, a terminal) are accounting, not contenders. And a conflict whose current holder has no graceful-stop hook opens no prompt, since "keep running" would be the only possible answer; Flow still shows it as over budget.
A fourth property falls out of the design instead of needing a rule someone has to remember: it stays dormant until claimed. No timer, no background process, no file watch. Nothing runs and nothing costs anything until a domain actually registers a claim.
| Piece | State |
|---|---|
| Core substrate | Shipped |
| Ollama claimant | Real, live-verified on NVIDIA |
| llama-swap claimant | Real, live-verified on NVIDIA via llama-server PID adoption |
| LM Studio claimant | Real, through the same shared local-inference claimant as Ollama and llama-swap |
| System-memory claims | A model a backend reports resident in RAM (not on the GPU) claims system memory |
| Gaming claimant | Real, live-verified via GameMode PID adoption |
| AI-to-Gaming negotiation | Proven with both sides real |
| Dev claimant | CPU claims for builds a launcher wrapper reports, sized by their declared worker count, at background priority. Nothing scans command lines |
| Security claimant | Profile and workload passport only; the claim seam exists but is unwired until an engagement's real cost is measured |
| NVIDIA capacity detection | Hardware-verified |
| AMD capacity detection | Written to spec, not yet run on real AMD hardware |
| Intel capacity detection | Declares nothing on purpose. Intel's shared framebuffer has no separate VRAM budget to arbitrate |
| Resource map UI | Shipped as Flow, a Command Center tab (2.0.5). See below |
llama-swap. Set a llama-swap host in Settings, AI and each model it runs becomes a claim. llama-swap reports model names but not memory, so Aphotic matches each model to the llama-server process serving it and claims that process's measured VRAM, once, under the llama-swap owner. Choosing Suspend unloads the model through llama-swap's own API. A llama-swap on another machine holds no VRAM here, so it claims nothing.
LM Studio and Ollama. Both feed the same claimant. VRAM comes from the model's own process where there's a PID to adopt, and from the backend's own report otherwise; memory a backend reports resident outside the GPU becomes a system-memory claim.
Command Center (Super+D) → Flow is the live map of the engine's state:
- Reservoirs — each declared resource (GPU VRAM, CPU, memory) and how much is claimed. A contended one is marked.
- Workloads — each claimant with its phase, grouped by plane (AI, gaming, security, dev).
- Claim lens — select a node to see every claim behind it: amount, priority, origin.
- Reported work and What changed — the workload passports and action receipts behind a node (what started, what was asked to stop, and whether it did), with an Export receipts button.
- Negotiation bar — a pending negotiation shows at the bottom with a projection of the outcome, and can be answered there ("Keep both" or "Request graceful stop") as well as from the prompt.
- Shell activity — an opt-in layer, off by default, that shows what Aphotic itself is using. Measured, never claimed, so it can't cause a negotiation.
Flow listens only while it is visible and adds no process scanner of its own.
Loading a local model also switches the desktop into inference mode (blur, shadows and animations off, pausable plugins paused) until 20 seconds after it unloads. See Supported Features.
Honest limitation: the engine stays dormant on any install without a local model loaded, a game registered with GameMode, or a reported dev build. Most installs have never seen it negotiate anything. That's a roadmap gap, not a documentation one. See Project Status.
- Why Aphotic — the VRAM-crash problem that made this the flagship feature
- Architecture — where the Resource Engine sits in the shell
-
Plugin System — the
profilecapability, for a plugin that wants to register its own claimant (Gaming Profile is the worked example)