docs(13): content-grid defect fixed + the peer/owned gap that blocks check 2

Records why 13-15's check 2 cannot pass as written (peers/owned scopes have no
caller) and the merge design settled before stopping, so the next session does
not rediscover that setArchyContent replaces rather than merges.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-06 15:46:42 -04:00
co-authored by Claude Opus 5
parent aac81503c3
commit 2ecd5ef8c0
@@ -26,6 +26,33 @@ Then: write `13-UAT.md`, fill `13-VALIDATION.md`'s map, close 13-15, close the p
Known gaps to record rather than fix: music view (D-13 independent track), Routstr live paid
request (protocol unverified, zero allowance), E-09 naive-user comprehension study.
## Content grid (13-15 check 2) — one defect FIXED, one gap OPEN
**FIXED `aac81503`: the grid dropped everything except music.** The AIUI-03 stale-response
guard in `contextBroker.ts` used ONE counter for every `content:request`, so different kinds
cancelled each other. `useArchy.ts` init fires `content('all','own')` then `library('own')`
back to back; both sequence numbers are assigned synchronously before either awaits, so the
first ALWAYS resolved stale and was silently discarded. Films, podcasts and own files never
reached the grid — only music did, and nothing logged because discarding is the guard working
as written. Guard is now keyed by `kind:scope`. 23/23 contextBroker tests.
**OPEN: peer and owned content is unreachable.** `scope` accepts `'own' | 'peers' | 'owned'`
but grep finds NO call passing `peers` or `owned` — they exist only in type signatures. The
sole live call is `requestArchyContent('all','own')` at init. **There is no prompt that
fetches peer files; no text→content-request path exists at all.** (`preferredFirstTab` only
picks the recommendation TAB LABEL — films/songs/podcasts/tvshow — and never requests node
content.) So 13-15's check 2 as written ("real peer/owned files render") cannot pass.
Design settled before stopping, for whoever finishes it:
- Fetch all three scopes and merge into ONE `setArchyContent` call. `setArchyContent`
(`useContentPanel.ts:295`) **replaces** panelFilms/panelSongs/panelPodcasts, so three
separate pushes would have the last writer wipe the other two. Merge in `useArchy.ts`,
dedupe by id, leave `setArchyContent`'s contract alone.
- The per-scope fan-out cost is already bounded node-side: 02-08 capped
`content.browse-peer`'s concurrency and shortened its timeout after it starved Chromium's
connection pool. So auto-loading peers at init is defensible; an explicit control is the
conservative alternative. **Operator has not chosen** — was asked, not answered.
## Node/infra tasks (not phase 13)
- **Gated-app iframe login** (`session timeout` in-frame, works in a tab). Mechanism confirmed: