docs: item 2 done — grants node-side, verified across a daemon restart

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-06 20:58:27 -04:00
co-authored by Claude Opus 5
parent 762c72b4d0
commit 4891e1babc
+24 -1
View File
@@ -74,7 +74,30 @@ session; it now answers 200 through the gate. Item 4's private-films path is unb
Still worth a human pass: a real NIP-07 **browser extension** login (this proved the
transport and the app's acceptance, using the node's key rather than the extension's).
### 2. AI Data Access grants → node-side (unblocks everything AI)
### 2. AI Data Access grants → node-side — ✅ DONE, deployed + verified (`762c72b4`)
Cause confirmed: `localStorage` is per-ORIGIN and a node answers on several (LAN,
Tailscale, `<host>.local`, hostname), so grants made at one address were simply never set
at another. It also made a working content path look broken — every scope silently returns
nothing without a grant, so "ungranted" and "empty library" are indistinguishable.
`settings/ai_permissions.rs` (session_policy shape: atomic temp+rename, sanitised on read
AND write, **fails closed** on a corrupt file) + `ai.permissions.get/.set`, absent from the
unauthenticated allowlist. Store seeds from localStorage for instant paint, then reconciles;
**migration pushes local grants UP when the node has none**, so upgrading never silently
revokes what someone already granted. Node wins otherwise, so a revocation on one device
takes effect everywhere. Hydration happens ONCE at broker start — the first attempt did it
per-gate and the existing broker tests caught it by failing on consumed mocks.
Live proof on archi-dev-box: unauthenticated → 401 (dispatched, not "unknown method");
set `["media","files","BAD ONE","../etc/passwd"]` → stored `["files","media"]` (malformed
dropped); written to `/var/lib/archipelago/settings/ai_permissions.json` owned by
`archipelago`; **survives `systemctl restart archipelago`** — the actual complaint.
Rust 7/7, store 18/18, broker 23/23.
NOTE: testing left `media` + `files` GRANTED on archi-dev-box. That is the state the
operator needs for content anyway, but it was set by the test, not by them.
### 2b. (superseded — original note)
`aiPermissions.ts` uses `localStorage` (`archipelago-ai-permissions`), which is PER-ORIGIN.
A node has many origins, so grants vanish when you switch address/device. Move behind an RPC,
localStorage as offline fallback, migrate existing local grants. This is what made a films