atp — fountain-coded file transfer

SkillFiles & storage

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.

Available today. Use it from your connected AI after setup.

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 machinesscripts/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 environmentscripts/smoke.sh (real loopback transfer, exit 0 = healthy)
Send/receive a file or treeCanonical Invocations below — pick the row from Choose a Transport first
Judge whether a transfer succeededexit code 0, or pipe the report into scripts/check-report.sh
Decode an error messageFailure→Fix table, then TROUBLESHOOTING.md
Look up a flag's exact semanticsCLI.md
Set up keys/certs, tune a lossy link, benchmarkOPERATIONS.md
Embed transfer capability in a Rust projectLIBRARY.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 — 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.)

SituationTransportAuth you must provide
CLI default; scripted/legacy pipelinestcpnone
Lossy/latent link (Wi-Fi, WAN, cross-continent)rqatp rq-keygen key on both ends, or --rq-allow-unauthenticated-lab on both (trusted lab only)
Encryption requiredquicreceiver --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:

  1. committed — false means nothing was written to the destination.
  2. sha_ok / merkle_ok — the integrity verdict (fail-closed; a false here with committed=true cannot happen).
  3. feedback_rounds — 0 on clean links; growing numbers mean loss-driven repair rounds (expected on bad links, suspicious on a LAN).
  4. 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)

SymptomCauseFix
direct rq transfers require symbol authenticationrq without keyatp rq-keygen → both ends, or lab flag on both
QUIC cert error at handshakeverification working as designed--ca must sign the receiver's cert; --server-name must match a SAN (defaults to target host)
object size exceeds limit4 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 CPUdebug builduse release binaries / install.sh
Connect/handshake timeout ~30–60 swrong port, UDP blocked, or another process on the socket pairverify 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

NeedRead
Full flag reference per subcommand, env vars, per-transport resolutionCLI.md
Playbooks: keys/certs, ssh bootstrap, daemon, tuning, honest benchmarkingOPERATIONS.md
Exact error strings → root cause → fixTROUBLESHOOTING.md
Library embedding (crate features, Cx runtime, module map)LIBRARY.md
Save a known-good peer setup for instant reusePEER-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