Login
Check-in [6cd4d2edae]
Login

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

Overview
Comment: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

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ocx | ci
Files: files | file ages | folders
SHA3-256: 6cd4d2edaebdc05b473fc622073d952ace1f2ec0d188bf5b3a8709595610203c
User & Date: opus 2026-09-30 15:44:54.374
Context
2026-10-01
12:30
Feel good about the first axiom. This is trying to reset things with a solid human review. check-in: a3fa673be0 user: jkridner tags: ocx-human-feedback
2026-09-30
16:08
Step 4: a session's lifetime, and its own record

Purpose: step 4 of the agreed build order (374b12e82e), on the lifetime design (257b282d36, recorded in a2743b4924). The maintainer asked to continue the plan to its end, to review then.

Shape: - A `completes` session ends once its work is done (Serve.done?). A command's is done when nothing waits. A model's is done once its report is on the record, unless its own latest post is a question, which keeps it waiting until answered. `workspace serve` passes the definition's lifetime to Serve.run; a `stays` session waits as before. - A session works and reports on its own record: `serve` on another record than its workspace's works there by focus. The workspace stays bound to its own record, where its definition and branch listeners are read. Workspace#rebind is gone. - The workspace page's Start form takes the record to work on, by completion over the ten most recent, defaulting to the workspace's own. The launch resolves it and refuses a prefix naming none. - The Sessions list names the record the session works on, from its ~/run. A stopped `completes` session with a report shows "completed: SUMMARY". - The launch action moved to cgi_workspaces.cr, keeping cgi.cr within 400 lines. "end on its report" is built in events.json.

Origin: opus, on 374b12e82e and 257b282d36. Intent: a short session costs one Start, works on the record it was started for, and ends by itself. Expression: src/ocx/serve.cr, tools/workspace.cr, src/ocx/workspace.cr, src/ocx/sessions.cr, src/ocx/cgi_workspaces.cr, src/ocx/cgi_agents.cr, src/ocx/cgi.cr. Demonstrates: spec/ocx/serve_spec.cr, spec/ocx/workspace_spec.cr, spec/ocx/console_workspaces_spec.cr, crystal run ci.cr: - a completing session's report ends it without waiting; - its own open question makes it wait; - a staying session waits either way; - focus leaves the binding on disk; - a launch on another ticket puts its note there, and the workspace stays bound; a prefix naming nothing is refused; - the page shows "completed:" with the report; - CI green, 225 examples, coverage 96.4%.

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

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

Changes
Unified Diff Side-by-Side Diff Patch
Changes to docs/design/state.schema.json.
Changes to spec/ocx/console_workspaces_spec.cr.
Changes to spec/ocx/daemon_spec.cr.
Changes to src/ocx/cgi_workspaces.cr.
Changes to src/ocx/daemon.cr.
Changes to src/ocx/host_state.cr.
Changes to tools/ocxd.cr.