# 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 ```text 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 ```text Protocol: HTTPS Transport: TCP Port: 443 Direction: debby -> osa.smilepowered.org ``` The current ISO URL uses the public OSA path: ```text 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 ```text 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 ```text 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`. ```sh cd /home/clawdie/clawdie-iso ``` ```sh TEST_ID="osa-clean-download-$(date -u +%Y%m%dT%H%M%SZ)" ``` ```sh SERVER_DIR="/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID" ``` ```sh mkdir -p "$SERVER_DIR" ``` ```sh date -u '+server_pcap_start_utc=%Y-%m-%dT%H:%M:%SZ' > "$SERVER_DIR/timestamps.txt" ``` If the debby public IP is known: ```sh dumpcap -i vtnet0 -f 'host 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: ```sh 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: ```sh capinfos "$SERVER_DIR/osa-vtnet0-https-90s.pcapng" > "$SERVER_DIR/capinfos.txt" ``` ```sh 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: ```sh curl -4 ifconfig.me ``` Run the bounded real-path HTTP/1.1 range test: ```sh 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: ```sh ip route get ``` 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: ```sh scp root@osa.smilepowered.org:/home/clawdie/clawdie-iso/tmp/network-tests/$TEST_ID/osa-vtnet0-https-90s.pcapng . ``` Or over Tailscale SSH/IP: ```sh 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. ```json { "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": "", "filter": "host 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 ` 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: ```text 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: ```text 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. ## Related Documents - `doc/COLIBRI-PI-CONTROL-PLAN.md` - `doc/CONTROLPLANE-MESSAGE-CONTRACT.md` - `doc/CONTROLPLANE-ARCHITECTURE.md`