A record of how v1 was first built, kept as it stood; protocol v1 itself is protocol-v1.md, and what is built next is parity-v1.md.
Protocol v1 becomes the code one slice at a time. Each slice is a check-in that passes the gate, and its specs are drawn from the failure cases, so the cases become acceptance tests as the slices land; the table at the end says which slice makes each case pass. The maintainer asked for this order at the terminal, 2026-10-12: one more review of the protocol, then building v1 with its failure cases as acceptance tests ("yes, please").
The call and response that came before v1 kept working until the last slice, which moved the two scenarios in SCENARIOS.md to v1 and removed the call, the response and the code only they used, as the maintainer has asked of what nothing uses (2026-10-09: "just remove what we don't know how to use").
Slice v1.1: messages, read and written
A module of the protocol layer, src/ocx/messages.cr, beside today's records:
- Finding a message: the fenced blocks of a post's or ticket change's
text, paired as CommonMark pairs fences; the first block opened by
or a bare```json
whose JSON repeats no key and carries```ocx, a whole number naming version 1. Any other text, block or version is no message. - Reading it: into the struct of its kind,
run,stop,startedorended; a kind it does not know is ignored, as is a key it does not know, but in a run'slimits. - Checking a run: a required field missing, a value of the wrong type or
form, an empty command, a limit it does not know,
and
branchorown_threadagainstno_passwordare refused, with the noteendedwill carry. - Writing one: the fenced block, its JSON pretty.
The entries guard learns v1's kind, so every kind the code writes stays a
word of the glossary. Cases 14 and 15 pass as messages.
Slice v1.2: what a node decides
The protocol's rules for one run, as one function with no Fossil in it: from
a run, the messages in its thread with who sent each, the node's own reports,
what it offers, and what is in its care, the one thing the node does next:
refuse with a note, wait, prepare and start, end it stopped or lost, or
nothing. Its specs are the failure cases about runs, each a table of inputs
and the act they lead to, so the rules are shown to agree with each other
before any of them touches a repository.
Slice v1.3: on the server's repository
Runs and stops read from forum posts and ticket changes, who sent each by its
receipt, and reports written as the node user, for the artifacts the hook is
given and nothing else (HISTORY.md decision 39). The specs run on a scratch
fossil new repository.
Slice v1.4: receipt, and nodes on clones
The server's read-only receipt tool (built); a node on a clone (built:
node, HISTORY.md decision 43): it pulls and acts on what the pull brought,
asking receipt over HTTPS, signed in as its node user through Fossil's login
page; its run users' passwords in a file only its account reads; its own
reports known by their receipts' missing address, each sent to the server
before it goes on, started before a launch; and a run user working for the
node of the first run that named it. Not built yet: a person's writes sent
through the server's web page. The specs run Fossil's own server and a clone
(spec/ocx/remote_node_spec.cr).
Slice v1.5: runners and limits
Preparing and launching: the checkout resolved once and named in started,
the program the run's command names, with its env and homes
(HISTORY.md decisions 40 to 42; until decision 42, a runner's wiki page
sandbox/NAME gave any program but command's), every program given its
run on its standard input, and the limits enforced, or the run
refused. Built ahead of v1.4, at the maintainer's word (2026-10-12,
"continue"), so that a run runs on the server's node first.
Slice v1.6: sessions
The delivery contract of sessions: what the hook
is given from started on, in receipt order, nothing given before its sender
is known, as lines of JSON on the program's standard input, with no delivery
state kept (built); and the node's check at its start
(section 5), which answers what its going down
left, so the crash cases pass end to end, not only as decisions: hook --node
USER runs it (built).
Slice v1.7: the tools
create, run (a manual start and a trial), stop, post, audit,
push and status on v1's messages, each gated and answering as
the tools say. Built: create, from a pattern's URL,
by convention the wiki page run/NAME, as an admin or setup last wrote it; run's manual start; stop; and
post, which writes no OCX message; the three that write on the served
repository have its node act at once (HISTORY.md decision 39). Not built yet:
run --trial and push, so a node refuses a run asking for no_password,
branch or own_thread.
Slice v1.8: the scenarios on v1
The two scenarios run on v1, and the call and response are removed, with the
code only they used (built: each scenario's steps that work run in its spec,
and the terminal sessions, the runner adapters, attach, queue and the
workspace tool are gone). The glossary's section for the call and response
waits on the maintainer's word on removing it.
The cases, by slice
| Cases | Slice |
|---|---|
| 14 (contradictory limits) | v1.1 |
1, 2, 4 (crashes), 9 to 11 (stops), 17 (a forged report), 25, 26 (user) |
v1.2 |
| 13 (a missed signal), 16 (a forged run) | v1.3 |
| 19 to 21, 23, 24 (across hosts) | v1.4 |
| 5 to 7 (starting) | v1.5 |
| 15 (a program not on the host) | v1.5 |
| 3 (a watcher gone), 12 (delivery) | v1.6 |
| 8 (two manual starts), 22 (a program's post) | v1.7 |
| 18 (an agent's trial) | v1.7, with the trial, not built yet |