Login
Documentation
Login

OCX message. A JSON block in a forum post or a ticket change, fenced in Markdown: write it with a line

```json
, the JSON, and a line
```
; a reader also takes a bare
```
fence. Other text may come before or after it, and nodes ignore it; keep it short. An artifact holds one OCX message: a reader takes the first fenced block whose JSON has an ocx key, and ignores any other. Every message has "ocx": 1, a kind, and node: the one node it is for, named by its repository's server-code (40 hex digits, matched exactly). There are four kinds:

Every message but a run names the run it is about in its field run: the run's Fossil hash, in full, in hex. It is written where that run is, as a reply in its thread or as a change to its ticket. Several runs may share a thread or a ticket; each is answered on its own. A message never changes: an edit of one is ignored, so to change a request, stop it and send another.

Run. The OCX message of kind run: a request that a node run one program. Its fields, besides ocx, kind and node, are these, and those that Runner, Subscription and Limits add:

{"ocx": 1, "kind": "run", "node": "6cbe285e95a3a124176569ee9243f2a4e9ecdc20",
 "objective": "Build check-in abc123 for the board; it passes when the build succeeds.",
 "runner": "command", "command": ["make", "board"], "checkout": "abc123",
 "user": "builder", "session": false, "limits": {"wall": "30m"}}

Started and ended. The node's reports on a run, written where the run is.

{"ocx": 1, "kind": "ended", "node": "6cbe…", "run": "FULL-HASH-OF-THE-RUN", "outcome": "exited", "exit": 0}

A stop for a run that is already over does nothing. A run with a started and no ended is running; a run with an ended is over. So a run's OCX messages come in one of these orders, and no other:

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:

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:

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.

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.

Sender. The Fossil user an artifact was received from. Each repository records it for every artifact it receives, by an authenticated sync, through its web page, or by a write on the repository itself. For a write on the repository itself it records whatever user the writer names, so on a node only OCX's tools write, each naming the user it signed in. A repository does not copy senders to its clones: only the repository that received an artifact knows who sent it. The user written inside an artifact is whatever its writer's clone said, and proves nothing by itself. OCX decides by sender:

Who may read threads, tickets and check-ins is Fossil's own business, by its capabilities; OCX adds nothing to it.

Verdict. A tag on a check-in that records a judgement of it: audited for one made by a person or an agent, ci for a program's check. Write it as a raw tag (Fossil's --raw), so it never becomes a name for the check-in. A reader reads older sym-audited and sym-ci tags as verdicts too. Its value is pass: or fail:, then the reason on one line, then (against X), where X names the objective it was judged against: a run's full hash, or the path of a file that states the objective, such as PLAN.md, read as it stands in the check-in judged. Two examples:

Anyone may write an audited verdict, with OCX's audit tool or with Fossil's own fossil tag add; it needs no run. But a verdict on your own check-in never counts: the author of a check-in cannot pass it. A ci run writes a ci verdict, as the run's user, on each check-in it checks, against the run itself.

Reading verdicts. A verdict counts when its sender may add one (see Sender). A run named in it must be about the check-in: its checkout is that check-in, or its checkins include the check-in's branch. Fossil shows only a tag's latest value on a check-in, but keeps every tag change, with its user, in its event table (type g). So a reader takes each user's latest verdict from there, and every user's latest verdict counts. How to combine them is the reader's choice: any fail fails, a majority, one named reviewer. OCX's queue and activity, CI checks and merge gates are all readers. Only the node knows senders: a reader there counts by sender; a reader on a clone can count only by the user named in each tag change, and says its count is unverified.