note-251110-issue-10-session-summary

Issue Implementation Session Summary

Date: 2025-11-10
Issue: - Handle whtnxt://connect Custom Protocol
Status: ๐Ÿ”„ In Progress - Foundation Complete, Integration Remaining


Session Overview

This session focused on establishing the architectural foundation for P2P connections in WhatNext, including the critical decision to use libp2p and the utility process pattern.


Major Decisions Made

โœ… Decision 1: P2P Service as Utility Process

Decision: Run P2P networking in a separate Electron utility process, isolated from main and renderer.

Rationale:

  • Clean separation of concerns (MVC-like pattern)
  • Process isolation prevents P2P crashes from taking down the app
  • Easier testing and debugging
  • Aligns with future migration to standalone /service directory

Documented: /docs/notes/note-251110-p2p-utility-process-architecture.md


โœ… Decision 2: libp2p Over Simple-peer

Decision: Commit to libp2p despite steeper learning curve.

Rationale:

  • Native mesh networking (essential for multi-peer collaboration)
  • Built-in security (Noise protocol, cryptographic peer identity)
  • mDNS auto-discovery (killer feature for local collaboration)
  • Multiple transports (WebRTC, TCP, WebSocket, QUIC)
  • Long-term maintainability (Protocol Labs backing)
  • Aligns with user sovereignty principle (DHT-based peer discovery)

Trade-offs Accepted:

  • 2-3 week learning curve investment
  • 500KB bundle size (acceptable for desktop app)
  • Higher initial complexity

Documented: /docs/notes/note-251110-libp2p-vs-simple-peer-analysis.md


โœ… Decision 3: Architecture-First Approach

Decision: Build proper architectural foundations now, not after MVP.

Rationale:

  • Easier to refactor with clear abstractions
  • Shared core library enables future test peer infrastructure
  • Well-documented learnings serve as institutional knowledge
  • Reduces technical debt

Commitment: Rigorously document all learnings, discoveries, and decisions.

Documented: /docs/notes/note-251110-libp2p-learning-roadmap.md


Work Completed

1. Shared Core Library (/app/src/shared/core)

Purpose: Environment-agnostic code shared across main, utility, and renderer processes.

Files Created:

  • โœ… types.ts - Core P2P type definitions (PeerId, ConnectionState, P2PMessage, etc.)
  • โœ… protocol.ts - whtnxt:// URL parsing and generation utilities
  • โœ… ipc-protocol.ts - Message contracts for inter-process communication
  • โœ… index.ts - Barrel export

Key Features:

  • Protocol URL parsing: whtnxt://connect/<peerId>?relay=โ€ฆ
  • PeerID validation (supports CIDv0, CIDv1, base58, base32)
  • Type-safe IPC message creation
  • Extensible message protocol for future features

LEARNING NOTES:

  • Inline comments explain "why" decisions were made
  • Functions are documented with their purpose and libp2p concepts
  • Validation functions include examples of valid/invalid inputs

2. P2P Utility Process (/app/src/utility)

Purpose: Runs libp2p node in isolated Node.js process.

Files Created:

  • โœ… p2p-service.ts - Utility process entry point with libp2p node management

Key Features:

  • libp2p node lifecycle (start/stop)
  • MessagePort communication with main process
  • Event listeners for peer discovery and connections
  • mDNS auto-discovery configuration
  • Connection manager with limits
  • Comprehensive logging

Minimal libp2p Configuration:

{
  connectionEncryption: [noise()],       // Noise protocol for encryption
  streamMuxers: [yamux()],               // Stream multiplexing
  transports: [webRTC()],                // WebRTC for P2P
  peerDiscovery: [mdns()],               // Local network auto-discovery
  connectionManager: { maxConnections: 10 }
}

LEARNING NOTES EMBEDDED:

  • Why each libp2p configuration option was chosen
  • Known limitations (e.g., WebRTC may need polyfill in Node.js)
  • Future improvements (add TCP/WebSocket transports)
  • Event handling patterns

3. Documentation Created

