OOrion OS

Developer Handbook · Version 1.0

Orion OS — Developer Handbook

Orion OS is the product name for this stack.

Appendix A covers SAL JSON-RPC, first-bootd HTTP, catalog, and ports (see below).


1. Introduction

Orion OS is a minimal, modular, AI-oriented Linux desktop built to be:

  • Fast — small init, predictable boot, localhost-first services
  • Understandable — thin layers: kernel, init, compositor, session, apps
  • Extensible — catalog-driven apps, YAML profiles, JSON-RPC SAL
  • Self-hosting-friendly — developer edition can carry tooling for building the OS
  • AI-friendly — intent routing and a pluggable AI backend (HTTP)

The shipping stack uses Alpine Linux userland, a custom shell init (init/init.sh installed as /init), Weston (Wayland compositor), and Rust binaries for services and applications. Control and introspection go through SAL (System Abstraction Layer) over JSON-RPC on HTTP.

2. System architecture

Layers from hardware upward:

Hardware
  → Linux kernel (Alpine linux-lts in shipped images)
  → PID 1: init/init.sh (/init)
  → udev, seatd, optional Windows compat daemon, net-status, update-checker
  → Weston (DRM/fbdev) or compositor-watchdog wrapper
  → devtoolsd → SAL (sal-backend-linux) → ai-backend (+ ai-shell), background-loader
  → First-boot flow OR session-launcher → Hub / AI UI / catalog apps

Compositor path. By default init tries compositor-watchdog when USE_COMPOSITOR_WATCHDOG is non-zero and the binary exists; otherwise it starts Weston directly (MYO_COMPOSITOR_BACKEND: auto, fbdev, or drm).

Service pattern. Long-running components are started as background processes from init, with logs under /var/log/myo/services/<name>.log.

Workspace layout (this repository).

AreaPurpose
init/PID 1 script
apps/Application crates
services/Daemon crates
sal/backends/linuxSAL JSON-RPC server (sal-backend-linux)
ai/backend, ai/ai-uiAI HTTP backend and UI
crates/Shared libraries (sal-types, profile-core, catalog-core, …)
build/Rootfs overlay, image scripts, installer
profiles/Boot profiles consumed by SAL / background-loader
catalog/apps.yaml, categories
internet-hub/Hub layout and config

3. Boot and init

3.1 Sequence

  1. Firmware loads the kernel (installed image or live media).
  2. Kernel runs /init (copy of init/init.sh).
  3. Init mounts essential filesystems, prepares XDG_RUNTIME_DIR, starts udev and seatd.
  4. Optional net-start (firewall / NetworkManager baseline).
  5. Compositor (Weston or watchdog).
  6. devtoolsd (before SAL, for dev tool forwarding).
  7. SAL, ai-backend (loop with optional reload on exit 75), ai-shell, background-loader.
  8. If /etc/myo/firstboot-done is missing: first-bootd then first-boot UI; otherwise session-launcher after Wayland is ready.
  9. Init stays alive in a sleep loop (PID 1).

3.2 Important environment variables

Documented in the header of init/init.sh. Highlights:

VariableTypical meaning
WESTON_BINPath to Weston; empty skips direct Weston (watchdog may still run)
SAL_BINDefault /usr/bin/sal-backend-linux
SAL_URLUsed by loader; default http://127.0.0.1:8750/rpc
SAL_DANGEROUS=1Allows privileged SAL operations (mount, packages, modprobe, power mode); unsafe by design
FIRST_BOOTD_LISTENDefault 127.0.0.1:8793
NET_STATUS_LISTENDefault 127.0.0.1:8791
HUB_CONFIGInternet Hub YAML (dev trees may use repo path)
PROFILES_DIR, BOOT_PROFILEProfile YAML and boot profile name
LOADER_REAL_APPLY=1Loader may run real package/service apply from profile

4. Editions

Two editions drive UX and optional tooling:

EditionIntent
userMinimal surface; no developer-centric extras
developerTooling, workspace expectations, dev-oriented Hub tiles / intents

The active edition is stored in /etc/myo/edition (values user or developer). Image build scripts set this via staging (assemble-rootfs.sh).

5. Core services

Representative services (Rust daemons under services/):

ServiceRole
net-statusLocal HTTP API for connectivity; SAL calls NET_STATUS_URL
update-checkerUpdate metadata (not full OS updater in v1)
compositor-watchdogRestarts compositor / fallback UX
devtoolsdForwards dev SAL methods to local tooling
first-bootdLoopback HTTP API for the wizard
background-loaderApplies boot profile via SAL RPC
session-launcherStarts session after first-boot completes
sal-backend-linuxSAL JSON-RPC
ai-backendHTTP server for AI UI (POST /prompt placeholder path)

Most speak HTTP on localhost; SAL uses JSON-RPC POST on /rpc (and /).

