Native trust limit
Admission can trust native code. Containing native speed without operator trust is still open.
BUILD
Implement three verbs. Declare a manifest. Your creature runs, reloads, and travels on the same substrate the lab runs on.
THE SURFACE
A creature is a unit of capability. It implements ModuleInstance, speaks through
the Bus, and carries one manifest.
The SDK depends only on aether and gawd-manifest, never on the kernel.
That keeps native daemons, WASM beasts, and script critters on one load path.
Native rule: spawn every thread through managed::spawn so the Sanctum can join it
before unload.lifecycle
load context once
process envelopes
drain before unload
manifest
WHAT RUNS TODAY
The source-first release is pre-1.0 and unaudited, but these mechanisms are real enough to build against. Native code is still trusted by admission; hosted federation and production hardening come later.
QUICKSTART
A native daemon is a Rust type that implements the trait and declares its entrypoint. No kernel imports appear anywhere in it.
use gawd_sdk::prelude::*;
#[derive(Default)]
struct Echo;
impl ModuleInstance for Echo {
// Called once when the Sanctum loads the creature.
fn bind(&mut self, ctx: ModuleCtx) -> Result<()> {
ctx.log("echo bound");
Ok(())
}
// Called for every envelope routed to this creature.
fn handle(&mut self, env: Envelope) -> Outcome {
env.reply(env.body()) // emit a new envelope back through the Bus
}
// Called before unload; return once every spawned thread has joined.
fn shutdown(&mut self, _deadline: Deadline) -> Result<()> {
Ok(())
}
}
// Registers the entrypoint the manifest names.
declare_module!(Echo); Drive it from sanctumd, the same machine-native control surface an agent uses.
Each command flows through admission, engine load, and routing.
sanctum> load ./echo.toml ./libecho.so
loaded [email protected] (daemon)
sanctum> bind handler echo
sanctum> send echo "ping"
echo → "ping"
sanctum> unload echo
unloaded echo (threads joined, rss stable) There is no hosted product UI yet. Talk to us about access →
A REAL ONE, STEP BY STEP
Echo shows the shape. A redactor earns its keep: it sits on the bus, strips secret-looking tokens from messages, then reloads a smarter version with no downtime.
One file of truth: name, tier, role, and no host capabilities.
# redactor.toml — the only metadata the Sanctum trusts
name = "redactor"
version = "0.1.0"
abi = { backend = "native", entry = "redactor" }
provides = ["filter"] # the role other creatures bind to
capabilities = [] # reads the message and replies. nothing else. Three methods again. The work lives in handle: clean the body, reply with it.
use gawd_sdk::prelude::*;
#[derive(Default)]
struct Redactor;
impl ModuleInstance for Redactor {
fn bind(&mut self, ctx: ModuleCtx) -> Result<()> {
ctx.log("redactor online");
Ok(())
}
fn handle(&mut self, env: Envelope) -> Outcome {
env.reply(redact(env.body())) // forward the cleaned message
}
fn shutdown(&mut self, _d: Deadline) -> Result<()> { Ok(()) }
}
declare_module!(Redactor); The redaction is plain Rust. The substrate never inspects it; the rule is yours alone.
fn redact(body: &str) -> String {
let mut out = Vec::new();
for word in body.split_whitespace() {
if looks_secret(word) { out.push("‹redacted›") } else { out.push(word) }
}
out.join(" ")
}
fn looks_secret(w: &str) -> bool {
w.len() >= 20 && w.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_')
} Load it, bind it to filter, send it a message.
sanctum> load ./redactor.toml ./libredactor.so
loaded [email protected] (daemon)
sanctum> bind filter redactor
sanctum> send redactor "ship with key sk_live_9F2aQ7bX4rT1cE6dW0p"
redactor → "ship with key ‹redacted›" Add a rule for email addresses, rebuild, and swap it in. The Sanctum drains the old instance, joins its threads, and loads the new one without a restart.
# next build also masks anything with an @ — rebuild, then:
sanctum> reload redactor ./libredactor.so
reloaded [email protected] (threads joined, rss stable)
sanctum> send redactor "ping [email protected] about the key"
redactor → "ping ‹redacted› about the key" That is the contract: a manifest, three methods, and your logic in between. Reload, routing, and sandboxing belong to the substrate.
OPEN PROBLEMS
These are unsolved in the general case. If one is your kind of problem, this is the work.
Admission can trust native code. Containing native speed without operator trust is still open.
Daemons, beasts, and critters should evolve without a flag day.
Realm peers need clean store-and-forward convergence after drift or partition.
Verifiable randomness has a reference creature. Consensus and weighting remain deployment models.
Get build notes.
Source releases, demos, and notes when there is code to try.