Workspaces & modules
Facts verified 2026-07-30 by claude-code/2026.07. Generated from the authored source at docs/llm-wiki/workspaces.md — the wiki owns these facts (ADR: D1 of docs/plans/20260811_documentation_system_execution.md). Edit that file, then regenerate: python docs/portfolio/_build/generate_wiki_pages.py.
The two role workspaces
- Routes:
/w/<slug>/…. Slugs:data-explorer(Data Explorer — prepare campaign evidence) andintegrity(Integrity Engineer — triage evidence, drive governed action). - Same shell, different module sets and default AI engine per workspace.
The shell
WorkspaceShell(web/components/workspaces/workspace-shell.tsx) composes: left sidebar (workspace switcher + module nav,web/components/sidebar.tsx), context bar (scope + Assistant toggle ⌘J,workspace-context-bar.tsx), and the docked Assistant panel (workspace-assistant-panel.tsx;BubbleChatlauncher on mobile).- Modules group into workflow stages (
WorkspaceNavigationGroup): scope → prepare → review → act → assist. - The same
ModuleIdcan be labeled differently per workspace (e.g.insights= “Notes” in Data Explorer, “Findings” in Integrity).
The module plug-in contract
- Contract lives in
web/lib/workspaces/:config.ts(ModuleIdunion +WORKSPACESconfig),modules.ts(MODULE_REGISTRY: Record<ModuleId, WorkspaceModule>),navigation.ts(buildSidebarModuleItems),context.tsx(WorkspaceProvider),context-policy.ts(CONTEXT_POLICIES). - A module entry declares:
id,label,icon,path(URL segment under/w/<workspace>/),requires(dataset|organization|none),requiredRole. ModuleIdis the single source of truth — a missing registry entry is a type error, plus a test asserts one entry per id.- Adding a feature = registering a module, not rewiring the shell.