6. Application model

  • Apps are Rust crates under apps/<name>/ (see workspace Cargo.toml members).
  • Ship as ELF binaries installed to /usr/bin in the rootfs (via assemble-rootfs.sh).
  • UIs use WebView or native stacks as implemented per app.
  • Discovery happens through catalog/apps.yaml and the Internet Hub (hub.yaml).

Adding an app means: implement the crate, list it in the workspace, ensure the binary is staged by assemble-rootfs.sh, add a catalog entry, and optionally Hub tiles and AI intents.

7. Catalog and Internet Hub

Catalog (catalog/apps.yaml)

Each app entry commonly includes:

  • id, name, description
  • command — binary name on $PATH (older docs said binary; this repo uses command in YAML)
  • tags — categories / filters
  • install, hidden, autostart
  • download_behavior — e.g. mode: process vs open_webpage with url

Categories may be listed in catalog/categories.yaml.

Internet Hub

The Hub resolves tiles and sections from internet-hub/hub.yaml (and related assets). Catalog entries tie apps to user-visible launchers; the Hub organizes high-level navigation (system tiles, external links, etc.).

8. AI layer

  • Intent router: ai/backend/src/intent.rs maps natural phrases to SAL actions (e.g. start process, SAL calls). Extend phrases for synonyms; keep help strings accurate.
  • Backend: Axum HTTP server; default listen 127.0.0.1:8787 (AI_LISTEN). POST /prompt is the integration seam (placeholder semantics as of this handbook).
  • UI: ai-ui connects users to the backend.

When adding a feature reachable by voice/text, update intents, catalog, and any Hub entry together so discovery stays coherent.

9. SAL overview

SAL is implemented by sal-backend-linux (crate sal-linux).

  • Transport: HTTP POST JSON-RPC to http://127.0.0.1:8750/rpc by default (SAL_LISTEN).
  • Semantics: Methods are namespaced strings such as sal.system.ping, sal.process.start, sal.network.status.
  • Safety: Mutations that touch disks, packages, kernel modules, or power policy require SAL_DANGEROUS=1 in the environment; otherwise structured blocked responses are returned (see Milestone 4 rules in repo).
  • Process and profiles: sal.profiles.*, sal.process.*, sal.services.* integrate with the profile loader and init expectations.

Full method list and request shapes are in Appendix A.

10. First-boot experience

Components

  • first-bootd — Axum server on FIRST_BOOTD_LISTEN (default 127.0.0.1:8793), localhost-only.
  • first-boot — WebView (or embedded UI) calling that API; FIRST_BOOTD_URL tells the UI where to connect.

Completion marker: /etc/myo/firstboot-done. After it exists, init skips the wizard and starts session-launcher (when Wayland and paths are valid).

Extending the wizard: evolve the first-bootd state machine and matching UI screens; keep endpoints documented in Appendix A.

11. Developing applications

  1. Create apps/<name>/ with Cargo.toml and src/main.rs.
  2. Register the crate in the workspace root Cargo.toml.
  3. Ensure assemble-rootfs.sh copies the binary (see its for b in … list).
  4. Add catalog/apps.yaml entry (command matches the installed binary name).
  5. Optional: internet-hub/hub.yaml tile; ai/backend/src/intent.rs phrases.

Quality bar: small binaries, explicit errors, respect edition if behavior differs.

12. Developing services

  1. Create services/<name>/ with Axum or minimal event loop as needed.
  2. Expose a clear localhost HTTP API if other components must call it.
  3. Wire startup in init/init.sh via start_bg <logical-name> <binary> … (follow existing patterns; keep logs under /var/log/myo/services/).
  4. Documentendpoints beside the crate or in this handbook's appendix if stable.

Guidelines: bounded timeouts, structured JSON responses, no unnecessary global state.

13. Profiles and background loader

  • Profiles: YAML under profiles/ (installed to PROFILES_DIR, default /usr/share/myo/profiles).
  • Boot profile: BOOT_PROFILE (default minimal) passed to background-loader, which calls sal.profiles.apply over SAL_URL.
  • LOADER_REAL_APPLY: when set, loader may perform real package/service operations from the profile (subject to SAL_DANGEROUS gates).

Use profiles to describe “what should be true” after boot without hard-coding every sequence in init.

14. Edition-aware development

Read /etc/myo/edition at runtime:

let edition = std::fs::read_to_string("/etc/myo/edition")?;
if edition.trim() == "developer" {
    // dev-only menus, shortcuts, or SAL paths
}

Avoid baking edition checks into shared libraries unless necessary; prefer feature flags at the app boundary.

15. Debugging and logs

