clawdie-ai/doc/INTERAGENT-RUN-CONTRACT.md
Operator & Codex c5820dec84 Document Colibri Pi control plan
Park the Pi-only control simplification and cross-host run contract so other agents can review before implementation starts.

---
Build: pass | Tests: pass — 2456 passed (182 files)
2026-05-24 19:26:19 +02:00

7.6 KiB

Interagent Run Contract

Date: 14.maj.2026
Status: PLANNED — use as the first Colibri testground

Purpose

Use the OSA ↔ debby network throughput test as a practical testground for interagent communication while also diagnosing the public ISO download path.

This frees two birds at once:

  1. Validate the public XFCE USB artifact download path.
  2. Prove a simple cross-host coordination contract for future Colibri work.

Roles In The First Test

OSA / FreeBSD
  Role: server-side capture and summary
  Agent: Codex ISO Builder or FreeBSD/Pi operator agent
  Interface under test: vtnet0
  Scratch path: /home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID

Debby / Linux
  Role: client-side download, optional client capture, summary
  Agent: Hermes/Pi Linux operator agent
  Scratch path: ~/.local/state/hermes/net-tests/$TEST_ID

Domedog / Linux
  Role: optional coordinator hub
  Agent: operator-side Pi/Colibri prototype
  Function: aggregate manifests and display state, later via Herdr if useful

Protocol Separation

There are three separate protocol layers. Keep them separate in reports.

1. Download Under Test

Protocol: HTTPS
Transport: TCP
Port: 443
Direction: debby -> osa.smilepowered.org

The current ISO URL uses the public OSA path:

https://osa.smilepowered.org/downloads/iso/clawdie-xfce-quindecim-usb-24.05.26-9ba32d9.img.gz

This should traverse the public internet to OSA vtnet0, not tailscale0, unless the URL or routing is changed to a 100.x.y.z Tailscale address.

2. Packet Capture

Mechanism: local libpcap capture
Tools: dumpcap, tcpdump, tshark, capinfos
Network port: none for the capture itself

Packet capture writes local .pcapng files. The pcap is not streamed between hosts during capture.

3. Artifact Transfer If Needed

Protocol: SSH file transfer
Transport: TCP
Port: 22
Tools: scp or rsync -e ssh
Preferred path: Tailscale SSH/IP when available

Raw pcaps are binary diagnostic artifacts. Do not commit them to git.

Summary-First Exchange Rule

Agents exchange summaries first. Raw pcaps move only if summaries are not enough.

Exchange these text artifacts first:

  • TEST_ID
  • exact URL
  • host role
  • timestamps
  • curl timing output
  • capinfos output
  • tshark -q -z conv,tcp output
  • retransmit/reset/PMTU notes if collected
  • local pcap path

Only then, if deeper analysis is needed, pull the raw .pcapng via scp or rsync over SSH/TCP/22.

OSA Server-Side Workflow

Use a repo-local scratch path, not /root/net-tests.

cd /home/clawdie/clawdie-iso
TEST_ID="osa-clean-download-$(date -u +%Y%m%dT%H%M%SZ)"
SERVER_DIR="/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID"
mkdir -p "$SERVER_DIR"
date -u '+server_pcap_start_utc=%Y-%m-%dT%H:%M:%SZ' > "$SERVER_DIR/timestamps.txt"

If the debby public IP is known:

dumpcap -i vtnet0 -f 'host <DEBBY_PUBLIC_IP> and (tcp port 443 or icmp or icmp6)' -a duration:90 -w "$SERVER_DIR/osa-vtnet0-https-90s.pcapng"

If it is not known yet:

dumpcap -i vtnet0 -f 'tcp port 443 or icmp or icmp6' -a duration:90 -w "$SERVER_DIR/osa-vtnet0-https-90s.pcapng"

Then summarize locally:

capinfos "$SERVER_DIR/osa-vtnet0-https-90s.pcapng" > "$SERVER_DIR/capinfos.txt"
tshark -r "$SERVER_DIR/osa-vtnet0-https-90s.pcapng" -q -z conv,tcp > "$SERVER_DIR/tcp-conversations.txt"

Debby Client-Side Workflow

If the public IP is needed for the OSA capture filter:

curl -4 ifconfig.me

Run the bounded real-path HTTP/1.1 range test:

