Runner. How a node runs a run's program; the run's node says where. A
node offers some runners, and OCX's status lists them; a node answers a run
whose runner it does not offer with ended, refused. Every runner runs its
program in a fresh checkout of the run's checkout: a check-in's hash, or a
branch's name, meaning its latest check-in. The runners:
commandruns the program named in the run'scommand(a list: the program, then its arguments) once, to completion: a build, a test, a check of one check-in.ciruns it for every check-in. It is always a session: for each check-in on a branch in the run'scheckins, it runs the run'scommandonce, to completion, in a fresh checkout of that check-in, and records the result as aciverdict on it (see Verdict).- An agent runner, such as
claudeorcodex, runs that agent program, usually as a session. Its program, the home files its runs share and its environment come from the node's wiki pagesandbox/NAME, written by a user holding admin or setup. The run'sremote(true or false, default false) says whether people may also reach the session through the agent's own remote control, as Claude's offers; what is said that way leaves no artifact.
For both, command is what is run, and the run's objective says in words
what counts as passing. So to run something once, use command; to run it for
every check-in on some branches, use ci. Special hardware is a node, not a runner: to test each
check-in on dev on a board attached to a host, send a ci run whose node is
that host's, such as
{"runner": "ci", "command": ["make", "board-test"], "checkins": ["dev"], …}.
Subscription. What a session is given while it runs, set by two fields of its run, both optional and empty by default:
checkins: branch names. Each check-in that arrives on one of them, unless the run's own user sent it, is given asCheck-in HASH on BRANCH by USER.hears: Fossil users. Each post one of them makes in the run's thread, or each change one of them makes to the run's ticket, is given asPost HASH from USER:orChange HASH to TICKET from USER:, followed by its text as written, which may run over several lines.
A session is first given Run HASH: OBJECTIVE. Deliveries reach its program's
input whole, one at a time, in the order they arrived; one that arrives while
the program is busy waits its turn. USER is the user Fossil received the
artifact from. Nothing is given to, or kept for, a run that is not running, and
a run that is not a session is given nothing. A run's own posts, such as its
questions, answers and progress, are plain posts in its thread, with no OCX
message.
Limits. What a node holds a run's program to, in the run's limits. Each
is optional; a limit left out takes the node's own default, and the node's
started report lists, in a limits of the same shape, every limit it
applies. A node that cannot enforce a limit a run asks for answers it ended,
refused.
- Time and resources:
wall(a whole number followed bys,m,hord),cpu(seconds, in total),memory(bytes, or a number followed byK,MorG),processes(at once). Reaching one ends the run,budget. - What it sees:
network(true or false), andread_onlyandread_write(lists of absolute host paths). Besides these it sees only its checkout, its program and the host's system files, which it may only read. - What it may write in Fossil:
no_password(true or false): the program holds no password for its user. Its posts, verdicts and check-ins go through OCX's tools, which the node runs as its user.branch(a branch name): its check-ins go on that branch only.own_thread(true or false): it posts only in its run's thread or ticket.
branch and own_thread are enforced by OCX's tools, so asking for either
also means no_password. A tool refuses a write these forbid, and the run
goes on. Without no_password, the program's Fossil capabilities are its
only limit in Fossil.