Platform Architecture
Mirrored from
docs/*.md in the Aegis repositoryAEGIS PLATFORM ARCHITECTURE BLUEPRINT
» **Status:** Phase Zero — primary deliverable.
» **Role:** The source of truth for every future engineering decision. Code is secondary to this document.
» **Test for every decision:** "Will this still make sense after 20 brokers, 100 engineers, 500,000 users, and 50 product modules?"
» **North star:** Aegis is not an app. Aegis is a platform. Everything — including our own products — is a plugin.
---
1. PHILOSOPHY
1.1 The Core Constraint
**Every product is a plugin.** Mission Control, Protection, Portfolio, Intelligence, Options Lab — each is a plugin registered into the platform. Aegis core provides infrastructure; plugins provide product meaning.
This mirrors how VS Code grew from an editor into an ecosystem: core stayed small, extensions did the work. It forces clean boundaries, makes incorrect implementations difficult, and lets Aegis scale from 5 modules to 50 without redesign.
1.2 Platform vs. Feature
Concern | Platform (core) | Plugin (product)
Command Palette | The registry + UI | Registers its commands
Panel system | The layout engine | Registers its panels
Notifications | The bus + UX | Emits notifications
Data grid | The rendering engine | Supplies columns/data
Theme | The token system | Uses tokens, contributes forms
Persistence | The store engine | Declares its slices
1.3 Five-Year Horizon
This architecture must support, without redesign:
• Desktop, Web, Tablet, Mobile
• Embedded broker widgets
• AI copilots (each a plugin)
• Marketplace plugins (third-party)
• Enterprise deployments (multi-tenancy)
• Developer SDKs (the same SDK we use internally)
• Multi-window workspaces
• Real-time collaboration
• Shared dashboards
• Cloud sync
• Offline operation
• 20 brokers, 100 engineers, 500K users
1.4 System of Record
The runtime is the **Aegis Host**. The SDK is how plugins talk to it. There is exactly one extension mechanism: the SDK. If a feature cannot be expressed through the SDK, the SDK — not the feature — is missing something.
---
1A. REVISED LAYERED MODEL (POST-REVIEW)
┌─────────────────────────────────────────────────────────┐
│ PLUGIN LAYER (everything product — mine and yours) │
│ apps/ protection/ portfolio/ intelligence/ broker-*/ │
├─────────────────────────────────────────────────────────┤
│ SDK LAYER (the contract — typed, versioned, stable) │
│ registerWorkspace/Widget/Rule/Panel/... │
├─────────────────────────────────────────────────────────┤
│ DOMAIN LAYER (shared business vocabulary + catalog) │ ◀ NEW
│ Position, Portfolio, RiskEvent, Rule, Decision, │
│ Exposure, Broker, Order, Execution, Capital, Behavior │
│ + Domain Event Catalog + Capability Registry │
├─────────────────────────────────────────────────────────┤
│ FRAMEWORK LAYER (interaction systems, no product) │
│ Command, Panel, Widget, DataGrid, Timeline, Chart, ... │
├─────────────────────────────────────────────────────────┤
│ PLATFORM SERVICES (long-lived shared services) │ ◀ NEW
│ Sync, MarketData, Notification, Broker, Storage, │
│ AI Runtime, Settings, Analytics, Telemetry, Flags, │
│ License — consumed by frameworks; often wrap domain │
├─────────────────────────────────────────────────────────┤
│ CORE LAYER (runtime primitives, no product) │
│ Host, lifecycle, store engine, event bus, Workspace, │
│ Window, Persistence, State Sync, Offline, Real-time, │
│ Permission, Plugin loader, Capability Registry │
└─────────────────────────────────────────────────────────┘
**Dependency rule:** Layers may only depend on layers below. Framework may import Domain (types + capabilities) and consume Platform Services. Framework never imports a plugin. Core never knows a product exists. Plugins never import Framework internals — only the SDK.
1A.1 Why Domain is a real layer, not a folder
Trading concepts are **universal language**, not incidental types. `Position`, `Portfolio`, `RiskEvent`, `ProtectionRule`, `Decision` mean the same thing to Protection, Portfolio, Intelligence, and every broker. Without a domain layer, each plugin invents its own `Position` shape and the platform silently forks. Domain makes incorrect implementations hard: a plugin cannot render an `Exposure` that isn't derived from sourced positions, because the domain type enforces it.
1A.2 The Capability Registry — first-class (see §9A)
Broker integration is not `if broker == Zerodha`. It is:
Broker → Capabilities (SupportsRealtimeTicks, SupportsOrders, ...)
→ Products consume capabilities
The Capability Registry is a Core primitive. Products ask `supports("RealtimeTicks")` — never `broker === "Zerodha"`. This keeps broker count and product count independent: 20 brokers, 50 products, no cross-multiplication.
---
2. LAYERED MODEL
┌─────────────────────────────────────────────────────────┐
│ PLUGIN LAYER (everything product — mine and yours) │
│ apps/ protection/ portfolio/ intelligence/ broker-*/ │
├─────────────────────────────────────────────────────────┤
│ SDK LAYER (the contract — typed, versioned, stable) │
│ registerWorkspace/Widget/Rule/Panel/... │
├─────────────────────────────────────────────────────────┤
│ FRAMEWORK LAYER (interaction systems, no product) │
│ Command, Panel, Widget, DataGrid, Timeline, Chart, │
│ Notification, Overlay, Dialog, Inspector, ContextMenu, │
│ Toolbar, Search, Selection, History, Undo/Redo, │
│ Theme, Telemetry, ... │
├─────────────────────────────────────────────────────────┤
│ CORE LAYER (runtime primitives, no product) │
│ Host, App lifecycle, Store engine, Event bus, │
│ Workspace Manager, Window Manager, Persistence, │
│ State Sync, Offline, Real-time, Permission, Plugin loader │
└─────────────────────────────────────────────────────────┘
**Dependency rule:** Layers may only depend on layers below. Framework never imports a plugin. Core never knows a product exists.
---
3. THE SDK — THE DEFINITIVE CONTRACT
The **Aegis SDK** (internal) exposes typed registration functions. Everything a plugin can do goes through here.
// The single entry point every plugin imports.
import { Aegis, defineWorkspace } from "@aegis/sdk";
export default defineWorkspace({
id: "aegis.protection",
title: "Protection Engine",
description: "The safety system.",
register(ctx) {
ctx.registerCommand({ id: "protection.newRule", label: "New rule" });
ctx.registerPanel({ id: "protection.detail", title: "Rule detail" });
ctx.registerWidget({ id: "protection.status", title: "Protection status" });
ctx.registerShortcut({ id: "goto-protection", keys: "⌘⇧P", goto: "aegis.protection" });
ctx.registerNotificationType("rule.triggered", { level: "critical" });
ctx.registerTimelineFeed({ id: "protection.events", title: "Protection log" });
},
});
**The `register()` con
… (truncated — see repository docs/*.md for the full document)This is a condensed in-app view. The full document lives in the repository at
docs/platform_architecture.md.