LocationContents
/var/log/myo/init.logPID 1 log (stdout/stderr of init)
/var/log/myo/services/*.logPer-service logs
/var/log/myo/*.logOther consolidated logs (e.g. AI backend)

Use the log-viewer app on device. On failure, init prints fallback messages to the configured TTY (MYO_STATUS_TTY, default /dev/tty1) listing useful paths and ps/tail hints.

Host development: scripts/run-dev.sh / scripts/run-dev.ps1 coordinate SAL + loader + AI for local iteration (see script headers).

16. Build and release images

Shipping bootable .raw and .iso is Linux-centric (chroot, grub-install, losetup, …).

  • Quick reference: build/SHIP.txt, build/build-prerequisites
  • One-shot (Linux): ./build/scripts/build-images.sh [user|developer]
  • Docker: Dockerfile.ship + docker-ship.sh (privileged) with build/in/bin mounted

Windows checkout: use WSL2, Docker, or a Linux VM to produce images; native Windows Rust is fine for cargo check of crates but not for full image builds.

Cross-target binaries: build/scripts/build-linux-musl-release.sh (Docker-based musl builds including GUI crates by default).

17. Installer

The installer lives under build/installer/ and targets installation from live media: disk selection, edition, rootfs copy, bootloader setup, reboot. See installer scripts and build/SHIP.txt for install-to-disk.sh usage.

18. Contributing

  • Rust 2021, workspace rustfmt consistency where applicable
  • Prefer small focused binaries and clear HTTP/JSON contracts
  • New user-visible surfaces: update catalog, Hub, and intents together
  • Security: never widen SAL_DANGEROUS defaults; document risky flags in init.sh
  • PRs should state what changed and how to verify (cargo check, image smoke, manual step)

19. Roadmap themes

PhaseFocus
FoundationBoot, SAL Milestone coverage, compositor session, catalog
ExperiencePolish first-boot, settings, connectivity, AI UX
PlatformBroader hardware, renames (myoorion paths), CI depth, optional backends

Exact milestones live in repo plans and .cursor/rules; treat this table as directional.


Appendix A — Developer API reference

A.1 SAL JSON-RPC

Endpoint: HTTP POST to /rpc or / on the SAL listen address (default http://127.0.0.1:8750).

Envelope: standard JSON-RPC 2.0 (method, params, id). Responses use JsonRpcResponse in sal-types (success result or structured error).

Representative methods (non-exhaustive; see sal/backends/linux/src/dispatch.rs for the full match):

MethodCategory
sal.system.pingVersion / milestone
sal.system.fallback_statusCompositor watchdog / fallback
sal.system.update_statusUpdate-checker snapshot
sal.network.list_interfacesSysinfo network interfaces
sal.network.statusHostname, kernel, load, connectivity via net-status
sal.network.connect_wifiStub (no credential handling in tree)
sal.gpu.infoDRM sysfs on Linux
sal.gpu.load_driverSimulated / gated real modprobe
sal.audio.list_devices/proc/asound on Linux
sal.audio.set_profileRouting stub
sal.power.statusSysinfo + /sys/class/power_supply
sal.power.set_modeGated cpufreq / policy
sal.storage.list_mountsMounts / sysinfo disks
sal.storage.mount / sal.storage.unmountGated mount/umount
sal.packages.list_installeddpkg/rpm style listing on Linux
sal.packages.install / sal.packages.removeGated package managers
sal.profiles.list / status / applyProfile YAML
sal.services.start / sal.services.stageService control
sal.process.list / start / killProcess table
sal.dev.*Forwarded to devtoolsd when configured

Parameters are method-specific (serde_json structs in the Linux backend). Invalid params return INVALID_PARAMS RPC errors.

A.2 first-bootd HTTP API

Base URL: http://127.0.0.1:8793 by default (FIRST_BOOTD_URL / FIRST_BOOTD_LISTEN). Server must bind loopback only.

MethodPathPurpose
GET/stateWizard state / progress
POST/set-editionJSON body, e.g. { "edition": "developer" }
POST/set-usernameJSON body, e.g. { "username": "alice" }
POST/set-networkNetwork step payload (see first-bootd implementation)
POST/finishComplete wizard (theme and related fields per handler)

CORS is open on localhost for browser/WebView convenience; do not expose this port beyond the device.

A.3 Catalog schema (practical)

Under apps: list entries using fields such as:

- id: my-app
  name: "My App"
  description: "Short description"
  website: ""
  package: ""
  command: my-app
  tags: [tools]
  install: true
  hidden: false
  autostart: false
  download_behavior:
    mode: process

For external downloads use mode: open_webpage and url.

A.4 Default localhost ports

ComponentDefault listen
SAL127.0.0.1:8750
AI backend127.0.0.1:8787
Internet Hub127.0.0.1:8790 (INTERNET_HUB_LISTEN)
net-status127.0.0.1:8791
first-bootd127.0.0.1:8793

Override via environment where supported.

A.5 AI backend routes (integration)

The AI backend exposes static UI fallbacks and POST /prompt for the assistant flow (ai/backend). Treat non-stable routes as internal until documented in crate main.rs.

End of Orion OS Developer Handbook.