archy/docs/session-handoff-2026-06-18.md
archipelago 1bce694ebb feat(ui): mobile mesh tabs, AIUI-style audio player, cloud grid + map fixes
UI (this session):
- Global audio player now scales the whole interface into the space above it
  on desktop (sidebar + main) and docks directly above the tab bar on mobile;
  it stays visible while navigating.
- Mesh mobile redesign: floating Chat / BTC / Dead Man / AI / Map tab strip
  with a single fixed, internally-scrolling pane (page no longer scrolls);
  tabs hide while a conversation is open; floating back button; collapsible
  Device panel (starts collapsed); keyboard-aware conversation sizing via
  VisualViewport so the chat sits just above the keyboard.
- Cloud file grid: uniform 4/3 card heights (folders + images match).
- Swipe left/right switches tabs on the Apps and Web5 screens.
- Map tool fills its pane (no bottom gap); fix skewed Share Location toggle
  on mobile (global min-height rule was deforming the switch).
- Trim redundant helper copy from the mesh AI tab.

Also bundles pre-existing in-progress work that was already in the tree:
mesh listener/session + wallet + container + bitcoin-status backend changes,
docker UI updates, and assorted other UI tweaks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 09:52:26 -04:00

8.6 KiB
Raw Blame History

Session handoff — 2026-06-18

UPDATE (later same day): ALL OPEN ITEMS RESOLVED + DEPLOYED (v1.7.99-alpha → .116 + .198).

  • #6 Pay-with-QR timeout — real bug (both LNDs confirmed healthy by user). FIPS-first dial ate the whole budget before the working Tor fallback ran. Added PeerRequest.fips_timeout cap (fips/dial.rs); invoice/onchain request+status calls fast-fail FIPS (6s) + short Tor window (25s/15s); frontend ceilings 60s→45s. Large downloads keep the full FIPS timeout.
  • #7 !ai gate — added denied-asker capture (MeshState.assist_denied/DeniedAsker, assist.rs::record_denied) → mesh.assistant-status.denied_askers → "Recently denied" list with one-click Allow in MeshAssistantPanel.vue.
  • #8 peer-file 403 — NOT a DID reset. Asymmetric federation: .198 had .116 trusted but .116 never added .198. Re-federated (.198 → .116 nodes.json, trusted). Verified: .116 /content/<peersonly> = 403 w/o DID, 200 (177KB png) with .198's DID. Plus clearer 403 message + client surfaces the body. Listing left visible ("locked preview", user's choice).
  • Dual-ecash receive — active modal is ReceiveBitcoinModal.vue (not the commented-out Web5SendReceiveModals.vue); already used dual-detect wallet.ecash-receive, fixed Cashu-only wording.
  • fedimint-clientd icondocker_packages.rs arm → fedimint.png + fedimint-clientd.png asset.
  • Cashu → 🥜HomeWalletCard.vue.

Deploy notes confirmed: binary swap needs atomic mv over the running file (cp → "Text file busy"); frontend rsync WITHOUT --delete to preserve the aiui/ subdir in /opt/archipelago/web-ui.

Resume point for the multi-issue bug-fix + deploy session on .116 (archi-thinkpad, local dev/validation node) and .198 (resilience node). Work was done in ~/Projects/archy. A separate agent's fedimint dual-ecash work landed as commit 4288ae78 during the session (don't re-touch wallet.rs / fedimint_client.rs / prod_orchestrator.rs / Web5SendReceiveModals.vue without checking with them).

DEPLOY STATUS — done

