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)
298 lines
7.6 KiB
Markdown
298 lines
7.6 KiB
Markdown
# 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 <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:
|
|
|
|
```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 <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:
|
|
|
|
```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": "<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:
|
|
|
|
```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`
|