bQUARKz 1663ab5413
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
housekeeping
2026-05-15 10:46:58 +01:00

96 lines
3.2 KiB
Markdown

---
id: LSN-0043
ticket: system-os-domain-facades
title: SystemOS Domain Facades
created: 2026-05-15
tags: [runtime, os, services, api-surface, lifecycle, fs]
---
## Context
`SystemOS` became the owner and mediator for core OS services: VM runtime,
lifecycle, filesystem, memcard, window management, task/process state and
logging. That ownership boundary is correct, but exposing every service field
and operation on the root made the OS surface too broad.
The solution was not to split ownership back out of `SystemOS`; it was to split
the public access surface into short-lived domain views.
## Key Decisions
### Use method-based domain facades
**What:** `SystemOS` exposes domain entry points such as:
```rust
os.lifecycle()
os.sessions()
os.vm()
os.fs()
os.window()
```
Each accessor returns a borrow-friendly facade over `SystemOS` internals.
**Why:** Direct fields such as `os.lifecycle.suspend_task(...)` look attractive,
but they force ownership shape too early. Method-based views preserve Rust
borrowing flexibility while still making the domain boundary explicit.
**Trade-offs:** Callers write `os.lifecycle().suspend_task(...)` instead of
`os.lifecycle.suspend_task(...)`. The extra call is worth the cleaner ownership
model.
### Keep logging on the root
**What:** `os.log(...)` remains root-level.
**Why:** Logging is cross-cutting, short and used by multiple domains. It is not
a broad policy surface in the same way lifecycle, VM, fs or window management
are.
**Trade-offs:** The root is not empty, but it remains intentionally small.
### Hide migrated internals
**What:** Direct access to internal fields such as task/process managers, window
manager and VM runtime should disappear once the corresponding facade exists.
**Why:** Public internals let callers bypass OS policy. Facades force callers to
use the semantic boundary instead of stitching together lower-level services.
**Trade-offs:** Tests need domain-level inspection helpers instead of reaching
into raw fields. That is better than keeping production internals public for
test convenience.
## Patterns and Algorithms
Use a short-lived view when an operation needs access to several `SystemOS`
fields:
```rust
os.lifecycle().crash_task(task_id, Some(&report));
os.vm().tick(vm, signals, hw);
os.window().set_focus(window_id);
```
The facade should borrow `SystemOS` or the necessary internals; it must not own
duplicated state. If a domain later becomes a true independently owned service,
that should be a separate decision.
## Pitfalls
- Do not solve a wide root by moving ownership out of `SystemOS` prematurely.
- Do not keep raw managers public just because tests need inspection.
- Do not make facades long-lived when short-lived method calls avoid borrow
pressure.
- Do not invent new filesystem behavior while creating an `fs()` facade; expose
existing behavior first.
## Takeaways
- Ownership boundary and public API shape are separate architectural questions.
- `SystemOS` can remain the owner while exposing a narrower domain-oriented API.
- Method-based facades are a pragmatic Rust shape for OS domains that coordinate
multiple internal services.
- A small root API makes OS policy harder to bypass and easier to document.