feat(reasonix): run a supervised serve worker with steerable threads
Stacks on #2909. Adds a durable Reasonix worker per host, so threads stay warm and can be opened and steered without restarting the engine.
What
home-manager/services/reasonix— launchd (RunAtLoad+KeepAlive) and systemd (Restart=always) units runningstart.sh, which binds an ephemeral loopback port, publishesport/pid/tokenunder~/.local/state/reasonix, and reuses the generated token across restarts. Gated togalacticafor the proof of concept.- fish
rxthreads—status/list/open/new/send/steer/tailclient. Reads the published port and token, addresses threads bysessionPath, steers via the turn-scopedenqueue_steerqueue op (which auto-discovers the liveturnIdfrom/runtime-states). - fish
rxgoal— arms a goal and kicks the first round. Arming alone does not schedule a round:kickGoalDriveris reachable fromEditGoalDurableandTurnDone, but not fromSetGoalDurable(whatPOST /goaluses), so an idle armed goal stays atroundsStarted 0. The function submits one bootstrap turn whoseTurnDonestarts the chain. Also--statusand--clear. - Specs:
spec/reasonix_server_spec.sh(13),spec/reasonix_goal_spec.sh(7), plus coverage entries.
Verification
make nix-build— built; generatedreasonix-server.plistverified (ProgramArguments,PATH,RunAtLoad,KeepAlive)shellspec spec/reasonix_server_spec.sh— 13 examples, 0 failuresshellspec spec/reasonix_goal_spec.sh— 7 examples, 0 failuresshellspec spec/coverage_spec.sh— 129 examples, 0 failuresshellspec spec/reasonix_config_spec.sh spec/reasonix_server_spec.sh spec/reasonix_goal_spec.sh spec/coverage_spec.sh— 169 examples, 0 failures
Proven live on galactica via launchctl bootstrap: worker state = running, last exit code = (never exited); three concurrent threads resident; a real turn completed (turnStatus: completed, persistenceStatus: ready); mid-turn steer accepted (outcome: applied) and its text reached the model's transcript.
Known limitations
sendposts to/inbox/items, which has nosessionPathfield — it always queues to the foreground thread.steeraddresses correctly. Fix is to routesendthrough/inbox/queue.- Autonomous goal rounds were not observed firing over HTTP: goal pursuit calls
update_goal, which blocks on theaskpermission gate unattended, andgoalRoundEligibilityrequires theexclusivev3 binding. Both are upstream, not dotfiles. make nix-switchis required to make the worker permanent across reboots; the POC ran from a Nix-store plist vialaunchctl bootstrap.
Pre-existing
spec/reasonix_config_spec.sh has 4 failures on the base branch (tomlq availability in the hydrate tests). Verified present with these changes stashed.
Summary by cubic
Adds a durable Reasonix serve worker per host so threads stay resident and can be opened and steered without restarting the engine. Also fixes open and send so a message to a named thread lands in that thread instead of the foreground one, and ships the thread client as a fish function.
- Adds launchd (
RunAtLoad+KeepAlive) and systemd (Restart=always) units runningstart.sh, which binds an ephemeral loopback port and publishesport/pid/tokenunder~/.local/state/reasonix, reusing a generated token across restarts. - Adds fish
rxthreadsforstatus/list/current/open/new/send/steer/tail, reading the published port and token and addressing threads bysessionPath;newnow reads back the foreground session id instead of the empty 204 body. - Fixes
openandsendrequest contracts:opennow sendssessionIdto/resume, andsendselects the target thread before enqueuing because/inbox/itemshas nosessionPathfield. - Adds fish
rxgoalto arm a goal and submit a bootstrap turn, because HTTP arming alone does not schedule the first round; also supports--statusand--clear. - Adds specs for the server, the goal function, and coverage entries.
Known limitations
sendstill routes through/inbox/items; routing through/inbox/queueis the intended fix.- Autonomous goal rounds were not observed firing over HTTP: goal pursuit blocks on the
askpermission gate, andgoalRoundEligibilityrequires theexclusivev3 binding. Both are upstream, not dotfiles.