In Linux, everything is a file. In RyeOS, everything is data.
RyeOS is portable verified execution. That portability describes signed execution data moving between compatible nodes; the current production distribution is Linux x86-64. See the platform support matrix.
(RYE Your Execution.)
Work in RyeOS — a tool run, a multi-step workflow, a scheduled job — is data: signed, content-addressed, durable. Durability here means the explicit filesystem and recovery contract, not cross-filesystem transactions or identical guarantees on every platform. Because it is data, it can prove what it is, who authorized it, and what it actually did. And because it is data, it can move: to another machine, across a restart, into the future. A run whose process dies resumes from its own record. Work pushed to another node carries its trust with it instead of borrowing the machine's.
That is the whole idea. Everything in this repository is that one property at a different layer:
- Signed items and bundles — behavior you can install and trust because resolution verifies its signature and content identity. Enforced isolationing additionally pins verified entry bytes through execution.
- Threads — every execution has an identity and a durable event log. The log is the run: tail it live, replay it, resume it, cancel it.
- Keys — the only actors. An operator, a node, an agent: each is a signing key, and anything that acts, acts by signing. Every piece of work traces back to the key that stands behind it, and trust is always a decision about a key, never about a machine.
- Remotes — push work to another node with signed requests and scoped grants. Trust travels as data, never as ambient machine access.
- Content-addressed state — history is the source of truth; databases and even running processes are rebuildable projections of it.
None of this is AI-specific — remove every LLM runtime and the property stands. But an execution substrate that doesn't care what the executor is turns out to be exactly what LLM work needs: directives make an LLM call into a signed, durable, resumable execution like any other, and an agent is simply a signing key with a body of signed work — not a process, not a session.
╭──────────────╮ MCP: one cli tool
│ AI client │──────╮
╰──────────────╯ ▼
╭──────────────╮ ╭──────────────╮ ╭──────────────╮ ╭─────────────╮
│ operator │─▶│ ryeos CLI │ HTTP │ ryeosd node │ signed requests │ other nodes │
╰──────────────╯ │ bundle verbs │──────▶│ execution + │◀───────────────▶│ │
╰──────────────╯ │ state │ CAS sync ╰─────────────╯
╰──────┬───────╯
│
╭─────────────────────────┴─────────────────────────╮
│ signed bundles, CAS objects, refs, threads, vault │
╰───────────────────────────────────────────────────╯
The node, ryeosd, is where data becomes act: it holds keys, checks
signatures, executes at the frontier, and owns durable state. It is
deliberately the least special part of the system — any node with the right
trust can be the site of an execution, because everything that matters is in
the data.
RyeOS is built around a few primitives:
| Primitive | Meaning |
|---|---|
| Item | A signed unit of behavior or context: tool:, directive:, knowledge:, graph, service, config, runtime, schema. |
| Bundle | A signed distribution unit containing items, schemas, binaries, CLI descriptors, and publisher trust metadata. |
| Node | The local daemon and system space. It verifies bundles, executes items, owns state, and exposes HTTP services. |
| Thread | A tracked execution: event log, lifecycle, lineage, continuation chain, receipts, cancellation, and replay. |
| CAS | The authoritative append-only state store. Hashes identify events, snapshots, manifests, and project objects. |
| Ref | A signed mutable pointer into CAS, such as a project head, chain head, or bundle registration. |
| MCP bridge | A local single-user adapter exposing one cli tool that shells out to the ryeos binary. |
ryeos execute tool:ryeos/core/identity/public_key
ryeos execute directive:ryeos/examples/continuing_researchTools are executable programs. Directives are LLM-evaluated programs with permissions, limits, context, and inheritance. Both are resolved from signed bundle or project data before execution.
ryeos thread list
ryeos thread get <thread-id>
ryeos thread tail <thread-id> # live event stream
ryeos thread children <thread-id> # lineage-linked child threads
ryeos thread chain <thread-id> # continuation chain
ryeos thread cancel <thread-id>
ryeos events replay <thread-id>The event log is the execution, so tailing a thread is watching the execution object grow at its frontier, and replay is reading it back. Steering and cancellation act on the same control plane the node uses internally.
State graphs describe multi-step programs as YAML DAGs with conditional edges, foreach execution, hooks, caching, and persisted state. Graphs run through the same signed execution and thread machinery as tools and directives: long runs continue across segment cuts as chained threads, and work fans out into detached, lineage-linked child threads.
ryeos scheduler register <spec>
ryeos scheduler list
ryeos scheduler pause <id>
ryeos scheduler show-fires <id>Schedules fire items on cron or interval rules. Each fire creates a normal thread with normal history and result inspection.
ryeos remote configure --descriptor ./prod.remote.yaml
ryeos remote admit \
--remote prod \
--token "<one-time-token>" \
--label dev-machine \
--scopes "ryeos.execute.service.objects/has,ryeos.execute.service.objects/put,ryeos.execute.service.objects/get,ryeos.execute.service.system/push-head"
ryeos remote doctor --remote prod
ryeos remote execute \
--remote prod \
--item-ref tool:my/heavy-compute \
--project /absolute/path/to/projectRemote execution uses node keys, signed requests, scoped grants, and content-addressed sync. A descriptor is a trust pin, not a credential; runtime authority lives in the target node's authorized-key store.
The supported production target is Linux 6.9 or newer on x86-64 with glibc.
The kernel floor supplies the pidfd process-group and authenticated Unix-peer
primitives used for durable cancellation and lifecycle control. Official
container images are currently linux/amd64, and packaged bundle executables target
x86_64-unknown-linux-gnu. Other targets are tracked in the
platform support matrix and must not silently bypass
the isolation or durability contracts.
AUR packages (ryeos, ryeos-mcp) are coming soon. Once published:
yay -S ryeos ryeos-mcp
ryeos init --node-profile full
ryeos start
ryeos node statusOn a capable terminal, ryeos init --node-profile full opens the
first-contact ceremony. It
discovers packaged bundles under /usr/share/ryeos, installs them into the
system space, creates operator and node keys, initializes trust and vault
material, and optionally connects a verified model provider. Use
ryeos setup to reopen provider/model setup later. Automation must use
ryeos init --non-interactive --node-profile full or
ryeos init --json --node-profile full. Every fresh init requires an exact
publisher-signed init profile; absence is never replaced with runtime defaults.
Isolation backends are ordinary, separately installed bundles. ryeos start
launches ryeosd. See the
execution isolation contract before
enabling or tightening the node-owned policy.
The user lifecycle surface is intentionally small:
ryeos init --node-profile full # interactive first-contact initialization
ryeos setup # reopen optional provider/model setup
ryeos start # bring the local node online
ryeos stop # stop it
ryeos node status # local node lifecycle status
ryeos node doctor # offline "why won't it start" checklistThe release workflow publishes a composed daemon image:
docker pull ghcr.io/leolilley/ryeos-standard:latestRemote nodes that own hosted Codex plus graph/directive workflow execution use the separately qualified composition:
docker pull ghcr.io/leolilley/ryeos-hosted-workflow:X.Y.ZProduction deployment should pin the resolved digest of the immutable version
tag rather than the mutable latest channel.
The image includes ryeosd, ryeos, core tools, and signed bundle trees. The
entrypoint runs ryeos init --non-interactive --node-profile standard for
first policy publication. On later boots it omits the init profile and asks
RyeOS to validate and preserve the existing complete signed generation before starting
ryeosd; the app root lives at /data/app on the persistent /data volume,
so keys, trust, and runtime state survive redeploys. Release containers rely
only on the official publisher key compiled into ryeos; the entrypoint does
not infer trust from files baked into the image. The signed standard init profile
explicitly owns isolation and every other required node policy. Keep /data on
a named volume:
docker volume create ryeos-data
docker run -d --name ryeos \
-p 8000:8000 \
-v ryeos-data:/data \
ghcr.io/leolilley/ryeos-standard:latest
docker exec ryeos ryeos node statusA locally built image signed by a development or custom publisher requires an explicit trust acknowledgement at startup:
docker run -e RYEOS_TRUST_BAKED_PUBLISHERS=1 ryeosd-full:devThat switch pins the image's PUBLISHER_TRUST.toml files before preflight. Do
not use it for release images. See the
official publisher trust contract
for the complete operator contract.
When an upgrade intentionally changes the signed node-policy schema or the image's exact bundle-set profile, stop the old container and opt into the one-time clean cut on its persistent volume:
docker run -e RYEOS_RESET_NODE_POLICY_GENERATION=1 \
-v ryeos-data:/data ghcr.io/leolilley/ryeos-standard:latestThe entrypoint asks one locked init to replace the complete signed policy generation and align the trusted profile's prospective exact bundle inventory. The prior fence is invalidated before mutation and a new signed completion fence is written before the daemon starts. It preserves identity, trust, vault credentials, execution history, project heads, and all other node state. Remove the variable after the successful upgrade; policy replacement is never automatic.
The release gate exercises default-disabled startup and signed execution
without extra capabilities or an isolation backend. Back up the ryeos-data
volume before upgrades; it contains node identity, trust, vault, and durable
execution state.
This release is an explicit no-backcompat runtime-schema cutover. Before restarting the new daemon on every existing node, stop the daemon and discard the incompatible thread history and project heads:
ryeos node reset execution-history --include-project-heads \
--confirm --confirm-project-headsThe reset is destructive, so retain the pre-upgrade backup. Startup fails closed when predecessor launch metadata is still present rather than silently projecting it into the current runtime contract.
Source installs do not stage an isolation implementation. Backend bundles are authored and installed separately when an operator chooses to use one.
git clone https://github.com/leolilley/ryeos.git
cd ryeos
./scripts/pkg/install-local-direct.sh \
--populate --all --trust-source-publishersThe first source install builds and publishes the complete artifact base.
Subsequent installs reuse its exact closed bundle generations by default, or
can rebuild only selected Cargo packages with --populate --crates "...".
Checkout bundles are normally signed by the development publisher, so the
example makes that trust decision explicit.
Without --trust-source-publishers, the installer accepts only the official
publisher compiled into ryeos and rejects any source-supplied publisher
document whose decoded key is non-official before changing the installed node.
Use --populate --crates "<package ...>" for focused development rebuilds and
reserve --populate --all for release/E2E qualification.
After installation, initialize the local system space. The terminal ceremony
can start the node for optional provider setup; ryeos start remains
idempotent if setup was skipped or initialization was non-interactive:
ryeos init --node-profile full
ryeos start
ryeos node statusOpen either operator surface from a project directory:
cd /path/to/project
ryeos tui
# or
ryeos webRun a signed example and inspect its durable thread:
ryeos execute directive:ryeos/examples/continuing_research
ryeos thread list
ryeos thread tail <thread-id>To exercise the core recovery guarantee, stop and restart the node while the example is active, then inspect the same thread and its continuation chain:
ryeos stop
ryeos start
ryeos thread get <thread-id>
ryeos thread chain <thread-id>If startup fails, ryeos node doctor performs the offline lifecycle and state
checks. The terminal and browser clients are projections over the same durable
threads; closing either client does not cancel the underlying work.
The MCP adapter is deliberately thin. It exposes one tool, cli, which invokes
the ryeos binary. The available commands come from the installed signed
bundles, so adding a bundle can add CLI verbs without redeploying the MCP
server.
Example MCP configuration:
{
"mcpServers": {
"ryeos": {
"command": "ryeosd-mcp"
}
}
}The MCP tool accepts argv for ryeos:
{
"tool": "cli",
"args": ["execute", "tool:ryeos/core/identity/public_key"],
"project_path": "/path/to/project"
}The MCP server is for local single-user stdio use. Do not expose it directly on the network without a separate authentication boundary.
RyeOS behavior is shipped as bundles — installable signed .ai/ trees. A
bundle may contain:
- item YAML and Markdown;
- schemas and composer rules;
- runtime and handler binaries;
- CLI command descriptors;
- knowledge docs;
- publisher trust metadata;
- content-addressed manifests and refs.
Installed bundles are verified before use. Bundle-owned binaries live inside the
signed bundle tree and are resolved by hash; they are not arbitrary programs
copied onto PATH.
The repository currently includes bundles such as:
| Bundle | Purpose |
|---|---|
core |
Node, trust, identity, signing, state, service, and bundle primitives. |
standard |
Execution-facing workflows: directives, tools, graphs, threads, scheduler, and runtimes. |
web |
Web-oriented tools and runtimes. |
browser |
Browser automation tools. |
ryeos-ui |
UI/operator-facing bundle assets. |
hosted-node |
Admission services and schemas for a hosted remote target. |
central-auth |
Reusable app-level auth primitives for RyeOS-backed projects. |
RyeOS state follows a three-tier truth model:
| Tier | Mutable? | Rebuildable? | Purpose |
|---|---|---|---|
| CAS objects | No | N/A | Authoritative events, snapshots, manifests, and project objects. |
| Signed refs | Yes | No | Entry points into the CAS graph. |
| SQLite projection | Yes | Yes | Query performance only. |
Writes are CAS-first. If a projection update fails after the CAS write succeeds, the daemon can rebuild the projection later by walking signed heads through CAS. That makes the event graph the source of truth, not an incidental database file. The same tiering applies one level up: a running process is a rebuildable projection of its thread's durable state.
| Path | Purpose |
|---|---|
crates/kernel/lillux |
Low-level signing, hashing, atomic IO, process, and primitive execution support; see the durability matrix. |
crates/engine/ryeos-engine |
Item resolution, composition, policy facts, and execution planning. |
crates/engine/ryeos-executor |
Execution dispatch and runtime integration. |
crates/daemon/* |
Daemon crates: app core, HTTP API, bundle install, node lifecycle, and UI assets. |
crates/bin/cli |
ryeos, the operator CLI and MCP target. |
crates/bin/daemon |
ryeosd, the local node daemon. |
crates/clients/* |
Client surfaces: shared ryeos-ui base, terminal, and web. |
crates/runtimes/* |
Directive, graph, and knowledge runtimes. |
crates/state/* |
Durable state, scheduler, and vault crates. |
crates/tools/* |
Bundle-owned tool binaries and handler protocols. |
bundles/* |
Signed bundle source trees. |
integrations/mcp/ryeosd |
Python MCP stdio adapter exposing the cli tool. |
scripts/ |
Bundle population, validation, local install, and development workflows. |
deploy/ |
Container entrypoints and package metadata. |
Contributor documentation is indexed in
RyeOS repository development knowledge.
Installed product and operator knowledge lives in the signed bundle trees,
primarily bundles/standard/.ai/knowledge/.
Use the repository scripts rather than hand-editing derived bundle state.
./scripts/gate.sh # run workspace tests without refreshing bundles
./scripts/gate.sh --refresh-bundles # explicit expensive bundle refresh, then tests
./scripts/pkg/install-local-direct.sh --trust-source-publishers # install dev-signed artifacts
./scripts/pkg/install-local-direct.sh --populate --crates ryeosd --trust-source-publishers # focused daemon rebuild + installCommon loops:
| Change type | Recommended loop |
|---|---|
| Rust-only compile feedback | cargo build or targeted cargo test -p <crate> |
| Rust affecting bundled binaries | install-local-direct.sh --populate --crates "<package ...>" ...; unselected payload generations remain exact. |
| Bundle YAML, schemas, tools, or runtimes | Targeted signing/publish flow; use ./scripts/gate.sh --refresh-bundles only for release validation. |
| Browser UI assets | ./scripts/dev-ui-assets.sh --background --open; no bundle refresh. |
| Daemon/CLI behavior with installed bundles | Target only ryeosd, ryeos-cli, or both through --populate --crates, then install. |
| Packaged layout repair | Run without --populate to reinstall the existing exact closed artifact generation. |
Hard rules for contributors and agents:
- Do not manually copy bundle-owned binaries into
/usr/binas a fix. - Do not edit signed bundle YAML and leave stale signatures.
- Do not add hardcoded fallbacks for stale bundle state; regenerate bundles.
- Restart a running daemon after reinitializing bundles so in-memory registries match disk.
MIT.