Login
Protocol version 2, proposed
Login

Written against the hook and poll design, which the daemon replaced (How a post reaches an agent); what it says of today's code is not current.

A proposal awaiting the maintainer, 2026-10-17. Nothing of it is built. The maintainer's direction: "fine to bump version. ok to forget version 1. just stop overloading "node". clone was better. use fossil terms in all cases a fossil term will work. use battery to validate definitions." Its password step follows their note of the same day: "using local secrets, like $$password$$ makes a lot of sense. the point is to try to grow clarity."

How it was made: two independent drafts, one starting from Fossil's words and one from a newcomer's reading, judged against each other (35 of 50 against 29); the better one, with six things taken from the other, then read by local models (section 5). The drafts, the judgement and every model's answers are in the tech-note.

Every word or name new in version 2 is marked NEW TERM and needs the maintainer's approval. Everything else is Fossil's word, a word the maintainer approved on 2026-10-13, or plain English. Fossil's words keep Fossil 2.27's meaning (fossil-scm.org/home/doc/trunk/www/: glossary.md, concepts.wiki, sync.wiki, caps/ref.html, hooks.md, backoffice.md, unvers.wiki; fossil help).

0. Decided since the first draft

1. Vocabulary

1.1 The words of version 2

Each meaning is written in version 2's words only. "Replaces" names the version 1 word, so a reader can map old text.

Word Meaning in version 2 Source Replaces
repository one Fossil database file holding a project's history Fossil
clone a repository made from another with fossil clone Fossil
server the Fossil server at the project's URL: "a publicly hosted Fossil server providing synchronization" (the maintainer) Fossil (fossil server); NEW TERM since version 1, still awaiting approval "the server" for its repository or its host
the server's repository the repository the server serves, which every clone syncs with (Fossil: every clone's "parent repository") Fossil "the server", "the served repository"
server-code 40 random hex digits Fossil gives a repository file when fossil new or a clone over HTTP makes it (config row server-code); a copy of the file keeps it Fossil
project code 40 hex digits every repository of one project shares Fossil
user Fossil's account (fossil user); a person or a program acts as one Fossil also "person", "Linux account"
login a user's name Fossil also "the node's login"
default user the user Fossil's command line acts as on a repository (fossil user default; -U) Fossil
capability, admin (a), setup (s) Fossil's letters on a user; the outer limit of what it may do Fossil
receipt the server's record of the user it received an artifact from, with the time Fossil (/rcvfromlist)
artifact, hash, check-in, checkout, branch, tag, wiki page, forum post, thread, ticket, ticket change, unversioned file Fossil's records Fossil
sync, push, pull moving artifacts between repositories Fossil
backoffice, after-receive hook Fossil's work after a page answers, and the command it runs Fossil
R a capability letter Fossil does not define, which OCX reads as "may send runs" Fossil's letter, OCX's meaning
host a computer holding a repository OCX acts on plain "machine", "node" (a computer)
the server's host the host the server runs on plain "the server" (its host)
host account a Linux account on a host NEW TERM "the node's account", "user" (Linux)
person a human plain "user" (a human)
OCX message a JSON block in a forum post or a ticket change: run, stop, started, ended approved
run an OCX message whose content is run; its hash names it approved also the tool run
the run's clone the repository the run's key clone names, which is to act on the run: a clone on any host, or the server's repository NEW TERM "the node"
OCX on the run's clone OCX acting on a run: on the server's repository through the hook, on a clone on another host through poll plain, from the words above "the node" (the actor)
the clone's user the Fossil user OCX acts as on the run's clone, named in the run's to; its reports must be received from it. On a clone poll made, that clone's default user; on the server's repository, the user the hook was installed with NEW TERM "the node's login", key node, "node user"
the process's user the Fossil user a run's process acts as, named in process.user NEW TERM "run user", "the run's user"
the process's clone the new clone the workspace step clone makes in the run's workspace, signed in as the process's user NEW TERM "the run's own clone"
the clone's owner whoever may write ROOT/settings/ on the clone's host; that person chooses the clone's user NEW TERM "the node's owner"
envelope, value, step, process, kept logs, manual run, layer as approved on 2026-10-13; "layer" as 2.0 gives it approved
to the envelope's key naming the user asked to act NEW TERM the key node
re the envelope's key naming the message answered, by hash NEW TERM the key run in a stop or report
publish a kind: a request that OCX publish a run's results again from its kept workspace NEW TERM
content what a message carries under its one kind key, read by layer 3 plain the flat keys of a run
in OCX's care a run OCX is preparing, running or publishing: from just before its workspace is made until its last publication is written approved ("in its care")
session, objective, pattern, subscription, delivery, sandbox, limits, workspace, verdict as defined in section 2 existing
watcher the OCX process, ocx2-hook --watch, that holds one run from before its workspace to its last publication approved 2026-10-22 (HISTORY.md decision 103)
hook OCX's after-receive hook, ocx2-hook Fossil's word
owner used only in "the clone's owner" "the node's owner"; the Linux owner of a file

