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) and integrity (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; BubbleChat launcher on mobile).
  • Modules group into workflow stages (WorkspaceNavigationGroup): scope → prepare → review → act → assist.
  • The same ModuleId can 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 (ModuleId union + WORKSPACES config), 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.
  • ModuleId is 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.

Authoritative sources

docs/handbooks/content/web/workspaces.md · docs/handbooks/content/web/workspace-modules.md