Skip to content

Repository files navigation

daemons — User-space Service Layer

The user-space service layer of the Airymax agent runtime: 15 daemon processes that turn the Airymax kernel into a running system, one governance daemon (supervisor_d) that keeps the cluster alive, plus the shared svc_common library.

Language: English | 简体中文

Version License C11


What this is

daemons is the service layer of the Airymax agent runtime. It contains 15 feature daemon processes — gateway_d, llm_d, tool_d, sched_d, market_d, monit_d, channel_d, notify_d, hook_d, mem_d, agent_d, a2a_d, think_d, cupolas_d, maths_d — one governance daemon supervisor_d (resident cluster supervision), and the shared static library svc_common (in common/).

Each daemon is its own OS process, owns exactly one domain, exposes a JSON-RPC 2.0 interface, and reaches its peers through the IPC service bus. gateway_d is the only process boundary that faces external clients; everything else stays internal.

External client ──HTTP / WS / SSE / MCP / A2A / OpenAI API──▶ gateway_d
                                                              │
                                                    JSON-RPC 2.0 over IPC bus
                                                              ▼
                      llm_d  tool_d  sched_d  mem_d  agent_d  …  (14 daemons)
                                                              │
                                                    atoms / syscall ──▶ kernel

Capabilities

  • Service-oriented — independent processes, IPC cooperation; each daemon can be started, scaled, upgraded, and replaced on its own.
  • Single responsibility — one core domain per daemon, so coupling stays low.
  • Endogenous security — svc_common links cupolas as a PUBLIC dependency, so every daemon inherits request authentication, input sanitization, audit, and sandboxing without writing any security code of its own.
  • Unified protocol — JSON-RPC 2.0 everywhere inside the runtime; MCP / A2A / OpenAI-API translation happens only at the gateway boundary.
  • Resilience — circuit breaker, API recovery with primary/backup failover, health checks, and automatic restart of degraded services.
  • Observability — every daemon reports metrics to monit_d and events to notify_d, and writes a per-process log you can read with airymaxrt logs <daemon>_d.
  • Lifecycle framework — one airy_svc_t state machine and one event-driven main loop (daemon_event_driver) shared by all 15 feature processes.

The daemons

# Daemon RPC namespace Responsibility
1 gateway_d — (entry point) Sole external boundary. Translates HTTP / WebSocket / SSE / MCP / A2A / OpenAI API to JSON-RPC 2.0 and forwards by namespace to the other 14 daemons. Contains no business logic.
2 llm_d llm.* LLM inference: streaming completion, token counting, cost accounting, response caching.
3 tool_d tool.*, plugin.* Tool and plugin registry, discovery, sandboxed execution, parameter validation, result caching.
4 sched_d sched.* Task and DAG scheduling, roadmap planning, round-robin / weighted / priority / ML strategies.
5 market_d market.* Agent / Skill / Tool / Template artifacts: search, install, versioning, uninstall.
6 monit_d monit.* Metrics collection and query, system and hardware info, health checks, alert rules, runaway-agent detection.
7 channel_d channel.* Data-plane application channels: channel create / join / send / receive and message routing.
8 notify_d notify.* Event fan-out: topic-based publish / subscribe over WebSocket, SSE, and sockets.
9 hook_d hook.* Hook and session registration; the hook engine itself lives in atoms/coreloopthree.
10 mem_d mem.* Persistent memory: write / search / get / delete / recent / evolve, hybrid TF-IDF + embedding retrieval, JSONL storage.
11 agent_d agent.* Agent lifecycle and the execution loop: run / run_stream / run_cancel, spawn / invoke / terminate / cancel.
12 a2a_d a2a.* Agent-to-Agent protocol: Agent Card registration and discovery, task state machine, message delivery.
13 think_d think.* Cognition service: two-pass interaction, pipeline orchestration, language front-end, review.
14 cupolas_d cupolas.*, policy.* Security policy decision point: permission checks, sanitization, audit, credential vault, network rules, policy load / activate / rollback.
15 maths_d maths.* Mathematics coprocessor: pure-C numeric and statistical evaluation, plus an optional symbolic backend.
16 supervisor_d — (governance ctrl endpoint) Governance daemon: declaration-driven reconcile of the cluster against the launch profile (spawn missing, reap stray), crash restart with exponential backoff, unified shutdown. Reconciles only, carries no business logic, links no business library (linkgate fail-closed).

Executable names keep the *_d suffix and match the CMake target names one for one (gateway_d, llm_d, …). Each subdirectory has its own README documenting its interface.

Layout

daemons/
├── CMakeLists.txt      # builds the 15 daemons + supervisor_d + svc_common
├── common/             # svc_common static library (shared service framework)
├── scripts/            # CI, local verification, static analysis, coverage
├── gateway_d/ … maths_d/   # one directory per daemon
├── Dockerfile.ci       # CI build environment
├── LICENSE             # AGPL-3.0 + Apache-2.0 dual license texts
└── NOTICE              # copyright and core-IP notice

Each daemon directory follows the same shape:

<name>_d/
├── CMakeLists.txt      # target <name>_d
├── README.md           # responsibilities, RPC interface, dependencies, how to run
├── include/            # public headers
├── src/                # sources (main.c registers the JSON-RPC methods)
└── tests/              # unit tests

svc_common (common/)

common/ builds the svc_common static library, which every daemon links PRIVATE. It provides the service framework (airy_svc_t, event driver, task dispatcher, bootstrap for IPC / ServiceDiscovery / Cupolas), the IPC client and service bus, the JSON-RPC method dispatcher and parameter validators, resilience components (circuit breaker, API recovery, input validator, log sanitizer), metrics and alerting, configuration, and the platform compatibility layer. See common/README.md.

Usage

Run

