<feed xmlns='http://www.w3.org/2005/Atom'>
<title>cloud9.git/docs, branch main</title>
<subtitle>9p for zig</subtitle>
<id>https://git.0x4200.cafe/cloud9.git/atom?h=main</id>
<link rel='self' href='https://git.0x4200.cafe/cloud9.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/'/>
<updated>2026-09-21T17:13:43Z</updated>
<entry>
<title>post registry + 9ns --mntgen: the /srv translation</title>
<updated>2026-09-21T17:13:43Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-21T17:13:43Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=3a23f6a29e47ace901bd4d82b9db4055fcc12bb9'/>
<id>urn:sha1:3a23f6a29e47ace901bd4d82b9db4055fcc12bb9</id>
<content type='text'>
cloud9.post: servers post their socket under a name in
$XDG_RUNTIME_DIR/9p (post/unpost, posted, dial, Watch) and
serve.Runner.listenPosted posts a server by name, unposting on stop.
Names are budget-checked against the 108-byte socket path; a claim
binds+listens at a private temp path and takes the name with atomic
renames under flock (RENAME_NOREPLACE for free names, RENAME_EXCHANGE
grab-verify-commit for stale ones): the registry path is never unlinked
by a claim, live names refuse with AlreadyPosted, foreign files with
NotSocket, and unpost removes only the caller's inode-matched entry.
Watch surfaces inotify overflow and a replaced registry dir.

9ns --mntgen [--mount DIR] -- PROGRAM: one FUSE mount at /mnt/9p whose
synthetic root lists the posted registry (no connection made); a walk
into an unmounted name dials it and runs the existing bridge dispatch
in a per-server worker thread, routed by mount index in the node id's
top bits (ordinals never reused, cap 4096); a dead server answers EIO
on its subtree and is re-dialed on the next walk. The dial watches
stop_fd through Tversion (connectWatched). All existing 9ns forms are
unchanged.

9proc's unix listener no longer blind-unlinks its path: a foreign
non-socket is refused (Occupied), a live server is refused
(AlreadyListening), only a refused socket is cleared, and stop()
unlinks only the listener's own inode-matched socket.

Hardened by adversarial review (GLM 5.3 x2 + DeepSeek V4.1 Flash, all
high-thinking): double-bind races on one name (0 in 180k rounds),
foreign-file TOCTOU deletions (0 in 4M flips), a 255-byte-name listing
panic, inotify queue overflow silently dropped, listenPosted silently
overwriting, dial-time Tversion hangs wedging the dispatcher, --debug
silently ignored in mntgen, and xattr/statx probes answering EPERM on
the synthetic root (broke `ls -l /mnt/9p`).