curl -L --http1.1 --range 0-536870911 -o /dev/null -w 'remote_ip=%{remote_ip}\nremote_port=%{remote_port}\ntime=%{time_total}s\nspeed=%{speed_download} B/s\n' https://osa.smilepowered.org/downloads/iso/clawdie-xfce-quindecim-usb-24.05.26-9ba32d9.img.gz

Route check for the public path:

ip route get <REMOTE_PUBLIC_IP_FROM_CURL>

If remote_ip is public and the route is not tailscale0, Tailscale is not in the ISO download data path.

Optional Raw Pcap Transfer

Pull OSA pcap from debby over SSH/TCP/22:

scp root@osa.smilepowered.org:/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/osa-vtnet0-https-90s.pcapng .

Or over Tailscale SSH/IP:

scp root@100.72.229.63:/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/osa-vtnet0-https-90s.pcapng .

Use rsync -e ssh instead of scp for resumable larger transfers.

Manifest Schema

Each side should write a small JSON manifest. This becomes the first concrete interagent message format for Colibri.

{
  "schema": "clawdie.interagent.run-manifest.v1",
  "test_id": "osa-clean-download-YYYYMMDDTHHMMSSZ",
  "role": "server-capture",
  "host": "osa",
  "agent": "codex-iso-builder",
  "started_at": "2026-05-14T12:00:00Z",
  "ended_at": "2026-05-14T12:01:30Z",
  "protocols": {
    "download": "HTTPS over TCP/443",
    "capture": "local libpcap",
    "artifact_transfer": "SSH over TCP/22 when needed"
  },
  "network": {
    "capture_interface": "vtnet0",
    "remote_host": "debby",
    "remote_public_ip": "<DEBBY_PUBLIC_IP>",
    "filter": "host <DEBBY_PUBLIC_IP> and (tcp port 443 or icmp or icmp6)"
  },
  "artifacts": {
    "pcapng": "/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/osa-vtnet0-https-90s.pcapng",
    "capinfos": "/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/capinfos.txt",
    "tcp_conversations": "/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/tcp-conversations.txt"
  },
  "summary": {
    "curl_time_total_sec": null,
    "curl_speed_download_bps": null,
    "retransmits_observed": null,
    "resets_observed": null,
    "pmtu_icmp_observed": null
  },
  "raw_transfer_required": false,
  "notes": []
}

Debby uses the same schema with role: "client-download" and its local artifact paths.

Tailscale Bottleneck Rule

For the current public ISO URL, Tailscale is probably not the download bottleneck because the tested URL resolves to the public OSA path and the OSA capture interface is vtnet0.

Prove this with:

  • curl remote_ip and remote_port
  • ip route get <remote_ip> on debby
  • OSA packet presence on vtnet0
  • absence of the same bulk flow on tailscale0

Tailscale can still affect:

  • SSH sessions
  • pcap transfer
  • interagent coordination
  • control/status polling

But that is separate from the public HTTPS download unless a 100.x.y.z path is used.

Colibri Integration Path

The run manifest is intentionally simple. Colibri can later ingest it as:

local run manifest(s)
  -> Colibri parser
  -> Clawdie task/activity state
  -> optional Herdr display on Linux

Do not make agents talk directly to each other as the primary design. Prefer a hub-and-spoke model:

OSA / FreeBSD spoke
  local safety: watchdog + hostd
  local artifacts: network-test summaries and pcaps

Debby / Linux spoke
  local artifacts: curl output, optional client pcaps

Coordinator hub
  Colibri aggregates manifests and Pi events
  Herdr optionally renders operator panes/status

The hub may be domedog or another operator Linux host. The hub is not allowed to bypass FreeBSD local safety.

Guardrails

  • Bind future sockets to loopback or Tailscale only; never 0.0.0.0 by default.
  • Use SSH keys and Tailscale ACLs for host-to-host transfers.
  • Keep status/read paths separate from command/write paths.
  • Raw pcaps stay out of git.
  • Summaries are exchanged before raw artifacts.
  • FreeBSD watchdog/hostd remain locally authoritative.
  • Every run gets a TEST_ID and manifests from each participating host.
  • doc/COLIBRI-PI-CONTROL-PLAN.md
  • doc/CONTROLPLANE-MESSAGE-CONTRACT.md
  • doc/CONTROLPLANE-ARCHITECTURE.md