Monorepo RFC 002 directory nomenclature
RFC-002 — Directory Nomenclature: engine vs. backend at L4
| Field | Value |
|---|---|
| Status | *ccepted*(2026 |
| Author(s) | Rodrigo (with Claude as scribe) |
| Date | 2026 |
| Affects | All modules that use engine/ as a distribution-form subdir |
| Depends on | monorepo-RFC-001-area-first-directory-structure.md, engine-product-pattern.md |
1. Summary
Rename the engine/ subdirectory — currently used to mean "the Go/server-side backend of a consumer product" — to backend/ across all modules in the monorepo. Reserve the word "engine" exclusively for reusable algorithmic components that are not tied to a specific product's server stack.
2. Background
2.1 Two uses of "engine" in the Stack today
The word "engine" currently appears in two distinct, incompatible senses:
*ense A — Distribution form (L4 directory name)*
engine/ at depth 4 (inside <area>/<theme>/<product>/engine/) is used to mean "the server-side Go component of this product". Examples:
suite/kmail/engine/ ← Kmail's HTTP backend (Next.js + Go API)
suite/play/engine/ ← Koder Play's Go backend
suite/pulse/engine/ ← Koder Pulse's Go backend*ense B — Engine+Product pattern (L3 brand name)*
In the engine+product pattern (engine-product-pattern.md), the B2B white-label product is called the "engine" and gets its own brand name as a directory at depth 3:
suite/pulse/orbit/ ← Orbit, the B2B engine of Koder Pulse
suite/play/media/ ← Koder Media, the B2B engine of Koder PlayThese are two entirely different things using the same word, causing confusion when reading directory trees.
2.2 What "engine" actually means technically
An engine is a *eusable, specialized algorithmic component*
- Portable: can run inside a backend, inside a frontend, inside a CLI, or standalone
- Stateless: given the same input, produces the same output (function/library semantics)
- Not tied to a specific product: it is a reusable capability, not a product's server
Examples of true engines in the Koder Stack:
kodec/ ← video codec: called by backends, CLIs, desktop apps alike
ai/recsys/ ← recommendation engine: stateless scoring, no HTTP server
lang/kode/ ← Kode language runtime: embedded in IDE, CLI, and cloudA *ackend* by contrast, is the *erver-side layer of a specific product*
- Client-server: communicates via HTTPgRPCWebSocket with clients
- Stateful: manages sessions, databases, queues
- Tied to one product: it is not reusable by other products at the library level
suite/kmail/backend/ ← Kmail's HTTP server (Go + Next.js)
suite/play/backend/ ← Koder Play's Go serverThe metaphor that clarifies the distinction:
The backend is the house; the engine is a specialized machine that works inside (or outside) it. All backends can contain engines, but an engine is not a backend.
3. Problem
3.1 "engine" at L4 is semantically wrong
suite/kmail/engine/ does not contain a reusable algorithm. It contains:
- An HTTP server with routes
- Database connections and session management
- Product-specific business logic
This is a *ackend* not an engine. Naming it engine/ misleads contributors and contradicts the actual meaning of the engine+product pattern at L3.
3.2 platform/ naming collision at different levels
RFC001 dissolved level directory. However, platform/ as a topplatform/ still appeared in the internal structure of products as the Go backend subdir (e.g. suite/kmail/platform/), creating a phantom collision: a reader sees "platform" and cannot tell whether it refers to L1 (the old infra category) or L4 (the backend). The rename to backend/ eliminates this phantom.
3.3 engine+product pattern is not about directory naming
The engine+product pattern names B2B products; it is about *rand identity* not directory structure. The B2B engine product gets a directory named after its brand (orbit, media, raven) — not a directory named engine/. The word "engine" in the pattern is a role description, not a directory name.
4. Decision
4.1 Rename engine/ → backend/ at L4
Every occurrence of <area>/<theme>/<product>/engine/ where engine/ is the Goserver-side backend of the consumer product is renamed to `backend`.
*efore:*
suite/
kmail/
engine/ ← Kmail's HTTP backend
raven/ ← Raven B2B email platform (brand name)
app/
mobile/
desktop/*fter:*
suite/
kmail/
backend/ ← Kmail's HTTP backend (clear: this is the server)
raven/ ← Raven B2B email platform (unchanged: brand name)
app/
mobile/
desktop/4.2 Reserve "engine" as a concept, not a directory role
The word "engine" should only appear in directory names when the component truly is a reusable algorithmic engine (Sense B above). Such components are usually:
- Libraries imported via
go.modorpubspec.yaml - SDKs or runtimes distributed independently
- Stateless scoring/processing components embedded in multiple products
The engine+product pattern's "engine" role description remains valid — it describes the B2B whitelabel brand, which always gets a *randname directory* never a generic engine/ directory.
4.3 Canonical L4 directory names
| Directory | Meaning | Example |
|---|---|---|
backend/ |
Server-side component of the consumer product (Go/Node HTTP) | suite/kmail/backend/ |
app/mobile/ |
Flutter Android+iOS app | suite/kmail/app/mobile/ |
app/desktop/ |
Flutter Linux+macOS+Windows app | suite/kmail/app/desktop/ |
app/tv/ |
JS/React TizenOS+WebOS app | suite/play/app/tv/ |
site/ |
Landing page (static) | suite/kmail/site/ |
<brand-name>/ |
B2B engine product (brand-named) | suite/pulse/orbit/ |
5. Impact
5.1 Paths that change
All 52 engine/ directories confirmed in the monorepo as of 20260428:
*uite