Login
Check-in [72ce3dca69]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Step 3: the daemon launches sessions as its children; Start and Stop go through it

Purpose: step 3 of the agreed build order (374b12e82e), on the daemon design (14d8477f84, recorded in aa3bbde87a). The console no longer spawns sessions: a launch is a post, and one parent sees every start and end.

Shape: - src/ocx/daemon.cr and bin/ocxd: - one per agents root, by a lock in AGENTS/ocxd holding its pid, with its pipe beside it; - the console on every page, and the wake hook on every run, make sure it runs. `ensure` returns when the new daemon prints "ready" once its pipe is open, or when it ends because another holds the lock: an event, with no timer and no hang; - it reads `post REPOSITORY HASH` and `stop LOGIN KEY`. - A launch note by an agent login starts the release's `workspace serve` as the daemon's child in its own session (setsid, clean environment), once per note: - beside a process it did not start, it launches nothing and says so on the record; - its own session there is stopped first, and the new one starts when that end is reaped; - each end is reaped and said on the record ("the session ended: exit N" or "stopped by signal TERM"). - Launch.start posts the definitions and the note, then hands the note to the daemon itself (the hook may be held by Fossil's backoffice). It refuses when another login's session serves the record, or when no daemon reads its pipe. It returns the note's hash. - Launch.stop: a session the daemon started is stopped by the daemon (its process group gets TERM); any other, such as a terminal session, is sent TERM here. Nothing waits: launch.cr's timer (PATIENCE) is gone. - Terminate refuses while a process runs in the workspace, instead of waiting for it to stop. - launch.pid is gone: a `workspace serve` with no ~/run yet is "starting". ~/run is believed only while the process table shows its pid there. - The hook hands every received artifact to the daemon. setsid's one call site is daemon.cr. ocxd is a release target.

Origin: opus, on 374b12e82e and 14d8477f84. Intent: every session has one parent that puts each start and end on the record; the console only posts and asks. Expression: src/ocx/daemon.cr, tools/ocxd.cr, src/ocx/launch.cr, src/ocx/cgi.cr, src/ocx/sessions.cr, src/ocx/serve.cr, tools/wake.cr, shard.yml, docs/. Demonstrates: spec/ocx/daemon_spec.cr, spec/ocx/console_workspaces_spec.cr, spec/ocx/serve_spec.cr, spec/ocx/processes_spec.cr, crystal run ci.cr: - one lock per agents root, with its pid; ensure starts a daemon program and returns on "ready" or on its end; - from the console, a launch note starts the release's `workspace serve` as the daemon's child, with only HOME and PATH, once per note; - a person's post, or an agent's that isn't a launch note, starts nothing; - a second launch replaces its own session and says the first's end; - beside another process, the launch is refused on the record; - Stop goes through the daemon, and its end is said; - another login's session on the record refuses the launch, and with no daemon the launch says it won't start; - Terminate refuses while a session runs; - CI green, 224 examples, coverage 96.3%, 10 tools build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrDxZLxg3rJ9AQNcwDvo3n

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ocx | ci
Files: files | file ages | folders
SHA3-256: 72ce3dca69c115a63499274caca2cd37d7ee05eca6d29c488d5b0663d6b4b5f4
User & Date: opus 2026-09-30 15:06:11.971
Context
2026-09-30
15:44
The console reports the daemon's health

Purpose: the maintainer, 2026-09-30: "cgi should report daemon health".

Shape: - Daemon.health: whether one runs (its lock), its pid, when it started, the release it runs, the sessions it is the parent of (from the process table), and the end of its log. - The daemon writes the release it started from into its lock (Daemon.claim), resolved through `current` when it starts, since its command line only says `current`. - The Sessions page starts with one line, e.g. "Daemon. Running since TIME (pid N), release R; the parent of K sessions". It flags a daemon on another release than the current one. When the daemon isn't running, it says each page starts it and shows the end of its log. - /state gains a `daemon` object, and its schema follows.

Origin: opus, on the maintainer's request in the terminal. Intent: the daemon's state is seen where sessions are, and read by Stone. Expression: src/ocx/daemon.cr, tools/ocxd.cr, src/ocx/cgi_workspaces.cr, src/ocx/host_state.cr, docs/design/state.schema.json. Demonstrates: spec/ocx/daemon_spec.cr, spec/ocx/console_workspaces_spec.cr, crystal run ci.cr: - not running, health says so and the page shows its log; - running, health gives this pid, release "one" and its child session, and the page gives the line; - a daemon on release "zero" is flagged as not the current release; - CI green, 224 examples, coverage 96.3%.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrDxZLxg3rJ9AQNcwDvo3n check-in: 6cd4d2edae user: opus tags: ocx, ci

15:06
Step 3: the daemon launches sessions as its children; Start and Stop go through it

Purpose: step 3 of the agreed build order (374b12e82e), on the daemon design (14d8477f84, recorded in aa3bbde87a). The console no longer spawns sessions: a launch is a post, and one parent sees every start and end.

Shape: - src/ocx/daemon.cr and bin/ocxd: - one per agents root, by a lock in AGENTS/ocxd holding its pid, with its pipe beside it; - the console on every page, and the wake hook on every run, make sure it runs. `ensure` returns when the new daemon prints "ready" once its pipe is open, or when it ends because another holds the lock: an event, with no timer and no hang; - it reads `post REPOSITORY HASH` and `stop LOGIN KEY`. - A launch note by an agent login starts the release's `workspace serve` as the daemon's child in its own session (setsid, clean environment), once per note: - beside a process it did not start, it launches nothing and says so on the record; - its own session there is stopped first, and the new one starts when that end is reaped; - each end is reaped and said on the record ("the session ended: exit N" or "stopped by signal TERM"). - Launch.start posts the definitions and the note, then hands the note to the daemon itself (the hook may be held by Fossil's backoffice). It refuses when another login's session serves the record, or when no daemon reads its pipe. It returns the note's hash. - Launch.stop: a session the daemon started is stopped by the daemon (its process group gets TERM); any other, such as a terminal session, is sent TERM here. Nothing waits: launch.cr's timer (PATIENCE) is gone. - Terminate refuses while a process runs in the workspace, instead of waiting for it to stop. - launch.pid is gone: a `workspace serve` with no ~/run yet is "starting". ~/run is believed only while the process table shows its pid there. - The hook hands every received artifact to the daemon. setsid's one call site is daemon.cr. ocxd is a release target.

Origin: opus, on 374b12e82e and 14d8477f84. Intent: every session has one parent that puts each start and end on the record; the console only posts and asks. Expression: src/ocx/daemon.cr, tools/ocxd.cr, src/ocx/launch.cr, src/ocx/cgi.cr, src/ocx/sessions.cr, src/ocx/serve.cr, tools/wake.cr, shard.yml, docs/. Demonstrates: spec/ocx/daemon_spec.cr, spec/ocx/console_workspaces_spec.cr, spec/ocx/serve_spec.cr, spec/ocx/processes_spec.cr, crystal run ci.cr: - one lock per agents root, with its pid; ensure starts a daemon program and returns on "ready" or on its end; - from the console, a launch note starts the release's `workspace serve` as the daemon's child, with only HOME and PATH, once per note; - a person's post, or an agent's that isn't a launch note, starts nothing; - a second launch replaces its own session and says the first's end; - beside another process, the launch is refused on the record; - Stop goes through the daemon, and its end is said; - another login's session on the record refuses the launch, and with no daemon the launch says it won't start; - Terminate refuses while a session runs; - CI green, 224 examples, coverage 96.3%, 10 tools build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrDxZLxg3rJ9AQNcwDvo3n check-in: 72ce3dca69 user: opus tags: ocx, ci

14:37
task --write --after posts, then shows what the writer wasn't shown

Purpose: the maintainer, c22a865bc6: "I don't know that it makes sense for your tool to hold you off when you have a response posted. I suppose you might like to know, so you have a chance to revise, but I suspect that lesser models could really be confused by that." 9a8e14a17d made --write --after refuse.

Shape: `task --write --after POST` posts the turn, then prints what others posted after POST that the writer hadn't been shown, with the next cursor, so it can answer or revise. Nothing it posted over is buried unseen, and no session is held off. An unknown cursor is still refused before anything is written. Usage and the survey follow.

Origin: opus, on c22a865bc6. Intent: the writer always learns of what it posted over, without a refusal to handle. Expression: tools/task.cr, docs/survey/functionality.json. Demonstrates: spec/ocx/turns_spec.cr (Dispatch.after, unchanged), crystal run ci.cr: green, 223 examples, coverage 96.1%. By hand on this thread: the reply 62bb0bae40, written --after 202ac563af, was posted, then showed c22a865bc6 as not yet shown, naming it as the next cursor.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrDxZLxg3rJ9AQNcwDvo3n check-in: 4c15fa8cb0 user: opus tags: ocx, ci

Changes
Unified Diff Side-by-Side Diff Patch
Changes to docs/design/events.json.
Changes to docs/design/modules.json.
Changes to docs/design/modules.md.
Changes to docs/precepts/exceptions.json.
Changes to docs/survey/functionality.json.
Changes to docs/survey/gaps.json.
Changes to shard.yml.
Changes to spec/coverage/ratchet.json.
Changes to spec/guards/external_programs_spec.cr.
Changes to spec/ocx/console_workspaces_spec.cr.
Added spec/ocx/daemon_spec.cr.
Changes to spec/ocx/processes_spec.cr.
Changes to spec/ocx/serve_spec.cr.
Changes to src/ocx/cgi.cr.
Changes to src/ocx/cgi_workspaces.cr.
Added src/ocx/daemon.cr.
Changes to src/ocx/launch.cr.
Changes to src/ocx/serve.cr.
Changes to src/ocx/sessions.cr.
Added tools/ocxd.cr.
Changes to tools/wake.cr.