From 71bf4f3eaf0d3f4c7fed26923b0532996682fcc4 Mon Sep 17 00:00:00 2001 From: archipelago Date: Thu, 6 Aug 2026 18:34:26 -0400 Subject: [PATCH] docs: scope the media/IndeeHub/AIUI work from on-device evidence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every item was observed on archi-dev-box or read from source, not inferred: the content-card parser mispairing titles with the previous description (the real cause of "idiotic responses" — the model's prose was correct), IndeeHub's three independent faults (empty public library, Nostr-only private auth, relay 502 on loopback), the fleet-wide gate bug that 401s credential-less PWA manifest fetches and app-owned auth endpoints, and AI Data Access grants living in per-origin localStorage when they are a property of the node. Input for a research + plan pass, explicitly not the plan itself. Co-Authored-By: Claude Opus 5 (1M context) --- .planning/MEDIA-AND-INDEEHUB-SCOPE.md | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 .planning/MEDIA-AND-INDEEHUB-SCOPE.md diff --git a/.planning/MEDIA-AND-INDEEHUB-SCOPE.md b/.planning/MEDIA-AND-INDEEHUB-SCOPE.md new file mode 100644 index 00000000..a93cf10e --- /dev/null +++ b/.planning/MEDIA-AND-INDEEHUB-SCOPE.md @@ -0,0 +1,98 @@ +# Media, IndeeHub & AIUI quality — scope from on-device evidence + +**Written 2026-08-06, end of session.** Every item below was observed on archi-dev-box or +read from source — none is inferred. This is the input for a proper research + plan pass, +not the plan itself. + +## A. The content-card parser is the "idiotic responses" bug + +Operator-visible symptom: asking for Bitcoin films produced good model prose, then cards +that were **wrong**: + +- `Banking on Bitcoin` captioned with *The Rise and Rise of Bitcoin*'s description +- `Cryptopia` captioned with *The Bitcoin Standard*'s +- `Documentaries:` and `Narrative Films:` rendered as if they were titles +- `The Social Network` captioned with *Related Financial/Tech Films:* + +Cause is `updatePanelFromText` (useContentPanel.ts) pairing title *n* with description +*n-1* and not excluding section headers. **The model was not at fault** — the card layer +mangled correct prose. Fix the parser before touching prompts. + +Deeper question for the research pass: a regex over prose is the wrong contract entirely. +The model should return **structured** recommendations (tool call / JSON), and the grid +should render those. D-12 already says node content is the source of truth for these +buckets; text-scraping is the legacy path that should shrink, not be patched forever. + +## B. IndeeHub — three independent faults + +1. **Content source.** Films are `projects` in IndeeHub's NestJS API + (`GET /api/projects` via its own nginx; port 4000 is not host-mapped; `/graphql` is the + SPA catch-all, NOT an API). On this node `/api/projects/count` = **`{"count":0}`** — + the public library is genuinely empty. `content.owned-list` (content.rs) has **no** + IndeeHub linkage; `owned` is Archipelago's own paid-content store. So AIUI has never had + a path to IndeeHub content and would render nothing even if wired. +2. **Signer / auth.** `GET /api/projects/private` → 401 + `{"message":"Cognito authentication is disabled. Use Nostr login."}`. Private films need + a **Nostr session**. `/api/auth/nostr/session` 401s through the gate (see C). An adapter + must therefore authenticate as the user — which lands on the phase's non-negotiable: + keys stay out of the browser and the model, so this belongs node-side behind a capability + grant. Same shape as follow-on Phase C (Nostr first-class). +3. **Relay is down independently.** `/relay` returns **502 direct on loopback**, bypassing + the gate — IndeeHub's own nginx cannot reach the relay container. `wss://relay.damus.io` + also fails from that page. Not a gate fault. + +## C. The app gate breaks apps that own their auth — FLEET-WIDE, highest priority + +Verified: `http://:7778/manifest.json` → **401 + the gate's login HTML**. + +- **A PWA manifest is fetched WITHOUT credentials** unless the tag sets + `crossorigin="use-credentials"`. The cookie is never sent, so the gate 401s it *even when + fully logged in*. This hits **every gated app with a PWA manifest**, not just IndeeHub. +- The app's service worker serves the cached shell, so the SPA boots ("Backend connected at + /api — real mode active") and only then does every network call 401 — which is why it + looks like an app bug rather than a gate bug. +- The gate also intercepts the app's own `/api/auth/nostr/session`, so IndeeHub can never + establish its own session. "Nostr login failed" / "Sovereign identity generation failed" + are all this one cause. + +Same class as the `.125` cookie-strip that broke every companion UI. The gate needs a +stated policy for (a) credential-less subresource fetches the browser sends by design and +(b) app-owned auth endpoints once a valid gate session exists. **Each exemption is a hole in +a security control and needs its own written justification** — do not batch-fix this. + +## D. AI Data Access grants do not survive — wrong storage layer + +`aiPermissions.ts` persists to `localStorage` (`archipelago-ai-permissions`). No logout path +clears it (only SystemDangerZone, by design). **localStorage is per-origin**, and a node has +many: `192.168.63.240`, `100.69.68.39`, `.local`, the Tailscale name. Granting on one +and returning via another shows everything off — which is exactly what "turns them all off" +looks like, and what made a films search look broken tonight. + +These grants are a property of the NODE ("what may the AI read"), not of one browser at one +address. They belong node-side behind an RPC, with localStorage as an offline fallback and a +migration so existing local grants are not silently dropped. + +## E. Also observed, unowned + +- `/api/app-catalog` → **502**, repeatedly, on the dashboard. +- AIUI web search blocked by CSP (`connect-src http://:*/aiui/`) — confirms the + already-recorded 13-09 decision that the web-search setting must drive the CSP node-side. +- `Failed to scroll to index N after 10 attempts` — ChatWindow scroll bug, cosmetic but loud. +- `strfry.png` / `.svg` 404 — missing app icon. + +## Suggested sequencing (to be challenged by the research pass) + +1. **C** — fleet-wide, user-visible, security-critical. Blocks any app with its own login. +2. **D** — one RPC; unblocks every AI content path and stops false "broken" reports. +3. **A** — parser fix now, structured-output contract as the real answer. +4. **B** — needs C and D first; the signer question is a design decision, not a task. + +## Nostr-first framing (per feedback_nostr_first_solutions) + +Worth researching rather than assuming: IndeeHub already speaks Nostr for identity, and the +node already holds Nostr identity material. A single node-side signer serving both the +dashboard and gated apps (NIP-07-style bridge, already precedented by `nostr-provider.js`) +would address B-2, the app-auth half of C, and Phase C's zaps at once. Media identity/ +distribution over Nostr (NIP-94/NIP-71 style events, Blossom for blobs) is the obvious +frame for "all the media types" and should be evaluated against the current +`content.*` RPC model before more sources are bolted onto it.