host: mount owner-written non-secret global config
ci / check (push) Successful in 10m37s

This commit is contained in:
Sausage Agent
2026-10-22 13:05:03 +00:00
parent 3d3f6f35fb
commit 5e701ab846
8 changed files with 150 additions and 3 deletions
+25 -1
View File
@@ -59,13 +59,15 @@ it exits. After 5 seconds, it kills the instance.
## Filesystem
Each instance sees three folders:
Each instance sees these mounts:
| Path | Access | Contents |
| --- | --- | --- |
| `/data` | read-write by its actor; readable by every actor | the actor's state |
| `/public` | read-write | the files that the actor publishes |
| `/actor` | read-only | the `actor/` folder of the world |
| `/config` | read-only | one non-secret global JSON file, owned by `shared` |
| `/global` | read-write for `shared`, read-only for all other actors | backing directory containing that same `config` file |
An actor can write only its own `/data`, but can read every actor's `/data` through `/actor/<id>/data/`. `/data` is not private: any unprotected secret file there is readable by every actor.
@@ -77,6 +79,28 @@ Files are plain POSIX files: a write is visible at once. To publish a file
so that readers never see half of it, write a temporary file and `rename` it
(the Rust SDK has `write_atomic`).
`/config` is global configuration, never credentials (in particular, never the
LLM proxy token). The host initializes it to `{}` without reading or copying
legacy actor settings. Configuration schema and typed edits belong to `shared`,
not the host. Ordinary actors cannot write either `/config` or its alias
`/global/config`: WASI mounts are read-only, with no message sender checks.
WASI preopens directories rather than individual files. The host mounts the
isolated world `global/` directory at `/` read-only and at `/global` with the
owner's write access. `shared` publishes atomically by writing a sibling such
as `/global/config.tmp`, closing it, then renaming it to `/global/config`.
New opens of `/config` see the replacement, including in already-running
actors; an already-open file retains its old inode. The root mount does not
expose the rest of the host world. Candidate tests get a scratch copy of
`global/`, so even `shared` tests cannot modify the live file.
On disk, the one JSON file is `<world>/global/config`. `<world>/config` is a
relative symlink to it, for native/world filesystem readers (including an
export of the world directory). Host-side atomic writers must replace
`<world>/global/config`, not replace the symlink. Starting an older world
adds the empty file and alias without changing actor state; an existing
regular `<world>/config` is moved into the backing directory on first use.
Send large or binary data as a path under `/actor/<id>/public/`, not inside a
message.