SHORTWAVE

Roadmap

M0–M8 milestones and the north-star Shortwave hardware device.

Roadmap

Milestones

M0 — De-risk (done)

Goal: Prove the JS crypto before any UI work.

scripts/derisk-nip17.ts — generates two keypairs, sends a NIP-17 gift-wrapped DM, Bob receives and decrypts it over public Nostr relays, prints NIP-17 DERISK PASS.

No hand-rolled crypto. Pure nostr-tools.

M1 — Scaffold (done)

Goal: npm run build clean, npm run dev runs, structure in place.

  • Next.js 15 + TypeScript + Tailwind v4 App Router
  • lib/nostr/, lib/identity/, components/ui/ skeleton
  • Chat and connect route stubs
  • Fumadocs /docs site

M2 — Design foundation (done)

Goal: Locked design language from forged-2 extracted into Forge + wired into Shortwave.

  • Forge v0 tokens seeded (mechaforge/forgetokens/tokens.css, tokens/tokens.json, tailwind-preset.js)
  • Shortwave consumes Forge tokens from lib/forge/tokens.css (source of truth: mechaforge/forge#1)
  • Space Mono primary instrument font (matches forged-2 exactly)
  • Full dark mono palette --forge-bg … --forge-ink-4 + signal-green --forge-signal accent rules
  • 8px grid: --forge-ctl 40px · --forge-head 64px · --forge-bar 96px · --forge-rail-w 296px
  • Zero radii — sharp/angular everywhere
  • Design language documented: /docs/design-language

M3 — Identity (done)

Goal: Nostr identity generated, persisted, and displayed in the instrument UI.

  • lib/identity/keypair.tsloadOrCreateIdentity() generates secp256k1 keypair, persists to localStorage (MVP — see docs/threat-model for upgrade path)

  • npub bech32 encoding via nostr-tools/nip19

  • Operator ID derived from pubkey (OP-XXXX from last 4 hex bytes)

  • Contacts: add by hex pubkey or npub1… bech32; persisted to localStorage

  • Identity panel in rail (96px, bottom-aligned with compose bar)

  • Geometric avatar marks: YOU / DETHKLAW / VOXEL / NULLKEY / GHOST

  • Relay status displayed in header (tick marks, connected / total count)

    TODO mechaforge/shortwave#13: source operator_id + avatar from Mini Mecha profiles; gate access.

M4 — Core chat — columnar ledger (done)

Goal: Real E2E NIP-17 send + receive, forged-2 columnar ledger UI.

  • lib/nostr/client.ts — real sendDM (NIP-17 gift-wrap via nip17.wrapEvent) + subscribeDMs (kind:1059 subscription with unwrapEvent)
  • Multi-relay: wss://relay.damus.io + wss://nos.lol (+ optional ws://127.0.0.1:7777 via NEXT_PUBLIC_LOCAL_RELAY)
  • Relay connection pool (shared across page session); dedup by event ID across relays
  • Ephemeral — no plaintext written to disk; in-memory session only
  • Columnar ledger thread (subgrid 5-column: time · avatar · operator · transmission · state)
  • Green left-rule + wash on outbound rows; no bubbles
  • Continuation rows (same sender within 2 min → blank avatar/operator cols)
  • Optimistic local echo on send
  • Channel header: operator name + operator ID + encryption/retention HUD metrics
  • Session note (key verified · E2E · no transcript)

M5 — Key lifecycle

Goal: Passphrase-locked key export/import; key rotation.

  • Export sk encrypted with user passphrase (WebCrypto AES-GCM)
  • Import from passphrase-locked file
  • Key rotation warning when key is old

M6 — Mobile layout + PWA (done)

Goal: Mobile-native responsive layout + installable PWA on iOS/Android.

  • Responsive contract: Desktop (≥ 600px) keeps forged-2 columnar ledger unchanged. Mobile (< 600px) uses approved mobile-1 stacked transmission cards layout.
  • Mobile layout: App bar (wordmark or back+peer) → Screen A (operators list with identity strip) → tap → Screen B (transmission card thread + pinned compose bar). Same lib/nostr send/receive engine — different layout only.
  • PWA manifest (app/manifest.ts): name "Shortwave", display: standalone, dark theme/background, maskable 192/512 icons.
  • Service worker (Serwist 9.x, MIT): app-shell cache only. Message data is never cached — ephemeral by design.
  • iOS niceties: apple-mobile-web-app-capable, black-translucent status bar, viewport-fit=cover for safe-area insets, apple-touch-icon.
  • Production placeholder icon: geometric signal mark + SW monogram in Forge techwear language (#0c0d0e bg, #4ea88b accent). Rod designs the hero brand mark in-house — this is a clearly-labelled placeholder.
  • Safe-area handling: compose bar and identity strip both use env(safe-area-inset-bottom) for home-indicator clearance. Top uses env(safe-area-inset-top) for notch/Dynamic Island.
  • Touch targets: all controls ≥ 44px.
  • Momentum scroll on thread and operators list (-webkit-overflow-scrolling: touch).

M7 — Relay configuration UI

Goal: Users can add/remove relays, test connectivity.

M8 — Groups (MLS)

Goal: Small-group encrypted channels (3–10 people).

  • OpenMLS (RFC 9420) for full PCS + forward secrecy
  • Group key management UI

North-star: the Shortwave hardware device

The long-term vision is a dedicated Shortwave device — a small, purpose-built appliance that removes the hosted-web-app delivery attack surface.

Phase 1: Pi appliance (earnable now)

A Raspberry Pi running the resilient-comms Rust core headless — pre-provisioned with identity, relay list, and contact keys.

  • Software exists today (rc-cli in resilient-comms)
  • Hardware: Pi Zero 2W + USB keyboard + small OLED or e-ink display
  • Cost: ~A$50–80/unit

Phase 2: Curated kit

Curated BOM (Pi + LoRa HAT + enclosure + pre-flashed SD card).

Phase 3: Custom device (earned by usage)

Custom device with integrated LoRa radio and secure element. North-star only — earned by proven usage.


Current state (2026-06-09)

  • Rust core: dogfoodable — encrypted 2-person messenger works, relay-redundant
  • Radio software tier: 7/7 impairment tests passing
  • Web app: M0 + M1 + M2 + M3 + M4 + M6 done — forged-2 columnar ledger + mobile-1 stacked cards + installable PWA
  • Radio hardware: 2 Meshtastic nodes ordered