Commit Graph
27 Commits
Author SHA1 Message Date
surma 8d058666dc cargo.build, the WASI test runner, the console, and core.notify ordering
- cargo.build (native): one source copy, tests under WASI, release
  build to /state/cargo/builds/<n>/, process groups killed on cancel.
  The host writes the SDK copy to /plugins/cargo/sdk/ at start.
- sausage test-runner: one instance per test, in parallel, with its own
  mount table (empty world, package folder at its path); answers
  core.lock, core.unlock, core.notify, core.log.
- The console: rustyline, notifications while typing, ls/cat through the
  process view, methods, ps, log, activate, revert, stop, kill.
- core.notify on stdout is handled in order, before the response.
2026-10-23 01:42:19 +01:00
surma edc2d1a63b core: sausage-vfs per process (/, /proc, /self, /run), activation, graph, watcher, upgrades
- /proc is a core layer: core/ (PROTOCOL.md, graph.json, graph.dot,
  locks.json, plugins/<name>/discover.json and client.rs) and one folder
  per process (info.json, log, and its /self files).
- Locks are released only after the task ended, the store dropped, and
  in-flight file operations returned.
- core.activate and core.revert with copies, discovery, compatibility
  checks of imports and consumers, groups, force. An admission gate
  makes the snapshot of old processes complete.
- Graph of discover documents by hash, refreshed by a file watcher.
- Upgrades: grace periods (x-sausage-grace), stop, service restarts,
  rpc.retired.
- SDK plugins in the real core (cli/tests/sdk.rs).
2026-10-23 01:05:19 +01:00
surma 8542b9fcb8 sausage core: modules per topic, journal writer thread with WAL and batches, hash cache by metadata, 49 tests per rule
Blank stdout lines give no warning. core.exit requests the exit in its
own handler.
2026-10-23 00:32:33 +01:00
surma 4882edf243 sausage core part 1: a process per call, routing, tree, stop and kill, locks, journal, boot
Checkpoint. Removes the old host. A quality rework follows (modules,
journal writer thread, hash cache, finer tests).
2026-10-23 00:12:02 +01:00
surma a536d873e6 cargo: compile C for wasm32-wasip2 with a WASI clang
ci / check (push) Successful in 18s
The Nix package, the dev shell, and the test check set CC_wasm32_wasip2
and AR_wasm32_wasip2 to the clang of pkgsCross.wasi32 (wasi-libc), so
build scripts with the cc crate work, for example rusqlite with bundled
SQLite. The runtime-toolchain check links C into a probe with the
packaged host and an empty PATH.
2026-10-22 20:16:38 +01:00
Sausage Agent 34e2f35272 Add writable /self alias alongside /public and /data
ci / check (push) Successful in 15s
2026-10-22 13:35:13 +00:00
Sausage Agent f932ab9719 Mount the writable world root for every actor
ci / check (push) Successful in 3m9s
2026-10-22 13:29:38 +00:00
surma f1af07506f broker: upgrade and rollback keep a stopped actor stopped
ci / check (push) Successful in 8m42s
ci / check (pull_request) Successful in 4m38s
A stopped actor gets the new version installed, keeps its mailbox and does
not run main until the next start. Running actors still restart on the new
version. The upgraded and rolled_back answers say whether the actor runs.
2026-10-22 10:11:36 +01:00
Sausage Agent a72e42a8c9 headless: register signal handlers synchronously, split tests, drop deployment examples and wording
ci / check (pull_request) Successful in 1m36s
ci / check (push) Successful in 11s
2026-10-18 15:31:41 +00:00
Sausage Agent 01a821ab72 Add --headless mode (no stdin read, runs until SIGTERM/exit) + systemd/NixOS examples
ci / check (push) Successful in 2m44s
2026-10-18 15:24:20 +00:00
agent-pool-12 22590c608d cargo: run host unit tests before builds
ci / check (push) Failing after 8m51s
2026-10-17 15:50:09 +00:00
agent-pool-9 e8df22fe06 host tests: reuse the existing drain helper
ci / check (push) Successful in 8s
2026-10-17 07:23:30 +00:00
agent-pool-9 0995824c01 Watch the world folder: auto spawn/upgrade, broker watch/unwatch, retire scan
ci / check (push) Failing after 7m36s
The host watches the whole world folder recursively with the notify crate
(any writer counts, .sausage-tmp-* skipped, ~100 ms coalescing per path).
A new or changed actor/<id>/actor.wasm (or new folder actor/<id>) is
booted as at start once quiet: new = spawn (tested first), changed =
upgrade. The broker `scan` request is gone; the boot pass stays, plus a
full pass when the OS watcher overflows.

New broker requests watch/unwatch {path} (saved in actor.json `watches`)
deliver fs_changed {path, op: write|create|remove|rename, to?} from `fs`,
not routed, dropped when the mailbox is full; overflow sends every watcher
one fs_changed {path:"/actor", op:"rescan"}.

