atp — fountain-coded file transfer
SkillFiles & storageRun, 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.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the atp — fountain-coded file transfer skill
What this skill tells your AI
The instructions your AI receives, as published by dicklesworthstone/atp in skills/atp/SKILL.md and read by ahel’s review.
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:
# Linux / macOS (also fine over ssh for the remote end)
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 — checkatp --versionbefore trusting flag semantics below. - Since v0.3.7
--symbol-sizeis automatic per transport (1400 on rq, 1144 on quic). Pre-0.3.7 binaries require--symbol-size 1144by hand on QUIC or they fail closed at startup. --rq-auth-key-hexon--transport quicis 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-olderatp --helphas nobond-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
# Encrypted fountain tier (quic — the policy default; certs per OPERATIONS.md)
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
# Authenticated fountain tier (rq — the fallback; one shared key, no certs)
KEY=$(atp rq-keygen) # once; or ATP_RQ_AUTH_KEY_HEX
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"
# ssh-bootstrap one-liner — say --transport rq explicitly: the CLI default is
# tcp, which violates the policy; rq bootstrap auto-generates a per-transfer
# key (quic bootstrap works too once the peer has certs — see the profile)
atp send ./dataset user@host:/backups/dataset --transport rq
atp serve ./inbox --transport rq --rq-auth-key-hex "$KEY" # persistent daemon
atp send ./dataset host:8472 --dry-run # plan JSON, sends nothing
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.
# One command on the receiving machine (donors need atp on PATH via ssh):
atp bond-pull /data/big.tar ./inbox --donors ubuntu@h1,ubuntu@h2,ubuntu@h3 \
--advertise 10.0.0.5:8473 # control address donors dial — explicit,
# never inferred; wildcard fails closed
# Or run the legs yourself:
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 # on each donor
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-byteson 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|quicwork 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 useright after a previous run = TIME_WAIT; wait a few seconds or change--listenport.- 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-labon 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-nameinstead. - 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-sizeon 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-gcmover 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>.mdfirst; 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.
Signals
- GitHub stars
- 80
- Forks
- 4
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
atp- Source
- github.com/dicklesworthstone/atp