All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
96 lines
3.2 KiB
Markdown
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.
|