docs(13-06): retarget plan to in-repo aiui/ (D-19)

Mechanical path swap: AIUI's composables now live at aiui/packages/app/...
in this repo (git subtree import, D-19), not at the old separate clone
/home/archipelago/Projects/AIUI. Drops the "separate development branch to
push" language accordingly. Verified every retargeted path exists on disk
before rewriting; task content and must_haves are otherwise unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-03 17:05:47 -04:00
co-authored by Claude Opus 5
parent e1624dda08
commit 97aa758d7d
@@ -11,8 +11,8 @@ files_modified:
- neode-ui/src/api/__tests__/filebrowserStreamUrl.test.ts
- neode-ui/src/services/contextBroker.ts
- neode-ui/src/types/aiui-protocol.ts
- /home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts
- /home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts
- aiui/packages/app/src/composables/useArchy.ts
- aiui/packages/app/src/composables/useContentPanel.ts
autonomous: true
requirements: [AIUI-03]
@@ -42,8 +42,8 @@ must_haves:
to: "neode-ui/src/composables/archyContentAdapter.ts"
via: "content:push handler adapts content.* RPC records before they cross the iframe boundary"
pattern: "adaptContentItems"
- from: "/home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts"
to: "/home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts"
- from: "aiui/packages/app/src/composables/useArchy.ts"
to: "aiui/packages/app/src/composables/useContentPanel.ts"
via: "setArchyContent() writes panelFilms/panelSongs/panelPodcasts directly, bypassing updatePanelFromText's regex path"
pattern: "setArchyContent"
---
@@ -105,7 +105,7 @@ Symbols created by **this plan**:
`contentRequestSeq` (private field — the concurrency guard)
- `types/aiui-protocol.ts`: `AIUIContentRequest`, `ArchyContentPush`
**AIUI (`/home/archipelago/Projects/AIUI`, branch `development`)**
**AIUI (`aiui/`, in-repo since D-19 — no longer a second repository or a `development` branch to push)**
- `composables/useArchy.ts`: `requestArchyContent`
- `composables/useContentPanel.ts`: `setArchyContent`, `archyContentActive` (ref)
@@ -115,7 +115,7 @@ untouched.
Unchanged by design and therefore **not** new symbols: `FilmGrid.vue`, `SongGrid.vue`,
`NewsGrid.vue`, `ContentGridView.vue`, and every `Film`/`Song`/`Podcast` type in
`packages/core/src/types/content.ts`.
`aiui/packages/core/src/types/content.ts`.
</artifacts_this_phase_produces>
<execution_context>
@@ -151,7 +151,7 @@ Unchanged by design and therefore **not** new symbols: `FilmGrid.vue`, `SongGrid
- `sanitizePath` traversal handling is unchanged by the fix — a path containing `..` is still resolved and never escapes root.
</behavior>
<read_first>
- `/home/archipelago/Projects/AIUI/packages/core/src/types/content.ts` lines 7-70 — the exact target shapes: `Film` (line 7), `FilmSource` (23), `SongSource` (37), `Song` (44), `Podcast` (63). **This file is read, never modified** — D-12 keeps AIUI's design exactly.
- `aiui/packages/core/src/types/content.ts` lines 7-70 — the exact target shapes: `Film` (line 7), `FilmSource` (23), `SongSource` (37), `Song` (44), `Podcast` (63). **This file is read, never modified** — D-12 keeps AIUI's design exactly.
- `core/archipelago/src/content_server.rs``ContentItem` and `AccessControl` (`Free | PeersOnly | Paid`), the source shape being mapped from.
- `core/archipelago/src/api/rpc/content.rs``content.list-mine`, `content.browse-peer`, `content.owned-list`, `content.preview-peer`, and the MIME auto-filing logic around line 668 (the classification precedent to stay consistent with).
- `neode-ui/src/api/filebrowser-client.ts` in full — CONTEXT.md names this "the known leak to fix rather than propagate", and **this task fixes it**, so read the whole client, not just the leaking function. The four facts that make the fix small and safe: `login()` (lines 55-83) sets the filebrowser JWT as a **cookie** with `path=/` and `SameSite=Lax` on the page's own origin; `baseUrl` (line 43) is `window.location.origin + '/app/filebrowser'`, so a media element's request for it is **same-origin**; a same-origin subresource request carries that cookie automatically and `SameSite=Lax` does not restrict same-site subresources; and filebrowser's own auth reads the `auth` cookie, which is why its own web UI works without a query parameter. The credential in the query string is therefore redundant, not load-bearing.
@@ -195,7 +195,7 @@ Write the tests FIRST in `archyContentAdapter.test.ts`, one per `<behavior>` bul
- `cd neode-ui && npx vitest run src/api/__tests__/filebrowserStreamUrl.test.ts` exits 0 — the pre-existing leak is closed and pinned
- `grep -vE '^\s*(//|\*|/\*)' neode-ui/src/api/filebrowser-client.ts | grep -cF 'raw${safePath}?'` returns 0 — `streamUrl` appends no query component
- `cd neode-ui && npx vitest run src/components/__tests__/MediaLightboxPip.test.ts` exits 0 — the lightbox's `streamUrl` consumer did not regress
- `git -C /home/archipelago/Projects/AIUI diff --exit-code -- packages/core/src/types/content.ts packages/app/src/components/content/FilmGrid.vue packages/app/src/components/content/SongGrid.vue` exits 0 — D-12's "props unchanged" held
- `git diff --exit-code -- aiui/packages/core/src/types/content.ts aiui/packages/app/src/components/content/FilmGrid.vue aiui/packages/app/src/components/content/SongGrid.vue` exits 0 — D-12's "props unchanged" held
- `cd neode-ui && npx vue-tsc --noEmit` exits 0
</acceptance_criteria>
<reversibility rating="costly">D-12's grid-source swap is rated costly in CONTEXT.md — the grids stay prop-driven and the source behind them is swappable, but every consumer is written against this mapping's field semantics. Flagged, not gated.</reversibility>
@@ -241,15 +241,16 @@ Do not add a second postMessage channel, do not relax `this.allowedOrigin`, and
<task type="auto">
<name>Task 3: AIUI renders Archy content in the grids it already has</name>
<files>/home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts, /home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts</files>
<files>aiui/packages/app/src/composables/useArchy.ts, aiui/packages/app/src/composables/useContentPanel.ts</files>
<read_first>
- `/home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts` lines 1-45 — the module-level `panelFilms`/`panelSongs`/`panelPodcasts` refs and the mock imports, and `updatePanelFromText` at line 80 with its export list at 495-520.
- `/home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts` — the `__AIUI_EMBEDDED__` detection at lines 80-81 and the existing `archyBridge.requestContext(cat).then(...)` shape at line 134. **Mirror this; do not invent a third convention.**
- `/home/archipelago/Projects/AIUI/packages/app/src/pages/ChatPage.vue` — the live render tree (`ContentGridView`). **Note `ContentPanel.vue` is dead code and must not be built through** (CONTEXT.md Deferred).
- `/home/archipelago/Projects/AIUI/packages/app/src/composables/__tests__/` — the existing suite, including `contentExtraction.test.ts`, which must stay green.
- `aiui/packages/app/src/composables/useContentPanel.ts` lines 1-45 — the module-level `panelFilms`/`panelSongs`/`panelPodcasts` refs and the mock imports, and `updatePanelFromText` at line 80 with its export list at 495-520.
- `aiui/packages/app/src/composables/useArchy.ts` — the `__AIUI_EMBEDDED__` detection at lines 80-81 and the existing `archyBridge.requestContext(cat).then(...)` shape at line 134. **Mirror this; do not invent a third convention.**
- `aiui/packages/app/src/pages/ChatPage.vue` — the live render tree (`ContentGridView`). **Note `ContentPanel.vue` is dead code and must not be built through** (CONTEXT.md Deferred).
- `aiui/packages/app/src/composables/__tests__/` — the existing suite, including `contentExtraction.test.ts`, which must stay green.
</read_first>
<action>
Work in `/home/archipelago/Projects/AIUI` on branch `development`.
Work in `aiui/` within this repo (D-19 — AIUI is no longer a second repository; there is no
`development` branch to switch to and no second remote to push).
In `useContentPanel.ts` add `setArchyContent(bundle: { films?; songs?; podcasts? })`, which writes the module-level `panelFilms`/`panelSongs`/`panelPodcasts` refs directly, and an `archyContentActive` ref it sets true. Export both. Then guard `updatePanelFromText` so that when `archyContentActive` is true it does **not** overwrite the film/song/podcast buckets from regex-scraped model prose — the Archy-sourced grids are the source of truth for those three buckets when a node is supplying them. Leave the rest of `updatePanelFromText` (books, TV, images, places, magazine, code, recipes, news) untouched: those still have no Archy source and are outside D-12's slice.
@@ -257,26 +258,28 @@ Do **not** delete `contentExtraction.ts` or its regex path. `13-PATTERNS.md` cal
In `useArchy.ts` add `requestArchyContent(kind, scope)` following the existing `archyBridge.requestContext` shape, and call `setArchyContent` from its `content:push` handler. Register the handler alongside the existing bridge listeners; do not add a second `window.addEventListener('message')`.
Do not touch `FilmGrid.vue`, `SongGrid.vue`, `NewsGrid.vue`, `ContentGridView.vue` or `packages/core/src/types/content.ts` — D-12 is explicit that only the data source changes. Do not revive `ContentPanel.vue`, `ArchyAppsGrid.vue`, `FavoritesGrid.vue`, `DiscoverPanel.vue`, `RecipeDetail.vue` or `AppDetail.vue`.
Do not touch `FilmGrid.vue`, `SongGrid.vue`, `NewsGrid.vue`, `ContentGridView.vue` or `aiui/packages/core/src/types/content.ts` — D-12 is explicit that only the data source changes. Do not revive `ContentPanel.vue`, `ArchyAppsGrid.vue`, `FavoritesGrid.vue`, `DiscoverPanel.vue`, `RecipeDetail.vue` or `AppDetail.vue`.
Record honestly in the summary that TMDB posters, web search and RSS remain 404 on a node because their Vite plugins are dev-server-only — a `Film` adapted from a peer file has no `posterUrl` and the grid must render its existing no-artwork state rather than a broken image.
Commit and push on `development`, staging explicitly by path.
Commit as part of this repo's normal history, staging explicitly by path per `CLAUDE.md`'s commit
discipline — there is no separate `development` branch to commit on and no second push to make
(D-19 retires that step; only this repo's own remote applies).
</action>
<verify>
<automated>cd /home/archipelago/Projects/AIUI/packages/app &amp;&amp; npx vitest run</automated>
<automated>cd /home/archipelago/Projects/AIUI/packages/app &amp;&amp; npx vue-tsc --noEmit</automated>
<automated>cd /home/archipelago/Projects/AIUI &amp;&amp; git diff --exit-code HEAD~1 -- packages/app/src/components/content/ packages/core/src/types/content.ts</automated>
<automated>cd aiui/packages/app &amp;&amp; npx vitest run</automated>
<automated>cd aiui/packages/app &amp;&amp; npx vue-tsc --noEmit</automated>
<automated>git diff --exit-code HEAD~1 -- aiui/packages/app/src/components/content/ aiui/packages/core/src/types/content.ts</automated>
</verify>
<acceptance_criteria>
- `grep -q 'setArchyContent' /home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts` and it appears in the export list
- `grep -q 'archyContentActive' /home/archipelago/Projects/AIUI/packages/app/src/composables/useContentPanel.ts`
- `grep -q 'requestArchyContent' /home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts`
- `grep -c 'ContentPanel' /home/archipelago/Projects/AIUI/packages/app/src/composables/useArchy.ts` returns 0 — the dead path was not revived
- `git -C /home/archipelago/Projects/AIUI diff --exit-code HEAD~1 -- packages/app/src/components/content/` exits 0 — no grid component changed
- `cd /home/archipelago/Projects/AIUI/packages/app && npx vitest run` exits 0 (`contentExtraction.test.ts` still green — the regex path was guarded, not removed)
- `cd /home/archipelago/Projects/AIUI/packages/app && npx vue-tsc --noEmit` exits 0
- The commit is pushed to `development`
- `grep -q 'setArchyContent' aiui/packages/app/src/composables/useContentPanel.ts` and it appears in the export list
- `grep -q 'archyContentActive' aiui/packages/app/src/composables/useContentPanel.ts`
- `grep -q 'requestArchyContent' aiui/packages/app/src/composables/useArchy.ts`
- `grep -c 'ContentPanel' aiui/packages/app/src/composables/useArchy.ts` returns 0 — the dead path was not revived
- `git diff --exit-code HEAD~1 -- aiui/packages/app/src/components/content/` exits 0 — no grid component changed
- `cd aiui/packages/app && npx vitest run` exits 0 (`contentExtraction.test.ts` still green — the regex path was guarded, not removed)
- `cd aiui/packages/app && npx vue-tsc --noEmit` exits 0
- The commit lands in this repo's normal history — no separate push to a second remote is expected or possible (D-19)
</acceptance_criteria>
<done>With a node supplying content, `FilmGrid` and `SongGrid` render real peer/owned/paid records through their unchanged props; with no node, AIUI's own regex path still works exactly as before.</done>
</task>
@@ -305,13 +308,13 @@ Commit and push on `development`, staging explicitly by path.
| T-13-36 | Tampering | Peer-authored filename rendered as HTML | medium | mitigate | Vue's template interpolation escapes by default and no `v-html` is introduced; the adapter emits plain strings and never markup |
| T-13-37 | Spoofing | Two peers' byte-identical files merged into one card, hiding which peer served it | medium | mitigate | Cards key on `id`, never on filename+size; asserted by the adjacency test |
| T-13-38 | Denial of Service | Stale slow response overwrites fresher grid data | low | mitigate | `contentRequestSeq` guard; asserted by the out-of-order test |
| T-13-SC | Tampering | npm/pip/cargo installs | high | mitigate | **Zero** packages added in either repo. No install task, so no legitimacy checkpoint required |
| T-13-SC | Tampering | npm/pip/cargo installs | high | mitigate | **Zero** packages added, in neode-ui's package.json or in `aiui/`'s own pnpm workspace (D-19: `aiui/` carries its own `package.json`/lockfile in-repo, but this plan adds nothing to it). No install task, so no legitimacy checkpoint required |
</threat_model>
<verification>
- `cd neode-ui && npx vitest run src/composables/__tests__/archyContentAdapter.test.ts && npx vitest run src/services/__tests__/contextBroker.test.ts && npx vitest run src/views/__tests__/chatAiuiEmbed.test.ts` all green
- `cd /home/archipelago/Projects/AIUI/packages/app && npx vitest run && npx vue-tsc --noEmit` green
- `git -C /home/archipelago/Projects/AIUI diff --exit-code HEAD~1 -- packages/app/src/components/content/ packages/core/src/types/content.ts` exits 0
- `cd aiui/packages/app && npx vitest run && npx vue-tsc --noEmit` green
- `git diff --exit-code HEAD~1 -- aiui/packages/app/src/components/content/ aiui/packages/core/src/types/content.ts` exits 0
- No adapter-produced URL carries a credential query parameter, and `filebrowserStreamUrl.test.ts` is green
</verification>