5.1 KiB
Spike results
Date: 2026-10-15. Host: Scout container (8 cores), Rust 1.99, Wasmtime 49.0.3,
wstd 0.6.8. All numbers come from sausage run with release builds.
1. Host, broker, routing, filesystem — works
sausage initbuilds the agent and registers it.sausage runstarts the broker,cargo, the console, and every registered actor.- Routing, replies (
reply_to), publish to subscribers, andundeliverableerrors work. - Read-only: a write to
/actor/<other>/public/...fails with "Operation not permitted". A write to/actor/<self>/public/...fails too. A write to/public/...works. - Commit on close: while
fs-aholds/public/y.txtopen,fs-bgets "No such file".fs-aitself also gets it through a second descriptor. The temporary file does not appear in listings. After the close,fs-breads the content. - Append:
appendto an existing file copies the old content. Readers see the old version until the close. - Crash with an open file: the write is discarded, and the old version stays.
- Escapes:
/data/../../../../etc/hostnameand/actor/../private/agent/data/config.jsonfail. - Hard kill of the host: after
kill, no.sausage-tmp-*files remained, and the nextsausage runstarted every actor again.
2. Async stdin + HTTPS in one actor — works
examples/fetch (wstd) handles ping at once while a 2-second HTTPS
request runs. HTTPS and plain HTTP both work through wasi:http, and the host
does TLS. Bodies go to /public/fetch/<n>, and the reply contains the
global path.
One server (http://neverssl.com/) never answered. curl also hangs on it,
so the server is the cause. But a request without a timeout keeps its task
alive, and the actor then did not exit on shutdown. The broker killed it
after 5 s, as designed. Actors should set HTTP timeouts.
3. Upgrade cycle — works
- No loss during a swap:
tickersent 200 messages tonotesat 50 ms intervals.noteswas upgraded from v1 to v2 during the stream. The swap happened after tick 68. The v1 snapshot has ticks 1–68, and v2 has ticks 1–200, in order, with no gaps. - Parked message:
{"type":"crash"}crashed v1. The broker restarted v1 and kept the message. After the upgrade to v2 (which handlescrash), the broker delivered it again, and v2 answerednot_crashing. - Crash loop: an upgrade to
examples/crasherpassed the smoke test (it crashes after 3 s). It crashed 3 times in about 10 s. The broker rolled back to v2 with its data and sentrolled_backto the console. - Explicit rollback v2 → v1 restored the v1 snapshot.
- Rejections: a compiler error comes back as
build_failedwith the rendered diagnostics. A failing transcript rejects the upgrade, and the old version keeps running. Invalid IDs and..paths are rejected.
4. Agent — works with both API shapes
gpt-6-luna(OpenAI Responses) through the vendors proxy:- Asked "which actors exist", it called
brokerlistand answered in about 4 s (2 inferences). - Asked for a
counteractor, it took these steps without help:- It wrote
Cargo.toml,src/main.rs, andtests/basic.jsonl. - It built the crate with
cargo(1.9 s). - It spawned the actor (the tests passed).
- It sent increment, increment, get (1, 2, 2).
- It read
/actor/counter/public/value.txt.
- It wrote
- Asked "which actors exist", it called
- Self-upgrade: asked to change its own prompt, it took these steps:
- It copied its source and changed only
prompt.md(a 3-line diff). - It built the change and upgraded
agent. - The upgrade stopped it in the middle of the turn. The new version
resumed the turn from
/data/turn.jsonand answered with the new signature.
- It copied its source and changed only
claude-haiku-4-5(Anthropic Messages): the same conversation continued, with tool calls.
5. Measurements
| What | Result |
|---|---|
| Round trip actor → actor → actor | p50 88 µs, p99 172 µs |
| Sequential round trips | ~10,400 per second |
Warm cargo build, small actor |
0.5–1.9 s |
Warm cargo build, agent |
5.5 s |
First build of the agent (init) |
17 s |
| Component compile, small actor | ~70 ms |
| Component compile, agent (870 KB) | ~290 ms |
| Host start, 8 actors compiled in parallel | ~0.8 s each |
| Host RSS with 8 running actors | ~117 MB |
First release build of sausage |
~9 min (Wasmtime) |
Caveat: ~/.cargo/config.toml in this container sets kache as the
rustc-wrapper. kache caches compiler outputs across projects, so the
first build of the agent (17 s) is probably faster than on a clean machine.
Next steps I suggest
- A
matrixactor (WASM,wstd, long-polled/sync). The agent could write it, with you checking the result. - Cache compiled components (
Component::serialize,.cwasmfiles) to remove the compile time at host start. - A network allow-list per actor, for example in a manifest in the source folder.
- A sandbox for builds (for example
bwrap), because build scripts run natively. - Context compaction for the agent's conversation.
- A better console (line editing, history).