Architecture Decision Records:

  1. โœ… note-251110-p2p-utility-process-architecture.md - Utility process design

    • Process isolation rationale
    • IPC communication protocol
    • Architecture diagrams
    • Migration path to standalone service
  2. โœ… note-251110-libp2p-vs-simple-peer-analysis.md - Library selection analysis

    • Feature comparison matrix
    • NAT traversal strategies
    • Mesh networking requirements
    • RxDB replication integration
    • Bundle size trade-offs
    • Risk analysis
  3. โœ… note-251110-libp2p-learning-roadmap.md - Learning strategy

    • Phase-by-phase milestones (Weeks 1-10)
    • Documentation templates
    • Experiment ideas
    • Knowledge sharing strategy
    • Open questions to investigate
  4. โœ… note-251110-libp2p-first-implementation-learnings.md - Early discoveries

    • Dial requires multiaddrs, not just peer IDs
    • PeerID string vs libp2p PeerId object conversion
    • WebRTC transport configuration challenges
    • mDNS peer filtering strategies
    • Utility process vs worker threads
    • Build configuration needs

Key Learnings Documented

Learning: Dialing Peers Requires Multiaddrs

Problem: whtnxt://connect/<peerId> URLs only contain peer ID, but libp2p's dial() requires full multiaddr (IP + port + transport).

Solutions Identified:

  1. mDNS discovery populates peerStore with multiaddrs (MVP approach)
  2. Include relay multiaddr in URL query params (Phase 2)
  3. DHT peer routing for global peer lookup (Phase 3)

Learning: WebRTC in Node.js Utility Process

Potential Blocker: @libp2p/webrtc may require browser APIs not available in Node.js.

Investigation Needed:

  • Test if WebRTC works in utility process
  • Check if wrtc polyfill is needed
  • Consider @libp2p/webrtc-direct as alternative
  • Add TCP/WebSocket transports as fallbacks

Status: โš ๏ธ Needs testing before proceeding


Learning: mDNS Discovers All libp2p Peers

Problem: mDNS will discover IPFS Desktop and other libp2p apps on same network.

Solution for MVP: Post-connection handshake filtering

  • Accept all discovered peers
  • Send WhatNext-specific handshake message
  • Disconnect if peer doesn't respond correctly

Remaining Work (Issue)

Immediate Next Steps

  1. โš ๏ธ BLOCKER: Test libp2p WebRTC in Utility Process

    • Create minimal test script
    • Verify WebRTC transport works in Node.js
    • Add fallback transports if needed (TCP, WebSocket)
  2. Update Build Configuration

    • Add utility process as tsup entry point
    • Output to dist/p2p-service.js
    • Test bundled utility process can be spawned
  3. Implement Main Process Integration

    • Register whtnxt:// protocol handler (app.setAsDefaultProtocolClient())
    • Spawn utility process on app startup
    • Forward protocol URLs to utility process via MessagePort
    • Relay utility events to renderer via IPC
  4. Update Preload Script

    • Expose P2P connection API to renderer:
      • window.electron.p2p.connect(peerId)
      • window.electron.p2p.onConnectionRequest(callback)
      • window.electron.p2p.getConnectedPeers()
  5. Build Minimal UI (Renderer)

    • Connection status indicator
    • List of discovered peers
    • Connection request dialog
    • Manual multiaddr input for testing
  6. Test End-to-End

    • Start two Electron instances on same WiFi
    • Verify mDNS discovers both peers
    • Test manual connection via whtnxt:// URL
    • Verify connection events propagate to UI

Blockers & Risks

โš ๏ธ High Priority Blockers

  1. WebRTC in Node.js: Needs immediate testing

    • If WebRTC doesn't work, must add TCP/WebSocket transports
    • May need wrtc polyfill package
    • Could delay timeline by 1-2 days
  2. Build Configuration: Utility process bundling not tested

    • tsup may need special config for worker threads
    • Dependencies (libp2p) may not bundle cleanly
    • Could require webpack/rollup instead of tsup

Medium Priority Risks

  1. PeerID Conversion: Need @libp2p/peer-id package

    • Missing utility for string โ†” PeerId object conversion
    • Low risk: Well-documented libp2p API
  2. MessagePort Communication: Not tested in Electron

    • Electron's utilityProcess API is relatively new
    • May have quirks or limitations
    • Fallback: Use traditional child_process.fork()

