{
  "as_of": "f3a128266d",
  "schema": "docs/survey/functionality.schema.json",
  "behaviors": [
    {
      "name": "Reach Fossil and git through named operations",
      "event": "person: any tool, at the command line, on the web page or through MCP, that reads or writes a repository; the hook and the git export likewise",
      "purpose": "Keep Fossil and git replaceable: callers ask for operations named for what they do, and another implementation, such as a Crystal one reading a clone's database directly, takes over without any caller changing (README.md, Loose Coupling; ROADMAP.md, Fossil).",
      "shape": "Fossil::Place's operations, by what they do: settings and logins, a ticket's changes, a thread's posts, the ocx-message tag on each artifact holding an OCX message, read and added, each post, ticket change or control artifact of tags OCX composes stored whole, with its tag, by one fossil command, check-ins and tags with who wrote each, clones, checkouts and syncs, and the git export; the fossil program implements them on the host or in a sandbox through a private transport, a command that met a writer outside OCX holding the repository, storing nothing, run again once Fossil has waited, outside OCX's lock beside the repository, for that writer to let go, within two stated bounds, and Crystal reads a checkout's database directly, query-only, held to the same contract, its SQL and artifact formats in src/ocx/fossil/ alone; git's two operations, the refs offered and the pack sent.",
      "parts": [
        "src/ocx/fossil.cr",
        "src/ocx/fossil/repository.cr",
        "src/ocx/fossil/tickets.cr",
        "src/ocx/fossil/forum.cr",
        "src/ocx/fossil/stored.cr",
        "src/ocx/fossil/message_tags.cr",
        "src/ocx/fossil/checkins.cr",
        "src/ocx/fossil/sync.cr",
        "src/ocx/fossil/direct.cr",
        "src/ocx/git.cr"
      ],
      "origin": "The maintainer, 2026-10-07: Fossil.run exposed no operation that says what it does, so there was no direct way to make Fossil replaceable; precept I7's \"the function that wraps it, which is where another implementation takes over\".",
      "reads": [
        "a repository, a clone or a checkout, through fossil",
        "a git export, through git"
      ],
      "writes": [
        "ticket changes, forum posts, tags, check-ins, logins' passwords and hooks, through fossil"
      ],
      "specs": [
        "spec/ocx/fossil_spec.cr",
        "spec/guards/external_programs_spec.cr",
        "spec/ocx/command_spec.cr",
        "spec/ocx/hook_spec.cr",
        "spec/ocx/message_tags_spec.cr"
      ],
      "used_by": [
        "every tool",
        "the hook",
        "the git export"
      ],
      "state": "demonstrated",
      "coupling": "Fossil 2.27's command line, its SQL schema, its forum, ticket and control artifact formats and its bundle file, and git 2.x's upload-pack, each in its own module."
    },
    {
      "name": "Stage a release",
      "event": "person: bin/ocx2 stage CHECKOUT | import RUN | accept | rollback | release | follow SERVER --root ROOT",
      "purpose": "Offer a gated, built and smoked copy of a committed check-in's programs for a person to accept, keeping the previous release for rollback.",
      "shape": "DIR/staged/NAME holding built programs, gate.txt and an inventory; stage builds a checkout, while import counts a builder's run and reports by server receipts, checks shared files and copies and smokes them before offering next. Import removes the three shared files. Accept copies next into DIR and moves current and previous; rollback swaps them. All hold one root lock; dry runs write nothing. Release reads current and previous, their names and inventories, and listed files as base64, for signed-in setup logins or owner-listed builders; it never writes. Follow is a command-line step for the client root's owner: sign in as the daemon's clone user, read current, fetch missing files and check all hashes before accepting and serving, keeping previous; an already current release changes nothing, and a previous release needs no fetch. The person restarts with confine daemon.",
      "parts": [
        "src/ocx/staging.cr",
        "src/ocx/importing.cr",
        "src/ocx/commands/release_import.cr",
        "src/ocx/staging_checkout.cr",
        "src/ocx/releases.cr",
        "src/ocx/worktree.cr",
        "src/ocx/commands/release.cr",
        "src/ocx/commands/release_operations.cr",
        "src/ocx/commands/release_read.cr",
        "src/ocx/commands/follow.cr",
        "src/ocx/server/release.cr"
      ],
      "origin": "Slice 0.5 of docs/slices.md (stone, ba2c79940b), rebuilt from the reference tools/deploy.cr and HISTORY.md decisions 19 and 21; commands of the one program since slice 1.",
      "reads": [
        "the checkout and its uncommitted changes",
        "shard.yml",
        "the built programs in bin"
      ],
      "writes": [
        "a release directory under DIR/staged",
        "the next, current and previous links"
      ],
      "specs": [
        "spec/ocx/staging_spec.cr",
        "spec/ocx/release_commands_spec.cr",
        "spec/ocx/release_import_spec.cr",
        "spec/ocx/ci_commands_spec.cr",
        "spec/guards/provenance_spec.cr",
        "spec/ocx/release_read_spec.cr",
        "spec/ocx/follow_spec.cr"
      ],
      "used_by": [
        "the stager",
        "the release root's owner"
      ],
      "state": "demonstrated",
      "coupling": "crystal and shards in the checkout, fossil for the check-in, and the release root's layout."
    },
    {
      "name": "Run the one program",
      "event": "person: bin/ocx2 [--json] [--repository REPOSITORY] [--user USER] [TOOL [ARGUMENTS] [--dry-run]] [-- WORDS]",
      "purpose": "Reach every command from a terminal, as text or JSON, and see usage and status with no command.",
      "shape": "Each tool a typed definition: its input, output and the context it receives are elements whose JSON and shapes are derived from their types, and its one method performs every operation through a log that honors the dry-run flag in one place. A field's name or value, a flag or the tool's name that is not UTF-8 or holds a NUL is refused, naming it, before any tool reads it. Every answer carries that log of typed operations, the result only when the tool ran to the end, and why it stopped, an operation that failed other than by a refusal named by its error's first line alone. No tool named is the list, the tools with the derived shape of each input, which MCP's tools/list renders; help adds the output, context and answer shapes; status shows the context as resolved. The entry point restores inherited standard descriptor flags on exit, including explicit exit, preserving both blocking and non-blocking pipes.",
      "parts": [
        "src/ocx/refusal.cr",
        "src/ocx/elements.cr",
        "src/ocx/shape.cr",
        "src/ocx/log.cr",
        "src/ocx/command.cr",
        "src/ocx/commands.cr",
        "src/ocx/text.cr",
        "src/ocx/cli.cr",
        "src/ocx/entry.cr",
        "src/ocx/fossil.cr",
        "src/ocx/commands/list.cr",
        "src/ocx/commands/status.cr",
        "tools/ocx2.cr",
        "tools/stdio.cr"
      ],
      "origin": "Slice 1 of docs/slices.md (ec2-user, a001dc306e; stone, 16a5a0e43d, 7d1ff175d5, b11f0b92af).",
      "reads": [
        "the arguments",
        "the environment's names, and a CGI request's fields by name"
      ],
      "writes": [
        "standard output and error"
      ],
      "specs": [
        "spec/ocx/command_spec.cr",
        "spec/ocx/elements_spec.cr",
        "spec/ocx/dry_run_spec.cr",
        "spec/guards/typing_spec.cr",
        "spec/runners/stdio_spec.cr"
      ],
      "used_by": [
        "people at a terminal",
        "scripts"
      ],
      "state": "demonstrated",
      "coupling": "Every command class, found by walking Command's subclasses."
    },
    {
      "name": "Echo the input",
      "event": "person: bin/ocx2 echo WORD [--option OPTION] [--flag], or the same through the CGI or MCP",
      "purpose": "Show that each way in delivers the same arguments, by answering with exactly what was read.",
      "shape": "One argument of each kind (a positional word, an option's value, a switch) answered as read, with how the program was started and the caller's login and capabilities; changes nothing; anyone may run it; a missing argument is refused by name with the usage line.",
      "parts": [
        "src/ocx/commands/echo.cr"
      ],
      "origin": "Slice 0.5 of docs/slices.md, \"The one tool: what was given\"; stone asked for it in session, 2026-10-05.",
      "reads": [
        "the arguments"
      ],
      "writes": [
        "standard output"
      ],
      "specs": [
        "spec/ocx/harness_spec.cr"
      ],
      "used_by": [
        "the harness",
        "anyone checking a way in"
      ],
      "state": "demonstrated",
      "coupling": "None beyond the command frame."
    },
    {
      "name": "Serve the commands as pages",
      "event": "request: GET or POST ext/ocx2-cgi[/COMMAND]",
      "purpose": "Give a browser, or Stone asking for JSON, every command as Fossil's own pages do, as the viewer Fossil authenticated.",
      "shape": "The facts Fossil and the server set; the list, each command as a card with its form, the capabilities it needs marked for the viewer and what it would do now, its header linking console, a page of its own, of which it draws no card, drawing nothing a command does not answer; or a command's answer, its result before its log, and its own card, inside Fossil's skin, or the command's JSON; a command that writes nothing taken from any request, one that may change something only by a POST from OCX's own page, never from another page of the site, such as a file a user committed, which Fossil serves under /doc (HISTORY.md decision 111).",
      "parts": [
        "src/ocx/cgi.cr",
        "src/ocx/markdown.cr",
        "src/ocx/page.cr"
      ],
      "origin": "Slice 1 of docs/slices.md.",
      "reads": [
        "Fossil's CGI fields for the request and viewer"
      ],
      "writes": [
        "the HTTP answer",
        "an audited tag on the served repository",
        "an answer to a question, a post or ticket change as the viewer"
      ],
      "specs": [
        "spec/ocx/styles_spec.cr",
        "spec/ocx/elements_spec.cr",
        "spec/ocx/harness_spec.cr"
      ],
      "used_by": [
        "people in a browser",
        "Stone"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's extension root and its CGI fields."
    },
    {
      "name": "Offer the commands as MCP tools",
      "event": "session: bin/ocx2-mcp, or bin/ocx2 --mcp as an agent's configuration names it, on standard input and output; or bin/ocx2 --mcp-http HOST:PORT, each message an HTTP POST to /mcp on loopback; or bin/ocx2 --mcp-tunnel TUNNEL-ID, its key in OCX_TUNNEL_KEY, long-polling a provider's tunnel; or bin/ocx2 --mcp-ollama URL --model NAME --steps N --system TEXT, a run's command, a local model at an Ollama server its caller",
      "purpose": "Give an agent every command as a tool with its schema, answering with the same JSON; and give a local model the checkout's tools alone as OCX's own agent, its run's objective worked, each reply printed before its calls run and each answer after, and its last words posted as the run's user.",
      "shape": "JSON-RPC 2.0, one message a line: initialize, tools/list (ocx.NAME with the Input as schema) and tools/call (text, structured JSON and isError); a JSON configuration's entry made here, at the edge, for a runner that keeps its MCP servers in JSON.",
      "parts": [
        "src/ocx/mcp.cr",
        "src/ocx/mcp_http.cr",
        "src/ocx/mcp_tunnel.cr",
        "src/ocx/mcp_ollama.cr",
        "src/ocx/ollama.cr"
      ],
      "origin": "Slice 1 of docs/slices.md; trunk's src/mcp_server.cr.",
      "reads": [
        "JSON-RPC messages",
        "a run's line and a delivery's, on standard input",
        "an Ollama server's chat replies"
      ],
      "writes": [
        "JSON-RPC answers",
        "each reply and each answer of a model's exchange, a JSON line on standard output",
        "the model's last words, a post or ticket change as the run's user"
      ],
      "specs": [
        "spec/ocx/mcp_spec.cr",
        "spec/ocx/harness_spec.cr",
        "spec/ocx/mcp_http_spec.cr",
        "spec/ocx/mcp_tunnel_spec.cr",
        "spec/ocx/mcp_ollama_spec.cr"
      ],
      "used_by": [
        "agents",
        "local models, as a run's command"
      ],
      "state": "demonstrated",
      "coupling": "The MCP protocol version 2024-11-05. Ollama's /api/chat, not streamed, with tool calls."
    },
    {
      "name": "Answer and run protocol v1's runs for a node",
      "event": "host: the daemon's whole pull after a chat message or empty answer, and once at each start; watcher: a completed pull or the run's process ending",
      "purpose": "Be the node a run names: answer each run for it that it may not or cannot start, that a stop came before, or whose program is lost, so that no run is left open and none is answered twice; run the rest, giving each session what it subscribes to.",
      "shape": "One daemon per machine pulls complete clones, publishes completion numbers and decides every unsettled run. Each detached watch command holds its run lock, keeps taken, ending and done states, posts through Fossil's pages and gives each new arrival once in server order. Waiting runs are evaluated again in later daemon rounds.",
      "parts": [
        "src/ocx/acting.cr",
        "src/ocx/server.cr",
        "src/ocx/exchange.cr",
        "src/ocx/watcher.cr",
        "src/ocx/decisions.cr",
        "src/ocx/bounds.cr",
        "src/ocx/messages.cr",
        "src/ocx/fossil/said.cr",
        "src/ocx/session.cr",
        "src/ocx/workspaces.cr",
        "src/ocx/sandbox.cr",
        "src/ocx/messages/run.cr",
        "src/ocx/steps.cr",
        "src/ocx/launch.cr",
        "src/ocx/acting/view.cr",
        "src/ocx/acting/sharing.cr",
        "src/ocx/care.cr",
        "src/ocx/relay.cr",
        "src/ocx/stopping.cr",
        "src/ocx/terminal.cr",
        "src/ocx/terminal/typed.cr",
        "src/ocx/commands/watch.cr",
        "src/ocx/publication.cr"
      ],
      "origin": "docs/slices-v1.md, slices v1.1 to v1.3, v1.5 and v1.6: the maintainer at the terminal, 2026-10-12, asked for protocol v1 to be built with its failure cases as acceptance tests.",
      "reads": [
        "every public protocol message up to a complete pull's highest receipt, and the server's receipts for their senders",
        "what each sender may do, as Fossil grants it",
        "the posts, ticket changes and check-ins Fossil lists, each check-in's branch, and their receipts",
        "for a run from a user holding R alone, the run isolation rules (HISTORY.md decision 132)"
      ],
      "writes": [
        "run states, completion numbers and daemon.log beneath ROOT/state",
        "reports through /forume2 and /tktedit as the node user",
        "verdict tags pushed once to ocx-server and unversioned shares synced there"
      ],
      "specs": [
        "spec/ocx/acting_spec.cr",
        "spec/ocx/daemon_review_reports_spec.cr",
        "spec/ocx/care_spec.cr",
        "spec/ocx/watcher_spec.cr",
        "spec/ocx/turned_away_spec.cr",
        "spec/ocx/ending_spec.cr",
        "spec/ocx/workspaces_spec.cr",
        "spec/ocx/program_spec.cr",
        "spec/ocx/decisions_spec.cr",
        "spec/ocx/steps_spec.cr",
        "spec/ocx/examples_spec.cr",
        "spec/ocx/messages_spec.cr",
        "spec/ocx/hook_spec.cr",
        "spec/ocx/session_spec.cr",
        "spec/ocx/terminal_spec.cr",
        "spec/ocx/sandbox_spec.cr",
        "spec/scenarios/talk_spec.cr",
        "spec/ocx/message_tags_spec.cr",
        "spec/ocx/ends_spec.cr",
        "spec/ocx/asked_spec.cr",
        "spec/ocx/writers_spec.cr",
        "spec/ocx/watch_spec.cr",
        "spec/ocx/clone_host_spec.cr",
        "spec/guards/protocol_names_spec.cr",
        "spec/ocx/publication_spec.cr"
      ],
      "used_by": [
        "the node's daemon, each detached watcher and a person starting a manual run on the agent machine"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's receipts (RCVFROM) and user table, and its forum and ticket tables; protocol v1's messages."
    },
    {
      "name": "Say who sent an artifact",
      "event": "request: the web page's receipt, which a node on a clone asks over HTTPS as the node user; or bin/ocx2 receipt --artifacts 'HASH ...' [--capabilities-of USER] on the served host or in a clone's checkout",
      "purpose": "Let a node or a reader on a clone learn who sent each artifact, by the server's receipt, since a clone's own receipts name its pulls (docs/protocol-v1-fossil.md, section 3).",
      "shape": "For each artifact, by its hash in full: the user the served repository received it from, that user's capabilities there as Fossil grants them, inherited ones included, the receipt's number and the artifact's row number, which order what it received; or that it has not received it, which is also the answer to a caller who may not read (who lacks Read, o, or for a private artifact, x). For a user, their capabilities, and whether the repository holds the wiki edits they save (its modreq-wiki on, and the user lacking ModWiki, l), or the ticket changes they make in its pages (its modreq-tkt on, and the user lacking ModTkt, q), for a moderator, to a caller who may read. Never an address. From a clone's checkout, the server's own receipt asked unsigned, its reason given when it refuses, and its answer refused unless it is of the artifacts asked, in order, and the user asked.",
      "parts": [
        "src/ocx/commands/receipt.cr",
        "src/ocx/server.cr",
        "src/ocx/exchange.cr",
        "src/ocx/receipt_service.cr"
      ],
      "origin": "docs/slices-v1.md, slice v1.4: the maintainer at the terminal, 2026-10-12, chose that a node asks the server who sent an artifact (option a, HISTORY.md decision 37).",
      "reads": [
        "the served repository's receipts and users"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/receipt_spec.cr",
        "spec/ocx/receipt_service_spec.cr"
      ],
      "used_by": [
        "the daemon and watchers on clones, through the server's receipt page"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's blob, rcvfrom, private and user tables, and its modreq-wiki config row."
    },
    {
      "name": "Write a run",
      "event": "person: bin/ocx2 create [--pattern URL] (--title TITLE | --to POST | --ticket TICKET) [--objective TEXT] [--login LOGIN] [--user USER] [--fields JSON] [--of CHECK-IN] [--reset-password] on the served host, or the web page's create form; agent: ocx_create in its run's clone's checkout",
      "purpose": "Write a run (docs/protocol-v1.md, section 3) without typing its fields each time: a pattern, such as the wiki page run/NAME, holds a way of working once, as data, and create writes the run from it with the fields given over it.",
      "shape": "Merge the pattern's JSON fields and the explicit input, checking protocol syntax before writing a run as the caller: a new thread, reply or ticket comment. Its node must be named; a run user may be made for an administrator's request. Approve a kept password for the run's node, changing it only for an explicit admin or setup reset. Refuse an existing user with no kept password for a node on another host; preserve the local password-file path. From a checkout, pull first, take the pattern version the server confirms an administrator sent, then push the reply or ticket comment. The daemon and watcher answer the request later.",
      "parts": [
        "src/ocx/commands/create.cr",
        "src/ocx/commands/create_destination.cr",
        "src/ocx/exchange.cr",
        "src/ocx/served.cr",
        "src/ocx/writes.cr",
        "src/ocx/messages.cr",
        "src/ocx/fossil/wiki.cr",
        "src/ocx/commands/post.cr",
        "src/ocx/commands/receipt.cr"
      ],
      "origin": "The maintainer at the terminal, 2026-10-12: keep create with wiki assistance for the data patterns, its argument \"a URL to fetch a defined JSON block as a starting default\".",
      "reads": [
        "the pattern at its URL",
        "the post replied to, or the ticket",
        "from a clone, the server's receipts for the pattern page's versions"
      ],
      "writes": [
        "the run: a forum post or a ticket change, as the caller, tagged ocx-message by the same command"
      ],
      "specs": [
        "spec/ocx/create_spec.cr",
        "spec/ocx/create_password_spec.cr",
        "spec/ocx/create_approval_spec.cr",
        "spec/ocx/create_addressing_spec.cr",
        "spec/ocx/daemon_review_logins_spec.cr",
        "spec/ocx/clone_publication_spec.cr",
        "spec/scenarios/build_spec.cr",
        "spec/scenarios/ci_spec.cr",
        "spec/ocx/message_tags_spec.cr",
        "spec/ocx/daemon_review_safety_spec.cr"
      ],
      "used_by": [
        "people with admin or setup, from the web page or a command line on the served host",
        "agents holding R, from their run's clone, as a build of their check-in",
        "a CI session's process, run/ci's, from its clone, as a build of each check-in it is given"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's forum artifacts, stored with their tags by bundle import; a wiki page's Markdown as Fossil renders it (a json block as <pre><code class=\"language-json\">)."
    },
    {
      "name": "Start a manual run by hand",
      "event": "person: bin/ocx2 run RUN --repository CLONE on the agent machine",
      "purpose": "Start a run whose manual is true, which its node leaves waiting for a person, so a person decides when it starts.",
      "shape": "Read the run on the named clone and its project password file, ask the server for its sender and decide it by hand; hand watch --by-hand with explicit server credentials. It refuses a clone with no completed pull and reads no run or report beyond that pull.",
      "parts": [
        "src/ocx/commands/run.cr",
        "src/ocx/served.cr",
        "src/ocx/writes.cr",
        "src/ocx/hook.cr"
      ],
      "origin": "The maintainer at the terminal, 2026-10-12: keep \"the session/cgi-based run tool (run)\"; docs/protocol-v1-tools.md, run.",
      "reads": [
        "the run on the explicitly named clone",
        "the clone's project password file, with server and credentials paths",
        "server receipts and local care"
      ],
      "writes": [
        "a detached ROOT/current/ocx2 watch RUN --by-hand, with clone, server and credentials arguments",
        "the watcher's per-run log"
      ],
      "specs": [
        "spec/ocx/run_spec.cr"
      ],
      "used_by": [
        "people with admin or setup, from the web page or a command line on the served host"
      ],
      "state": "demonstrated",
      "coupling": "The current release's watch command, the project password files and the server's receipt page."
    },
    {
      "name": "See where each run stands",
      "event": "person: bin/ocx2 status on the served host, or the web page's status, for any viewer",
      "purpose": "Let a person see each run of the node that has not ended and why it waits, so a session that is not answering is told apart from one that never started, as on cleave, 2026-10-14.",
      "shape": "On the served repository, read runs for every node user an administrator's run names, leaving in_care absent. On a node's clone with its project password file, show the node's offer (node user, clone server-code and enforced limits), read care and processes locally and the senders from receipts. status reads the hook's export standing and the last round from daemon.log. A clone read uses its daemon completion number and logs sign-in before reading local care; the served page shows no node decision note.",
      "parts": [
        "src/ocx/commands/status.cr",
        "src/ocx/acting.cr",
        "src/ocx/acting/view.cr",
        "src/ocx/care.cr",
        "src/ocx/decisions.cr"
      ],
      "origin": "The parity item for trunk's console Sessions and Workspaces views; step 15 of the parity order, design 18; the maintainer, KEEP.md, 2026-10-16: \"I do like status showing status from all the projects on a host\"; and, 2026-10-19: \"I think adding related processes in workspace sandboxes is also needed for local stuff\" and \"Let's just use the information the system gives us\".",
      "reads": [
        "record runs for every node user an administrator's run names",
        "local care and processes only with a clone and its project password file",
        "the export hook and the last daemon.log round",
        "the release root's current link"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/run_spec.cr",
        "spec/scenarios/talk_spec.cr",
        "spec/ocx/message_tags_spec.cr"
      ],
      "used_by": [
        "people on the web page or a command line on the served host"
      ],
      "state": "demonstrated",
      "coupling": "The node's lock in ROOT/state, which every round and watcher holds to write a report, and Fossil's read capabilities 2 and r."
    },
    {
      "name": "Stop a run",
      "event": "person: bin/ocx2 stop RUN on the served host, or the web page's stop form",
      "purpose": "Ask a run's node to end it: a program running is ended, and a run not yet started is answered stopped.",
      "shape": "A fenced stop for the run, written as the caller where the run is: a reply to its post or a change to its ticket. Its watcher acts after the next completed pull.",
      "parts": [
        "src/ocx/commands/stop.cr",
        "src/ocx/served.cr",
        "src/ocx/writes.cr"
      ],
      "origin": "docs/protocol-v1.md, section 3; docs/protocol-v1-tools.md, stop.",
      "reads": [
        "the run and the node it names"
      ],
      "writes": [
        "the stop: a forum post or a ticket change, as the caller, tagged ocx-message by the same command"
      ],
      "specs": [
        "spec/ocx/run_spec.cr",
        "spec/ocx/message_tags_spec.cr"
      ],
      "used_by": [
        "people with admin or setup, from the web page or a command line on the served host"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's forum artifacts and ticket changes."
    },
    {
      "name": "Join a run's terminal",
      "event": "person: bin/ocx2 attach RUN at the node's host, as the account the node runs as",
      "purpose": "See and type into the terminal a run's process is on, as at any terminal, and leave it running.",
      "shape": "The terminal's socket found by the run's hash or a prefix of it in the node's directory, ROOT/state/runs/RUN.terminal, which the watcher binds (0600) while the process runs and only the account the node runs as may open; the person's window's size sent first, a line, which the run's terminal takes on, Linux telling its program at once (SIGWINCH), so a full-screen one redraws to fit with no key, then each key they type, while they see what it shows, their terminal raw meanwhile and given back as it was; Ctrl-] leaves it, the terminal taking its own window, 50 by 200, again, its program told so, before the connection closes; one person at a time, a second waiting; one who does not keep up misses what was shown meanwhile, never holding the process back; and a process that ends closes the connection. The joining side is OCX's own code, which copies what the process shows to the person's terminal, reading none of it, so the process cannot make it run anything, as it could a terminal multiplexer's client (HISTORY.md decision 83). Offered on the command line alone.",
      "parts": [
        "src/ocx/commands/attach.cr",
        "src/ocx/terminal.cr",
        "src/ocx/terminal/typed.cr",
        "src/ocx/care.cr"
      ],
      "origin": "docs/protocol-v1-tools.md, attach; 59db010dbe's attach restored on protocol v1's terminal, on the maintainer's words of 2026-10-19 (HISTORY.md decision 83).",
      "reads": [
        "the node's directory, for the terminal's socket",
        "the person's terminal: its window's size and their keys"
      ],
      "writes": [
        "the person's keys, into the run's terminal",
        "what the run's terminal shows, to the person's terminal"
      ],
      "specs": [
        "spec/ocx/attach_spec.cr",
        "spec/ocx/terminal_spec.cr",
        "spec/ocx/dry_run_spec.cr"
      ],
      "used_by": [
        "a person at the node's host, as the account the node runs as"
      ],
      "state": "demonstrated",
      "coupling": "Linux's pseudo-terminals and Unix sockets, a socket bound and reached through a descriptor of its directory, in /proc/self/fd, as its whole name may be no longer than 108 bytes."
    },
    {
      "name": "Serve a repository's git export",
      "event": "request: GET or POST <ext>/git/NAME.git/... from a git client",
      "purpose": "Let mirrors outside OCX fetch what Fossil holds, from the export Fossil itself writes.",
      "shape": "git's smart HTTP, upload-pack only: the advertised refs and a pack for what is wanted, a gzipped request accepted; a push 403, a viewer without o or h 403, no export 404, a request over 50 MB 413, unreadable gzip 400, an export git cannot read 500.",
      "parts": [
        "src/ocx/git_export.cr",
        "src/ocx/git.cr",
        "src/ocx/entry.cr"
      ],
      "origin": "Slice 5 of docs/slices-parity.md; the reference's src/ocx/git_http.cr in ocx-cgi.",
      "reads": [
        "the repository's last-git-export-repo setting",
        "the git export"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/git_export_spec.cr"
      ],
      "used_by": [
        "git mirrors outside OCX"
      ],
      "state": "unused",
      "coupling": "git 2.x's upload-pack --stateless-rpc, and Fossil 2.27's git export and its setting."
    },
    {
      "name": "Keep a repository's git export current",
      "event": "hook: Fossil's own after-receive hook, %F git export --if-mirrored -R %R; person: bin/ocx2 export",
      "purpose": "Have the git export Fossil writes hold every check-in, so mirrors and clones of an imported upstream fetch what Fossil holds, without a clock.",
      "shape": "Fossil's backoffice runs its own export command, installed by hook. A repository with no export does nothing. The export command also keeps it by hand and reads its standing.",
      "parts": [
        "src/ocx/mirror.cr",
        "src/ocx/commands/export.cr",
        "src/ocx/hook.cr"
      ],
      "origin": "Slice 40 of docs/slices-git.md; trunk's mirror-sync and its daemon's poll_git_exports, without the clock.",
      "reads": [
        "the repository's last-git-export-repo setting",
        "fossil git status",
        "the export's last run"
      ],
      "writes": [
        "the git export, through fossil git export",
        "the export's lock, ask and last run, in its .git"
      ],
      "specs": [
        "spec/ocx/export_spec.cr",
        "spec/ocx/dry_run_spec.cr"
      ],
      "used_by": [
        "the hook",
        "the maintainer, closing a gap by hand"
      ],
      "state": "unused",
      "coupling": "Fossil 2.27's git export, its git status lines and its last-git-export-repo setting."
    },
    {
      "name": "Onboard a project",
      "event": "person: ocx2 project NAME DAEMON_ROOT [--from UPSTREAM] [--mirrors DIR] [--kinds \"session\"], on the host or web page",
      "purpose": "Make a served repository from git or empty, ready for agents and milestone cards.",
      "shape": "Make the repository in a working directory, keeping the sandboxed git import when --from is given; export and place it by one rename; join the login group; install the export hook, set the timeline chat user and ticket fields, file node and run passwords privately under DAEMON_ROOT/state, and add its clone to that root's project password directory. Refuse a daemon root without node/. The web page runs detached from its own release root.",
      "parts": [
        "src/ocx/commands/project.cr",
        "src/ocx/commands/project_operations.cr",
        "src/ocx/projects.cr",
        "src/ocx/projects_detached.cr",
        "src/ocx/session.cr",
        "src/ocx/git.cr",
        "src/ocx/tasks.cr",
        "src/ocx/launch.cr",
        "src/ocx/sandbox.cr",
        "src/ocx/fossil/direct.cr",
        "src/ocx/fossil/sync.cr"
      ],
      "origin": "Slice 39 of docs/slices-git.md; trunk's import-project, its git half.",
      "reads": [
        "the served repository and its public URL, chat user, login group and export location",
        "the upstream when --from is given",
        "the daemon project password directory"
      ],
      "writes": [
        "the new served repository and git export",
        "node and run users and their private credentials",
        "the daemon project password directory",
        "milestone and due ticket fields"
      ],
      "specs": [
        "spec/ocx/import_spec.cr",
        "spec/ocx/imports_detached_spec.cr",
        "spec/ocx/dry_run_spec.cr",
        "spec/ocx/tasks_spec.cr"
      ],
      "used_by": [
        "the maintainer, bringing a project into OCX"
      ],
      "state": "demonstrated",
      "coupling": "git 2.x's clone, fast-export and marks; Fossil 2.27's import --git, its marks and its git export's .mirror_state."
    },
    {
      "name": "Record a verdict on a check-in",
      "event": "person: bin/ocx2 audit CHECK-IN pass|fail NOTE, the web page's form, or an agent's ocx_audit",
      "purpose": "Let a second user judge a check-in in Fossil, so the audit guard and anyone reading the tags see who judged what.",
      "shape": "A tag audited on the check-in, its value the verdict, a colon and the note, made as the caller: in a clone and pushed, or on the served repository as the viewer; the check-in's author refused; read back as the served repository holds it, a refused push reported as no verdict.",
      "parts": [
        "src/ocx/commands/audit.cr"
      ],
      "origin": "Slice 4 of docs/slices-parity.md; the reference's tools/audit.cr, which did not refuse an author or read its tag back.",
      "reads": [
        "the check-in and its author",
        "the audited tag as the served repository holds it"
      ],
      "writes": [
        "an audited tag on the check-in"
      ],
      "specs": [
        "spec/ocx/verdict_spec.cr"
      ],
      "used_by": [
        "reviewers, people and agents"
      ],
      "state": "unused",
      "coupling": "Fossil 2.27's tag add and push, which refuses a tag from a login without Check-In with an Error line and still ends Push done."
    },
    {
      "name": "List the check-ins no verdict has judged",
      "event": "session: a reviewer run's program's ocx_unaudited through its run's MCP, or a person's bin/ocx2 unaudited [--branch BRANCH] in a clone's checkout or on the served repository, or the web page's unaudited",
      "purpose": "Show a reviewer the check-ins still waiting for a verdict: the backlog from before its session's started, which the session is not given (protocol v1, section 9), and any still waiting later.",
      "shape": "A tool reading only: the public check-ins that change files, on a branch or every branch, oldest first in the server's order, at most 50, with how many there are, less each that an audited or sym-audited verdict that counts has judged by docs/protocol-v1-verdicts.md's reading rules, pass or fail alike: its value of a verdict's form, from a user holding i when read, who is no node's login and neither sent the check-in nor is named in it, against a file or a run about the check-in; every tag change read from the control artifacts' T cards, who sent each from the server's receipts; from a clone, the server's own unaudited asked unsigned.",
      "parts": [
        "src/ocx/commands/audit.cr",
        "src/ocx/fossil/checkins.cr",
        "src/ocx/fossil/said.cr",
        "src/ocx/server.cr",
        "src/ocx/exchange.cr",
        "src/ocx/history.cr"
      ],
      "origin": "The parity item for trunk's bin/reviewer and the console's Audits, which listed the check-ins nobody but their author had judged; docs/protocol-v1-tools.md, unaudited.",
      "reads": [
        "the served repository's check-ins, control artifacts, receipts, users and runs",
        "from a clone, the server's unaudited tool"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/verdict_spec.cr",
        "spec/scenarios/audit_spec.cr",
        "spec/ocx/daemon_review_history_spec.cr"
      ],
      "used_by": [
        "reviewers, people and agents, a reviewer's session among them"
      ],
      "state": "unused",
      "coupling": "Fossil's event, blob, mlink, private, tagxref (for a branch) and rcvfrom tables, its control artifacts' T card format, and the server's unaudited tool answering unsigned, which needs nobody to hold Read (o)."
    },
    {
      "name": "Write a plain post",
      "event": "person: bin/ocx2 post TO TEXT [--for USER] [--decision] in a clone's checkout or on the served host, a program's ocx_post, or a press of console's",
      "purpose": "Let a person or a run's program answer in a thread or on a ticket as its user, from its own clone or on the served repository, with no OCX message in it.",
      "shape": "A reply in the thread of the post replied to, composed as Fossil's forum artifact, stored in the caller's clone, indexed, by one command, then pushed, or a change to a ticket made there and pushed; on the served repository, stored there, or the ticket changed there, as the caller; refusing text that holds an OCX message, and naming the post or change when the push did not reach the served repository. Given a user, the text is written as a question for that user, an OCX message after Markdown saying it in words, each reference resolved where the caller is to the one artifact, ticket, tech-note or wiki page it names and written as a link from the repository's root, a file's lines as its artifact's, linked by its title, refused when it would ask no one, its decision could wait for a moderator in a thread or in a ticket's pages, its user may not read and edit a wiki page it references or would wait for a moderator there, or a reference is a link elsewhere, names nothing or several, or names what the server has not received; given decision, as the caller's decision, whoever they are, for the question named, where it is, its sender's closing it, refused to a question its sender has closed; and refused, writing nothing, when the text would not read back as the question or decision it was made from.",
      "parts": [
        "src/ocx/commands/post.cr",
        "src/ocx/fossil/forum.cr",
        "src/ocx/question.cr",
        "src/ocx/fossil/referenced.cr"
      ],
      "origin": "Slice 6 of docs/slices-parity.md; docs/protocol-v1-tools.md, post.",
      "reads": [
        "the post replied to, or the ticket"
      ],
      "writes": [
        "a forum post or a ticket change, as the caller"
      ],
      "specs": [
        "spec/ocx/post_spec.cr",
        "spec/ocx/questions_spec.cr",
        "spec/scenarios/question_spec.cr"
      ],
      "used_by": [
        "run programs in their clones, people at a terminal in a clone, and people deciding a question from console"
      ],
      "state": "unused",
      "coupling": "Fossil 2.27's forum artifact format, its bundle import command, and a push needing Check-In."
    },
    {
      "name": "Say what waits on a user, as data",
      "event": "request: questions, on the web page, /ext/ocx2-cgi/questions, JSON for a client such as Stone; or bin/ocx2 questions [--for USER] on the served host or in a clone's checkout, or ocx_questions",
      "purpose": "Give the questions put to a user, and every other open question, as data, the same at every entry point, derived from the record and never stored (PLAN.md, precept C4), for console and any client to show (HISTORY.md decision 100).",
      "shape": "Of every question and decision the ocx-message tag names, what Fossil holds private left out: each question for the user that they have not decided, whoever else has, waits on it, oldest first in the server's order; each the user sent, or a run they sent asked, that has a decision is theirs to confirm; every other question not closed is open; a decision counts from anyone where its question is, and only its sender's, or that of whoever sent its run, closes it. Each question's fields once: the post or ticket change asking it, where it is, its thread's or ticket's title and link, who sent it and when, whom it asks, its words, options, stakes and run; what it replies to and each reference, described by one query for all, by its title, full URL and excerpt, each hash in it shown by its artifact's title, only as far as the caller may read it (2, r, j, o); its decisions, each by its note, titled so; and who may confirm it. No post's text, nor its block beside the question it holds. From a clone's checkout, the server's receipt tool says who sent each question and decision.",
      "parts": [
        "src/ocx/commands/questions.cr",
        "src/ocx/questions.cr",
        "src/ocx/history.cr",
        "src/ocx/question.cr",
        "src/ocx/fossil/said.cr",
        "src/ocx/fossil/described.cr"
      ],
      "origin": "docs/parity-v1.md: trunk's console views For you and Open questions (src/ocx/console.cr and questions.cr at a46d73f5bf); the maintainer, 2026-10-22: \"`questions` and `status` stayed locked in a ui agnostic/compatible tool\".",
      "reads": [
        "the served repository's questions and decisions, by the ocx-message tag, with their receipts, or from a clone the server's",
        "the posts, ticket changes and tickets, tech-notes, check-ins, files and wiki pages the questions refer to, with their receipts, and the repository's public URL"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/questions_spec.cr",
        "spec/guards/question_spec.cr",
        "spec/ocx/described_spec.cr",
        "spec/scenarios/question_spec.cr",
        "spec/ocx/daemon_review_history_spec.cr"
      ],
      "used_by": [
        "console, and clients such as Stone"
      ],
      "state": "unused",
      "coupling": "Fossil's forumpost, ticket, ticketchng, blob, rcvfrom, private and config tables, and its ticket-closed-expr setting, and for what a question refers to its event, mlink, filename, tag and tagxref tables, the ticket table's title and comment, and the content of posts, pages and files."
    },
    {
      "name": "Show a person's view",
      "event": "request: console, on the web page, /ext/ocx2-cgi/console, its own page, linked from the list's header; or bin/ocx2 console [--for USER] on the served host or in a clone's checkout, or ocx_console",
      "purpose": "Let a person see the questions put to them, and every other open question, then what runs, laid out for each entry point, with what to press next (HISTORY.md decisions 98 and 100).",
      "shape": "It reads questions' answer and the record's runs for every node user an administrator's run names, as status reads them. Given a clone and its project password file, it reads local care through the last complete pull. It shapes them for reading: each question with who asked it and how long ago, where, what it changes and its decisions; waiting, what to read first; in the viewer's own view, holding what post needs, a press of post per option, the recommended first, one for their own words, and one to confirm what they may close. Then the runs that have not ended, and of those that ended the five received last, each with where it is, who sent it, its user, its phase and since when. No hash is shown but in a link or a press. On the web, a page of its own in Fossil's skin, nothing on it but cards, a line per other open question, a table of runs and one link to the list, each press a button posting to post that comes back to the page, saying what was written; at the command line and over MCP, focused text, each press the exact command line, each excerpt's lines quoted; JSON, the view's data. From a clone's checkout no run is shown unless --login is given.",
      "parts": [
        "src/ocx/commands/console.cr",
        "src/ocx/shown.cr",
        "src/ocx/console_page.cr",
        "src/ocx/console_text.cr"
      ],
      "origin": "docs/parity-v1.md: trunk's console views For you and Open questions (src/ocx/console.cr and questions.cr at a46d73f5bf).",
      "reads": [
        "questions' answer",
        "the record's runs for every node user an administrator's run names; given a clone and its project password file, local care through the last complete pull"
      ],
      "writes": [
        "a decision, as the viewer, by post, from a press"
      ],
      "specs": [
        "spec/ocx/console_spec.cr",
        "spec/ocx/styles_spec.cr",
        "spec/scenarios/question_spec.cr"
      ],
      "used_by": [
        "people on the web page or at a terminal, and clients such as Stone"
      ],
      "state": "unused",
      "coupling": "questions' answer and status's reader of the record's runs for every node user an administrator's run names, or local care through the last complete pull given a clone and its project password file; Fossil's Markdown, which reads HTML within a paragraph and the Location a page answers."
    },
    {
      "name": "Read a thread or ticket",
      "event": "session: a run's program's ocx_thread through its run's MCP, or a person's bin/ocx2 thread OF in a clone's checkout or on the served repository",
      "purpose": "Let a run's program read what was said where its run is, OCX messages and the node's reports included, which a session hearing the thread is not given, as protocol v1, section 9, lets it read its thread itself.",
      "shape": "A tool reading only: the thread or ticket any of its posts or changes names, found as post finds it, a ticket by a change's hash too; each post or text-adding change in the order the server received them, with its hash, the user the server received it from, when its artifact says it was written, and its text, at most 20, after a given post the server has received; a private one, such as a post awaiting moderation, only for one holding x; in a clone it pulls first, refusing a pull that does not reach the server, and asks the server's receipt tool who sent each, refusing when the server lets no one read what the clone pulled.",
      "parts": [
        "src/ocx/commands/thread.cr",
        "src/ocx/fossil/said.cr",
        "src/ocx/fossil/tickets.cr"
      ],
      "origin": "The parity item for trunk's task --wait, task --status and console --for, which showed an agent what others posted; docs/protocol-v1-tools.md, thread.",
      "reads": [
        "the run's clone, pulled, or the served repository",
        "the server's receipts, through its receipt tool"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/thread_spec.cr"
      ],
      "used_by": [
        "run programs in their clones, and people at a terminal in a clone"
      ],
      "state": "unused",
      "coupling": "Fossil's forumpost and ticketchng tables, and the server's receipt tool answering unsigned, which needs nobody to hold Read (o)."
    },
    {
      "name": "Tag the messages left untagged",
      "event": "person: bin/ocx2 tag_messages on the served repository named outright or in a clone's checkout, or the web page's form; a program's ocx_tag_messages",
      "purpose": "Let anyone holding Check-In do the back-fill the node's check does (HISTORY.md decision 84) without a hook: every OCX message tagged, so status and a round find it by its tag (the maintainer, 2026-10-20: \"getting the hook needs setup, but tagging the runs does not\").",
      "shape": "Every post and ticket change holding an OCX message read, as the daemon and watcher read them, and each lacking its ocx-message tag, or carrying a wrong value, tagged in one control artifact as the caller, one alone with fossil tag add --raw: on the served repository, received from the caller; from a clone's checkout, pulled first, tagged in the clone and pushed, naming why when the push did not reach the server. It answers each kind tagged with its artifacts, writes nothing when every message carries its tag, and decides nothing about any run.",
      "parts": [
        "src/ocx/commands/tag_messages.cr",
        "src/ocx/acting/view.cr",
        "src/ocx/fossil/message_tags.cr"
      ],
      "origin": "The maintainer, 2026-10-20: \"getting the hook needs setup, but tagging the runs does not\", then \"it is a start. go.\"; docs/protocol-v1-tools.md, tag_messages.",
      "reads": [
        "every post and ticket change holding an OCX message, on the served repository or in the caller's clone, pulled"
      ],
      "writes": [
        "one control artifact of ocx-message tags, as the caller, pushed from a clone"
      ],
      "specs": [
        "spec/ocx/tag_messages_spec.cr"
      ],
      "used_by": [
        "people holding Check-In, on the served repository or in a clone"
      ],
      "state": "unused",
      "coupling": "Fossil's control artifact format and its bundle import command, its tag, tagxref, forumpost and ticketchng tables, and a push needing Check-In."
    },
    {
      "name": "Install or remove the hook, and say where it stands",
      "event": "person: bin/ocx2 hook | unhook on the served host, or the web page's forms; status for any viewer",
      "purpose": "Have Fossil's backoffice run its own git export after each receipt, so the export follows each check-in; let anyone see whether the hook is installed, the other programs it runs, its backoffice settings and its chat timeline user.",
      "shape": "hook installs %F git export --if-mirrored -R %R once, replacing any old ocx2-hook command and leaving other hooks alone. unhook deletes both commands. Standing reads the other after-receive programs, backoffice settings and chat-timeline-user; no root or node is installed.",
      "parts": [
        "src/ocx/hook.cr",
        "src/ocx/commands/hook.cr",
        "src/ocx/commands/status.cr"
      ],
      "origin": "Slice 10 of docs/slices-parity.md; the reference console's hook page and its hook and unhook actions.",
      "reads": [
        "the repository's hooks setting",
        "backoffice-nodelay and backoffice-disable",
        "chat-timeline-user"
      ],
      "writes": [
        "the repository's hooks setting"
      ],
      "specs": [
        "spec/ocx/hook_spec.cr"
      ],
      "used_by": [
        "the maintainer, installing the hook on the served host"
      ],
      "state": "unused",
      "coupling": "Fossil 2.27's hook add and delete, its hooks JSON named by place, its backoffice settings and its git export command."
    },
    {
      "name": "Ask for a login, approve it, collect its password",
      "event": "person: on the asker's machine, bin/ocx2 register SERVER-URL PASSWORDS-FILE [--login LOGIN] [--capabilities LETTERS], or daemon before its login is approved; an admin may open the link it printed, the web page's approve with its form filled, and press once, or run bin/ocx2 approve LOGIN KEY CAPABILITIES on the served host. asker: its POST to collect",
      "purpose": "Let anyone with a command line ask for a login on the server, which an admin may approve, like Fossil's self-registration, but the user is made only when an admin approves: no step by hand but the press, no person typing or choosing a password, and no page or command showing one (HISTORY.md decisions 73 and 76).",
      "shape": "register makes a code, keeps it with the login and the capabilities asked in the asker's file of passwords, readable by its owner alone, and prints a link naming them and the code's SHA-256, the same at every call; approve makes the user the link names, holding exactly the capabilities asked, refusing a, s, u, v, none and any letter Fossil does not define but R, with a random password kept with the code's key in the served repository's config row ocx-node-key-LOGIN, apart from the secrets a run may name; it refuses a login already a user it did not make or that no longer holds the password it set, and keeps the password when approved again for the same key. collect gives the password for the code whose key matches, to anyone; register sends the code in a POST's body and keeps the password in place of the code.",
      "parts": [
        "src/ocx/commands/logins.cr",
        "src/ocx/commands/register.cr",
        "src/ocx/exchange.cr",
        "src/ocx/fossil/repository.cr",
        "src/ocx/cgi.cr"
      ],
      "origin": "The maintainer, 2026-10-16, of the build machine's two accounts: \"why would i need 2 accounts on my server for that remote instance? why is it even a question?\", \"don't forget to eliminate manual steps\", and of the plan, \"sure\". The maintainer, 2026-10-16 and 17, of logins in general: \"the login chosen by the user with cli access should dictate the greatest capability extended to the OCX application, just like it is for cli usage of fossil\" (HISTORY.md decision 76).",
      "reads": [
        "the served repository's users and their capabilities",
        "the served repository's config rows ocx-node-key-LOGIN",
        "the asker's file of passwords"
      ],
      "writes": [
        "the login, its capabilities and password",
        "the served repository's config row ocx-node-key-LOGIN",
        "the asker's file of passwords: its code, then its password"
      ],
      "specs": [
        "spec/ocx/logins_spec.cr"
      ],
      "used_by": [
        "anyone asking for a login from its own command line, a node on a clone among them; an admin, from the asker's link"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's user and config tables, a config row of no group Fossil syncs; Fossil's extension root, which runs OCX's page for a viewer holding nothing"
    },
    {
      "name": "Let a user send runs, or no longer",
      "event": "person: an admin opens the web page's send_runs, as a link ?user=USER, and presses once, or runs bin/ocx2 send_runs USER [--off] on the served host; or an MCP client acting as an admin calls ocx_send_runs",
      "purpose": "Give a user R, which OCX reads as \"may send runs\", or take it away, from the web page by one press, since Fossil's own user page may drop a letter Fossil does not define and R was otherwise added only at the server's command line (HISTORY.md decision 109).",
      "shape": "send_runs reads the letters the user holds of its own, then adds R or takes it out in one SQL statement, which writes nothing where they already say what is asked and leaves every other letter as it is then, one another writer gave the user after that read among them (HISTORY.md decision 111); it answers the user's capabilities as receipt reads them, inherited ones included, with a note when the user holds admin or setup, which send any run with or without R, or still holds R from Fossil's own users; it refuses Fossil's own users nobody, anonymous, reader and developer, a user the repository lacks, and a caller without admin. On the web page a GET shows its dry run with its form filled from the link; only a POST from OCX's own page changes anything.",
      "parts": [
        "src/ocx/commands/send_runs.cr",
        "src/ocx/fossil/repository.cr",
        "src/ocx/fossil/said.cr",
        "src/ocx/cgi.cr"
      ],
      "origin": "The maintainer, 2026-10-22 and 23: \"the Fossil UI really fights the \"R\".\" and \"i can only add R from the cli. i need a helper to add it from here.\" (HISTORY.md decision 109).",
      "reads": [
        "the served repository's users and their capabilities, their own and those Fossil's own users lend them"
      ],
      "writes": [
        "the user's capabilities"
      ],
      "specs": [
        "spec/ocx/send_runs_spec.cr",
        "spec/ocx/dry_run_spec.cr"
      ],
      "used_by": [
        "an admin, giving R to a user create or approve did not make, such as one made before decision 104"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's user table, written in one statement as Fossil's user capabilities command writes it, which keeps a letter Fossil does not define; Fossil's extension root, which runs OCX's page"
    },
    {
      "name": "Set a secret a run may use",
      "event": "person: bin/ocx2 secret NAME VALUE on the served host, or the web page's secret form",
      "purpose": "Give a run what it must not show, such as a tunnel's key, without putting it in the run's text or on the host's disk by hand.",
      "shape": "An admin sets the served repository's setting ocx-secret-NAME; a run sent by an admin names it as $$secret:NAME$$ in its process's env, and the node fills it in there alone, writing its name, never its value, wherever it would be shown.",
      "parts": [
        "src/ocx/commands/secret.cr",
        "src/ocx/fossil/repository.cr"
      ],
      "origin": "The maintainer's approved plan for the mcp-tunnel branch, 2026-10-14: \"An instance-only (not copied during clone) config setting seems like a better way to communicate it to the tunnel client.\"",
      "reads": [
        "the served repository's settings"
      ],
      "writes": [
        "the served repository's setting ocx-secret-NAME"
      ],
      "specs": [
        "spec/ocx/secret_spec.cr"
      ],
      "used_by": [
        "a run's process, through its node"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's config table, a setting of no group Fossil syncs; the node's watcher reads it"
    },
    {
      "name": "Sync an agent's work through the call",
      "event": "session: an agent's ocx_sync, through its run's MCP, or bin/ocx2 sync BRANCH in a clone's checkout; and ocx_commit_and_sync_guide, anywhere, and ocx_commit_and_sync, from an agent's own machine",
      "purpose": "Let an agent that will not keep a Fossil login key land its check-ins on the server, and take others back, with the data in the call.",
      "shape": "The agent's bundle, base64, is read before anything is imported: each check-in on the agent's working branch, never trunk, its comment stated as save and commit_and_sync state one, a title and Intent, Expression and Demonstrates lines each saying something; then imported into the run's clone and pushed as the run's user; and with have, the clone pulls and answers a bundle of that check-in and every one after it. commit_and_sync commits as save does, every change once each test has passed, and answers the bundle; the guide answers the steps for the agent's own shell.",
      "parts": [
        "src/ocx/commands/sync.cr",
        "src/ocx/fossil/sync.cr",
        "src/ocx/commands/commit_and_sync.cr",
        "src/ocx/commands/stated.cr"
      ],
      "origin": "The maintainer at the terminal, 2026-10-14: \"the `commit-and-sync` or really just `sync` is the ONLY operation that is required and it needs to go over the MCP connection, if we cannot invoke any code on the agent's machine.\"",
      "reads": [
        "the agent's bundle",
        "the run's clone"
      ],
      "writes": [
        "the run's clone",
        "the server, by its push, as the run's user"
      ],
      "specs": [
        "spec/ocx/sync_spec.cr",
        "spec/ocx/commit_and_sync_spec.cr",
        "spec/ocx/stated_spec.cr",
        "spec/ocx/remote_agents_spec.cr"
      ],
      "used_by": [
        "an agent through its run's MCP"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's bundle export, ls, cat and import, and the clone's remembered password"
    },
    {
      "name": "Edit a run's checkout and save it",
      "event": "session: an agent's ocx_context, ocx_find, ocx_read, ocx_edit, ocx_test and ocx_save through its run's MCP, or bin/ocx2 with those tools in a clone's checkout; and ocx_wiki_read, ocx_wiki_edit, ocx_unversioned_list, ocx_unversioned_get and ocx_unversioned_put",
      "purpose": "Let an agent, a weak local model included, read, change, test and save the run's own checkout, and share wiki pages and unversioned files, with no clone, Fossil or password of its own.",
      "shape": "Every path is from the checkout's root and stays inside it; read gives text exactly, its line numbers apart; edit replaces text that appears once, or with old empty adds to the file's end; test runs the tests the project names in ocx-tests.json, or one, and records the changes they passed with; save commits on the working branch, agent/ and the user and eight hex digits, once each test has passed with the checkout as it is, its comment stated as src/ocx/commands/stated.cr says, and pushes as the run's user; wiki_edit changes a page as edit changes a file, and wiki_read reads a page as the server holds it now; an unversioned file is written against the hash it replaces. Every answer says ok, and on a refusal next_step.",
      "parts": [
        "src/ocx/checkout_files.cr",
        "src/ocx/commands/reading.cr",
        "src/ocx/commands/editing.cr",
        "src/ocx/commands/saving.cr",
        "src/ocx/commands/sharing.cr",
        "src/ocx/commands/unversioned.cr",
        "src/ocx/fossil/unversioned.cr"
      ],
      "origin": "The maintainer, 2026-10-15: \"produce a set of easy to use agent tools available over the remote MCP that even local agents could use to perform editing\"; and answering docs/agent-tools-proposal.md: \"include wiki and unversioned files (for binary file sharing)\".",
      "reads": [
        "the run's checkout and clone",
        "the project's ocx-tests.json"
      ],
      "writes": [
        "the run's checkout and clone",
        "the server, by its push, as the run's user",
        "ocx-tests-passed.json beside the checkout, in its workspace"
      ],
      "specs": [
        "spec/ocx/checkout_tools_spec.cr"
      ],
      "used_by": [
        "an agent through its run's MCP",
        "the battery's local models"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's changes, extras, add, commit, push, pull, wiki and uv commands"
    },
    {
      "name": "Measure local models with the agent tools",
      "event": "person: crystal run battery/main.cr -- --models LIST --out DIR, on a host with an Ollama server",
      "purpose": "Show, with numbers, how well local models do saved tasks with OCX's tools over its MCP, and which shape of a tool or an answer helps them, so the tools are judged by the models they are for.",
      "shape": "Each task is data in battery/tasks: an objective, the checks that score it, the wiki pages and the project the scratch server starts with, its tests in ocx-tests.json. Each trial makes a scratch server and a run's workspace and holds the conversation OCX's own agent holds (src/ocx/ollama.cr): it offers the tools of the checkout's group through Ollama's tool calling, takes calls a model writes as text too, and ends when the model stops, at its step budget or at its wall; it is scored from the server, never the model's word, and every exact request, tool answer and reply is on its record. The variant plain takes ok and next_step out of the answers. With --audit REPOSITORY, it measures auditing instead: each model rates check-ins against the README's four virtues as written, through Ollama's structured output, a score and a reason for each and a verdict; on seeded pairs, the same change clean and with one known fault, whether it rates the faulty one lower on that virtue, fails it and names the fault, and passes the clean one; on check-ins of the history with a verdict recorded, whether it agrees; and over trials, whether its verdicts hold. With --read LIST, it measures reading instead: each model is handed OCX's documents, or sections of them by anchor, as the checks in battery/readings name them, with no tools, and answers each check's questions through Ollama's structured output, a numbered choice and the section it rests on; right is the right choice resting on a section that settles it, partial the right choice resting on another, so a document a client's author misreads is found before a client is written against it.",
      "parts": [
        "battery/audit.cr",
        "battery/audit_run.cr",
        "battery/audit_score.cr",
        "battery/main.cr",
        "battery/project.cr",
        "battery/reading.cr",
        "battery/reading_run.cr",
        "battery/run.cr",
        "battery/score.cr",
        "battery/summary.cr",
        "battery/task.cr",
        "battery/tasks/add-function/files/check_clamp.cr",
        "battery/tasks/add-function/files/spec/limits_spec.cr",
        "battery/tasks/add-function/files/src/limits.cr",
        "battery/tasks/fix-and-document/files/spec/sensor_spec.cr",
        "battery/tasks/fix-and-document/files/src/sensor.cr",
        "battery/tasks/fix-bug/files/spec/math_spec.cr",
        "battery/tasks/fix-bug/files/src/math.cr",
        "battery/tasks/multi-file-bug/files/spec/blink_spec.cr",
        "battery/tasks/multi-file-bug/files/src/blink.cr",
        "battery/tasks/multi-file-bug/files/src/units.cr",
        "battery/trial.cr",
        "src/ocx/fossil/scratch.cr",
        "src/ocx/mcp_ollama.cr",
        "src/ocx/ollama.cr"
      ],
      "origin": "The maintainer, 2026-10-15: \"can you make a crystal based battery to test the tools with local agents?\"",
      "reads": [
        "the battery's tasks",
        "an Ollama server",
        "the reading checks and the documents they name"
      ],
      "writes": [
        "a scratch project per trial",
        "each trial's record, the outcomes and a summary, under the directory given"
      ],
      "specs": [
        "spec/battery/battery_spec.cr",
        "spec/battery/audit_spec.cr",
        "spec/battery/reading_spec.cr"
      ],
      "used_by": [
        "the maintainer, deciding the tools' shapes"
      ],
      "state": "demonstrated",
      "coupling": "Ollama's /api/chat with tools, and OCX's MCP in the same process"
    },
    {
      "name": "Run a node: the daemon",
      "event": "host: bin/ocx2 daemon, under the host's service manager, which starts it again after it exits",
      "purpose": "Pull whole clones and hand open runs to watchers without ever launching a run twice after a restart.",
      "shape": "One machine lock; a signed-in node user per clone; named remotes; completion numbers by rename; watchers keep taken, ending and done under each run lock and post reports through Fossil pages.",
      "parts": [
        "src/ocx/fossil/pulls.cr",
        "src/ocx/server/pages.cr",
        "src/ocx/completion.cr",
        "src/ocx/daemon.cr",
        "src/ocx/commands/daemon.cr",
        "src/ocx/watcher/state.cr",
        "src/ocx/watcher/giving.cr",
        "src/ocx/watcher/reports.cr",
        "src/ocx/watcher/process.cr"
      ],
      "origin": "The design page \"How a post reaches an agent\", approved by the maintainer with \"go\" (2026-10-26).",
      "reads": [
        "the project password directory",
        "whole pulls and server receipts",
        "completion numbers and run states"
      ],
      "writes": [
        "clone pulls",
        "run states and completion numbers",
        "reports through Fossil pages",
        "daemon.log"
      ],
      "specs": [
        "spec/ocx/clone_server_spec.cr",
        "spec/ocx/completion_spec.cr",
        "spec/ocx/pulls_spec.cr",
        "spec/ocx/run_states_spec.cr",
        "spec/ocx/daemon_spec.cr",
        "spec/ocx/daemon_review_safety_spec.cr",
        "spec/ocx/daemon_review_history_spec.cr",
        "spec/ocx/daemon_setup_spec.cr",
        "spec/ocx/run_pages_spec.cr",
        "spec/ocx/giving_spec.cr",
        "spec/ocx/daemon_pages_spec.cr",
        "spec/ocx/server_pages_spec.cr",
        "spec/ocx/daemon_refusals_spec.cr",
        "spec/ocx/daemon_reads_spec.cr",
        "spec/ocx/giving_arrivals_spec.cr"
      ],
      "used_by": [
        "the agent machine's service manager"
      ],
      "state": "demonstrated",
      "coupling": "Fossil HTTP pages and named remotes, Linux inotify and file locks."
    },
    {
      "name": "Answer cards across repositories",
      "event": "person: cards or card through the CLI, CGI or MCP",
      "purpose": "Give each front end the same data and sentence from wiki card definitions across project clones.",
      "shape": "Read a card/NAME wiki JSON definition, select indexed Fossil columns in each named repository, order and limit combined items, and render its sentence. Missing optional tables and ticket columns yield no items.",
      "parts": [
        "src/ocx/commands/cards.cr",
        "src/ocx/fossil/cards.cr"
      ],
      "origin": "The maintainer, 2026-10-29, as quoted in HISTORY.md decision 129.",
      "reads": [
        "card/NAME wiki pages in the definitions repository",
        "forum, check-in, ticket and tag indexes in each named repository"
      ],
      "writes": [],
      "specs": [
        "spec/ocx/cards_spec.cr"
      ],
      "used_by": [
        "the console and offline readers such as Stone"
      ],
      "state": "demonstrated",
      "coupling": "Fossil 2.27 wiki, forum, event, ticket and tag indexes."
    },
    {
      "name": "Reach MCP as a connector, acting as one login",
      "event": "person: presses connector on the page, holding setup; a connector such as claude.ai's posts to ext/ocx2-cgi/mcp?key=KEY",
      "purpose": "Let a voice chat reach OCX while its person is away from the console, as one login holding only what it needs, never one holding admin or setup, its key made by a person's press and never by an agent (ollama forum posts f101f1c518 and 2527feb6cd).",
      "shape": "connector keeps the SHA-256 of a new key for a login holding neither admin nor setup and shows its URL once, or revokes it; each POST to the page's mcp with the key is one JSON-RPC message answered as MCP's, as the login kept for the key with the capabilities Fossil gives it then, listing and calling only status, questions, thread, post and ticket; 401 for a key that acts as no one, 405 for anything but a POST.",
      "parts": [
        "src/ocx/connector.cr",
        "src/ocx/commands/connector.cr"
      ],
      "origin": "The maintainer, 2026-11-05 (ocx-console posts 093cd88820 and 7fdfd4fd79): Claude's voice client reaching OCX while travelling, through one login approved by clicks; Fossil 2.27 passes an ext program no Authorization header, so the key is in the URL (ollama forum post 2be6a86560).",
      "reads": [
        "the served repository's connector keys and the login's capabilities",
        "what status, questions, thread and post read"
      ],
      "writes": [
        "the served repository's connector key for a login, by a person's press"
      ],
      "specs": [
        "spec/ocx/connector_spec.cr"
      ],
      "used_by": [
        "claude.ai's custom connectors"
      ],
      "state": "demonstrated",
      "coupling": "MCP's Streamable HTTP, one JSON message a POST; Fossil 2.27's ext CGI fields and user table."
    },
    {
      "name": "File a plain ticket",
      "event": "person: ticket, on the page or through a connector, on the served repository",
      "purpose": "Put an idea into Fossil as a ticket, as the maintainer's plan for Claude's connector asks first (\"Write (gated): create a Fossil ticket\"), with no run sent and no ticket a run files as its own record (precept A5).",
      "shape": "ticket starts an Open ticket titled and described as given, as the caller, refusing a clone's checkout, text holding an OCX message, a title not one line, a caller without NewTkt (n), and one without ModTkt (q) where the server holds new tickets for a moderator.",
      "parts": [
        "src/ocx/commands/ticket.cr",
        "src/ocx/writes.cr",
        "src/ocx/fossil/tickets.cr"
      ],
      "origin": "The Codex review of OCX's MCP for voice, finding 6 (ollama forum post 23f89f73da): no tool filed an ordinary ticket.",
      "reads": [
        "whether the served repository holds new tickets for a moderator"
      ],
      "writes": [
        "a new ticket's first change, as the caller"
      ],
      "specs": [
        "spec/ocx/ticket_spec.cr"
      ],
      "used_by": [
        "the connector",
        "the page"
      ],
      "state": "demonstrated",
      "coupling": "Fossil 2.27's ticket change artifact and its default ticket fields title, comment, status and mimetype."
    }
  ]
}
