Login
Check-in [bc12df02a0]
Login

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

Overview
Comment:Step 6: restart stopped sessions on a chosen release, and re-exec the daemon in place

Purpose: step 6 of the agreed build order (374b12e82e). The maintainer, 14d8477f84: no automatic relaunch, but "a CGI-based trigger to restart all stopped persistent session workers", with a release to choose so a bad one can be escaped. Accepting a release re-execs the daemon in place, keeping its pid and its children (027446fbe9).

Shape: - Restart: - The Sessions page shows a Restart button when some of this project's stopped sessions, started from the console, have a definition that stays running. One choice goes with it: the current release, or the previous one. - The restart action puts a new launch note on each such session's record, naming the release when one is chosen, and refuses a release that is neither current nor previous. - Launch.start takes the release and ends the note with ", on release NAME"; the daemon then runs that release's `workspace`, or the current one when this host lacks it. - Re-exec: - Accept and Rollback hand the daemon `reexec`. bin/ocxd's callback execs the current release's program in place, keeping its pid. - On every start the daemon adopts the `workspace serve` processes it is the parent of, reading repository, login and record from their command lines, which Processes::Found now carries. - It reaps spawned and adopted children alike through the runtime's reaper (Crystal::System::SignalChildHandler.wait), and reaps once at start in case one ended during the exec. Children are kept by pid. - After a re-exec the daemon's standard output is already closed, so "ready" is not required then. - Definitions.latest_session? reads a refused definition as nil for a page listing many. Design and survey marked built.

Origin: opus, on 374b12e82e and 14d8477f84. Intent: nothing restarts by itself, one button restarts what should stay, on a release you choose; a new release reaches the daemon without losing its sessions. Expression: src/ocx/daemon.cr, tools/ocxd.cr, src/ocx/launch.cr, src/ocx/sessions.cr, src/ocx/cgi_workspaces.cr, src/ocx/cgi.cr, src/ocx/processes.cr, src/ocx/definitions.cr. Demonstrates: spec/ocx/daemon_spec.cr, spec/ocx/console_workspaces_spec.cr, spec/ocx/definitions_spec.cr, crystal run ci.cr: - re-exec calls what the program gives; - a launch naming release "two" runs two's program and says so; - a second daemon adopts that child and reaps its end onto the record; - the Restart button offers the previous release, restarts on it and on the current one, refuses an unknown one, and restarts nothing once the definition completes; - a refused session definition reads as nil; - CI green, 227 examples, coverage 96.5%.

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: bc12df02a01736589dc99c2c4f61dd6b67b87b82479bb4ba8f0f6102fd88e1b0
User & Date: opus 2026-09-30 16:30:08.427
Context
2026-09-30
16:54
The daemon gets its own page with Stop and Start; the nav drops its numbers

Purpose: the maintainer, 2026-09-30: the daemon's line "should show on the main page or on it's own page and provide a stop/start, which it does not", and of the nav, "get rid of the numbers. they don't mean what you think".

Shape: - A Daemon page (?view=daemon) in the setup nav shows what the daemon does, its status line and its log's end. It has one button: Stop while it runs, Start while it doesn't. The Sessions page no longer carries the line. - Stop sends the daemon TERM and leaves a mark beside its lock (Daemon.stop). No page or hook starts it again until Start, which clears the mark and starts it (Daemon.start). Its sessions run on, each in its own session. - A launch while it is stopped is refused, saying to start it on the Daemon page. Health and /state say whether it was stopped from the console. - A daemon that started before it wrote its release says "release unknown". - The nav reads Hook, Agent logins, Workspaces, Sessions, Daemon, without numbers, and the messages and docs that quoted them follow.

Origin: opus, on the maintainer's terminal requests. Intent: the daemon is seen and controlled where it belongs, one page. Expression: src/ocx/cgi_workspaces.cr, src/ocx/cgi.cr, src/ocx/daemon.cr, src/ocx/launch.cr, src/ocx/host_state.cr, docs/. Demonstrates: spec/ocx/console_workspaces_spec.cr, spec/ocx/daemon_spec.cr, spec/ocx/agents_spec.cr, crystal run ci.cr: - the page shows not running with Start; - a stand-in holding the lock is stopped by Stop and ends on TERM; - then the page says stopped, and nothing starts it; - Start clears the mark; - a launch while stopped is refused with the way on; - a running daemon's line, and an older release's flag, move to the page; - CI green, 227 examples, coverage 96.5%.

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

16:30
Step 6: restart stopped sessions on a chosen release, and re-exec the daemon in place

Purpose: step 6 of the agreed build order (374b12e82e). The maintainer, 14d8477f84: no automatic relaunch, but "a CGI-based trigger to restart all stopped persistent session workers", with a release to choose so a bad one can be escaped. Accepting a release re-execs the daemon in place, keeping its pid and its children (027446fbe9).