Card #91 (multi-host step 1).
2026-10-17 07:12:04 +00:00
agent-pool-8 3e90cd73d3 Keep discovery test file at served root 2026-10-16 21:47:17 +00:00
agent-pool-8 845c961f4f Expose advertised actor-served files in directory listings 2026-10-16 21:47:17 +00:00
Sausage agent d6d3c9a2f2 Bare sausage creates ./world if needed and runs it (default app)
ci / check (push) Successful in 5s
- cli: the subcommand is optional; without one, sausage runs ./world and
  runs init first when ./world is not a world yet (test: cli/tests/cli.rs).
  So `nix run git+https://gitea.surma.technology/surma/sausage` works.
- flake: .#loop without a folder runs bare sausage.
- README: mention the bare command and the bare loop.
2026-10-16 21:09:06 +00:00
Sausage Agent c1f182d9b6 broker: remove op deletes an actor (on top of tap/untap)
ci / check (push) Successful in 8s
{"type":"remove","actor"} shuts the actor down normally, drops its
mailbox, supervisor and actor.json entry (so also its subscriptions and
tap), and deletes /actor/<id>/. Native actors cannot be removed.
Re-applied from card-1-broker-remove (3c91747) onto card-2-broker-tap.
2026-10-16 11:48:50 +00:00
Sausage Agent 49453fa9af broker: tap/untap = receive a copy of every routed message
ci / check (push) Successful in 12m13s
Tapped copies {type:tapped, message:{id,from,to,reply_to,body}, ts} are
delivered directly (never tapped themselves), dropped when the tapper's
mailbox is full, and the tap is saved in actor.json like subscriptions.
2026-10-16 11:14:09 +00:00
Sausage Agent 2ff30ecf70 Actor-served files: /actor/<id>/fs/
ci / check (push) Successful in 10s
File operations under /actor/<id>/fs/ become messages from `fs` to <id>
(fs_read, fs_write, fs_mkdir, fs_remove, fs_rename) with a 10 s timeout.
vfs.rs wraps the wasi:filesystem implementation of wasmtime-wasi.
2026-10-16 01:25:11 +00:00
Sausage Agent 3435b556fb Broker exit request and nix run .#loop for self-updating hosts
- broker: `{"type":"exit"}` answers `exiting`; `sausage run` then stops all
  actors and exits with code 75.
- flake: apps `loop` / `loop-internal` run `nix run --refresh git+ssh://.../surma/sausage -- run <world>`
  in a loop; exit code 0 (/quit) ends the loop, anything else restarts.
- PROTOCOL.md, README.md, test in cli/tests/host.rs.

Not compiled: written by the Sausage agent, which cannot build the native host.
2026-10-16 00:37:25 +00:00
surma bcde6ba325 Plain POSIX files: remove commit on close (fs.rs)
Staging every write until close broke tempfile, git, and SQLite, which
expect normal files. Actors that need an atomic publish write a temporary
file and rename it; the SDK has write_atomic for that.
2026-10-15 23:33:20 +01:00
surma 599ee510cb fs: a rename of the open file itself no longer drops the staged write
The pending commit moved to `to.join("")`, which has a trailing slash, so
the commit rename failed and the staged file was deleted.
2026-10-15 23:12:03 +01:00
surma 285f77a9e2 Sockets: running actors get TCP, UDP, and DNS through wasi:sockets; candidates get no network 2026-10-15 19:27:45 +01:00
surma 11144b947e Trim the harness to what it needs to keep going
Host:
- test first: a new version is tested where it lies; only an installed
  version goes to versions/, and instances run from there
- data/ and public/ are shared by all versions; no snapshots; rollback
  restores code only
- no re-delivery, status.json, list, remove/archive, smoke test, data/
  hiding, or stdin timeout; rollback needs a version
- supervisor.rs split out; one place for installing a version
- init only writes the agent folder; run installs it like any actor
- console: @actor, text to the agent, /help, /quit

Agent:
- every text goes out as a broadcast; 5-line prompt; 5 tools that describe
  themselves; turn.json only marks an active turn

Docs: PROTOCOL.md, README.md, DECISIONS.md, AGENTS.md rewritten.
Examples: only notes and notes-v2.
2026-10-15 13:35:45 +01:00
surma cee862275c Agent integration tests against a fake inference endpoint 2026-10-15 12:39:39 +01:00
surma 9d575b6a62 Host: fixes from the review, with regression tests
- one live instance per actor: check after the lock; dropping an instance kills it
- state snapshots keep target/ and .git/; only source copies skip them
- one shutdown deadline; output during shutdown is still routed
- deliveries route stdout meanwhile; a stuck stdin kills the instance
  (no partial lines) and the sender gets undeliverable; control requests
  are not blocked by a stuck delivery
- Host::stop aborts running broker and cargo requests first
- compile a version before installing it; roll back if it does not start
- unique archive names; a failed archive keeps the actor manageable
- commit on close: truncate without create; directory renames
- candidates see SAUSAGE_VERSION and the existing state of a new actor
- the host publishes PROTOCOL.md at /actor/broker/public/
2026-10-15 12:03:26 +01:00
surma bfd9339d25 Integration tests for routing, filesystem, upgrades, rollback, cargo, and paths 2026-10-15 11:24:07 +01:00