.agents/skills/deep-review/references/dimensions/compatibility.md
The same change must work across every surface this product ships to. Authors (and reviewers) habitually validate only their own dev setup — typically cloud edition + web desktop + light mode + latest client + personal workspace — and every other cell of the matrix is where regressions hide.
| Axis | Variants to hold in mind |
|---|---|
| Theme | light / dark (cssVar.* tokens handle both; hardcoded colors break one) |
| Platform | desktop app (Electron) / web desktop / web mobile / React Native |
| Client version | released desktop/mobile clients keep calling old endpoints after the server deploys |
| Agent runtime | client-side runtime vs server runtime (gateway enabled or not) |
| Deployment | Vercel (serverless: no local fs persistence, execution time limits) vs Docker (long-lived process) |
| Edition | open-source self-hosted (business slots return safe no-op defaults) vs cloud (commercial overrides active) |
| Tenancy | personal context (workspaceId === null) vs workspace context (workspace-scoped data, permissions, member sharing) |
src/spa/router/desktopRouter.config.tsx but not desktopRouter.config.desktop.tsx (or vice versa) — causes blank screens; desktopRouter.sync.test.tsx must stay green(mobile) counterpart or responsive handlingPRECONDITION_FAILED / 410 Gone) instead of blind successuseActiveWorkspaceId / workspaceSlug) or be explicitly personal-only by designsrc/app/(backend)/webapi/...) or auth surfaces (src/app/spa-auth/..., src/routes/auth/...), or changed @lobechat/business-* exports — downstream deployments override/extend these paths; flag so they can adaptnext, drizzle-orm, ...) — downstream lockstep required; call out in the PR description.agents/skills/spa-routes/SKILL.md — router pair invariant, mobile/desktop variants.agents/skills/react/SKILL.md — theming/token rulesgit log -p on the deleted route) before trusting that a procedure is unused — inspect what removed the caller and whether released clients predate itworkspaceId is null (personal / self-hosted) and when the involved business slots return their open-source defaults — both paths must stay sound.