Spaces — a desktop platform that freezes and thaws whole workspaces
One surface, many contexts
One machine has to serve many unrelated work contexts.
And switching between them means manually reopening apps, re-tiling windows, and paying for idle ones in GPU and RAM. The class is one surface, many contexts: reshaping a machine to a use without forking the logic per platform.
What it is
A desktop platform that organizes a machine into compartments — Spaces — each with its own apps, window layout, and local-model context. A keystroke summons a takeover surface; selecting a Space switches to it with its apps launched and snapped into a panel grid. Background Spaces freeze — their processes suspended, GPU and RAM reclaimed — and thaw on return with state intact. It runs on GNOME and Hyprland from a shared core, currently on an X1 Pro handheld and a fleet dev box.
Where it generalizes
This is the endpoint / workspace layer: one machine reshaped into switchable work contexts with their resources reclaimed — endpoint standardization that scales across a fleet. Shipped and dogfooded on an X1 Pro, GNOME surface v0: menu → launch → snap → freeze → thaw.
The unit of organization
A Space is data. The windows are a projection.
A Space is a named work context — a set of apps, a window layout, and a local-model assignment, held together as one switchable unit. The desktop holds several; one is foreground at a time, the rest are dormant. Switching between them is a single selection, not a manual reopening of windows and a re-tiling of the screen.
A takeover surface on a keystroke
A keystroke brings up a full-screen, per-Space configurable menu of the available Spaces and their actions. On GNOME the summon rides the existing Activities press — no Super-key rebind, no new global shortcut, no custom compositor.
Selecting a Space resolves it
Its apps launch if they are not already running, and the live OS windows snap into the zones its layout defines — each Space's apps place onto its own workspace.
Real windows, really tiled
The panel grid is a real tiling layout over real OS windows: the windows snapped into a Space's zones are the same windows the window manager owns, repositioned — not reparented copies or embedded views.
Back to the surface
Leaving a Space, or summoning another, returns to the surface. The surface is a GNOME shell extension layered over the stock session, so the rest of the desktop keeps working as it did.
Defined in data, not code
The state that defines a Space lives in a .space manifest — which apps it launches, how they place into the layout grid, and what local-model context it carries. That description is the durable artifact; the running windows are a projection of it. Because the definition is data, a Space can be authored, edited, and re-summoned without the apps being open at edit time.
The shared core and the adapter seam
One layout engine, two window managers, one seam between them.
The platform-independent work — the Space data model and the zone and layout math that decides where a window goes — is one Rust crate with no UI dependency. It computes placement; it does not know how a window is moved. Two platforms sit on top of that one core, driven by the same math.
Shared core, native front-ends
The Space data model and the zone/layout math live in one Rust core with no UI dependency. Each platform gets a native front-end over that core: a GNOME shell extension and a Hyprland layer-shell renderer.
The `WindowManagerAdapter` trait
The gap between “where a window should go” and “make the window go there” is a trait each platform implements — the seam that lets a single layout engine target two different window managers without the core knowing which one it is talking to.
Driven directly
Hyprland accepts placement commands directly, so its adapter drives the compositor without an intermediary.
Through a companion
GNOME exposes no external window-control API, so its adapter routes through a companion that translates the core's placement contract into Mutter's move_resize_frame calls — the move/resize primitive GNOME's window manager does expose.
The pieces
WindowManagerAdapter trait Hyprland driven directly; GNOME via a companion → Mutter `move_resize_frame` .space — a shared schema the front-end reads the layout, warden owns the launch, the console authors it llama.cpp on Vulkan · vLLM handheld iGPU · fleet dev box — served on the machine, not over a network Local models
Each Space can carry a local open-weight model as part of its context. The serving backend follows the hardware: on the X1 Pro handheld the model runs on the integrated GPU through llama.cpp on Vulkan; on the fleet dev box it runs through vLLM. The model assignment is part of a Space's definition, so summoning a Space brings up its model context alongside its apps and layout.
The freeze-and-thaw daemon
A Space you've left doesn't need CPU, GPU, or RAM.
warden is the Rust daemon that takes them back. When a Space goes to the background its processes are paused, not terminated, and the resources it held are reclaimed; on return it resumes with state intact.
The cgroup-v2 freezer
warden suspends a background Space's processes through the cgroup-v2 freezer — the kernel mechanism that stops a control group's tasks without killing them — and reclaims the GPU and RAM the Space held.
State intact on return
On return, warden thaws the group and the Space resumes with its state intact, because the processes were paused, not terminated.
Small, tested against the real thing
Roughly 1,800 lines of Rust. It speaks D-Bus for IPC, is managed by systemd, and its tests run against real systemd slices rather than mocks.
Lifecycle, not isolation
The freezer suspends a group's scheduling; it does not put the group in its own namespace, restrict what it can see, or sandbox its data. warden reclaims resources from an idle Space; it does not contain a running one. That distinction is deliberate — it is the line between what is shipped and what is still design intent.
Where it stands
Freeze is shipped. Enforcement is not.
What runs today, what is in build, and where implementation stops and design intent begins — stated plainly.
Running today on the X1 Pro
The GNOME surface v0 loop — menu → launch → snap → freeze → thaw — on GNOME 49.6/Wayland, over the shared core.
Toward daily use and the fleet
A Space as a dedicated GNOME workspace (the allocator); multi-monitor placement; daemon hardening for daily use; lightweight authoring and a one-command fleet install.
in progressThe per-Space sandbox
The per-Space data boundary / ACL is not implemented. Spaces are organizational, not enforced — warden freezes a Space, it does not isolate one. The boundary is the design intent for keeping a local model scoped to one Space.
design intentLicensing
Open-core, two tiers. Third-party packages run as separate processes over IPC and do not link the host crate, so they fall outside the AGPL derivative-works boundary; a commercial license covers embedding the host without AGPL obligations.