The runtime is brought up by the airymaxrt launcher; resident cluster supervision is owned by supervisor_d — declaration-driven reconcile against the launch profile (spawn missing, reap stray), crash restart with exponential backoff, and a unified shutdown. Aux daemons are activated on demand: when a first bus call finds its target unreachable, gateway_d sends a one-way activate request to the supervisor. You normally never start a daemon by hand.

airymaxrt                 # terminal UI — starts the runtime and its services
airymaxrt status          # current runtime state
airymaxrt doctor          # component health check
airymaxrt logs 100        # last 100 lines of runtime log
airymaxrt logs llm_d      # log of one daemon
airymaxrt monitor         # continuous observation

Other subcommands are cli, profile, update, uninstall, reinstall. There is no airymaxrt start — running the launcher with no arguments starts everything.

To exercise a single daemon's interface directly, start it and send JSON-RPC to its socket:

<build-dir>/bin/maths_d                     # listens on the runtime dir

On POSIX the endpoint is a Unix socket <runtime-dir>/<name>.sock, resolved from the runtime root, so a manually started daemon joins the same bus as one reconciled by supervisor_d. On Windows the daemon serves the local TCP loopback 127.0.0.1:<port>; the per-daemon default port is documented in its README.

Build from source

Prerequisites: CMake ≥ 3.16, a C11 compiler (GCC / Clang / MSVC), cJSON. Optional: GTest (unit tests), lcov + genhtml (coverage), cppcheck (static analysis).

cmake -S . -B ../daemons-build -DCMAKE_BUILD_TYPE=Release
cmake --build ../daemons-build --parallel

Keep the build directory outside the source tree.

CMake options:

Option Default Description
BUILD_DAEMON POSIX ON, Windows OFF Build the daemon cluster (set by the parent build)
BUILD_TESTS ON (forced OFF on Windows) Build unit tests and enable CTest
BUILD_COVERAGE OFF Instrument for coverage and add the coverage target
BUILD_ALL_PLATFORMS OFF Cross-compile for all platforms

Configuring with BUILD_DAEMON=OFF skips this module with a warning. On Windows, build the daemons and the CLI explicitly:

cmake -S . -B ../agentrt-build -DBUILD_DAEMON=ON -DBUILD_CLI=ON

The official Windows release packages do ship the daemons and the CLI; only a plain source build leaves them off by default.

Artifacts and installation:

ctest --test-dir ../daemons-build --output-on-failure
cmake --install ../daemons-build --prefix /opt/airymax   # binaries → <prefix>/bin
  • 15 feature daemon executables plus supervisor_d in ${CMAKE_BINARY_DIR}/bin/
  • svc_common static library, consumed privately by each daemon
  • Daemon public headers installed under include/agentrt/

CI scripts

Script Purpose
scripts/ CI entry: build, test, cppcheck, coverage
scripts/local-ci.sh Local CI simulation
scripts/static-analysis.sh cppcheck static analysis
scripts/verify-coverage.sh Coverage collection and threshold check

Interfaces

Service lifecycle — one state machine shared by all daemons (airy_svc_state_t): NONE → CREATED → INITIALIZING → READY → RUNNING → PAUSED → STOPPING → STOPPED, with ZOMBIE for stop timeouts and ERROR for failures. Startup order is init → load config → register with service discovery → serve → graceful shutdown.

Capability flags — a daemon advertises what it supports through airy_svc_config_t.capabilities: AIRY_SVC_CAP_NONE / ASYNC / STREAMING / CANCELABLE / PAUSEABLE / THROTTLE / BATCH / PRIORITY / TIMEOUT.

Error codes — the standard AIRY_E* set from commons, extended by daemon-level aliases in daemon_errors.h.

#include "svc_common.h"
#include "ipc_service_bus.h"

int main(void)
{
    airy_svc_config_t cfg = {
        .name           = "my_daemon",
        .version        = "0.1.16",
        .capabilities   = AIRY_SVC_CAP_ASYNC | AIRY_SVC_CAP_CANCELABLE,
        .max_concurrent = 64,
        .timeout_ms     = 5000,
        .auto_start     = true,
        .enable_metrics = true,
    };
    /* svc_auth inherits Cupolas request authentication automatically. */
    return 0;
}

Relationships

daemons is a composition layer: it does not define kernel primitives, it turns them into running processes.

Dependency What daemons uses
commons Logging, configuration, networking, tokens, cost, observability, platform paths and the authoritative IPC headers — reached transitively through svc_common
atoms Syscall entry surface for downward dispatch; hook_d links the CoreLoopThree hook library directly
cupolas Security dome, PUBLIC-linked by svc_common; cupolas_d exposes it as a service
protocols JSON-RPC 2.0 / AgentsIPC envelope on the IPC bus; A2A and MCP adapters at the gateway
heapstore Persistence for daemon state, registries, and budgets
gateway The gateway library that gateway_d wraps as a service
Consumer What it uses
SDK / Agent applications The gateway's JSON-RPC 2.0 surface, through daemon client libraries shipped by the SDK
Command line and terminal UI Memory read/write, cognition, status and logs
Ecosystem tooling and skills Daemon services via the SDK

Documentation

Design documents, interface references, and application guides live in the Airymax documentation repository under AirymaxRT/. Start with AirymaxRT/README.md; the API reference is in AirymaxRT/30-interfaces/.

License

Copyright (c) 2025-2026 SPHARX Ltd.

This module is dual-licensed under either:

SPDX-License-Identifier: AGPL-3.0-or-later OR Apache-2.0

Full license texts are in LICENSE; the copyright and core-IP notice is in NOTICE. You may choose either license. AGPL-3.0-or-later applies by default; Apache-2.0 is offered for downstream integration scenarios the AGPL does not accommodate.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages