<feed xmlns='http://www.w3.org/2005/Atom'>
<title>cloud9.git/9agents/test, 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-25T20:52:33Z</updated>
<entry>
<title>9agents: /active/&lt;h&gt;/&lt;pid&gt;/chat, the conversation as one file per message</title>
<updated>2026-09-25T20:52:33Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-25T19:40:49Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=1c1b192d4ef59199a7196229d56901b1f6512678'/>
<id>urn:sha1:1c1b192d4ef59199a7196229d56901b1f6512678</id>
<content type='text'>
Each message of a claude or codex agent's transcript is a file named
&lt;id&gt;-&lt;kind&gt;: the id is its position in the transcript from 0, as 8
digits so the names sort; the kind is user, assistant, thinking, system
or agent, and a tool call is named after its tool (00000002-bash) and
its result after the call (00000003-bash-result). A file is the message
as text (a tool call: its name, then its input); its mtime is when it
was said.

chat.zig indexes a transcript incrementally, keyed by (dev, ino) and
checked by birth time and a hash of its first and last indexed bytes, so
a file rewritten in place is indexed again. It holds offsets, never
bytes: every read reads the file, and a read resumes where the last one
stopped so a long message is not decoded from its start each time. The
indexes and the runner live in lazily backed mappings (NORESERVE,
NOHUGEPAGE), and the fid table is 32768 so a kernel mount can hold every
message of a long chat.

A 9agents started inside a user namespace (from a 9ns-wrapped terminal)
cannot read /proc/&lt;pid&gt;/fd of processes outside it, so the fd route
never resolved codex there; /active now also finds a codex session
through the thread writer locks it holds (/proc/locks), via = lock.

Fixes to /active found on the way: a fifo in place of a transcript or
record no longer blocks the daemon; a transcript is opened from its
pinned root a component at a time, so a symlinked directory or a
sessionId with .. cannot reach outside it; slot generations are 24 bits,
so a stale node id cannot come to name another agent; listing a harness
rescans; an agent that had not resolved yet is asked again.

Co-Authored-By: Claude Opus 5.5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Rename 9harness to 9agents; README, file-backed qids, worded errors</title>
<updated>2026-09-25T20:52:33Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-22T13:30:02Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/cloud9.git/commit/?id=df20863879fe2d83077534f4726a985ffc239def'/>
<id>urn:sha1:df20863879fe2d83077534f4726a985ffc239def</id>
<content type='text'>
- 9harness/ becomes 9agents/ (build option -D9agents, package paths).
- 9agents serves /README, reports qid paths from the file's (dev, ino)
  and qid versions that move with the file, and names its refusals.
</content>
</entry>
</feed>