Tests: root 80/80, 9ns 47/47, 9proc 60/60, integration 88/88 +
mntgen 37/37, adversarial 213/0, freestanding riscv32 gate green.
</content>
</entry>
<entry>
<title>9web: multiplexer, HTTP view of the tree, live streams, richer page</title>
<updated>2026-09-20T06:53:17Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T06:53:17Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=f1b53c1533539aecbf16ad19fd9156deae091f92'/>
<id>urn:sha1:f1b53c1533539aecbf16ad19fd9156deae091f92</id>
<content type='text'>
One upstream 9P connection now serves any number of browser WebSocket
sessions and, with --serve, plain 9P clients over TCP or Unix (a 9pserve-
style frame remux: tags and fids remapped, Tflush forwarded, reconnect on
upstream loss). /fs/&lt;path&gt; maps HTTP onto the tree: GET file or directory
(JSON or HTML), Range, HEAD with 9P headers, PUT (create, truncate, append,
trailing slash makes a directory), DELETE, and ?follow=1 or text/event-stream
turning a blocking read into server-sent events with Tflush on disconnect.
The page gains a lazy tree, stat panel, create, rename, delete, upload and
follow mode. --probe embeds 9proc for self-introspection. New mux-test and
http-fs-test steps; e2e still passes.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add cloud9.serve: an std.Io runner around the file-server engine</title>
<updated>2026-09-20T05:33:02Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T05:33:02Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=ba7ec40782ba7020d82a56896a5eb1b52578d6aa'/>
<id>urn:sha1:ba7ec40782ba7020d82a56896a5eb1b52578d6aa</id>
<content type='text'>
Runner(Backend, Options, Limits) listens on Unix or TCP, runs a reader and a
serve task per connection in one Io.Group, pushes frames into an fs.Server,
and lets the backend answer now or later from any task or thread (reply,
flush, wake); Tflush, greet timeout, connection limit, close and stop with
cancellation are covered by tests over real sockets. The engine and the
backend contract stay Io-free, so the push/step mode for freestanding
targets is unchanged. Documented as the two ways to drive the engine.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>9proc core becomes a backend of cloud9.fs; engine gains optional features</title>
<updated>2026-09-20T04:47:29Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T04:47:28Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=66f2e492c348677ab3050f5e378b9eb4c04c98ce'/>
<id>urn:sha1:66f2e492c348677ab3050f5e378b9eb4c04c98ce</id>
<content type='text'>
9proc's own fid table, walk loop and dir-read engine are replaced by
cloud9.fs.Server; the tree (static, vars, providers) is served through the
engine's Req/Reply contract with node ids that keep the old qid scheme.
Providers may answer later by returning error.Again (parked in the engine,
retried each step, Tflush -&gt; EINTR); no new files are exposed.
Engine (backward compatible, all opt-in via Backend.features / Options):
create, remove, wstat, reference accounting for backends that count
handles, a salted fid index, name_capacity 0 (names from getattr),
Reply.ename for backend-chosen error text, Attr.path/version/atime.
Engine-level error strings and the 217-byte msize floor now apply to 9proc;
tests updated accordingly.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add the file-server engine: cloud9.fs.Server(Backend, Options)</title>
<updated>2026-09-20T03:58:22Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T03:58:22Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=65209217b5b68f56bc0bd5bc6c4dce33911ded59'/>
<id>urn:sha1:65209217b5b68f56bc0bd5bc6c4dce33911ded59</id>
<content type='text'>
The asynchronous 9P file-server engine from the Pardes editor moves into the
library: fid table, walks, directory cursors, a job/slot model where backend
replies arrive later by tag (status again = parked), Tflush cancellation and
orphaned fids on hangup. Allocation-free, no OS calls, no std.Io; comptime
Options (fid, slot, park data, name and user capacities) replace the
editor's constants. Backend contract types (Req, Reply/ReplyWith, Op,
Status, Attr, E, error strings) live here. 29 engine tests plus the client
tests that sat beside it in Pardes.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Rename programs: 9player -&gt; 9ns, introspect -&gt; 9proc, app -&gt; web (9web)</title>
<updated>2026-09-20T02:28:22Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T02:28:22Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=ba996acfcad1698adbf4a1834fe50e73b1c6cab9'/>
<id>urn:sha1:ba996acfcad1698adbf4a1834fe50e73b1c6cab9</id>
<content type='text'>
Directories, binaries, build options (-D9ns, -D9proc), step names, module
name (9proc), thread and fs names, env var NINEPLAYER_MOUNT -&gt; NINE_MOUNT,
docs and test scripts. Browser assets move to web/static.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add 9player and introspect as programs beside the library</title>
<updated>2026-09-20T00:26:05Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-20T00:26:05Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=b05abcba3ea09ea106ad28364c6e40a3ec31b890'/>
<id>urn:sha1:b05abcba3ea09ea106ad28364c6e40a3ec31b890</id>
<content type='text'>
9player/: FUSE mount CLI that mounts a 9P2000 tree into a fresh user+mount
namespace and runs a program in it (no root, no libfuse, no libc).
introspect/: the 9P debug/introspection library (freestanding core, value
renderers, Linux probe with threads/stacks/memory/breakpoints/panics) and
its demo server. Each has its own build fragment; the root build.zig wires
them behind -D9player/-Dintrospect with namespaced steps (9player-itest,
introspect-check-freestanding, programs-test, ...) and exports the
introspect module for dependents. This is the layout for related programs.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add reusable HTTP transport, serial gateway, and WASM file browser</title>
<updated>2026-09-16T14:18:48Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-14T17:28:15Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=ae310a207534b33b7321dd2b9f423a73b1969159'/>
<id>urn:sha1:ae310a207534b33b7321dd2b9f423a73b1969159</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Implement base 9P2000 sessions, shared transports, and conformance probes</title>
<updated>2026-09-14T17:20:25Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-14T17:10:28Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=5f24c4a2284a0af84fb9d116f7a39f6a58e42ae9'/>
<id>urn:sha1:5f24c4a2284a0af84fb9d116f7a39f6a58e42ae9</id>
<content type='text'>
</content>
</entry>
</feed>
