docs(attachments): zero-friction quick start — no peer.sh, no send.sh#176
docs(attachments): zero-friction quick start — no peer.sh, no send.sh#176kitplummer wants to merge 4 commits into
Conversation
…o send.sh Replaces the manual `peer.sh` step with `PEAT_NODE_PEERS` using deterministic endpoint IDs (HKDF-SHA256 offline derivation), and adds `PEAT_NODE_ATTACHMENT_OUTBOX_WATCH` so files dropped in the outbox auto-distribute with no `SendAttachments` call. Two separate compose files (`node-a/`, `node-b/`) match the peat-local-a / peat-local-b pattern: each node runs from its own directory, peers over `host.docker.internal` so the two Docker projects stay network-isolated, and publishes its iroh UDP port to the host for direct QUIC. Works on macOS Docker Desktop and Linux Docker Engine (`extra_hosts: host.docker.internal:host-gateway`). `docker-compose.two-node.yml` is also updated with `PEAT_NODE_PEERS` (service-DNS addresses, same derived IDs) and `OUTBOX_WATCH`, for the single-machine single-project case. README gets a two-minute quick start at the top; the two-node delivery section drops the `peer.sh` step. Smoke-tested: file dropped in `node-a/outbox/` arrived in `node-b/inbox/` via direct QUIC (~8s).
peat-bot
left a comment
There was a problem hiding this comment.
Peat QA Review (SHA: f6b80ce)
Docs-only PR under examples/compose/attachments/. No changes to proto/sidecar.proto, Rust source, src/crypto.rs, src/watcher.rs, Cargo.toml, chart/peat-node/, or zarf.yaml. All env vars referenced (PEAT_NODE_PEERS, PEAT_NODE_DISABLE_MDNS, PEAT_NODE_ATTACHMENT_OUTBOX_WATCH) and the peat-node derive-id subcommand are confirmed to exist in src/main.rs and src/identity.rs.
[WARNING] Teardown commands in README.md use a non-existent docker compose -C flag
examples/compose/attachments/README.md:26-27:
docker compose -C node-a down -v
docker compose -C node-b down -vdocker compose does not accept -C (that's make/tar syntax). Users following the quick start verbatim will hit "unknown shorthand flag: 'C' in -C". The startup block in the same file uses cd node-a && docker compose up -d correctly — match that pattern for teardown:
(cd node-a && docker compose down -v)
(cd node-b && docker compose down -v)Or use the documented long form: docker compose --project-directory node-a down -v. Worth fixing because this is a zero-friction quick-start aimed at first-time users, and a broken teardown command on the very first try undermines the "no friction" framing.
[WARNING] PR test plan leaves the modified single-project docker-compose.two-node.yml unverified
The PR body explicitly leaves these checkboxes unchecked:
- "Verify on Linux Docker Engine (
extra_hosts: host.docker.internal:host-gateway)" - "Verify
docker-compose.two-node.yml(single-project) also works withoutpeer.sh"
The single-project two-node file was substantively rewritten (added PEAT_NODE_PEERS, PEAT_NODE_DISABLE_MDNS, PEAT_NODE_ATTACHMENT_OUTBOX_WATCH, removed the peer.sh/send.sh flow it was previously coupled to). The new node-a/+node-b/ directory pattern was smoke-tested; the in-place edits to the legacy file were not. Either smoke-test it or note in the PR that the file is being kept on a "should still work" basis with a follow-up to confirm — the docs claim users can use it as an "alternative (both nodes in one compose project)" but that path isn't validated.
docker compose -C is not a valid flag (that's make/tar syntax). Replace with subshell pattern to match the startup style: (cd node-a && docker compose down -v) (cd node-b && docker compose down -v) Also smoke-tested docker-compose.two-node.yml: file dropped in outbox-a/ arrived in inbox-b/ via service-DNS QUIC with no peer.sh.
peat-bot
left a comment
There was a problem hiding this comment.
Peat QA Review (SHA: 6456e1b)
Incremental review since f6b80ce. Delta is docs-only — a single fix to teardown commands in examples/compose/attachments/README.md. No changes to proto/sidecar.proto, Rust source, src/crypto.rs, src/watcher.rs, Cargo.toml, chart/peat-node/, or zarf.yaml.
Status of prior findings
- Resolved: [WARNING] Teardown commands in
README.mduse a non-existentdocker compose -Cflag. The new commit replacesdocker compose -C node-{a,b} down -vwith(cd node-{a,b} && docker compose down -v)atexamples/compose/attachments/README.md:26-27, matching the fix suggested in the prior review and the startup-block pattern in the same file.
[WARNING] Single-project docker-compose.two-node.yml remains unverified
Restated from prior review — still unaddressed by this delta. The PR body's test plan still leaves these checkboxes unchecked:
- "Verify on Linux Docker Engine (
extra_hosts: host.docker.internal:host-gateway)" - "Verify
docker-compose.two-node.yml(single-project) also works withoutpeer.sh"
The single-project file was substantively rewritten in the prior commits on this branch (added PEAT_NODE_PEERS, PEAT_NODE_DISABLE_MDNS, PEAT_NODE_ATTACHMENT_OUTBOX_WATCH, removed the peer.sh/send.sh flow). The README still advertises it as an "alternative (both nodes in one compose project)" path (README.md:34-35) but that path is not validated. Either smoke-test it before merge, or note in the PR body that it is being kept on a "should still work" basis with a follow-up — the docs claim users can use it, and a broken alternative undermines the "zero friction" framing this PR is built around.
Both nodes dial each other simultaneously at boot. The outbound dial from the first node exhausts its 3 retries before the peer's iroh endpoint is ready, logging ERROR. The connection succeeds immediately after via the peer's simultaneous inbound dial. Documented as expected startup noise so users know to look for INFO: connected to peer rather than treating the ERROR as a failure. Tracks: peat-node#177
peat-bot
left a comment
There was a problem hiding this comment.
Peat QA Review (SHA: 07cfd29)
Incremental review since 6456e1b. Delta is docs-only — a single paragraph added to examples/compose/attachments/README.md (lines 34–39) explaining that an ERROR peat_node: failed to connect to peer … after 3 attempts log line during the first ~15s of two-node startup is expected (both nodes dial simultaneously; the inbound dial wins), and pointing users at the INFO peat_node::node: connected to peer line as the success signal.
No changes to proto/sidecar.proto, Rust source, src/crypto.rs, src/watcher.rs, Cargo.toml, chart/peat-node/, or zarf.yaml. None of the protocol / crypto / mesh-pin / Helm / language-runtime / cross-repo criteria are touched.
Status of prior findings
- Resolved: [WARNING] Single-project
docker-compose.two-node.ymlremained unverified. The PR body's test plan now ticksSmoke-tested docker-compose.two-node.yml (single-project): file dropped in outbox-a/, appeared in inbox-b/ with no peer.sh call, and the Linux Docker Engine /host-gatewaycheckbox is explicitly annotated as a tracked follow-up (host-gateway is a Compose 3.9+ feature; not tested here, tracked as follow-up). Both prongs of the prior WARNING are addressed.
New findings
No findings.
node-a/node-b are separate compose projects, so each got its own isolated default network with no route between them; the host.docker.internal bridge fails on Docker Desktop (its UDP proxy mangles the iroh QUIC handshake → 'error 48: invalid peer certificate: UnknownIssuer'). Join both to a pre-created external 'peat-mesh' network and dial by container name. README documents the network-create-first flow and why isolation made them unpeerable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
peat-bot
left a comment
There was a problem hiding this comment.
Peat QA Review (SHA: 9fcff9f)
Incremental review since 07cfd29. Delta is example-only — docs and two examples/compose/attachments/{node-a,node-b}/docker-compose.yml files. No changes to proto/sidecar.proto, Rust source (including src/crypto.rs and src/watcher.rs), Cargo.toml, chart/peat-node/, or zarf.yaml. None of the wire-contract / Connect-surface / encryption-at-rest / mesh-pin / Helm-Zarf / watcher-TLS / language-runtime / cross-repo criteria are touched.
Implementation pivot in this commit: replaces host.docker.internal peering + published iroh UDP host ports with a shared external Docker network (peat-mesh), and rotates the demo shared key from the all-zeros value to a freshly generated one with deterministically re-derived endpoint IDs. The README explicitly documents this as a fix for a Docker Desktop QUIC routing failure (error 48: invalid peer certificate: UnknownIssuer). The demo shared key remains a documented demo value with an in-file generation recipe, which is the expected pattern for the examples/compose/ tree (not subject to the chart/peat-node/ / zarf.yaml embedded-credentials rule).
Status of prior findings
Prior review was clean ("No findings"). Nothing to re-verify.
New findings
- [WARNING] PR Summary and test plan are stale relative to the implementation pivot. The Summary still says "each running from its own directory and peering over
host.docker.internal" and the smoke-test checkbox[x] Smoke-tested node-a/ + node-b/ end-to-end ... via direct QUIC in ~8sdescribes the prior approach — which the README in this same commit now documents as broken on Docker Desktop. Update the PR body to (a) describe the sharedpeat-meshexternal network as the actual peering mechanism and (b) confirm the smoke test was re-run against the new setup. The README's specificity about the failure mode is strong implicit evidence the author verified the fix, but the merged PR record should match the code that's actually shipping so the test-plan-as-evidence pattern stays usable for incremental reviews.
|
The two-device split ( Why it failed: Fix (this commit): both compose files join a pre-created A separate |
Summary
node-a/docker-compose.ymlandnode-b/docker-compose.yml— two separate compose files matching the peat-local-a/b pattern, each running from its own directory and peering overhost.docker.internal. Nopeer.sh, nosend.sh.docker-compose.two-node.ymlwithPEAT_NODE_PEERS(service-DNS, same derived IDs) andPEAT_NODE_ATTACHMENT_OUTBOX_WATCH— same zero-friction experience for the single-project case.README.md; update two-node delivery section to droppeer.sh.Root cause
Others couldn't get sync working because
peer.sh/send.shrequired manual steps after startup. The fix: pre-configured peering viaPEAT_NODE_PEERSwith offline-derived endpoint IDs (HKDF-SHA256(shared_key, "iroh:" + node_id)), andPEAT_NODE_ATTACHMENT_OUTBOX_WATCHfor hands-off file delivery.How it works
Deterministic endpoint IDs for the zero demo key:
Reproduced with:
peat-node derive-id --shared-key "AAAA...A=" --node-id <name>Test plan
node-a/+node-b/end-to-end: both nodes started from their directories, file dropped innode-a/outbox/, appeared innode-b/inbox/via direct QUIC in ~8sdocker-compose.two-node.yml(single-project): file dropped inoutbox-a/, appeared ininbox-b/with nopeer.shcalldocker compose down -von both cleans up correctlyextra_hosts: host.docker.internal:host-gateway) —host-gatewayis a Compose 3.9+ feature; not tested here, tracked as follow-up