Skip to content

Local services lifecycle

AI OS ships a complete Linux recovery path for the local app and all four reviewed scheduler jobs. The repository owns the inputs; installation and activation remain explicit local-operator actions.

Surface Owner Normal persistence
App and local bridges on port 5189 scripts/dev.sh tmux session; no restart policy
Voice broker on port 8099 Vite when configured managed child; no restart policy
Host/local refresh ai-os-agent-aggregate.timer systemd user timer
Trend Finder refresh ai-os-trend-finder.timer systemd user timer
Dream review ai-os-dream.timer systemd user timer
Full aggregate compatibility refresh ai-os-aggregate.timer manual opt-in

External Hermes, OpenClaw, Codex, provider, container, and tunnel services are not owned by this lifecycle. AI OS may integrate with them without managing their startup.

On a fresh checkout:

Terminal window
cp -n data/ai-os.scheduler.example.json data/ai-os.scheduler.json

The reviewed baseline enables agent-aggregate, trend-finder, and dream. It keeps the full aggregate compatibility timer disabled. Preserve any reviewed cadence or Dream time that you intentionally changed.

Timer intent is status metadata. It does not install or activate an operating system timer.

When the reviewed units are already installed for the current checkout, restore the three normal timerEnabled values, review the catch-up warning below, and run:

Terminal window
systemctl --user daemon-reload
systemctl --user enable --now \
ai-os-agent-aggregate.timer \
ai-os-trend-finder.timer \
ai-os-dream.timer
scripts/dev.sh

Use the complete render and install path when a definition is missing, points to another checkout, or has unexplained drift.

Validate and render the eight committed service/timer assets:

Terminal window
bun run scheduler:systemd:check
bun run scheduler:systemd:render
systemd-analyze --user verify \
.ai-os/systemd/user/*.service \
.ai-os/systemd/user/*.timer

The renderer writes only under the ignored .ai-os/systemd/user/ directory. It does not call systemd or change active services.

Inspect differences before replacing an existing installation. Then install the rendered definitions:

Terminal window
AI_OS_USER_UNIT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
install -d -m 0755 "$AI_OS_USER_UNIT_DIR"
install -m 0644 \
.ai-os/systemd/user/*.service \
.ai-os/systemd/user/*.timer \
"$AI_OS_USER_UNIT_DIR/"
systemctl --user daemon-reload

All four services are one-shot units with Restart=no.

The timers use Persistent=true. Using --now after a missed scheduled time can immediately start one catch-up run. Review local provider/source configuration and possible Trend Finder or Dream usage before activation.

Terminal window
systemctl --user enable --now \
ai-os-agent-aggregate.timer \
ai-os-trend-finder.timer \
ai-os-dream.timer

The full aggregate timer remains a separate compatibility opt-in:

Terminal window
systemctl --user enable --now ai-os-aggregate.timer

Start the app:

Terminal window
scripts/dev.sh

When local voice credentials are configured, Vite also starts the voice broker. That managed child stops when the dev server closes.

Terminal window
curl -fsS http://127.0.0.1:5189/health
systemctl --user is-enabled \
ai-os-agent-aggregate.timer \
ai-os-trend-finder.timer \
ai-os-dream.timer
systemctl --user list-timers 'ai-os-*'
bun run scheduler:agents:status
bun run scheduler:trend-finder:status
bun run scheduler:dream:status

An idle one-shot service normally appears inactive/dead while its timer appears active/waiting.

Terminal window
scripts/dev.sh --stop
systemctl --user disable --now \
ai-os-aggregate.timer \
ai-os-agent-aggregate.timer \
ai-os-trend-finder.timer \
ai-os-dream.timer
systemctl --user stop \
ai-os-aggregate.service \
ai-os-agent-aggregate.service \
ai-os-trend-finder.service \
ai-os-dream.service

Set the four private timerEnabled values to false so local intent agrees with systemd state. Keep unit files, generated units, scheduler state, logs, and local data when you want a reversible shutdown.

The complete command-by-command operator procedure, drift inspection, recovery, platform boundary, and optional-process catalog live in the repository’s docs/runbooks/local-services-lifecycle.md runbook.