product

Glasses bring-up — handoff

Everything for the JQ-on-Mentra-Live glasses was built + merged the day the hardware arrived (2026-07-17). This doc is the pick-up point: what's done, what's left, and the one real unknown. Task: product_tasks "Glasses on-device bring-up

  • multi-user validation" (P1).

State: built + merged (nothing left to code for v1)

PRWhatMigration
earlierAisleAsk glasses: scan aisle, scan recipe, add-item, recap, next, got-it
#1338Durable device token (hjg_…, never expires)511
#1339/#1340Mantras: dashboard + "play my mantras" in-ear512
#1342Multi-user device links: backend + dashboard513
#1343Multi-user runtime: resolve-per-session + "link my glasses"513
2026-07-23SecondSet: job binding (companion/QR "scan job") + owner→tech async voice notes — INERT unless SECONDSET_ENABLED. Backend services/glasses-secondset.ts + glasses-qr.ts (sharp→jsqr) + routes/glasses.ts; glasses secondset.ts. Consent gate = active binding. Details: docs/ai/INDEX.md → "SecondSet".563 (human-provisioned)

All migrations 500–513 applied to prod (owner did this). App builds clean (apps/glasses, npm run builddist/index.js). Tests: npm test → 39/39.

Voice command set (single app = JQ): nudges ("what's my next step"), levers ("log a 20-minute walk for energy"), soundtrack ("play some music"), AisleAsk (add / next / got-it / recap / scan this aisle 📷 / scan this recipe 📷), Mantras ("play my mantras"), linking ("link my glasses <code>"). Full table: apps/glasses/README.md.

Remaining: on-device only (no more coding for v1)

1. Finish the Railway service

hivejournal-glasses is created + GitHub-connected (CLI), with the 2 non-secret vars set. In the Railway dashboard, finish:

  • Settings → Config-as-code path = apps/glasses/railway.json (root stays /).
  • Variables → add MENTRA_API_KEY + HIVEJOURNAL_TOKEN (the durable token, below). For multi-user, also GLASSES_APP_SECRET.
  • Networking → Generate Domain → copy the URL. Guide: docs/setup-guides/GLASSES_RAILWAY_DEPLOY.md. (The first auto-build fails until the config path is set — expected.)

2. Mentra console

console.mentra.glass → the app (fm.graphene.jq) → set server URL to the Railway domain; confirm Microphone + Camera permissions (camera = the scans).

3. Single-user smoke

Mint a durable token at /dashboard/glasses → "🔑 Connect this device" → set as HIVEJOURNAL_TOKEN. Prereqs or you'll hear fallbacks: a JQ voice clone (/dashboard/lovio/voice-setup) + an AisleAsk list (/dashboard/aisleask). Button-press → nudge. Then run every voice command.

4. Multi-user validation (the real test)

Set GLASSES_APP_SECRET (same value on the glasses server + HJ). Link a second wearer: owner mints a code at /dashboard/glasses → "👥 Link someone else's glasses", the wearer says "link my glasses, code …". Then verify:

  • Wearer A ≠ Wearer B — each hits their OWN account (nudges from their dream, their AisleAsk list, their mantras).
  • ⚠️ THE ONE UNKNOWN: that AsyncLocalStorage context propagates through Mentra's event handlers on real hardware. The per-session token lives in an ALS context wrapped around the button/transcription handler bodies (session.ts runWithSessionToken); the client reads it in authHeaders (hivejournal.ts). I'm confident ALS carries through the promise/timer chains, but "does it survive the SDK's event dispatch on-device" is unverified.
    • If it does NOT propagate: the fix is small — capture the session token explicitly in the handler closures and pass it to the client calls (add an optional token? param to the client fns) instead of relying on ALS. The ALS indirection is the only thing that would need replacing; everything else (resolve/link/token) is unaffected.

Single-user is byte-for-byte unchanged whether or not multi-user works (unset GLASSES_APP_SECRET → static-token path).

5. On-device tuning (all built blind)

  • Intent misfires/misses → tighten the regexes in intent.ts (or enable Sophia). Note what you said that mis-routed.
  • PhotorequestPhoto({size, compress}) values (medium signs / large recipes) are untested on the real camera; adjust for legibility vs transfer.
  • Transcription finality — we act on isFinal only; if laggy/double-firing, that's the spot.
  • Soundtrack ducking — duck-under-nudge timing is untested live.

Pointers

GLASSES BRINGUP HANDOFF — Docs | HiveJournal