- src/App.tsx is a shim re-exporting apps/omnihub-site/src/App.tsx (Canonical Truth Statement 2).
- src/stores/.ts re-export apps/omnihub-site/src/stores/.ts.
- src/components/dashboard/ contains only OmniTracePanel.tsx. There is NO src/components/dashboard/OmniDash.tsx.
HARD RULE: if a task targets a path under src/components/dashboard/ for OmniDash work, STOP and re-resolve to apps/omnihub-site/dashboard/. Editing src/ for dashboard work produces zero visible change and is the root cause of repeated false-win loops. Verify a path exists with the file tool before editing. Never invent paths or schema columns. Output UNCERTAIN:[gap] instead of guessing.
Architecture
AI orchestration control plane. React 18.3.1 + Vite 7 · Supabase Edge Functions (Deno) · Python FSM orchestrator (Render) · Cloudflare Pages. Domain apexomnihub.icu. Production Supabase project rtopreovkywofgwgmozi (ca-central-1). Package manager npm. TypeScript 5.9.x. Dev port 8080.
Tri-Force Pipeline
Guardian (policy/security) → Planner (decomposition/routing) → Executor (dispatch/MCP).
Canonical Path Registry (verified 2026-06-27)
| Layer | Path |
|---|---|
| OmniDash shell | apps/omnihub-site/dashboard/OmniDashShell.tsx |
| Modal host (sole chrome owner) | apps/omnihub-site/dashboard/components/OmniSpatialHost.tsx |
| Module renderer (moduleKey → component) | apps/omnihub-site/dashboard/components/ModuleRenderer.tsx (MODULE_COMPONENTS map) |
| OmniBoard wizard (3rd-party only) | apps/omnihub-site/dashboard/components/OmniBoardWizard.tsx |
| OmniBoard module shell | apps/omnihub-site/dashboard/components/modules/OmniBoardModule.tsx |
| Files module (upload entry) | apps/omnihub-site/dashboard/components/modules/FilesModule.tsx |
| OmniMedia widget | apps/omnihub-site/dashboard/components/media/OmniMediaLaunchWidget.tsx |
| OmniMedia player | apps/omnihub-site/dashboard/components/media/OmniMediaPlayer.tsx |
| OmniMedia store | apps/omnihub-site/src/stores/omniMediaStore.ts |
| Draggable widget | apps/omnihub-site/dashboard/DraggableWidget.tsx |
| Sidebar contract | apps/omnihub-site/src/contracts/omnidash-sidebar-widgets.ts |
| Integration ownership | apps/omnihub-site/dashboard/contracts/appIntegrationOwnership.ts (legacy single-owner; superseded by omniSurfaceOwnership.ts) |
| i18n | apps/omnihub-site/src/i18n/index.ts · locales.ts |
| Layout (top bar) | apps/omnihub-site/src/components/Layout.tsx |
| Edge router | supabase/functions/omnilink-port/index.ts |
| Migrations (additive only) | supabase/migrations/ |
| E2E | tests/e2e-playwright/ |
| Canonical truth | memory/omni-recall/docs/architecture/CANONICAL_TRUTH.md |
Surface Ownership Canon (Statement 28, 2026-06-28 — corrects Statement 27)
App integration has TWO distinct owners. Single-owner models are retired. The center-canvas "Integrated Apps" panel is NOT an owner — it is a display-only gallery.
| Surface | Owns | Forbidden |
|---|---|---|
| OmniBoard | third-party provider connections, connector sessions, connection specs | internal APEX app install, media, playback |
| APEX Apps | internal APEX ecosystem registry, MCP app connect/install flow | third-party provider connections |
| Integrated Apps Gallery | read-only display of integrated-app status tiles | any connection flow, any modal invocation, any CTA |
| Files | file upload, file management; FEEDS OmniMedia | — |
| OmniMedia | media catalog, gallery, playback, ingestion | third-party connections, app install |
| Language | locale selection + persistence (apex_locale) | — |
Rules: "Add APEX App" opens the MCP app modal (moduleKey apex-apps-mcp), NEVER OmniBoard.
Any non-owner surface hands off: third-party to OmniBoard, ecosystem to APEX Apps.
Statement 27's "Connections split" (Third-Party Connections / Connected APEX
Apps with a Connect App CTA) is RETIRED — it duplicated both owners. The
canvas panel (IntegratedAppsGalleryWidget, testid widget_apps/integrated-apps,
heading "Integrated Apps Gallery") shows status only: no split sub-panels, no
"Connect App" CTA, no modal invocation, non-interactive empty/"Awaiting" slots.
omniSurfaceOwnership.ts is the single source of truth; appIntegrationOwnership.ts
must re-export from it or be deprecated.
Modal Law
OmniSpatialHost owns ALL modal chrome (one shell, one close, one title, role=dialog, aria-modal, focus trap, focus return). Child modules render content only: no nested header, no second close button. Escape and backdrop click both close ordinary modals.
Honest-Gateway Law
OmniBoard omniboard-start proxies to ORCHESTRATOR_URL. If unset, an inline HMAC FSM fallback (OMNIBOARD_SESSION_SECRET) may run; if neither is set, show an honest "unavailable" gate. Never fake a successful connection. Never mark an app connected without a verified connector_sessions or connection_spec record.
Database — Critical Tables (RLS mandatory)
users · clients · payments · audit_log (append-only) · module_states · omnilink_links · omnimedia_assets (owner_user_id scoped). All public tables have RLS. SECURITY DEFINER functions pin search_path=public and revoke EXECUTE from anon.
- Consume the existing useViewport() hook (isDesktop today; extend to tablet/mobile as needed). Do not hardcode pixel widths where a breakpoint applies.
- Galleries and grids: fluid columns (CSS grid auto-fit/minmax), not fixed counts.
- Modals: full-height sheet on mobile, centered panel on desktop; touch targets >= 44px.
- Drag/drop: pointer-capture on desktop mouse; long-press allowed only for touch and must not degrade desktop. Layout persists per breakpoint: omnidash_layout_v2:{userId}:{breakpoint}.
- Every responsive surface ships a multi-viewport E2E (desktop + mobile minimum). No surface is complete until it is verified at all three viewports.
Repair loop: ISOLATE single unit → EVIDENCE (read source + logs, never fix without it) → ONE root-cause hypothesis → MINIMAL fix (blast radius enforced) → HEALTH GATE (typecheck + lint + build + tests green) → 3-line postmortem. Attempt ceiling 3, then HARD STOP → UNCERTAIN:[gap]. Return to ISOLATE with fresh evidence after any failure; never loop the fix step.
Output after a task: VERIFIED: [what] | HEALTH: [green/degraded] | TESTS: [pass count] POSTMORTEM: [3 lines] | NEXT: [single action or DONE]
Version 1.1.0 · Format Claude-native XML · Sole dev workflow for APEX-OmniHub License Proprietary — APEX Business Systems Ltd. Edmonton, AB, Canada