Dropped words:

1.2 Each overload today, and how it goes

Word Its senses today Version 2
node the actor; the key node (a login); "a node's login"; a computer ("nodes on other hosts"); $$node$$; ROOT/node/; --node on create, the installed hook and the watcher; ends_with_node; config rows ocx-node-key-; the code module Node gone. The actor is OCX on the run's clone; the login is the clone's user (the envelope's to, $$clone_user$$); a computer is a host; the rest are renamed in section 3
clone a repository made by fossil clone; the run key clone (a server-code prefix); the report key clone; the step clone; the value $$clone$$ Fossil's sense only. The key clone names the run's clone; the step clone makes the process's clone; its path is $$process_clone$$. One stretch, stated in 2.4: the run's clone may be the server's repository, which no fossil clone made. Fossil's glossary itself says "all project information resides in each clone of the repository"
user a Fossil user; process.user; "node user"; a person; a Linux account (sandbox uid); the CLI's --user and create --user a Fossil user only, always saying whose: the clone's user, the process's user. A human is a person, a Linux account a host account. create --user becomes --process-user
login a user's name; "the node's login" (a user); signing in a user's name only. Signing in is "sign in"; Fossil's page keeps its name /login. --login LOGIN names a login on register, poll, hook and the watcher alike
default user Fossil's; the fossil-first draft's "repository's default user" Fossil's only. poll now sets it on the clone it makes (2.5)
layer a level of a run; "OCX as a layer over Fossil" one of the protocol's four layers only (2.0): Fossil, envelope, content, patterns
check "the node's check"; poll --check; "a program's check" (ci); the gate's checks; check-in "reading every open run" (--all); a ci verdict is "a program's judgement"; the gate's checks stay the gate's, outside the protocol; check-in is Fossil's
server the Fossil server; its repository; its host; "staging server" the server; the server's repository; the server's host. A deployment's own host and address are no protocol word: its instructions name them, and examples use placeholders
run the message; the tool run; "run user"; a call of the hook the message only. The tool is start (NEW TERM); the run user is the process's user; the hook has calls
files step files; sandbox files; limit files step files only; created_files; file_size
capabilities Fossil's letters; the sandbox's Linux capabilities Fossil's only; linux_capabilities
session a run with process.session true; a Linux session (own_session) the run only; isolate_terminal
checkout Fossil's checkout (a directory); $$checkout$$ (a check-in's hash) the directory only, as $$tree$$; the hash is $$checkin$$
project Fossil's project; $$project$$ (the last part of the server's URL) Fossil's only; $$repository_name$$
owner "the node's owner"; a file's Linux owner; the maintainer's "a clone to have an owner" the clone's owner only

2. Protocol version 2

The node layer, one owner for each release root, woken by events, is proposed in its own draft. The protocol itself, written whole in version 2's words, is in two files: messages, senders, the key clone, users, values and the workspace (sections 2.1 to 2.7), and the sandbox, limits, process, subscriptions, a run's life, refusals and verdicts (sections 2.8 to 2.19).

3. Tools, options and names on disk

