These cases describe the implemented protocol. Their numbers remain useful to specs. A node means only the host where the daemon acts on runs, named by hostname.
Crashes and retries
The daemon stops. Detached watchers retain their locks. The restarted daemon pulls whole and reads every run again.
The watcher stops. A free run lock with durable
takenstate ends the old processes and postslost, never launches again.endingretries the held report;donedoes nothing. Malformed state is taken.Two watchers take one run. Only one takes its lock under the round lock. It decides again before preparing and launching.
An arrival is missed. Chat is only a wake. A whole pull finds artifacts by receipt; restart reads all runs again.
A run arrives twice. Its hash is unchanged. Its lock, durable state and counted reports prevent a second launch.
A stop precedes launch. Address and sender checks and refusal rows 1 and 2 precede the stop. The stop precedes later refusals and ends it
stopped.A stop follows launch. The watcher ends the process and its children, then posts
stopped. Other sessions in that thread stay.A process exits before a stop is read. The watcher uses the state it can confirm. A later stop changes no counted
ended.An artifact lies about its author. The server's receipt proves who sent it; its user card does not.
A report adds a key or outcome. Unknown report keys are ignored. An unfamiliar text outcome still ends the run. A stop with any content key is ignored.
Input and delivery
A process reads nothing. Input may close unread; its exit, rather than a broken pipe, ends the run.
A session reads slowly. A pipe bounds waiting input; OCX does not wait forever to add a whole line to a full pipe.
A wake is missed. The next chat answer, even empty, triggers a whole pull. A chat error item causes one new sign-in and retry; another ends the daemon.
Refusals
A run has an unknown key. It is refused, naming that key, including a key within one of its parts.
The command is absent.
startedis written, launch fails and it endsexitednonzero, with kept logs explaining why.A sender lacks permission. A matching address grants nothing. Without admin, setup or
R, it endsrefused.A report is forged. It counts only when received from the run's
to, answering it byre. Admin writing as admin cannot answer another user's run.A sandboxed agent starts a manual run. MCP withholds
run; start it on the acting clone's host.
Across hosts
A run names another clone. Only the full server-code and
toboth matching cause action. Others pass by without posting a refusal.The server is unreachable. A failed or incomplete pull publishes no completion. Pull or receipt failure ends the daemon, saying why, and nothing starts it again on its own: on a host with no OCX web page, as the client is, a person starts it (
confine daemon, inside the host's namespaces), and its watchers run on meanwhile, given nothing. The maintainer chose this over an automatic restart, which could loop (2026-11-02). OCX's web page, on a host whose settings name adaemon_root, starts one when none holds the lock underROOT/state/, as aarch64-1's settings do; the client's name none. A watcher's failed receipt read waits for another completion.A run is written into the acting clone. Without a server receipt it allows nothing. Pushed as its own
to, it is refused. Send runs as their actual senders.The process posts progress. Its own clone syncs as its process's user. A session elsewhere hears that user, not the acting clone's user.
The host stops around launch.
takenprecedesstarted, and launch waits for confirmation. Recovery never relaunches. A countedendedsettles it without local state too.An artifact is not received yet. It is skipped while later received artifacts may be given. If received later, it may then be given in server order. A failed receipt request gives nothing from that read and retries at the next completion.
The process names a clone's user. It is refused: a process must never be able to write that clone's reports.
Two runs share a process's user. Both may run at once: no per-user lock. Each collects the unchanged approved password. An explicit reset changes it. The separate lock for
Ralone remains.A clone's user writes audited. It never counts. See verdicts.
Removal once saved
A child remains at process exit. OCX ends the process's children before reading or removing the workspace.
The server lacks work. Changed files, extra files, a stash or unpushed artifacts keep the workspace.
ended.workspacesays why. A failed removal never claimsremoved.
A process that reads nothing
The run line exceeds the input pipe. A process exiting before reading it still ends with its own exit code.
A terminal fills. Typing stops when the process ends or a stop ends it. A session with
deliveries: startwaits for the next process.
The watcher’s failures
A program takes a log file's place. A directory named
stderr.logprevents that file being kept; logs may still be posted.The watcher fails after started. It ends the process, logs the failure, keeps a requested removal unread and posts
lost. Failed final posting leavesendingfor recovery. Publications already made stay made.
Children outside a sandbox
- An unconfined process leaves children. OCX ends its Linux session's process groups. A child starting a separate session with
setsidcan escape; only a sandbox confines it. Recovery checks start times and boot identity before ending old processes.
Other writers
- A post has no confirmed answer. At a new completion the watcher checks sender, text and reply target, retrying only if absent. It holds only its run lock while waiting; other runs may decide.
A sandbox left running
- A sandbox does not end with its parent. On stop OCX ends the remaining init after its outer process ends. A killed watcher relies on recovery finding what the old lock names. A sandbox in another session whose outer process already ended can outlive that link.
Rruns requireends_with_parent.
Daemon and completion failures
Chat fails or a pull hangs. A chat poll answering Fossil's error item, which it gives only to a login it no longer signs in, as once an admin saves that user in any repository of its login group, makes the daemon sign in again, once, from its own file, and ask again; only a second such answer, or any other chat failure, ends it, saying what Fossil said. A pull past ten minutes is killed and publishes no completion. Restart pulls before waiting again.
The daemon restarts with watchers running. Their locks stay held, those runs stay in care, done runs stay done and waiting runs are reconsidered.
A post's answer is lost. The next completion checks sender, text and target before retry. A stop confirmed while
startedis unknown prevents launch.A node reboots. State and completion files survive; locks do not. The daemon pulls whole first. The old lock's boot identity prevents ending a new process with a reused number.
A verdict is requested without i. Refused before launch. Files without
yare reported as not shared.
Passwords, addresses and publication
A lost collect answer can be collected again without changing a password. An unapproved login is refused. An older local password is used only when the server explicitly says none is approved. A new clone has a new server-code; old runs must be sent again naming it. Several published clone files require an explicit address. Added fields in server answers are ignored; required fields and receipt targets are still checked.
Completion and republication are built. A publication failure leaves the process's ended unchanged and retains the workspace. A publish retries unfinished publications under the run lock; see the rules.