| name | atp |
| description | Run, debug, and tune atp transfers (fountain-coded rsync alternative). Use when sending files with atp, picking transports or security tiers, reading reports, or embedding the asupersync crate. |
| dependencies | ["atp release binary (install.sh) — debug builds are orders of magnitude slower at RaptorQ decode","Both ends run atp; explicit tuning flags must match on both ends"] |
atp — fountain-coded file transfer
Dispatch (start here)
| You need to… | Do |
|---|
| Install or update atp (either end) | Update section below — one-liner, safe to re-run, keeps both ends on the same version |
| Roll atp out across the user's ssh machines | scripts/fleet-install.sh --list, ASK the user which hosts (all or some), then run it with their picks |
| Send to a machine you've sent to before | ~/.config/atp/peers/<host>.md — reuse the saved command verbatim; do NOT rediscover transport/certs/data-host |
| Verify atp works in this environment | scripts/smoke.sh (real loopback transfer, exit 0 = healthy) |
| Send/receive a file or tree | Canonical Invocations below — pick the row from Choose a Transport first |
| Judge whether a transfer succeeded | exit code 0, or pipe the report into scripts/check-report.sh |
| Decode an error message | Failure→Fix table, then TROUBLESHOOTING.md |
| Look up a flag's exact semantics | CLI.md |
| Set up keys/certs, tune a lossy link, benchmark | OPERATIONS.md |
| Embed transfer capability in a Rust project | LIBRARY.md — atp is the asupersync crate's transfer subsystem |
| Pull one file/tree from MANY machines at once (multi-donor "bonding") | atp bond-pull SRC DEST --donors u@h1,u@h2 --advertise <my-ip:port> — one command; see Multi-Donor Pull below (binaries ≥ v0.3.8 / current main) |
One Rule
Never trade integrity for speed, and never claim a speed atp did not earn.
Every transfer is SHA-256 verified and fails closed; every performance claim
must trace to the append-only evidence ledger (see Provenance). If a transfer
did not commit ("committed": true in the JSON report), it did not happen.
Transport Policy (standing owner preference)
"Optimal" means the fountain tiers: always quic (RaptorQ symbols under
TLS 1.3); rq as the fallback when QUIC is blocked. Never plain tcp for
interactive sends — the fountain-coded data plane is the entire point of
atp; a tcp transfer is what rsync already does. QUIC/TLS is built into every
atp binary (no feature flags, no extra install), and the ssh-bootstrap
one-liner works with --transport quic too. The Choose a Transport table
below is generic protocol guidance, not permission to pick tcp for
convenience.
Peer Profiles (zero-rediscovery repeat sends)
- Before any send, check
~/.config/atp/peers/<host>.md. If present, reuse
the saved command verbatim — transport, --data-host, cert paths,
--server-name, quirks are already solved.
- After the first successful transfer to a NEW peer (or when settings
change), write that file: the exact working command, why each non-default
flag is there, cert locations + expiry, last-verified date + result.
Template: PEER-TEMPLATE.md.
- Profiles live under
~/.config/atp/ — NOT inside the skill folder — so
skill upgrades/reinstalls never delete them, and both the Claude and Codex
copies of the skill share them.
- Profiles carry no secrets: quic needs no symbol key (TLS AEAD covers it)
and ssh bootstrap generates per-transfer rq keys; store only paths/flags.
Update / Install (do this when versions lag or differ)
When atp --version on either end is older than this skill's boundary card
— or the two ends differ — update BEFORE debugging flag or behavior
mismatches; explicit tuning flags must match across the pair and defaults
evolve. The installer is idempotent and safe to re-run:
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/atp/main/install.sh | bash
# Windows (PowerShell 5.1+)
irm https://raw.githubusercontent.com/Dicklesworthstone/atp/main/install.ps1 | iex
Pin a version with bash -s -- --version vX.Y.Z / -Version vX.Y.Z;
--skill also refreshes this skill. Verify after: atp --version +
scripts/smoke.sh.
Fleet rollout: offer to install/update atp on the user's ssh machines.
scripts/fleet-install.sh --list enumerates concrete ~/.ssh/config hosts;
present the list and let the user choose all or some (never assume), then
scripts/fleet-install.sh <picks…> (or --all). BatchMode ssh (no
password hangs), idempotent, per-host HOST/STATUS/version verdicts,
non-POSIX remotes reported for manual install.ps1. A fresh peer machine
becoming reachable is a natural moment to offer this.
Boundary Card (v0.3.7, 2026-07-10)
- Latest release: v0.3.7 (5 platform binaries + SHA256SUMS), built from
asupersync
64ebd17d3. Older binaries on PATH behave differently — check
atp --version before trusting flag semantics below.
- Since v0.3.7
--symbol-size is automatic per transport (1400 on rq,
1144 on quic). Pre-0.3.7 binaries require --symbol-size 1144 by hand on
QUIC or they fail closed at startup.
--rq-auth-key-hex on --transport quic is ignored (QUIC's TLS 1.3 AEAD
already authenticates datagrams); ≥0.3.7 prints a notice saying so.
- Multi-donor bonding has a full CLI trio (
bond-donate / bond-recv /
bond-pull) on main and in binaries after v0.3.7 — a v0.3.7-or-older
atp --help has no bond- subcommands; update both ends first.
- Honest losing cells (do not oversell): encrypted single huge files on
pristine fast links (rsync-over-ssh ~1.5×, trees ~2.5×); sender RSS can
peak ~10× rsync's on 2–10% loss links (receiver stays ≤ 18 MB).
Choose a Transport
(Generic protocol guidance — the Transport Policy above overrides this for
interactive sends: quic first, rq fallback.)
| Situation | Transport | Auth you must provide |
|---|
| CLI default; scripted/legacy pipelines | tcp | none |
| Lossy/latent link (Wi-Fi, WAN, cross-continent) | rq | atp rq-keygen key on both ends, or --rq-allow-unauthenticated-lab on both (trusted lab only) |
| Encryption required | quic | receiver --server-cert/--server-key; sender --ca unless the cert chains to a system root |
| "Just pick the best" | auto (quic→rq→tcp) | only engages beyond TCP with --no-delta (br-asupersync-dg8juf) |
Receiver --transport must match the sender's data plane. rq refuses to
run unauthenticated unless BOTH ends explicitly opt into the lab tier.
Canonical Invocations
atp recv ./inbox --listen 0.0.0.0:8472 --transport quic --once \
--server-cert cert.pem --server-key key.pem
atp send ./dataset receiver.example.com:8472 --transport quic \
--ca ca.pem --server-name receiver.example.com
KEY=$(atp rq-keygen)
atp recv ./inbox --listen 0.0.0.0:8472 --transport rq --once --rq-auth-key-hex "$KEY"
atp send ./dataset host:8472 --transport rq --rq-auth-key-hex "$KEY"
atp send ./dataset user@host:/backups/dataset --transport rq
atp serve ./inbox --transport rq --rq-auth-key-hex "$KEY"
atp send ./dataset host:8472 --dry-run
Multi-Donor Pull (bonding — N machines feed one receiver)
Donors holding a byte-identical copy each spray a residue-disjoint slice
of the same RaptorQ fountain; any K symbols from any mix reconstruct each
block, a dead donor's repair windows are reallocated to the survivors, and
goodput scales with donor count. Enrollment assigns each donor its
index/slice server-side; commit stays fail-closed sha+merkle.
atp bond-pull /data/big.tar ./inbox --donors ubuntu@h1,ubuntu@h2,ubuntu@h3 \
--advertise 10.0.0.5:8473
atp bond-recv ./inbox /local/byte-identical-copy --expect-donors 2 --listen 0.0.0.0:8473
atp bond-donate /data/big.tar --to receiver:8473
bond-recv standalone needs a local byte-identical SOURCE to derive the
transfer descriptor (the protocol never transmits it; enrollment fail-closes
on any transfer-id/merkle/metadata mismatch). bond-pull removes that need
by fetching the descriptor from the first donor over ssh. Descriptors commit
the portable content shape, so fleet replicas with different mtimes/OSes
still agree. Report adds enrolled_donors, per-donor donor_ingress, and
reallocated_repair_windows.
Exit Codes & Report
Contract (from main()): exit 0 ⇒ the transfer committed and verified;
exit 1 ⇒ failed closed with atp failed: <reason> on stderr. The JSON
report is on stdout, diagnostics on stderr — capture them separately
(atp send … > report.json 2> diag.log). Never parse stderr.
Reading the report — check in this order:
committed — false means nothing was written to the destination.
sha_ok / merkle_ok — the integrity verdict (fail-closed; a false here
with committed=true cannot happen).
feedback_rounds — 0 on clean links; growing numbers mean loss-driven
repair rounds (expected on bad links, suspicious on a LAN).
bytes_*, wall time, transport — what actually ran (matters with auto).
Remaining Gotchas (real, by design)
- Transfers > 4 GiB: raise
--max-bytes on both ends (deliberate
fail-closed ceiling, not a capability limit).
auto + delta: the QUIC→RQ ladder only engages with --no-delta;
otherwise auto = tcp. Explicit --transport rq|quic work fine with delta.
- Delta sidecar port: the receiver's planner listens on listen-port+1.
If firewalled, transfers still work — sender warns and falls back to
full-object transfer.
- Explicit tuning flags must match both ends (
--symbol-size,
--max-block-size, --repair-overhead). Defaults always agree; only
explicit values can diverge.
Address already in use right after a previous run = TIME_WAIT; wait a
few seconds or change --listen port.
- Not an rsync drop-in: no
--exclude, no --delete, no mirror-mode
semantics. It moves data fast and verified; it is not a mirroring toolchain.
Failure → Fix (fast path)
| Symptom | Cause | Fix |
|---|
direct rq transfers require symbol authentication | rq without key | atp rq-keygen → both ends, or lab flag on both |
| QUIC cert error at handshake | verification working as designed | --ca must sign the receiver's cert; --server-name must match a SAN (defaults to target host) |
object size exceeds limit | 4 GiB guard | --max-bytes N on both ends |
max_datagram_size (1200) must be at least symbol_size… | explicit oversize on quic (or pre-0.3.7 binary) | drop the flag; upgrade |
| Slow transfers, high CPU | debug build | use release binaries / install.sh |
| Connect/handshake timeout ~30–60 s | wrong port, UDP blocked, or another process on the socket pair | verify reachability; check the sidecar port too |
More: TROUBLESHOOTING.md
Anti-Patterns
- Don't "fix" an auth error with
--rq-allow-unauthenticated-lab on a
real link — it disables symbol auth on both ends. Generate a key instead.
- Don't look for a QUIC skip-verify flag. There isn't one; fix the cert
chain /
--server-name instead.
- Don't benchmark or bisect with a debug build — RaptorQ decode is
orders-of-magnitude slower; every conclusion will be wrong.
- Don't set
--symbol-size on one end only. Omit it everywhere (defaults
agree) or set it identically on both.
- Don't compare against lazy rsync. Claims are only valid vs
-aW --inplace --no-compress (+ aes128-gcm over ssh) — see OPERATIONS.md.
- Don't retry a failed transfer blind. Read
atp failed: <reason> on
stderr first — fail-closed errors state the exact fix.
- Don't interpret "optimal" as "least setup" and quietly use tcp. The
owner's standing policy is quic (rq fallback); tcp forfeits the fountain
data plane that justifies using atp at all.
- Don't rediscover a known peer. Check
~/.config/atp/peers/<host>.md
first; write it after any first successful transfer.
Reference Index
| Need | Read |
|---|
| Full flag reference per subcommand, env vars, per-transport resolution | CLI.md |
| Playbooks: keys/certs, ssh bootstrap, daemon, tuning, honest benchmarking | OPERATIONS.md |
| Exact error strings → root cause → fix | TROUBLESHOOTING.md |
| Library embedding (crate features, Cx runtime, module map) | LIBRARY.md |
| Save a known-good peer setup for instant reuse | PEER-TEMPLATE.md → ~/.config/atp/peers/<host>.md |
| Where these claims come from (ledger, beads, commits) | PROVENANCE.md |
Source of truth when this skill disagrees with reality: the asupersync
source at the commit pinned in this repo's UPSTREAM_REV, then atp --help
from the exact binary in use, then this skill. File a bead when they diverge.