Two second implementations, both removed rather than fixed.
DashboardPreview minted template panel ids with its own module-level counter,
tpl-1, tpl-2, no entropy, reset every page load. Two dashboards built from
templates in the same page load held panels with identical ids — and a panel id
is not decorative any more: agent_panels addresses an agent by
(dashboardId, panelId), and terminal-conn-<panelId> and file-viewer:<panelId>
key persisted state by it. The templates now call the core uid(), which is
exported from the Workspace barrel for the first time so there is one minter.
metasToRegistry is Object.fromEntries, so two apps sharing a key means one app
stops existing and every panel holding its appType renders the other. The todo
asked for a throw in dev; a throw takes down every dashboard at runtime for a
mistake made at edit time, so this is a test over the real meta list plus a
console.error. All 44 keys are unique, and the test now says so rather than the
doc.
Getting the real list into a test needed test-setup.ts to provide localStorage:
MusicPlayer/useLyricsOpen.ts reads it at import time, so the whole app graph was
unimportable from a test. That unblocks testing anything that pulls in a panel
app.
Also deletes officerdev/src/useAppRegistry.ts — a stub returning {} with a
different shape from the real hook, imported by nothing.