Today Version 2 Why
create --node LOGIN create --to LOGIN NEW TERM fills the envelope's to
create --clone PREFIX create --clone SERVER-CODE, in full fills the run's clone
(none) create --reset-password NEW TERM sets a new random password on an existing process's user and keeps it, when the sender asks
create --user USER create --process-user LOGIN NEW TERM fills process.user; the CLI's own --user stays Fossil's sense, the user the tool acts as
create with no node: "this host's node" with neither --clone nor --to: the server's repository's server-code and the hook's user, written into the run in full nothing left implicit in the message
create --pattern, --title, --to, --ticket, --objective, --fields unchanged; create refuses a pattern holding a version 1 key
run RUN, MCP ocx_run, the web page's run start RUN, MCP ocx_start, web page start NEW TERM the message keeps "run"; this starts a manual run. If not approved, the tool stays run
stop, post, audit, receipt, attach, secret, project, export, the release tools unchanged they name no node
status shows the repository's server-code, the clone's user, and the limits OCX enforces a sender copies clone from it
register SERVER-URL FILE --login LOGIN --capabilities LETTERS, approve LOGIN KEY CAPABILITIES, collect unchanged (approved)
poll ... [--login LOGIN] [--capabilities LETTERS] [--check] poll ... [--login LOGIN] [--capabilities LETTERS] [--all] NEW TERM; after making its clone it sets LOGIN as the clone's default user --all reads every open run
hook [--login LOGIN], unhook unchanged
installed hook: ROOT/ocx2-hook --log ROOT/node/hook.log --node LOGIN %R ROOT/ocx2-hook --log ROOT/hook.log --login LOGIN %R; hook replaces a command carrying --node one option name for the clone's user everywhere
watcher: ocx2-hook --watch RUN --node LOGIN ocx2-hook --watch RUN --login LOGIN
ROOT/node/ ROOT/care/ NEW TERM (OCX writes) and ROOT/settings/ NEW TERM (the clone's owner writes) one directory held two things and no name for either
r-senders.json in the release, from the tree (HISTORY.md decision 105) capability-R.json NEW TERM, in the release; its sandbox key capabilities becomes linux_capabilities names Fossil's capability
ROOT/node/unconfined ROOT/settings/unconfined
ROOT/node/hook.log ROOT/hook.log, a line per call of the hook
ROOT/node/round.lock ROOT/care/round.lock
ROOT/node/runs/RUN.lock, .inbox, .workspace, .log ROOT/care/RUN.lock, .inbox, .workspace, .log runs in OCX's care
ROOT/node/users/USER.lock removed: several runs of one process's user may run at once (2.5)
passwords file {"user", "password", "runs": {USER: PASSWORD}} {"clone_user", "password", "code"} NEW TERM each key says whose; a process's user's password is collected by each run, never kept on the host
a clone's host reading a run user's password from its file, which a person filled the step password collecting it with collect, after create approved it the existing approve and collect; no new tool
config rows ocx-node-key-LOGIN ocx-register-key-LOGIN NEW TERM the code register asked with
a workspace on disk ROOT/agents/USER/projects/PROJECT/RUN unchanged on disk; patterns write it with $$process_user$$ and $$repository_name$$
USAGE headings "Ask for a login", "Add a node on another host", "Be a node on another host" "Ask for a user", "Add a clone on another host", "Act on runs from a clone on another host"

4. Five sentences for a newcomer

  1. A person or program holding admin or setup on the server, or holding R within what a clone's owner allows, asks for work by posting a run: a JSON block in a forum post or ticket change.
  2. A run's envelope names in to the Fossil user asked to act, and its content names in clone the repository, by its full server-code; OCX on that repository, the server's through its hook or a clone through poll, acts on the run only if both are its own, and every other repository does nothing with it.
  3. The run's process acts as its own Fossil user, process.user, which is never a clone's user and never admin or setup, inside the workspace, sandbox and limits the run states in full.
  4. OCX writes started and ended as the clone's user, whose capabilities on the server, chosen by the clone's owner, are the most OCX on that clone can do.
  5. Who sent anything is the user the server's receipt names, never a name in the message, and an answer counts only when that receipt names the run's to and the answer's re is the run.

5. The battery

Each check handed a local model, through this host's Ollama with no tools and no code, Fossil's words, some sections of this design and a setting, then questions; each answer was scored against the expected answers, as the battery's definition tests were (docs/battery/defs at f68b57bd52). "Right" is the right outcome for the right reason; "partial", the right outcome for a wrong or missing reason. Haiku and Sonnet were not run.

Check Text handed Questions Gemma 31B Qwen 2.5 Coder 7B
1 sections 2.2, 2.3, 2.4, 2.5, 2.7, 2.12 and 2.14 twelve: which clone acts when two share a clone's user; a copied file; a forged ended from a user holding only i; a started from a user holding setup; a run naming its own sender as clone.user; an unauthorized run naming the right clone; a process's user that is a clone's user; works-for by server-code; what bounds OCX on a clone, and who chose it; what $$process_clone$$ is; a clone made again; who may stop a run 22 of 24 right, 2 partial (2 runs): both left out that builder is refused after a clone is made again 16 of 60 right (5 runs): the forged ended counted in 3; the setup user's started in 2; questions 6, 8 and 9 right in none
2 check 1's, its acting and counting rules rewritten as questions answered in order check 1's 21 of 24 right, 2 partial worse: the forged ended counted in 4 of 5
3 sections 2.5, 2.6, 2.7, 2.14 and 2.15, with the password step eight on the password step: where the password comes from and what the server checks; a run from a user holding R; a password written in the run; what started shows; another clone's user asking; asking again after started; whether a person presses or edits anything; the server's own repository 16 of 16 right (2 runs) 6 of 24 right, 13 partial (3 runs); no run gave the reason for a run from a user holding R, or said the server's own repository asks no tool
4 check 3's, the step's row saying both of those outright check 3's not run 8 of 24 right, 11 partial (3 runs); the same two missed in every run
5 sections 2.5 to 2.7, 2.14 and 2.15 once no run sets a password (section 0) eight: where the password comes from and whether a run changes one; a run from a user holding R; a password written in the run; what started shows; collecting with another clone's code; two runs of one user on two hosts at once; whether a person presses or edits anything; a later run of the same user 14 of 16 right, 2 partial (2 runs): both gave each host's own lock, not the unchanged password, as why two hosts' runs don't interfere 12 of 24 right (3 runs)

So the text in the draft is check 1's, and check 5's for the password step. Question 8 of checks 1 and 2 asked about a rule removed since: a process's user bound to the first clone that ran it. Checks 3 and 4 read the password step as it was then, setting a fresh password at each run; section 0 says why it changed. Gemma 31B reads the definitions whole. Qwen 7B does not apply the rules from text in any form tried, as in the battery's batches 5 and 6. OCX's code applies those rules; a small model in a session is never asked to, and should be handed only the sections its task needs.

6. What the implementation must touch

Code (src/ocx/):

Specs (spec/), about 492 occurrences:

Documents:

What disappears:

Demonstrations before version 2 is called built, each a spec or a scenario with an outcome read back from the server:

On hosts: on the server's host, ROOT/node/ moved to ROOT/care/ and ROOT/settings/, the hook reinstalled with hook --login; each clone's passwords file rewritten with the new keys, and poll run once to set its default user.

7. Order to build it in

Each step is its own check-in with its own specs, so the words, the behavior and what is kept on disk change in separate, demonstrated steps.

  1. The maintainer approves the new terms (or names others). Nothing is built before.
  2. docs/protocol-v2*.md, written whole from section 2, and the new GLOSSARY.md; a fresh reader checks them, as the battery does. One check-in.
  3. Messages and values: messages.cr, messages/run.cr, steps.cr, workspaces.cr, sandbox.cr, launch.cr, tasks.cr, with their specs. The version is 2 from here on.
  4. Acting and counting: node.cr to acting.cr, decisions.cr, session.cr, with the new specs of section 6.
  5. The password step: create's approval and the host's collect (2.5, 2.7), with its specs.
  6. Names on disk and options: care.cr, watcher.cr, hook.cr, bounds.cr, commands/hook.cr, commands/poll.cr (with set_default_user), commands/create.cr, run to start, status, the config rows.
  7. Every remaining "node" in comments, specs and documents; a guard spec that fails on version 1's key node, its option --node, the value $$node$$ and the path ROOT/node/ in src/ and spec/, and on the word "node" in the protocol documents and GLOSSARY.md, so the old sense does not come back; other software's uses of the word elsewhere stay.
  8. Full gate once, then stage. On the server's host: stop the open version 1 runs, move ROOT/node/, reinstall the hook, rewrite the patterns, and run one end-to-end run on the server's repository and one on a clone on another host. If the switch fails: roll the release back, move ROOT/care/ and ROOT/settings/ back to ROOT/node/, and reinstall the hook with --node.
  9. A reply in the ocx2 forum thread.