Use this file to discover all available pages before exploring further.
Spacebot isn’t a chatbot — it’s an orchestration layer for autonomous AI processes running concurrently, sharing memory, and delegating to each other. That’s infrastructure, and infrastructure should be machine code.
No garbage collector pauses. Predictable latency. When a channel is responding to a user, there’s no mystery pause while Python’s GC runs.
// This won't compile if there's a data racelet history = Arc::new(RwLock::new(Vec::new()));// Multiple readers OR one writer, enforced at compile timelet reader1 = history.read().await; // OKlet reader2 = history.read().await; // OKlet writer = history.write().await; // Blocks until readers drop
In Python or TypeScript, this is runtime bugs and race conditions.
They all share state. Rust’s ownership system prevents data races at compile time:
// From src/agent/channel.rstokio::spawn(async move { let conclusion = branch.run(prompt).await?; // Send conclusion back to channel via event event_tx.send(ProcessEvent::BranchComplete { ... })?;});
The compiler ensures:
branch is moved into the task (no shared references)
event_tx is cloneable (explicitly Sender<T> is Clone)
No data races on shared state
In Python:
# This might work, might not, who knows?async def run_branch(): result = await branch.run(prompt) # Is this thread-safe? Is event_tx still valid? event_tx.send(result)asyncio.create_task(run_branch())
// Change a typepub enum ProcessType { Channel, Branch, Worker, Compactor, Cortex, Voice, // New variant}// Compiler finds every place that needs updatingerror[E0004]: non-exhaustive patterns: `ProcessType::Voice` not covered --> src/llm/routing.rs:76:15 |76 | match process_type { | ^^^^^^^^^^^^ pattern `ProcessType::Voice` not covered
The compiler is your pair programmer. It finds every place that needs updating when you change a type.In Python:
# Add new process typeclass ProcessType(Enum): CHANNEL = "channel" BRANCH = "branch" WORKER = "worker" VOICE = "voice" # New# Good luck finding every place that needs updating# Runtime errors in production if you miss one
$ cargo build --release Compiling spacebot v0.1.0 Finished release [optimized] target(s) in 2m 34s# All these are checked at compile time:# - No data races# - No null pointer dereferences # - No use-after-free# - No type mismatches# - Exhaustive pattern matching# - Lifetime validity
In Python or TypeScript:
# All good!$ mypy .Success: no issues found# Runtime:$ python main.pyTraceback (most recent call last): File "main.py", line 42, in process_message result = channel.history[i].contentAttributeError: 'NoneType' object has no attribute 'content'
Work-stealing scheduler — Efficient CPU utilization
No callback hell — async/await syntax
Backpressure — Built-in flow control
Tracing integration — Structured logging and diagnostics
// Spawn 1000 concurrent tasksfor i in 0..1000 { tokio::spawn(async move { // Work happens here });}// Tokio handles scheduling, no thread pool tuning needed
Python’s asyncio:
# Need to manage event loops, executors, thread poolsloop = asyncio.get_event_loop()executor = ThreadPoolExecutor(max_workers=10)for i in range(1000): loop.run_in_executor(executor, task)
// This query is checked at compile time against the database schemalet memory = sqlx::query_as::<_, Memory>( "SELECT id, content, memory_type, importance FROM memories WHERE id = ?").bind(id).fetch_one(&pool).await?;
If the schema changes, your code won’t compile until you fix the queries.Python ORMs:
# Typo in column name? Runtime error!memory = session.query(Memory).filter_by(remembery_type="fact").first()
Slow compile times — Full rebuilds take 2-3 minutes. Incremental builds are fast (seconds), but cold starts hurt.Steep learning curve — Ownership, lifetimes, async, Result types. First few weeks are rough.Smaller ecosystem — Fewer libraries than Python. Sometimes you have to build it yourself.More verbose — Rust code is longer than equivalent Python. Explicit > implicit.
TypeScript is better than Python for type safety, but:Still interpreted — V8 JIT is fast, but not as fast as machine codeGC pauses — Unpredictable latencyWeak type system — any, type assertions, runtime casts everywhereNo compile-time memory safety — Data races are possible
// This compiles, might crash at runtimelet history: Message[] | null = null;history.push(message); // Oops
Go is actually a decent choice. But:No sum types — Can’t express Result<T, E> ergonomicallyWeak error handling — if err != nil everywhere, easy to ignore errorsNo generics until recently — And they’re still limitedGC pauses — Better than Python/Node, worse than Rust
// Easy to ignore errorsresult, err := doThing()// Oops, forgot to check errresult.Process()