eslint-disable comments.
Layering rule
Before diving into per-plane boundaries, one rule applies everywhere:apps/* may depend on packages/*. Packages must never depend on apps. Apps consume packages
only through published entrypoints — no deep imports from @reflection/*/src/*.Per-plane boundaries
Realtime plane (apps/api + packages/brain-core)
Realtime plane (apps/api + packages/brain-core)
The realtime plane handles live voice sessions, knowledge retrieval, and session lifecycle.Allowed:
- Read reflection config, chunks, entities, and facts
- Write conversations, messages, and retrieval traces (session data)
- Bootstrap voice sessions with the managed provider
- Dispatch events to the background plane via Inngest
- Writing to sources, chunks, entities, or fact state directly
- Running background ingestion or eval execution in the realtime process
- Importing from
@reflection/db/queries/admin - Running LLM entity extraction in the realtime path
Background plane (apps/workers)
Background plane (apps/workers)
The background plane runs the ingestion pipeline — extraction, evaluation, and patch application.Allowed:
- Ingestion and candidate fact creation
- Evaluation and scoring of candidate facts
- Transactional patch application (promoting candidates to active)
- Using
@reflection/db/queries/adminfor write operations - Calling LLM APIs for extraction and evaluation via
@reflection/vendors
- Bypassing the eval/apply gate
- Setting active truth directly from raw external content without the candidate/eval path
- Serving user-facing requests or participating in realtime latency paths
API layer (apps/api)
API layer (apps/api)
The API layer handles authentication, authorization, and request routing.Allowed:
- Auth and role derivation from Clerk JWTs and bearer tokens
- Token issuance for voice sessions
- Dispatch metadata to background workers
- Reading from
@reflection/db/queries/read
- Trusting client role claims — roles are always server-derived
- Exposing database internals directly to clients
- Importing from
@reflection/db/queries/admin
Web frontend (apps/web)
Web frontend (apps/web)
The Next.js web application provides the user-facing dashboard and session interface.Allowed:
- Session bootstrap through the API via
@reflection/api-client - Rendering knowledge graph visualizations from API responses
- Auth via Clerk Next.js SDK
- Direct database access of any kind
- Privileged role assertions — the API determines access
- Importing from
@reflection/dbor any server-only package
iOS app (apps/ios)
iOS app (apps/ios)
The native Swift iOS app provides voice interaction and knowledge graph visualization.Allowed:
- Session bootstrap through the API via the native HTTP client
- Auth via Clerk iOS SDK
- Local voice session management with ElevenLabs
- Direct database access of any kind
- Privileged role assertions — the API determines access
Enforcement mechanisms
Boundaries are not advisory — they are enforced at three layers:| Layer | Mechanism | What it catches |
|---|---|---|
| ESLint | no-restricted-imports rules in eslint.config.mjs | Admin query imports from realtime/API, deep imports, direct vendor SDK imports outside packages/vendors, process.env outside designated files |
| Architecture guard | simplicity-guard.mjs in CI | Dynamic imports that bypass ESLint, cross-plane violations, vendor SDK isolation, file size budgets |
| File-scan tests | Dedicated test files in affected packages | Admin import violations (cannot be eslint-disabled), process.env isolation |
Related pages
- Two-plane architecture — why these boundaries exist.
- System invariants — the non-negotiable rules that boundaries enforce.
- Package map — how each package fits into the dependency graph.

