Login
Protocol version 2: Fossil, senders and clones
Login

This is the medium and authority of protocol version 2.

2.0 Layers

OCX's messages let people and agents ask for work and report on it in a Fossil repository, every request and answer kept, attributed and in order. A command, an agent or a host is one use of a message, not part of what every message is. Each layer reads only what it owns, uses only the layer below it, and hands the rest up unread.

Layer Input Responsibility Output On failure
1. Fossil artifacts sent by sync or the web stores each, named by its hash; records who sent it and in what order (its receipt); keeps posts in threads and changes on tickets; holds users and their capabilities artifacts, receipts, capabilities an artifact not received is not there to read
2. Envelope a post's or ticket change's text, and its receipt finds the message (messages); reads its version, to and re, and the one key naming its content's kind; hands the content, unread, to the reader of that kind the sender (from the receipt), the user asked to act, the message answered, the kind, the content not a message, or another version: ignored, and nothing written
3. Content one kind's content, with what layer 2 gave checks the content against its kind's table (kinds), the sender's capabilities, and a run's restrictions; acts; writes its answers as new messages whose re is the run started, ended, before publications not its own (2.4: a run's to and clone, or for an answer those of the run its re names): ignored, and nothing written; otherwise refused: an ended, outcome refused, saying why
4. Patterns a wiki page run/NAME, and what the sender adds holds one use's content: a command, an agent's arguments, a project's conventions a run's content, for create create refuses a pattern whose content layer 3 would refuse

OCX's code is layers 2 and 3; layer 1 is Fossil's, and layer 4 is data. A kind OCX does not read passes layer 2 untouched, for whatever reader it is meant for. A key layer 3 does not know, in a run, is refused, so no restriction is ever skipped because a lower layer could not read it. Nothing Fossil records is repeated in a message: who sent it is its receipt's, and where it is, its thread's or ticket's.

Fossil is the record

Fossil stores immutable artifacts named by hash. A forum edit or ticket change is a new artifact. Corrections and stops add to the record; they do not retract it. Forum threads and tickets say where a run is; its answers go there. A check-in records the files; an unversioned file can be replaced.

Every repository records its own receipts: sender, time and address. Receipts are not copied by sync. A clone's receipt for a pull names the pulling user, not the artifact's sender. An artifact's user card is its writer's claim. The server's receipt is the authority: its receipt number, then the artifact's row number, gives server order, never the writer's clock. Only OCX, its tools and host administrators write the acting repository file.

Finding messages

The envelope finds a version 2 block without reading its content. No version 1 block is read. A run, stop or report written by other means counts under the same rules.

Tools tag messages with raw ocx-message, its value the kind, and for a stop or report its re after a space. Reports posted through Fossil's pages need no tag: daemon, watcher and status read messages through a completed pull, regardless of absent, changed or cancelled tags. Questions still use the tag index; tag_messages repairs tags.

Senders and permissions

Each daemon and watcher asks the server's receipt page, signed in as the clone's user, about every artifact it decides by, including reports. It gives sender, inherited capabilities at the time of reading, and server order. A receipt that has not arrived gives no authority. If the server pulls from anywhere, it must pull as a user with none of the capabilities this protocol asks for.

Admin or setup may send runs and stops. A user holding R may send runs with the isolation its pattern sets, and stop its own runs. The run's sandbox and limits govern it; the clone needs no additional file to take it. One such run at a time is allowed under state/r-alone.lock. Refusals lists the bounds.

A process's clone syncs as the process's user. OCX reports and verdicts reach the server as the clone's user. A tool writing in a caller's checkout writes in its clone and pushes, so the server receives it as that caller. Who may read a thread, ticket or check-in is Fossil's own business.

Acting clones

A node is a host where OCX's daemon acts on runs, named by its hostname, such as x86-1 and aarch64-1. Each project has an acting clone on that host. The clone is a repository, not a node; its Fossil user is not a node.

A run's envelope to names the clone's user. Its content clone must be the acting repository's full server-code: 40 lower-case hex digits. Both must match before OCX acts; otherwise it passes by and writes nothing to Fossil. Missing or malformed addresses are passed by too. There is no actor on the server's repository in this design.

Make a clone with fossil clone, never by copying the file. A copy keeps the server-code and could act on the same run. A new clone has a new code; send a new run for it. Several clones may share a user because every run names its clone. All those clones share that user's authority: a report's receipt, not its repository, proves who wrote it.

A report counts only on the thread or ticket holding the run, if its re is the run and its sender is the run's to. A started also requires the run's sender to be a different user holding admin, setup or R. An ended needs no such sender, so a refusal counts. Admin's report sent as admin does not count for another user's run. The first counted started and ended, in server order, are used. The acting clone also knows its own writes before the server receives them. A launched run whose sender loses permission still must be stopped or answered lost; that revocation does not permit another launch.

Users and passwords

The clone's owner chooses the clone's user. The daemon requires g, o, C, 4 and w on the server, and unmoderated ticket writing, never admin or setup. i permits verdicts; y permits unversioned files. The clone's user is its local default user, holding setup in its own clone. The daemon keeps a named remote ocx-server for complete pulls, verdicts and files.

The process's user is named in process.user. It holds neither admin nor setup and is never the clone's user or another known clone's user. The watcher refuses any login ever named as a run's to, regardless of sender, and any login holding every node letter goC4w, inherited letters included. At create, the check also includes published clone files and local daemon entries. A build taking only files needs no Fossil account.

For a workspace that signs in, admin's create makes a missing process's user with a random password and approves it for the run's to. An existing kept password is approved unchanged for that login too. --reset-password explicitly resets an existing user's password; an existing remote user's password OCX does not keep requires that reset. Fossil's built-in users and clone users are never changed by this step. Approval and reset, including approve's reads and writes, hold the same lock beside the served repository. approve refuses a user create made: its approval has collectors but no registration code key. Approval reads fall back to the pre-rename ocx-node-key-LOGIN rows (decision 76 in HISTORY.md); the next write moves the row to ocx-register-key-LOGIN. A current row takes precedence.

The password step collects afresh through collect, signed in as the approved clone's user. That login can collect without a code; registration's code remains how an asker collects its own login. No run changes a password. The step holds it privately for clone, which remembers it in the process's new clone. It sets no value and writes nothing in started. A supplied password key or $$password$$ is refused.

The credentials reader retains the older runs map. It uses a local password from that map only when collect explicitly says the user has no approval for this login, including a registration whose for is empty; an approval permitting collection always wins. Thus older local credentials can still work, but cannot hide a failed request or override an approved reset. There is no per-user lock or binding to a clone. Several runs of one process's user may sign in at once on several hosts. An explicit reset invalidates the old password those processes hold, as a reset means to.

Published clone addresses

When its user holds y, the daemon publishes an unversioned file ocx-clones/LOGIN/SERVER-CODE.json holding {"login": "LOGIN", "clones": ["SERVER-CODE"]}, then syncs it. It holds public identities only, never passwords.

With no explicit clone, create uses the one local daemon address for the project and its user, when available. For an explicitly named recipient elsewhere it reads the published files. Only a file whose current bytes the server received from the login in its name counts; others are ignored, with that reason in a refusal when no trusted file remains. Exactly one trusted file must name exactly one clone for that login, with matching path and content. None, several, or malformed content require an explicit full server-code. It never defaults to the served repository's code where no daemon acts. From a checkout its default is that checkout's own clone code. Stale published files can therefore require the caller to choose.

What is kept on the host

Path Holds
ROOT/settings/credentials/NAME.json project server URL, user, password, registration code and requested capabilities; older runs map is still read
ROOT/settings/unconfined owner's permission to run without a sandbox
ROOT/state/clones/NAME.fossil the acting clone
ROOT/state/daemon.lock, daemon.log one daemon on the host, and its rounds
ROOT/state/round.lock, r-alone.lock serialized decisions, and one run from R alone
ROOT/state/completed/SERVER-CODE highest receipt of a whole pull, published by rename
ROOT/state/runs/RUN.lock, .state the watcher's lock and durable taken, ending or done state
ROOT/state/runs/RUN.state.publications durable values, kept log text and completed publication items; publish requests have an .answered marker beside them
ROOT/state/runs/RUN.inbox, .terminal session pipe and terminal socket
ROOT/state/runs/RUN.workspace, .log workspace path and watcher log
the run's directory its workspace, kept unless removal once saved succeeds

Only the host account may read private credentials, care and workspaces. Settings belong to the clone's owner; runtime state belongs to OCX. A nonempty old version 1 root directory is refused: stop its processes, move credentials and unconfined permission to settings and runtime files to care before starting the daemon. No user lock is made or consulted.

Verdicts and versions

Verdicts defines which judgements count. Stability defines additions within version 2. Server tool answers tolerate fields added by a newer server, nested result fields included. The fields needed by the current reader remain required; receipt answers for other artifacts or users are refused.