Shape: - Restart: - The Sessions page shows a Restart button when some of this project's stopped sessions, started from the console, have a definition that stays running. One choice goes with it: the current release, or the previous one. - The restart action puts a new launch note on each such session's record, naming the release when one is chosen, and refuses a release that is neither current nor previous. - Launch.start takes the release and ends the note with ", on release NAME"; the daemon then runs that release's `workspace`, or the current one when this host lacks it. - Re-exec: - Accept and Rollback hand the daemon `reexec`. bin/ocxd's callback execs the current release's program in place, keeping its pid. - On every start the daemon adopts the `workspace serve` processes it is the parent of, reading repository, login and record from their command lines, which Processes::Found now carries. - It reaps spawned and adopted children alike through the runtime's reaper (Crystal::System::SignalChildHandler.wait), and reaps once at start in case one ended during the exec. Children are kept by pid. - After a re-exec the daemon's standard output is already closed, so "ready" is not required then. - Definitions.latest_session? reads a refused definition as nil for a page listing many. Design and survey marked built.

Origin: opus, on 374b12e82e and 14d8477f84. Intent: nothing restarts by itself, one button restarts what should stay, on a release you choose; a new release reaches the daemon without losing its sessions. Expression: src/ocx/daemon.cr, tools/ocxd.cr, src/ocx/launch.cr, src/ocx/sessions.cr, src/ocx/cgi_workspaces.cr, src/ocx/cgi.cr, src/ocx/processes.cr, src/ocx/definitions.cr. Demonstrates: spec/ocx/daemon_spec.cr, spec/ocx/console_workspaces_spec.cr, spec/ocx/definitions_spec.cr, crystal run ci.cr: - re-exec calls what the program gives; - a launch naming release "two" runs two's program and says so; - a second daemon adopts that child and reaps its end onto the record; - the Restart button offers the previous release, restarts on it and on the current one, refuses an unknown one, and restarts nothing once the definition completes; - a refused session definition reads as nil; - CI green, 227 examples, coverage 96.5%.

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

16:16
Step 5: CI launched per check-in, one run at a time

Purpose: step 5 of the agreed build order (374b12e82e). CI completes per check-in (257b282d36, after stone's "ci should not stay, should it?", 3f6abf8cc4), with agent-sol's point (d38004971c) that green and red completion be guarded.

Shape: - The daemon's `post` reads a check-in, as well as a post. For each workspace of the project listening to that check-in's branch (listening/branch-NAME), whose login has a kept password and a binding: - it launches the workspace's session, which completes: CommandRunner tests the newest untested check-in, tags it, and exits; - while its own run is going, it only says so, and the run's end looks again; - beside a process not its own, it says the branch waits. - When a check-in's run ends well, the daemon launches again only if a listened branch's newest check-in is untested and isn't the one just tested. A run that leaves its check-in untested therefore can't launch itself over and over. - A check-in's run reports with its ci tag: only a run that failed says its end on the record, so the CI thread isn't filled with notes. - Daemon::Server#untested reads the newest check-in of each listened branch with no ci tag of the login's, from the served repository. - Design and survey marked built.

Needed on the host after acceptance (not done here): ci-ocx's session definition on f4054411ee and the session/ci template must say "completes", and the old `stays` ci-ocx serve must be stopped. Until then its process holds the workspace and the daemon lets trunk wait.

Origin: opus, on 374b12e82e, 257b282d36 and d38004971c. Intent: no idle CI process; each check-in's run has its own start, result and end. Expression: src/ocx/daemon.cr, docs/design/events.json, docs/survey/functionality.json. Demonstrates: spec/ocx/daemon_spec.cr, crystal run ci.cr: - a check-in launches ci's session; - a second during the run launches nothing, and the run's good end launches the newer one, the same one never twice; - a good end says nothing; a failed one says "exit 1" and launches nothing; - a tagged check-in is not untested; - an unprovisioned listener is passed over, and a foreign process makes trunk wait; - another branch launches nothing; - CI green, 226 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: fed6e1b31b user: opus tags: ocx, ci

Changes
Unified Diff Side-by-Side Diff Patch
Changes to docs/design/events.json.
Changes to docs/survey/functionality.json.
Changes to spec/ocx/console_workspaces_spec.cr.
Changes to spec/ocx/daemon_spec.cr.
Changes to spec/ocx/definitions_spec.cr.
Changes to src/ocx/cgi.cr.
Changes to src/ocx/cgi_workspaces.cr.
Changes to src/ocx/daemon.cr.
Changes to src/ocx/definitions.cr.
Changes to src/ocx/launch.cr.
Changes to src/ocx/processes.cr.
Changes to src/ocx/sessions.cr.
Changes to tools/ocxd.cr.