{
  "as_of": "3998ae4db6",
  "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, 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, 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/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"
      ],
      "used_by": [
        "every tool",
        "the hook",
        "the git export"
      ],
      "state": "demonstrated",
      "coupling": "Fossil 2.27's command line, its SQL schema and its forum artifact format, and git 2.x's upload-pack, each in its own module."
    },
    {
      "name": "Stage a release",
      "event": "person: bin/ocx2 stage CHECKOUT | accept | rollback",
      "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 the shard.yml targets built from tools/, gate.txt and source.txt; DIR/staged/next naming it; accepting copies it into DIR and moves current and previous; rolling back swaps them.",
      "parts": [
        "src/ocx/staging.cr",
        "src/ocx/releases.cr",
        "src/ocx/worktree.cr",
        "src/ocx/commands/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/guards/provenance_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]]",
      "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. Every answer carries that log of typed operations, the result only when the tool ran to the end, and why it stopped. 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.",
      "parts": [
        "src/ocx/refusal.cr",
        "src/ocx/elements.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"
      ],
      "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"
      ],
      "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, and each command as a card with its form, the capabilities it needs marked for the viewer and what it would do now, inside Fossil's skin, or the command's JSON; a command that needs a capability is taken only by a same-site POST.",
      "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"
      ],
      "specs": [
        "spec/ocx/styles_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",
      "purpose": "Give an agent every command as a tool with its schema, answering with the same JSON.",
      "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"
      ],
      "origin": "Slice 1 of docs/slices.md; trunk's src/mcp_server.cr.",
      "reads": [
        "JSON-RPC messages"
      ],
      "writes": [
        "JSON-RPC answers"
      ],
      "specs": [
        "spec/ocx/styles_spec.cr",
        "spec/ocx/harness_spec.cr"
      ],
      "used_by": [
        "agents"
      ],
      "state": "demonstrated",
      "coupling": "The MCP protocol version 2024-11-05."
    },
    {
      "name": "Log a hook run",
      "event": "hook: bin/ocx2-hook --log FILE REPOSITORY < ARTIFACTS",
      "purpose": "See each after-receive hook run, which Fossil keeps no record of, without opening the repository it was called for.",
      "shape": "One JSON line per run appended to the log named with --log (when, the repository, the received artifacts' hashes, and how long it took), read across releases, so no field is renamed and a field added is optional; nothing on standard output, which Fossil closes unread; a run that cannot log says why on standard error. It opens no repository and takes no command.",
      "parts": [
        "src/ocx/hook.cr"
      ],
      "origin": "Slice 0.5 of docs/slices.md, \"The harness\".",
      "reads": [
        "the received artifacts' hashes on standard input"
      ],
      "writes": [
        "the hook log"
      ],
      "specs": [
        "spec/ocx/harness_spec.cr",
        "spec/ocx/hook_spec.cr"
      ],
      "used_by": [
        "the Fossil server"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's after-receive hook and its %R substitution."
    },
    {
      "name": "Answer and run protocol v1's runs for a node",
      "event": "hook: bin/ocx2-hook --log FILE --node USER REPOSITORY < ARTIFACTS, as `ocx2 hook --node USER` installs it; and `ocx2 hook --node USER` itself, which checks the node's runs",
      "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": "On each hook run, for the artifacts Fossil listed and nothing else, a round under a lock in the node's directory: each run for the node among them, and each run a listed stop names, decided by protocol v1's rules (src/ocx/decisions.cr) from the repository's OCX messages and who the server says sent each (src/ocx/server.cr); an ended written for each refusal, stop before a start, or lost program, as a reply in the run's thread or a change to its ticket, as the node user; a running program's watcher asked to end it for a stop; and each run to start handed to a watcher, the hook again with --watch, which prepares it, writes started, performs its workspace steps, then runs its process inside its sandbox and limits as docs/protocol-v1.md's tables give them (src/ocx/steps.cr, src/ocx/launch.cr), its run first on its standard input, posts the kept ends of its STDERR and STDOUT, and writes ended; and each running session given what it subscribes to among the artifacts listed, after its started: a line of JSON in its inbox, which its watcher passes on to the program's standard input. Logged in the hook's line as answered, handed, unhanded (runs decided to start but not handed, outside a release root), ending, given, watched and reports. What the hook missed is found by a deliberate check, never swept up (HISTORY.md decision 39); and when the node starts, hook --node USER checks every run for it, answering lost a run whose program its going down left and handing on one never started (section 10).",
      "parts": [
        "src/ocx/node.cr",
        "src/ocx/server.cr",
        "src/ocx/watcher.cr",
        "src/ocx/decisions.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/node/view.cr",
        "src/ocx/care.cr",
        "src/ocx/relay.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": [
        "the artifacts Fossil lists as arrived",
        "the repository's forum posts and ticket changes holding an OCX message, and their receipts",
        "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"
      ],
      "writes": [
        "an ended for each run it answers, and a started and ended for each it runs, as the node user",
        "a fresh password on a run's user, and its workspace",
        "the hook log's answered, handed, unhanded, ending, given, watched and reports",
        "a line of JSON in a running session's inbox for each artifact it is given"
      ],
      "specs": [
        "spec/ocx/node_spec.cr",
        "spec/ocx/watcher_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/sandbox_spec.cr"
      ],
      "used_by": [
        "the Fossil server, once the hook is installed with --node"
      ],
      "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 its node user; or bin/ocx2 receipt --artifacts 'HASH ...' [--capabilities-of USER] on the served host",
      "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, to a caller who may read. Never an address.",
      "parts": [
        "src/ocx/commands/receipt.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"
      ],
      "used_by": [
        "nodes on clones, through `node` (HISTORY.md decision 43)"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's blob, rcvfrom, private and user tables."
    },
    {
      "name": "Be a node on another host",
      "event": "timer: bin/ocx2 node --repository CLONE SERVER-URL PASSWORDS-FILE [--check] on a build host or lab board, from cron or a timer, or a person there",
      "purpose": "Add a build machine or a lab board as a node of protocol v1, working from its own clone of the server, so runs can name hardware other than the server's host (docs/protocol-v1-fossil.md, section 5).",
      "shape": "Signs in to the server as the node user its file of passwords names, through Fossil's login page; pulls the clone; acts on the runs and stops among what the pull brought, or with --check on every run for the node, deciding each by who the server's receipt tool says sent each artifact, in the server's order; pushes each report it writes and goes on only once the server has it from the node user; and hands each run to start to a watcher, which runs the program as the run's user with the password the file holds, started reaching the server before the launch. A run user works for the node of the first run naming it; every other node refuses it.",
      "parts": [
        "src/ocx/commands/node.cr",
        "src/ocx/server.cr"
      ],
      "origin": "The maintainer at the terminal, 2026-10-13: protocol v1 was reviewed so that the build machine and lab boards could be added as nodes (HISTORY.md decision 43).",
      "reads": [
        "what the pull brought, and the clone's OCX messages",
        "the server's receipts, through its receipt tool",
        "the node's file of passwords"
      ],
      "writes": [
        "the clone, by a pull",
        "started and ended for each run, as the node user, pushed to the server",
        "the node's log line, and each run's workspace"
      ],
      "specs": [
        "spec/ocx/remote_node_spec.cr"
      ],
      "used_by": [
        "build hosts and lab boards, from decision 43 on"
      ],
      "state": "demonstrated",
      "coupling": "Fossil's login page, sync and receipts on the server; OCX's receipt tool on the server's web page."
    },
    {
      "name": "Write a run",
      "event": "person: bin/ocx2 create [--pattern URL] (--title TITLE | --to POST | --ticket TICKET) [--objective TEXT] [--node USER] [--user USER] [--fields JSON] on the served host, or the web page's create form",
      "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": "The fields of the first fenced JSON block of the text at the pattern's URL (Markdown, a wiki page as Fossil serves it, or a bare JSON object; of a wiki page of the served repository, its newest version an admin or setup wrote, read there), then those given by name, then those of --fields, each replacing what was there, known to OCX or not; the run checked as a node checks it and refused, writing nothing, when a node would refuse it; written as the caller on the served repository: the first post of a new thread, a reply in the thread of the post replied to, or a change to a ticket; and acted on at once by this host's node when the run names it, since a write on the repository itself starts no hook (HISTORY.md decision 39).",
      "parts": [
        "src/ocx/commands/create.cr",
        "src/ocx/served.cr",
        "src/ocx/writes.cr",
        "src/ocx/messages.cr",
        "src/ocx/fossil/wiki.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",
        "where the hook stands, and the node it names"
      ],
      "writes": [
        "the run: a forum post or a ticket change, as the caller",
        "what the node writes acting on it at once"
      ],
      "specs": [
        "spec/ocx/create_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, put with test-content-put and indexed with test-crosslink; 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 on the served host, or the web page's run form",
      "purpose": "Start a run whose manual is true, which its node leaves waiting for a person, so a person decides when it starts.",
      "shape": "The run found by its hash or a prefix of it; the round of this host's node over it, decided as started by a person (Situation's by_hand); handed to a watcher, which writes its started and ended as the node user, or refused with why: the node's answer, or that it is not waiting for a person.",
      "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 and the node it names",
        "where the hook stands, and the node it names"
      ],
      "writes": [
        "what the node writes: an ended for a run it refuses, and the hook's log line",
        "a watcher, started detached"
      ],
      "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 release root's link to the served release, through which the watcher is started."
    },
    {
      "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 in its thread, or a change to its ticket; acted on at once by this host's node when the run names it.",
      "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",
        "where the hook stands, and the node it names"
      ],
      "writes": [
        "the stop: a forum post or a ticket change, as the caller",
        "what the node writes acting on it at once"
      ],
      "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": "Fossil's forum artifacts and ticket changes."
    },
    {
      "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: when a check-in arrives; person: bin/ocx2 export on the served host, or the web page's form",
      "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 git export into the directory the repository's last-git-export-repo setting names, one run at a time: an ask left in the export's .git before its flock is tried, the holder exporting while one is left; the run kept there as JSON; a failed export refused with what Fossil said; the state as fossil git status gives it, and a dry run listing what awaits, the autopush and the last failure.",
      "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": "Import a git repository",
      "event": "person: bin/ocx2 import UPSTREAM NAME [--mirrors DIR] on the served host, or the web page's form",
      "purpose": "Bring a project kept in git into OCX as a served repository whose development serves back to git: what Fossil adds exports onto the upstream's own commits, so a clone of the upstream fetches it as a fast-forward.",
      "shape": "The upstream cloned bare, its branches written as git's fast-export stream with marks and imported into a new Fossil repository with Fossil's marks, each in a sandbox; the new repository placed beside the served one, its git export made of the clone with its state seeded from the two marks, and the hook installed as on the served one; last, it joins the served one's login group, so its admin, the caller, signs in to it as to the served one; the answer gives the public URL its administrator sets; tags stay git's; a run that fails leaves nothing, the new repository leaving the group first, and a name already served or exported is refused.",
      "parts": [
        "src/ocx/commands/import.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 upstream, in a sandbox",
        "the served repository's git export, hook and public URL"
      ],
      "writes": [
        "a new repository beside the served one",
        "its git export",
        "its hook",
        "the login group of it and the served one, in both"
      ],
      "specs": [
        "spec/ocx/import_spec.cr",
        "spec/ocx/dry_run_spec.cr"
      ],
      "used_by": [
        "the maintainer, bringing a project into OCX"
      ],
      "state": "unused",
      "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": "Write a plain post",
      "event": "person: bin/ocx2 post TO TEXT in a clone's checkout, or a program's ocx.post",
      "purpose": "Let a person or a run's program answer in a thread or on a ticket as its user, from its own clone, with no OCX message in it.",
      "shape": "A reply in the thread of the post replied to, composed as Fossil's forum artifact, put in the caller's clone and pushed, or a change to a ticket made there and pushed; refusing text that holds an OCX message, and saying when the push did not reach the served repository.",
      "parts": [
        "src/ocx/commands/post.cr",
        "src/ocx/fossil/forum.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"
      ],
      "used_by": [
        "run programs in their clones, and people at a terminal in a clone"
      ],
      "state": "unused",
      "coupling": "Fossil 2.27's forum artifact format and its test-content-put command, 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 ocx2-hook after each receipt, as the served release, so the git export follows each check-in; and let anyone see whether it is installed, when it runs and its last run.",
      "shape": "The release root's link ocx2-hook to current/ocx2 and its node directory; ROOT/ocx2-hook --log ROOT/node/hook.log %R added to the repository's hooks, once, one run otherwise replaced and other hooks untouched; status reads the hooks, the backoffice settings as Fossil reads them and the log's last line.",
      "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",
        "the hook log"
      ],
      "writes": [
        "the repository's hooks setting",
        "the release root's ocx2-hook link and node directory"
      ],
      "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, and its backoffice, started after a page that answers 200 and leased for a minute."
    }
  ]
}