Architecture Artifacts Created

Directory Structure

/app/src
  /shared               # ๐Ÿ†• Shared across all processes
    /core
      types.ts          # P2P type definitions
      protocol.ts       # whtnxt:// URL handling
      ipc-protocol.ts   # IPC message contracts
      index.ts          # Barrel export

  /utility              # ๐Ÿ†• Utility process (P2P service)
    p2p-service.ts      # libp2p node manager

  /main                 # Main process (existing)
    main.ts             # TODO: Add protocol handler, spawn utility
    preload.ts          # TODO: Expose P2P API

  /renderer             # Renderer process (existing)
    # TODO: P2P UI components

Documentation Structure

/docs/notes
  note-251110-p2p-utility-process-architecture.md
  note-251110-libp2p-vs-simple-peer-analysis.md
  note-251110-libp2p-learning-roadmap.md
  note-251110-libp2p-first-implementation-learnings.md
  note-251110-issue-10-session-summary.md  # This file

Success Metrics

What We've Achieved

  • โœ… Architectural foundation established
  • โœ… libp2p integration started with minimal config
  • โœ… Shared core library enables future test peers
  • โœ… Comprehensive documentation of decisions and learnings
  • โœ… Clear roadmap for remaining work

What Success Looks Like (Issue Complete)

  • whtnxt://connect/<peerId> URLs launch app
  • Two instances on same WiFi auto-discover via mDNS
  • User can click discovered peer to initiate connection
  • Connection established, displayed in UI
  • Foundation ready for RxDB replication (Phase 2)

Timeline Estimate

Original Estimate: 1-2 Weeks

Revised Estimate: 2-3 Weeks (due to Learning curve)

Breakdown:

  • Foundation (this session): โœ… Complete (~2 days)
  • WebRTC testing & fixes: โš ๏ธ 1-2 days
  • Build config & spawning: 1 day
  • Main/preload integration: 2 days
  • Renderer UI: 2 days
  • Testing & debugging: 2-3 days
  • Documentation polish: 1 day

Total: ~10-14 days (2-3 weeks)


Next Session Priorities

  1. Immediate:

    • Test WebRTC transport in utility process
    • Resolve any polyfill requirements
    • Update build scripts
  2. Short-term:

    • Complete main process integration
    • Update preload script
    • Build minimal UI
  3. Testing:

    • Two-instance mDNS discovery
    • Connection lifecycle
    • Error handling

Questions for Maintainer

  1. WebRTC Fallback: If WebRTC doesn't work in Node.js, should we prioritize fixing it or adding TCP transport first?

  2. UI Scope: For issue, should we build full UI (discovered peers list, connection dialogs) or minimal proof-of-concept?

  3. Testing Priority: Should we write automated tests before completing E2E flow, or validate manually first?

  4. Documentation Cadence: Is current documentation level appropriate, or should we document less and iterate faster?


References

  • Issue: Handle whtnxt://connect Custom Protocol
  • Spec ยง2.3: Backend & Network Architecture
  • Spec ยง4.3: Collaborative & Social Features
  • CLAUDE.md: Development Commands, Architecture Principles
  • libp2p Documentation
  • Electron utilityProcess

Commit Message Template (for next commit)

feat(p2p): Implement libp2p utility process foundation for issue #10

- Add shared core library for P2P types, protocol parsing, IPC contracts
- Implement P2P utility process with libp2p node manager
- Configure minimal libp2p (WebRTC, mDNS, Noise, yamux)
- Document architecture decisions and learning roadmap

Breaking changes: None (new feature, no existing code modified)

Refs: #10

End of Session Summary

Status: Foundation complete, ready for integration phase.

Confidence: High on architecture, medium on WebRTC compatibility (needs testing).

Next Steps: Test WebRTC in utility process, update build config, implement main process integration.

Documentation Quality: Comprehensive - all major decisions captured with rationale.

Learning Velocity: On track - expected to hit stride as libp2p concepts solidify.