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

110 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 icon** — `docker_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-scroll**`useControllerNav.ts` (wheel scrolls container under
pointer, not focused el) + `Mesh.vue` (`@wheel.stop.prevent`).
2. **Second-level cloud folder zoom**`CloudFolder.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" banner** — `bitcoin_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)
6. **"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.
7. **`!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`.
8. **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.