Protocol v1 is the standard: its artifacts count however
they are written. OCX's tools write them, and perform runs by hand, for people
and programs, as a convenience, never a requirement. Anyone may write the same
artifacts by other means, such as a verdict with fossil tag add or a run as a
forum post, and they count exactly the same. What a run's program writes
through a tool, the tool writes in the run's own clone, which reaches the
server as the run's user; what a person writes with a tool reaches the server
as that person, pushed from that person's clone when the tool runs in one.
The tools
createwrites arun, on the server, or on another host through the server's web page, as the user signed in; what it takes and fills in is in USAGE.md, "Write a run". It refuses, writing nothing, a run a node would refuse as written, one with a key version 1 does not define among them (protocol v1, section 15). From a clone's checkout, as a run's program writes one, it pulls first, writes the run as a reply or on a ticket in the clone and pushes it, so the server receives it from the caller, whose run its node decides by who sent it (section 11, row 1); there it makes no user and starts no thread, and of a wiki page pattern it reads the newest version, in the server's order, whose sender holds admin or setup as the server'sreceiptsays, never the clone's own receipts or user table. On the server, only a user holding admin or setup has a user made for a run. Itsofsets the check-in eachfilesstep takes, by a name the node resolves (section 5).run RUN --repository CLONEstarts a manual run on the agent machine, through the clone's project password file and last completed pull. It checks the run names this node user and clone, decides it by hand and hands it towatch --by-hand. The watcher locks and decides again before posting and launching; simultaneous calls can hand it twice but cannot launch it twice. It needs setup on the clone: the node user is its default user and holds setup there as the user who made the clone. CGI and MCP withholdrun. A refusal decision is handed to the watcher to post; the tool refuses a run already started, ended or in care. A manual run waiting only for a person can start; the tool refuses one its node leaves waiting because its user has another run in care, or it is from a user holdingRalone while another such run is in care (USAGE.md, "Start a manual run by hand").attachjoins a person's terminal to a running process whoseprocess.terminalis true: what they type reaches its STDIN, and they see what it shows, until they leave it running (protocol v1, section 8).stopwrites astopfor a run on the served repository; it schedules nothing. The watcher acts after a complete pull.postwrites a plain post in reply to a post, or a change to a ticket, named by its id or any of its changes. It refuses text holding an OCX message, so a program's posts never carry one. Givenfor, a user, it writes the text as aquestionfor that user (questions), withoptions, one per line, the recommended one first,stakes, andreferences. A reference may be a hash, a prefix, a ticket's or a tech-note's id, or a link of the server, whole, from its root, or from the host's root with the server's path again, a file's lines by Fossil'sln=, each at most nine digits, and a wiki page's/wiki?name=PAGEamong them; each is resolved where the caller is to the one artifact, ticket, tech-note or page it names, written as a link from the repository's root, a file's lines on its artifact's page, and linked by its title in the Markdown. Givenruntoo, a run's hash or a prefix of it, as a run's process reads its own on the first line of its standard input (protocol v1, section 8.1), it writes that run's hash in full as the question'srun, the run whose process asks it, found where the caller is, refusing a run whoseprocess.useris not the caller, or that takes nopasswordstep. Givendecision, it writes the caller'sdecisionfor the questiontonames, where that question is, whoever the caller is: the text becomes itsnote, and an option's number is written as that option's words, never the number; from the question's sender, or from whoever sent the run it names as asking it, when that run counts, by the server's receipts, the note says why it is answered, and the decision closes it, but for the first decision of the user it is for, which is what they decided (questions, section 2). It refuses a question's words, an option,stakesor a reason for closing it holding a hash or a link, a reason for closing it that is digits alone, and words past the bounds; aforthe server lacks, or naming the caller; for a question in a thread, a sender orforwhose posts there Fossil would hold for a moderator (holding neither4nor5), and on a ticket, one whose changes in its pages Fossil would hold (the server moderating ticket changes, and the user lackingq); a reference that is a link of another server or of no page it reads, gives a file's lines otherwise than as one line or one range, names nothing or several, names what Fossil holds private, or, from a clone, names what the server has not received; aforwho may not read and edit (j,k) a wiki page it references, or whose edits there Fossil would hold for a moderator (the server moderating wiki edits, and the user lackingl), unread by the asker until then; a decision on a question already closed, a check that is only a convenience, since a decision after that changes nothing; and any text that would not read back as the question or the decision it was made from. Each is written after Markdown saying the same in words, its own words escaped, a fence's backticks and tildes among them. To read an answer given on a wiki page, the asker reads the page itself, withwiki_reador Fossil's history, before confirming it. From a clone's checkout it writes in the clone and pushes, and the server'sreceiptsays what a user may do there, whether it holds their wiki edits or ticket changes for a moderator, who sent the question and its decisions, and the runs and theirstartedreports, and in what order; on the served repository, as from the OCX page,/ext/ocx2-cgi, it writes there.questionswrites nothing. Of every post and ticket change Fossil's index of tags says theocx-messagetag was ever put on, whatever its value, cancelled or not, each message saying what it is, leaving out what Fossil holds private, it answers what waits on a user, you unless named, as data, the same at every entry point (HISTORY.md decision 100).waitinglists each question for that user that they have not decided, whoever else has, oldest first in the server's order;to_confirm, each question that user may confirm that has a decision: one they sent, or one naming a run they sent as asking it, when that run counts;open, every other question still open. Each gives its fields once: the post or ticket change asking it, by its hash, where it is, its thread's or ticket's title and a link to it, who sent it and when its writer's clock says it was written, whom it asks, its words, options, stakes and run; what it replies to and each of its references, described by one read for all, by its title and full URL from the server's public URL, with an excerpt of at most 300 characters, an OCX message's block left out, or a file's lines (at most 20), each hash in a title or excerpt shown by its artifact's title, or cut to "…" when it names nothing here or several, only as far as the caller may read it (2,r,jfor a tech-note or a page,ofor a check-in or a file), the rest "not readable by you"; its decisions, each by its note, each hash in it shown so too; and who may confirm it. It holds no post's text. Threads go to a reader of the forum (2), tickets to a reader of tickets (r). From a clone's checkout it asks the server'sreceiptwho sent each question and decision, aspostdoes.consolewrites nothing. It shows a person what waits on a user, you unless named, and what runs, readingquestions' answer, and the runs of every node user an administrator's run names asstatusreads them: each not ended, and of those that ended the five the server received last, with where it is, who sent it, its user, where it stands and since when. Each entry point lays it out its own way: the web page as a page of its own, with no list of tools and no answer around it; the command line and MCP as focused text; JSON as the view's data. In your own view, holding whatpostneeds, each question waiting on you has a press ofpost --decisionper option, the recommended first, and one for your own words, and each you may close a press to confirm it answered: a button on the page, which comes back to console onceposthas written, and in the text the call that makes it, said once for each question: the command line, or over MCPocx_postwith its input as JSON. No hash is shown but in a link or a press. From a clone's checkout it shows no runs without--node; with that flag it reads this machine's care through the last completed pull.threadwrites nothing. Given the hash, or a prefix of it, of any post of a thread or any change of a ticket, such as a run's, it reads each post of that thread, or each change of that ticket that adds text, OCX messages included, oldest first in the order the server received them: its hash, the user the server received it from, when its writer's clock says it was written, and its text; at most 20, after a post or change the server has received. From a clone's checkout it pulls first, refusing a pull that does not reach the server, and asks the server'sreceiptwho sent each, a write the server has not received coming last, from no one; it refuses when the server lets no one read what the clone pulled from it (its user nobody lacks Read,o), sincereceiptanswers as to anyone. On the server it reads the server's own receipts, a private post, such as one awaiting moderation, only for one holding Private (x). A run's program may read with it what was said before the post it is given (protocol v1, section 9).auditwrites a verdict:passorfail, a note, and the objective it was judged against (verdicts).unauditedwrites nothing. It lists the public check-ins that change files, on one branch or every branch, that noauditedverdict that counts has judged, by the reading rules, pass or fail alike: oldest first in the order the server received them, at most 50, and how many there are. It reads every verdict's tag change from the control artifacts themselves, never only the latest Fossil shows, and who sent each from the server's own receipts; from a clone's checkout it asks the server's ownunaudited, unsigned, asreceiptis asked, so it lists only for a server whose user nobody holds Read (o). A reviewer's session reads with it the check-ins from before its run, which it is not given (protocol v1, section 9).receiptwrites nothing. Given the hashes of artifacts, it says of each the user the server received it from, that user's capabilities there, the number of the server's receipt and the artifact's row number, which order what the server received, or that the server has not received it; given a user, that user's capabilities there, and whether it holds the wiki edits they save, or the ticket changes they make in its pages, for a moderator. It never says the address an artifact came from, nor anything of one its caller may not read. It answers on the server; nodes and readers on clones ask it (Fossil, senders and nodes, section 3): a node signed in as its login through Fossil's login page, a POST ofuandpto/login, whose cookie signs later requests in, and a reader unsigned, as anyone; each with a POST to/ext/ocx2-cgi/receiptwhose body, never the URL, holdsjson=onandartifacts=HASH+HASHorcapabilities_of=USER, answered in full within ten seconds in the JSON every tool answers in.receipton a clone refuses an answer of other artifacts or another user than it asked.daemonserves this machine's clones under a service manager. The directoryROOT/node/credentialsnames projects: eachNAME.jsonholds the server URL and usesROOT/node/clones/NAME.fossil. At start and each minute it checks node capabilities, collects approvals and creates missing clones. It pulls whole before deciding, publishes completion numbers and hands unsettled runs to watchers, then waits on Fossil's chat. It runs on the command line alone (USAGE.md, "Run a node").watch RUN SERVER CREDENTIALS --repository CLONE [--by-hand]watches one run on the agent machine, holding its lock, keeping its state, deciding again, launching if allowed and posting through Fossil's pages. It gives session arrivals once, in server order at completed pulls, and acts on stops. Normally the daemon orrunstarts it. CGI and MCP withhold it.hookinstalls Fossil's own%F git export --if-mirrored -R %R, replacing oldocx2-hookcommands;unhookremoves both, leaving other hooks alone. They need setup on the served repository, no node user or release root, and are withheld from MCP. They schedule no run-work.register,approveandcollectlet someone ask for a login, which an admin may approve from the asker's link, and then collect its password with the asker's code (USAGE.md, "Ask for a login").status [--node]writes nothing. It shows the caller, release, export hook and chat timeline setting, readable open runs for every node user an administrator's run names, and the daemon's last logged round. With a clone's project password file it signs in as that node user, shows its server-code and enforced limits, and reads local care through the last completed pull; setup also sees local processes. The served view reads the record alone.tag_messageswrites only tags: it reads every post and ticket change holding an OCX message, and tags each that lacks theocx-messagetag, or carries a wrong value (Fossil, section 2), in one control artifact, as the caller, who needs Check-In (i) and no hook. On the server, from the web page or its host's command line naming it, the server receives the tags from the caller; from a clone's checkout it pulls first, tags in the clone and pushes, aspostdoes. Where every message carries its tag it writes nothing. It decides nothing about any run: a tag only chooses what is read.
Where they are offered, and what they answer
The command line, the web page and MCP offer every tool, but the web page has
no thread, since a person reads in Fossil's own forum and ticket pages
(the OCX page, /ext/ocx2-cgi, offers post as a card, and console, a
page of its own its header links, whose presses write the viewer's
decision with post), no stage, which would run a checkout's own code as
the web server's account, and no commit_and_sync, context, find, read,
edit, test, save, wiki_read, wiki_edit, unversioned_list,
unversioned_get or unversioned_put, which act on the caller's checkout;
and run, daemon, watch,
register and attach are offered on the command line alone, on their own
hosts; MCP has no approve or collect, since approving a login is a
person's decision and only its asker collects its password, no secret,
which a person sets, and no hook, unhook, export or project, since a
run's sandbox has no served repository. Each tool checks its
input before anything happens: naming a field it does not know is refused,
except the run's own keys given to create, which it writes as they are, and
so is any text, a field's name or its value, that is not UTF-8 or holds a
NUL; the refusal names the field. create's JSON fields, and a pattern's,
holding such text once their escapes are decoded, as \u0000 is a NUL, are
refused as a node refuses the run they make
(protocol v1, section 11, row 2), naming its
field.
Every tool takes dry_run, which checks everything and writes nothing, and
every tool answers in one shape: {"ok", "tool", "dry_run", "log", "result",
"stopped", "next_step", "took_ms"}.
result is the tool's output, once it has run to the end:
- for
create,stop,postandaudit, the hash of what it wrote, and forcreate, also where it was written and any user made; - for
daemon, the clones served and unapproved entries; - for
watch, the reports, any failure and whether the run waited; - for
thread, where it read, the thread or the ticket, its posts or changes, and how many more follow; - for
unaudited, each check-in listed with its branch, user and comment, and how many there are; - for
receipt, for each hash, its sender, their capabilities and the receipt's number, or that the server has not received it; for each user, their capabilities, and whether their wiki edits and ticket changes wait for a moderator; - for
questions, the questions as data, each with its fields, references described, decisions and who may confirm it; - for
console, a person's view: the questions, each with presses ofpost, then the record's runs; - for
run, the full run hash and the runs handed to a watcher; - for
status, what it says; - for
tag_messages, each kind of message it tagged, with the artifacts it tagged as holding one.
stopped says why it did not run to the end, naming the field at fault.
Why: Clarity (typed input, one answer shape), Loose Coupling (the same tools from every place, and none required), Demonstrability (the dry run).