Files
peerspeak/.agents/AGENTS.md
T
molluskandClaude Opus 4.8 02cb46550e Chat file attachments, stage 1: protocol + data model + pure seams
First slice of in-chat file/photo sharing (dedicated file plane, images
inline + file chips, session-only). This stage adds the wire types and
the pure, unit-tested logic; no transport or UI yet.

- protocol: new FILES_ALPN / FILES_PROTO (peerspeak/files/1) for the
  dedicated file-transfer plane. Bump GOSSIP_PROTO 1->2 + sig domain v2
  (Chat gained an attachment field, so cross-version peers fail fast
  rather than half-work) and Cargo 0.2.0 -> 0.3.0 per VERSIONING.md.
  BREAKING wire change: all peers must run >= 0.3.0.
- new src/files.rs: ChatAttachment descriptor (name/size/kind/id; bytes
  travel off-gossip), AttachmentKind, plus pure seams — sanitize_filename
  (path-traversal/control-char/length-safe), size_within_cap, image
  magic-byte sniffing + defensive limited decode (decode-bomb guard),
  32-byte request parsing, human_size. 13 unit tests.
- GossipMessage::Chat and RoomEvent::ChatMessage carry an optional
  ChatAttachment; send_chat takes Option<ChatAttachment>. Untrusted
  inbound descriptors are filename-sanitized + size-validated on ingest.
  serde(default) keeps the field forward-compatible at the JSON layer;
  +round-trip and pre-v2 back-compat tests.

The attachment id is a random 32-byte handle (rand, already a dep), not
a content hash — the fetch is authenticated + encrypted + member-gated,
so no crypto-hash dep is needed.

349 lib tests pass, clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 23:00:51 -04:00

1.8 KiB

PeerSpeak Codebase Layout and Architecture Rules

When working in the PeerSpeak repository, adhere to the following architectural boundaries and layout:

Code Layout

  • src/main.rs: The application entry point (initializes Tokio and the Iced GUI).
  • src/app/: The UI layer (Iced). Handles themes, views (Home, Room, Settings), and visual state. Must communicate with the core via message passing (UiEvent/CoreCommand), not direct function calls.
  • src/core/: The central orchestrator.
    • mod.rs: Manages the session lifecycle, ties together network and UI, and manages the async mixer tasks.
    • jitter.rs: Houses the adaptive playout delay JitterBuffer and Packet Loss Concealment (PLC) logic.
  • src/network/: The "Dual-Plane" transport layer.
    • gossip.rs (Control Plane): Built on iroh-gossip. Manages room rosters, verified membership, presence, and chat via cryptographically signed envelopes.
    • iroh_impl.rs (Data Plane): Manages raw QUIC endpoints and peer connections. Forwards UDP voice datagrams directly to peers for minimum latency.
  • src/audio/: Hardware audio backends.
    • Interfaces heavily with cpal_impl.rs (Windows/WASAPI) and pipewire_impl.rs (Linux).
    • CRITICAL RULE: The RT audio callbacks are strictly lock-free. They communicate with the async core exclusively via Single-Producer Single-Consumer (SPSC) ring buffers (HeapRb). Never allocate memory, log to stdout, or lock Mutexes on the RT threads.
  • src/codec/: Audio compression abstractions, standardizing on Opus at 48kHz mono (opus_impl.rs).

General Directives

  • Security: Audio admission is strictly derived from the verified gossip roster (S8). Never trust raw UDP sender IDs without validating against gossip.
  • Latency: Preserve the deterministic dialer vs acceptor logic in the QUIC layer to prevent connection loops.