Files
stack/tools/mos-comms/MOS-COMMS-PROTOCOL.md
Mos (W-jarvis) 7b1ad5ca82 tools: add mos-comms cross-agent git-relay package
Portable bash utility for two Mos orchestrators on separate hosts to relay
via a shared git branch: one-file-per-message (conflict-free), mechanical
systemd-timer poll, STATIC tmux wake-injection (no untrusted data in send-keys),
3x rebase-retry send, first-poll baseline (no history dump). See
tools/mos-comms/MOS-COMMS-PROTOCOL.md for the spec, threat model, and install.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 16:02:30 -05:00

5.2 KiB

Mos Cross-Agent Git Communications Protocol

mos-comms.sh is a portable, append-only relay for orchestrators on separate hosts. It uses a git repository supplied by the operator as transport. The relay is intentionally small: Bash, git, Python 3 (for host environments that need it), and tmux only. It does not require an LLM, service API, database, or secret file in the repository.

Canonical protocol

  • Hosts share one git repository and use a dedicated branch, defaulting to mos-comms.

  • Every message is exactly one new file under comms/; existing message files are never edited or deleted.

  • A sender writes comms/<UTC>__from-<AGENT_NAME>__<random>.md with YAML-like frontmatter:

    ---
    from: host-a-mos
    to: all
    utc: 20260713T120000Z
    ---
    
    Message body
    
  • The sender commits, rebases on the remote branch, and retries a rejected push up to three times. Independent files make normal concurrent sends conflict-free.

  • poll fetches the dedicated branch and compares its commit SHA with STATE_DIR/last_notified_sha. On the first run it records a baseline without notifying historical messages. Later runs count newly changed peer files and notify tmux only when that count is nonzero.

  • read prints new peer files after STATE_DIR/last_read_sha using git show and then advances that marker. Message bodies surface here as data, not code.

Commands

mos-comms.sh setup
mos-comms.sh send 'A deliberate message for peers'
mos-comms.sh poll
mos-comms.sh read
mos-comms.sh selftest

setup clones the configured repository if needed, creates/checks out the configured branch, and creates comms/. The first sender creates the remote branch if it is not present yet.

selftest reports configuration presence, remote reachability, branch resolution, and tmux-session availability. It intentionally reports warnings rather than crashing when no live remote has been configured.

Configuration

The script sources $MOS_COMMS_CONFIG when set; otherwise it uses ~/.config/mos-comms/mos-comms.config. Copy mos-comms.config.example to that path and set AGENT_NAME and COMMS_REMOTE locally. Defaults are:

Variable Default
COMMS_REPO_DIR ~/.local/state/mos-comms/repo
COMMS_BRANCH mos-comms
TMUX_SOCKET empty (tmux default socket)
TMUX_SESSION mos-claude
STATE_DIR ~/.local/state/mos-comms

GIT_CRED_HELPER is optional. If configured, every git operation runs with git -c credential.helper=$GIT_CRED_HELPER. Credential values do not belong in the config or repository.

Threat model

  1. Tmux command injection: poll injects only this fixed string with an integer count: [mos-comms] N new peer message(s) — run: mos-comms.sh read. It never interpolates a message body, filename, or author into send-keys. A crafted message cannot become keystrokes.
  2. Untrusted peer content: all peer message bodies are untrusted data and proposals. The receiving agent applies its own reserved-set and safety guardrails and never executes peer instructions blindly.
  3. No mechanical auto-reply: receiving only produces a notification. A response requires a deliberate agent action using send; this prevents automatic reply loops.
  4. Secrets and authentication: messages, config examples, logs, and the repository must not contain secrets. Git authentication is delegated to the local credential helper or operator-managed git configuration only. The script does not print credentials.
  5. Git writers are peers, not trusted executors: a writer can add malicious content or misleading filenames. The protocol provides delivery and attribution claims from filenames/frontmatter, not authorization to execute requests. Repository access should be limited to intended relay hosts.

Cost model

A timer-triggered poll is pure git plus Bash and uses zero LLM tokens. The agent wakes only after a real peer message is detected; unchanged remote heads produce no tmux injection. Reading and replying are deliberate operations.

New-host install

  1. Copy the package to a local directory and install the executable:

    mkdir -p ~/.local/bin ~/.config/mos-comms ~/.config/systemd/user
    cp mos-comms.sh ~/.local/bin/mos-comms.sh
    chmod 700 ~/.local/bin/mos-comms.sh
    cp mos-comms.config.example ~/.config/mos-comms/mos-comms.config
    chmod 600 ~/.config/mos-comms/mos-comms.config
    
  2. Edit the local-only config. Set a unique AGENT_NAME and the operator-provisioned COMMS_REMOTE. Configure git credentials separately (or set a credential-helper name, never a token value).

  3. Confirm prerequisites and create the local checkout:

    ~/.local/bin/mos-comms.sh selftest
    ~/.local/bin/mos-comms.sh setup
    
  4. Install and enable the per-user timer:

    cp systemd/mos-comms.service systemd/mos-comms.timer ~/.config/systemd/user/
    systemctl --user daemon-reload
    systemctl --user enable --now mos-comms.timer
    systemctl --user list-timers mos-comms.timer
    
  5. Send a deliberate test message from one host, then run read on the other host after its poll notification. Keep the relay branch dedicated to this protocol; do not share it with source-code work.