BEROUNOS for AI-native devices

The shell daemon

One daemon owns the system API.

shelld serves the launcher and the apps, starts and watches services, and exposes every capability of the system over HTTP and WebSocket.

shelld is the daemon at the center of Beroun. It serves the launcher and the apps, starts and tracks programs, and owns every API of the system. An app's page, a service, an MCP server and an agent all reach the system through it, and it knows which of them is calling.

Modules

ModuleRole
manifestReads and validates manifests and system views (format 1); capability and permission names; the OS version apps compare against
servicesThe service manager: module, process and child hosts; start rules, priority, memory budget, sleep behaviour, window take-over
sysapiMessageBox, system sounds, vibration
sysnoticeNotices the system raises by itself: network up or down, low battery, storage full
timectl, netctlClock, network time and time zone; Wi-Fi and network state. Each is an interface with a system implementation and a test double
extdisplay, extinputExternal display rules (stack, focus, messages) and the buttons-to-pointer logic
agents, a2a_bridge, a2a_clientThe task broker for apps' agents, and A2A 1.0 in both directions
appinstallInstall, update and remove store apps, with signature verification
caroline, caroline_ask, caroline_updateCaroline as a service; apps asking her; installing her updates
faceCaroline's talking head
ratatosk*The Ratatosk messenger: accounts, chats, end-to-end encryption, attachments, groups, audio and video calls
swThe shell's client of the owner's Camerlengo service: sign-in, session, speech recognition

Who is calling

The daemon recognises its caller and answers sensitive groups with 403 to everyone else.

CallerRecognised by
An app's pageThe address it was served from
A serviceHeader X-IntelliCat-Service-Id
An MCP serverHeader X-IntelliCat-Mcp
An agentHeader X-IntelliCat-Agent: <app>/<id>

HTTP API

Pages are served from /, /platform.js, /apps/<id>/… and /system/<id>/…. Everything else is under /api/. A taste of it:

# what is running, and what is the OS version curl localhost:8765/api/running curl localhost:8765/api/about # open an app, then ask the system how much memory each service takes curl -XPOST localhost:8765/api/launch -d '{"id":"calendar"}' curl localhost:8765/api/services # raise a notification curl -XPOST localhost:8765/api/notify -d '{"app":"calendar","text":"Dentist at 15:00"}'
GroupRoutes under /api/
Basicshealth, about, home, log, exit, buttons
Appsapps, launch, launch-arg, open, close, running, app/<id>/<path> (passes through to an app's service)
Servicesservices, services/start, /stop, /limit, /register, window/takeover
Input and powerhw, hw/button, hw/stick, hw/touch, hw/battery, power, power/sleep, osk/typing, beep
Files (memory card only)fs/list, read, write, mkdir, rename, copy, move, delete, space, fs/audio, fs/video
System APImsgbox, sound/*, vibra/* (System API)
Notificationsnotify, notifications/list, /dismiss, /clear, /read, /dnd
Settings, time, networksettings, settings/set, time/*, net/status, net/scan, net/connect
Accountauth/status, auth/login, auth/signup, account/session, wizard/…
Speechstt/start, stt/stop
Per-app storagedb/get, db/set: the database behind Platform.state and app settings
External displaydisplay, display/open, /close, /send, /launch, /focus
Storestore/catalog, installed, updates, install, remove
Agentsagents, agents/…, agents/sw
Messagingmsg/… (mail and messengers), rt/… (Ratatosk)
Carolinecaroline/start, /stop, /status, /ask, /voice, /settings, /apps, /app/tool, /sys/<area>/<op>
Faceface/job, face/play, face/status, face/stop

Other listeners: the A2A listener on 127.0.0.1:48772 (opened only when a manifest exposes an agent), the WebSocket /ws for input and typing events, and /appws, a per-page channel for events and display messages.

Launching

Apps come from manifests. config/apps.json lists extra launchables: native entries run as Wayland (or X11) clients, html entries open in a cog of their own. Store-installed apps appear and disappear without a restart.

The shared window

An app with frontend.window = "shared" has no process of its own. Its page is shown in the launcher's cog, one frontend at a time. Starting another app asks the open one to close, and it saves. MODE closes it the same way and the launcher returns. Services and the system may take the window over, as the Clock does to ring an alarm.

Launchertile chosen state.get()restore place App runsin the window onClosestate.set() Launcherback MODE or another app opening asks the app to close · 2 seconds to save MODE
Shared-window apps are one-at-a-time and always return to their place.

Services

A service is a backend that outlives an app's window. It is declared under services in a manifest (or in the system's own services list) and managed by the service manager.

FieldMeaning
hostmodule (an object of the shell's own code), process (a command started and watched by the manager), or child (started by another service and found among its descendants; not stoppable by the manager)
startsystem (at boot), open with required_by (with the app), or manual
priority0–100. Over the memory limit the lowest goes first; 90 and above never
memory_mbThe declared budget. GET /api/services shows each service's state and memory against the total limit
sleepThe service keeps running while the device sleeps
takeoverThe service may take the shared window
privilegedSystem services only
port, cmd, endpointsFor process services: {port} and {app} are filled in; endpoints expose paths through /api/app/<id>/<path> to the app's page, its MCP servers and its agents
A service with an endpoint, from the Clock
"services": [{ "id": "alarmd", "name": "Alarm clock", "host": "process", "cmd": ["python3", "{app}/alarmd.py", "{port}"], "port": 48801, "start": "system", "priority": 95, "memory_mb": 20, "sleep": true, // rings while the device sleeps "takeover": true // and takes the screen when it does }], "endpoints": [{ "path": "alarms", "methods": ["GET", "POST"], "service": "alarmd" }]

The app's page then calls GET /api/app/clock/alarms. The shell forwards it to the service and starts the service first if it is not running. Store-installed services use ports 49000–49999 and get their own data folder.

Notifications

The status bar shows the newest notification with an unread counter. A tap or SELECT opens the panel with Do not disturb, Clear all, and the notifications newest first, with app, time and unread marks.

  • A opens the app that raised it and removes the notification; X only removes it; B closes the panel.
  • Sources: the system itself (network, battery at 20% and 10%, storage 95% full), the Clock, the Calendar, messengers and any app through Platform.notify or POST /api/notify.
  • Do not disturb drops sound and vibration except the priority sounds alarm and ring.
  • An app sees the text of its own notifications only. Other apps get {event:"changed", unread, dnd}.
Status bar with a notification and a counter of 2
Two unread notifications.

Time and network

Time belongs to the system. Settings' Date & time page offers automatic time (on by default), the time zone and manual time, which is refused while automatic time is on. Network time is a one-shot sync run when the setting is turned on, when a network appears, and every hour, retrying every 15 seconds after a failure. Caroline has the same controls through Settings' tools.

Settings: Date and time
Date & time.
The Wi-Fi app
Wi-Fi is a system app over the network interface.

Accounts

The shell signs in to the owner's SquirrelWisdom account itself, with the same credentials file Caroline uses. First start shows a sign-in or sign-up screen and a start wizard. When an agent calls the owner's Camerlengo service, the shell adds the session and the key, and journals the call: agent, command, outcome and cost, never the parameters or results.

Logs and debugging

Logs are shell.log, app-<id>.log and one per daemon. WPE's remote inspector listens on port 9222 for any page. The shell page is also served at http://localhost:8765/, so an ordinary browser can open it.