A surgical deploy (binary + frontend + 2 companion images, not the .228-centric deploy-to-target.sh, to avoid clobbering .116's custom nginx) shipped to BOTH nodes:

  • .116: new binary /usr/local/bin/archipelago (backup at archipelago.bak-pre-deploy-*), frontend at /opt/archipelago/web-ui, localhost/{lnd-ui,bitcoin-ui}:latest rebuilt, :local tags dropped. Verified: /bitcoin-status serves age_ms; lnd-ui on Network=host listening 18083; /lnd-connect-info → 200; both companion containers carry new index.html.
  • .198: same (binary copied — .198 has no Rust toolchain, only npm+podman, so build-on-.116-then-copy is mandatory). Verified identically. Force-recreated both companions.

Build notes: release build ~9 min (opt-level 3). Frontend vite outDir = web/dist/neode-ui/ (NOT neode-ui/dist). Companion images: ensure_image_present only builds if image ABSENT, and prefers localhost/<base>:local over :latest — so to ship docker changes you must drop :local and rebuild :latest, then the reconciler (needs_repair compares rendered quadlet unit vs disk) recreates containers. bitcoin-ui needed an explicit systemctl --user restart (its quadlet unit text didn't change, so the reconciler didn't auto-recreate it).

FIXED & DEPLOYED

  1. Mesh chat/peer double-scrolluseControllerNav.ts (wheel scrolls container under pointer, not focused el) + Mesh.vue (@wheel.stop.prevent).
  2. Second-level cloud folder zoomCloudFolder.vue direction-aware (cloud-zoom-forward/-back, matched depth-forward/back magnitudes 0.75↔1.2).
  3. "FIPS Mesh" → "Fuck IPs Mesh"FipsNetworkCard.vue, Server.vue.
  4. .116 connect-wallet QR "failed to fetch" — lnd-ui migrated to host-network + same-origin nginx proxy: companion.rs (host_network:true, ports:[]), docker/lnd-ui/{Dockerfile(EXPOSE 18083),nginx.conf(listen 18083 + proxy /lnd-connect-info, /proxy/lnd/, /api/container/logs to 127.0.0.1:5678),index.html(getBackendUrl()→'' relative, credentials:'include')}. ROOT CAUSE was a cross-origin CORS failure (page on :18083 fetching :80). Verified working in incognito; the user's earlier "still broken" was a stale cached old page. Unit test lnd_ui_uses_host_network passes.
  5. .198 Bitcoin Knots stale "reconnecting" bannerbitcoin_status.rs (new server-computed age_ms field so the browser never subtracts across clocks; 20s STALE_GRACE_MS before flipping stale; RPC timeout 8s→12s) + docker/bitcoin-ui/index.html (snapshotAgeMs() uses server age_ms, falls back to old calc). Two root causes: browser/node clock skew + no grace on single failed polls (swap-thrash node).

OPEN ISSUES (diagnosed, NOT fixed)

  1. "Pay with QR" → request timeout — full invoice chain intact (hardened in 790da4bd); 60s timeout = seller node never answers (unreachable transport or hung LND). Runtime, needs 2 live nodes to repro. NOT a code defect found.

  2. !ai not working — DIAGNOSED, config fix (awaiting user policy decision). Assistant is assistant_trusted_only:true (/var/lib/archipelago/mesh-config.json). The trust gate is_sender_allowed (mesh/listener/assist.rs) only matches askers by archipelago pubkey/DID against federation-Trusted nodes.json, but RADIO (meshcore) askers present a firmware key, not the archipelago identity, so they're silently denied (journal: "AssistQuery denied … from=15 name=Arch Optiplex"; federation contact_id ≥ 0x80000000, low ids = radio). Claude key + model (claude-opus-4-8) tested HTTP 200 — NOT the problem. FIX: disable trusted_only, or add the asker's presented key to the allowlist. Full notes in memory project_mesh_ai_trusted_only_gate.

  3. Peer-file download .116→.198 "Access denied — federation peer required" — NEW, NOT yet fixed. Gate at content.rs:149 (returns on content_server::ServeResult::Forbidden). The requesting node isn't recognized as an authorized federation peer by the content server / per-file sharing ACL. User's strong hypothesis: a DID/identity reset changed a node's DID, so the sharing ACL / nodes.json holds the OLD identity and no longer matches. User also notes the file is still VISIBLE in the listing (so listing and download use different identity checks — inconsistency to investigate). NEXT: read content_server Forbidden logic, compare the requester DID/pubkey vs what's stored; check both nodes' server_info/identity vs each other's federation/nodes.json. Same THEME as #7 (identity matching) but a different mechanism.

NEW FRONTEND REQUESTS (not started — batch into one frontend rebuild+redeploy)

  • fedimint-clientd.svg 404 — new fedimint core-app (public/catalog.json:294) has no icon. App-icon convention /assets/img/app-icons/<id>.png (default) — add a fedimint-clientd icon (there's an existing fedimint.png to reuse/adapt). The 404 requests .svg so check the catalog/curated-icon entry.
  • Cashu icon → cashew emoji (🥜) — change the cashu wallet icon to a cashew nut emoji.
  • Receive ecash should support BOTH fedimint + cashu paste — currently the ecash receive only mentions Cashu for pasting a token; user expected the paste box to redeem both Cashu AND Fedimint ecash. Lives in the fedimint agent's recently-committed dual-ecash UI (Web5SendReceiveModals.vue / Web5Wallet.vue / WalletSettingsModal.vue) — investigate what they built before changing.
  • Console noise (lower priority): cdn.tailwindcss.com production warning in lnd-ui + bitcoin-ui (uses Tailwind CDN); api/app-catalog 502 (check if persistent). Latent backend nicety: /lnd-connect-info emits a DOUBLED Access-Control-Allow-Origin (backend empty ACAO
    • main-nginx add_header $http_origin) — harmless on the new same-origin page but should drop the backend's redundant CORS since lnd-ui now fetches same-origin.

ENV QUICK-REF

  • .116 archi-thinkpad: data /var/lib/archipelago, nginx root /opt/archipelago/web-ui, http :80 + custom nginx-proxy-manager; user reaches UI via Tailscale 100.69.68.39 AND LAN. Deploy SSH key ~/.ssh/archipelago-deploy is passphraseless; SSH-to-self + .198 work non-interactively.
  • .198: ssh archipelago@192.168.1.198 (passwordless sudo), podman+npm, NO cargo.
  • Companion build-dir precedence: /opt/archipelago/docker > ~/archy/docker > ~/Projects/archy/docker.
  • Uncommitted working-tree changes (mine, not yet committed): the 11 files for fixes #1#5.