swactor/docs/os-design/README.md

154 lines
7 KiB
Markdown
Raw Normal View History

# Swactor Distributed OS — Design Overview
## Vision
Swactor is evolving from a local actor runtime into a **distributed operating system** for running long-lived daemons across heterogeneous, churning machines.
**Primary use case**: Wire together personal hardware today; add on-demand spot compute (vast.ai, etc.) tomorrow. Machines pop in and out of the network. The system self-heals.
**Design principles**:
- **Churn is the norm**, not the exception. Every subsystem assumes nodes can disappear at any time.
- **General and flexible**. Minimal assumptions about what a node looks like — feature-gate hardware-specific code.
- **Layered**. The core runtime stays minimal. OS features are opt-in crates. Supervision is user-space, not kernel.
- **Frontend-agnostic**. Operational interfaces (commands, inspection) work identically from CLI, TUI, REST, or future transports.
## Current Capabilities
| OS Concept | What Swactor Has Today |
|---|---|
| Processes | Actor spawn/stop, lifecycle hooks, restartable with factory + max_restarts |
| Scheduling | Worker threads, fairness budget (64 msgs/tick), load-aware placement |
| IPC | Typed send, request/reply, per-actor VecDeque mailboxes |
| Naming | String-keyed `AddressMap` — node-local only |
| Fault tolerance | `catch_unwind` for panics, factory restart, dead actor cleanup |
| Backpressure | Per-actor mailbox capacity, DropNewest/DropOldest overflow |
| Networking | SWIM membership (Lifeguard extensions), TCP transport, bincode wire protocol |
| Directory | Kademlia DHT for `ActorAddress -> NodeId` resolution |
| Monitoring | WorkerStats/RuntimeStats, TUI dashboard, REST `/api/*`, investigate REPL |
| Distribution | Multi-node cluster, 5-node Docker test suite |
## What's Missing (This Design)
| Feature | Document | Priority |
|---|---|---|
| Actor Watching | [01-actor-watching.md](./01-actor-watching.md) | Foundation for everything |
| Cluster Registry | [02-cluster-registry.md](./02-cluster-registry.md) | Actors find each other across nodes |
| Node Capabilities | [03-node-capabilities.md](./03-node-capabilities.md) | Heterogeneous placement |
| Command Interface | [04-command-interface.md](./04-command-interface.md) | Operational control |
| Supervision | [05-supervision.md](./05-supervision.md) | Self-healing (user-space) |
## Crate Structure (After This Work)
```
swactor/ # core runtime — no network deps
src/
actor.rs # +watch/unwatch on ContextInner, ExitReason, ActorExited
worker.rs # +WatchRegistry, death notification phase
delivery.rs # (unchanged)
runtime.rs # (unchanged)
...
crates/
capabilities/ # NEW — hardware detection + placement constraints
src/lib.rs # NodeCapabilities, CapValue, PlacementConstraint
command/ # NEW — frontend-agnostic command dispatch
src/lib.rs # CommandRouter, CommandHandler, CommandRequest/Response
src/builtins/ # Built-in command handlers
distribution/ # SWIM + Kademlia + cluster registry
src/
registry.rs # NEW — ClusterRegistry, gossip-propagated naming
node.rs # +register_name, resolve_name, capabilities
messages.rs # +WatchRequest, UnwatchRequest, ActorExitedNotify
...
runtime-dashboard/ # TUI + REST — refactored to use command crate
python/ # PyO3 bindings
simulation/ # Network simulation
wasm/ # WASM bindings
```
## Dependency Graph
```
┌──────────────┐
│ capabilities │ (standalone — only serde + sysinfo)
└──────┬───────┘
│ optional
┌─────────┐ ┌──────▼────────┐
│ swactor │◄─────│ distribution │
│ (core) │ │ +registry │
└────┬────┘ └──────┬────────┘
│ │
│ ┌──────▼────────┐
└──────────►│ command │
└──────┬────────┘
│
┌──────▼────────────┐
│ runtime-dashboard │
│ (TUI + REST) │
└───────────────────┘
```
Key constraints:
- `capabilities` has **zero** dependency on `swactor` — it's a standalone detection library.
- `command` depends on `swactor` (needs `Runtime`, stats types) but NOT on `distribution`.
- `distribution` optionally depends on `capabilities` (for `NodeRecord` labels).
- `runtime-dashboard` depends on both `command` and optionally `distribution`.
## Feature Flags
### Core `swactor`
| Flag | Purpose |
|---|---|
| `getrandom` (default) | Cryptographic RNG for actor addresses |
| `serde` | Serialization for types |
| `tracing` | Structured logging |
| `transport` | Transport-agnostic remote messaging |
| `watching` (new) | Watch API on ContextInner/Ctx |
### `swactor-capabilities`
| Flag | Purpose |
|---|---|
| `detect` (default) | Auto-detect CPU, RAM, hostname via sysinfo |
| `gpu-nvidia` | Detect NVIDIA GPU via nvidia-smi |
| `gpu-vulkan` | Detect GPU via Vulkan API |
### `distribution`
| Flag | Purpose |
|---|---|
| `registry` (new, default) | Cluster-wide gossip-propagated naming |
| `capabilities` (new) | NodeCapabilities on NodeRecord |
## Implementation Order
Each feature is one PR, in dependency order:
```
PR 1: Actor Watching (local only)
└──► PR 2: Command Interface
└──► PR 3: Cluster Registry
└──► PR 4: Node Capabilities
└──► PR 5: Remote Watching (cross-node)
└──► PR 6: Supervisor library
```
**PR 1 — Actor Watching (local)**
Adds `WatchRegistry`, `ActorExited`, `ExitReason` to core runtime. Testable without any distribution. Foundation for everything else.
**PR 2 — Command Interface**
Extracts investigate.rs into `crates/command/`. Adds write commands (spawn, stop, drain). Immediately useful for operations.
**PR 3 — Cluster Registry**
Gossip-propagated naming in `crates/distribution/src/registry.rs`. Actors can find each other by name across nodes.
**PR 4 — Node Capabilities**
`crates/capabilities/` with auto-detection and placement constraints. Integrates with distribution for capability-aware placement.
**PR 5 — Remote Watching**
Wire protocol for cross-node watches. SWIM Dead triggers `ActorExited { reason: NodeDown }` for all actors on that node.
**PR 6 — Supervisor Library**
User-space supervisor pattern. Composes watching + registry + capabilities to auto-respawn actors after churn.