Login
OCX protocol v1: Fossil, senders and nodes
Login

What protocol v1 rests on and does not repeat: Fossil as the medium, how a message is found in a post or a ticket change, who sent an artifact, verdicts, nodes, tools and versions. Protocol v1 itself, the messages and what a node does with them, is written as tables there. These sections were tested on fresh readers with the rest of the protocol (the battery's definition tests), and each ends with the values in README.md that justify it.

1. Fossil, the medium

Everything that must last is a Fossil artifact: posts, check-ins, tags, ticket changes. These are the evidence of what happened; a host's own log is for diagnosing problems, and may be lost. OCX treats Fossil as a network whose every message lasts:

Each repository keeps a receipt for every artifact it receives: the time, the IP address it came from, and the Fossil user it was received from, by an authenticated sync, through its web page, or by a write on the repository itself, which has no address and records whatever user the writer names. So only a node, its tools and its host's administrators may write to a node's repository file. A repository does not copy its receipts to its clones, and a clone records everything it pulls as received from its own user, which holds setup there (Fossil 2.27, tried 2026-10-12): only the repository an artifact's writer sent it to knows who sent it. The user written inside an artifact is whatever its writer's clone said, and proves nothing by itself. Receipts are numbered as they arrive, and the artifacts of one receipt are taken by their record ids, as Fossil assigns them: that is the order this protocol means within a repository. Where readers on different repositories must agree, as on the latest verdict, the order is the server's (section 3).

Why: Demonstrability (artifacts are immutable, synced, readable later), Parsimony (no second store, no queue, no retries), Ax4 (every open request is found again after any failure).

2. Finding a message

An OCX message is a JSON block in a forum post of any mimetype, or in the text a ticket change adds to its ticket's comment (its icomment field): a fenced code block, its fences paired as Markdown (CommonMark) pairs them, opened by a line that is exactly

```json
or a bare
```
. Other text may come before or after it, and nodes ignore it; keep it short. A block holds an OCX message when its JSON repeats no key and has an ocx key, a whole number, naming a version the reader knows, whether or not the message is valid or acted on. A post's or change's message is the first such block carrying the newest protocol version the reader knows, read from the post's first version: an edit is ignored, so to change a request, stop it and send another. Several runs may share a thread or a ticket; each is answered on its own. What each kind of message holds, and who may send it, is protocol v1, section 3.

Why: Clarity (one envelope), Loose Coupling (anything that can write a post or a ticket change can send one).

3. Who sent it, and who may do what

The server is the repository people and nodes send their artifacts to, and that every clone syncs with; OCX's network has one. Who sent an artifact is the user the server received it from, by its receipt (section 1), with that user's capabilities on the server, inherited ones included, when the node decides.

If the server pulls from another repository at all, it pulls with Fossil's --user naming a user of its own who holds no capability this protocol asks for, so whatever it pulls allows nothing (Fossil 2.27, tried 2026-10-12). On a node whose repository is a clone, a tool that writes as a person writes on the server, through its web page, as that person.

So that the server gets every artifact from its writer, all a run writes reaches it as the run's user, from the run's own clone, synced by its process; all a node writes reaches it as the node user, which never holds admin or setup; and OCX's post never writes an OCX message. On a node, only the node, OCX's tools and the host's administrators write to the repository itself, each tool naming the user it signed in.

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

Why: Demonstrability (every act is attributed by the repository its writer sent it to), Ax1 (what each user may cause is fixed before it acts, and an artifact no receipt vouches for allows nothing), Parsimony (Fossil's receipts on the server are the one record of who sent what; HISTORY.md decision 37).

4. Verdicts

A verdict is a tag on a check-in recording a judgement of it, pass or fail with a reason and the objective it was judged against: audited for a person's or an agent's, ci for a program's. Anyone may write one, with OCX's audit or with fossil tag add, and it needs no run; but a verdict on your own check-in never counts, nor an audited verdict that a node user sent. Verdicts says how to write and count them.

Why: Ax2 (always judged against a named objective), Loose Coupling (a verdict needs no run, and any program may read one).

5. Nodes

A node is OCX acting on one repository on the host that runs its work: the server's, with OCX's hook installed, or a clone, run by OCX's node tool. It is named by its node user: a Fossil user of its own, which runs name in their node, as which the node writes its reports, and as which a node on another host syncs. Two hosts must never run as one node user, or both would act on the same runs. A node user holds the least it needs, never admin or setup: on the server's host, where the node writes into the repository itself and Fossil checks no capability, none, and no one holds its password; on another host, o to pull and i to push (Fossil 2.27, tried 2026-10-12). A node runs a process as its run's user only if it holds that user's password: the server's node sets a fresh one when it makes the run's workspace (HISTORY.md decision 29), and a node on another host holds those its administrator gave it, in a file only the node's account may read; it refuses any other run. A run's user works for one node: the node of the first run, in the server's order, that a user holding admin or setup sent naming it. Every node refuses a run whose user works for another, so the server's node never sets a new password on a user another node holds. A node runs one run at a time for each user: another waits, unstarted, until that one ends. OCX's status lists the limits a node enforces.

A node learns of an artifact only when the artifact reaches its repository. On the repository's server, that is as soon as it arrives. A node on any other host, such as a build host with its own clone, learns of a run only when it pulls its clone, how often being its own choice, and acts on it once the server says who sent it (section 3). On the server, Fossil tells the node of each arrival through its after-receive hook; on a clone, OCX's node tool pulls, and acts on what the pull brought as the hook acts on what Fossil gives it, and nothing else. Each report it writes it sends to the server at once, and goes on only once the server has received it from the node user. On the server's node, a run written with OCX's create is acted on at once, by create. A run written straight into a clone, such as a build host's, reaches the server only as received from its node user, which sends no runs, so the node refuses it: a build host's runs are sent to the server.

When a node starts, and whenever its administrator runs it again, such as after the hook's log shows a run that failed, a deliberate check reads from the repository every run that names the node, with its stops and reports, and decides each that has no ended by the state table of protocol v1, section 10: one whose process the node no longer has in its care is answered lost, ending the process first if it still runs; one in its care with a stop it may act on is ended; one with no started is decided as if it had just arrived. Nothing runs the check in the background. A process is in the node's care while the node's watcher of its run holds it: from just before its workspace is made until its ended is written.

Why: Ax4 (open runs are found again from the repository), Parsimony (the repository is the only state, and one user names a node and signs its reports), Loose Coupling (a build host joins by syncing a clone).

6. Tools

OCX's tools write these artifacts, and perform runs by hand, as a convenience, never a requirement: the same artifacts written by other means, such as a verdict with fossil tag add, count the same. OCX's tools are create, which writes a run; run, which starts a manual run by hand; attach, which joins a run's terminal; node, a node on another host; receipt, which says who sent an artifact; and stop, post, audit and status.

Why: Loose Coupling (the artifacts are the standard, and no tool is required).

7. Versions

Every OCX message carries "ocx": 1. What may be added to version 1, and what never changes, is protocol v1, section 15. A reader takes the block of the newest version it knows (section 2), so one post may carry a block for each version.

Why: Loose Coupling (other programs can rely on the formats), Clarity (meanings cannot drift, and nothing asked is silently dropped).