← All docs

Runtime Architecture

Mirrored from docs/*.md in the Aegis repository
AEGIS RUNTIME ARCHITECTURE v1.0

» **Status:** Phase Zero — foundational document #2.
» **Purpose:** The operating manual for the Aegis platform. The Platform Blueprint defines *structure* (what modules exist and how they nest). This document defines *behavior* (how Aegis operates while running — sequences, lifecycles, events, failures).
» **Relationship:** Blueprint = anatomy. Runtime Architecture = physiology.
» **Test for every decision:** "Does Aegis keep operating when a broker fails, the internet drops, an AI call times out, or a worker dies?"

---


0. GUIDING PRINCIPLES

1. **Graceful degradation is the default, not a mode.** Aegis is designed to keep working (with degraded fidelity, never degraded safety) when any subsystem fails.
2. **The broker is the source of truth.** The runtime reflects broker-reported state; it never infers or fabricates. Offline writes are visibly marked "pending," never masked as settled.
3. **Safety over completion.** Protection rules never silently fail closed *or* open. If evaluation is impossible, the runtime surfaces an explicit "UNKNOWN" state — it never guesses a rule outcome.
4. **Everything is evented.** No subsystem calls another directly across a boundary; it emits a domain event. This is what makes replay, undo, telemetry, and collaboration possible for free.
5. **Read-only is structural.** The connection layer enforces read-only; the UI cannot request otherwise.
6. **AI explains, never decides.** No model output reaches a user un-reviewed by the Safety Layer.

---


1. APPLICATION STARTUP

The full cold-start sequence, in order. Each step is idempotent; a crash mid-start resumes from the last completed checkpoint.

  Step | Subsystem | What happens | Failure handling
  1 | **Bootstrap** | Runtime environment probe (platform, memory, device form factor, network state). Compute a capability baseline from device/OS. | If probe fails, run in minimal mode with static UI.
  2 | **Core kernel** | Instantiate the Host, EventBus, Store engines, and the Capability Registry. Nothing user-facing renders yet. | A Core failure is fatal on desktop (log + crash screen); on mobile, show recovery.
  3 | **Plugin discovery** | Scan `plugins/` manifests (and remote marketplace index in enterprise). Resolve version + capability requirements. Build the plugin graph. | Unresolvable plugins are marked **disabled with a reason**, never crash the boot.
  4 | **Capability negotiation** | For each plugin, check the capability matrix (SDK version, broker capabilities, feature flags). Two-phase: collect, then activate. | Conflicts resolve by priority; losers are suspended with a clear diagnostic.
  5 | **SDK initialization** | Build the curated `PluginContext` for each plugin. Load first-party plugins (trusted, same context) and third-party (sandboxed). Run each plugin's `register()`. | A throwing `register()` is caught per-plugin; the plugin is disabled, the host continues.
  6 | **Theme initialization** | Read the persisted theme + density. Load design tokens; apply semantic token slots; respect `prefers-reduced-motion`. | Fall back to the platform default theme.
  7 | **Authentication** | Restore the session. Check refresh token; if valid, resume. If expired, route to re-auth / silent-reauth. | No session → show onboarding/lock screen, never a broken workspace.
  8 | **Broker discovery** | Reconcile persisted broker connections with their capability sets. Probe each connection's health. | A dead broker is marked "disconnected — retrying"; the rest of the platform remains live.
  9 | **Real-time initialization** | Establish the Realtime layer (WebSocket stream). Subscribe to tick topics and system channels. | No network → fall to polling; if neither, mark data "stale" (never wrong).
  10 | **AI initialization** | Instantiate the AI Runtime (model routing, prompt registry, safety layer). Do **not** open a model connection yet — models are lazy. | AI down → Decision Intelligence shows "unavailable," everything else works.
  11 | **Command registration** | All plugins' commands registered into the Command Bus. Build the palette index + shortcut map. | A bad shortcut conflicts visually, never fatally.
  12 | **Navigation registration** | Workspaces registered as navigable addresses. Build the breadcrumb + route table. | Registration is additive; no workspace blocks another.
  13 | **Telemetry startup** | Start the (opt-in) telemetry pipeline. Emit `app.started`. | Telemetry failure is silent and non-blocking.
  14 | **Background workers** | Start the scheduler (protection eval, polling, maintenance). Workers are supervised (see §9). | A worker crash restarts with backoff; the UI is never blocked.
  15 | **Health check + Workspace restoration** | Run a boot health check. Restore the last workspace layout + state if it validates; else launch the safe default (Mission Control). | Corrupt state → discard and start fresh, never seed the crash forward.

**Bootstrap budget:** cold start must paint the shell < 800ms on desktop Web, < 2s on mobile. Steps 5–12 are async and content-visibility: the shell renders as soon as the theme + shell are ready; workspaces hydrate progressively.

  1.1 IMPLEMENTED BOOT SEQUENCE (2026-08-06, `src/platform/bootstrap.ts`)

The production code boots the platform through one idempotent, non-throwing entry point, `bootPlatform()`:

RootLayout (every route)
  └─ <PlatformBootstrap />          (client, useEffect — never during render)
       └─ bootPlatform()
            ├─ telemetry    → installGlobalErrorHandlers()
            ├─ persistence  → initPersistence() (IndexedDB)
            ├─ vault        → bootVault()          → SecureVault (session mode)
            ├─ broker       → bootBrokerPlatform() → BrokerRuntime + adapters (mock/zerodha/groww)
            └─ protection   → bootProtectionRuntime() → ProtectionRuntime + default rules
                (protection metrics consume the broker runtime ⇒ broker boots first)

**Why the root layout (architectural fix):** boot used to live only in `PlatformBridge` (inside AppShell). Screens OUTSIDE the shell — auth, onboarding, OAuth callback — therefore triggered lazy render-time boots (`getBrokerRuntime()` during a render) that could throw synchronously and crash the page with no error boundary. Mounting the bootstrap at the root layout boots the platform in an effect before ANY screen mounts, so every runtime getter is a pure lookup of an already-booted singleton.

**Degradation contract (never throw):**
• Vault: no `crypto.subtle` (plain-HTTP origin) → `SecureVault` constructs locked; `unlock()` returns `false`. Broker sessions persist via the IndexedDB fallback instead.
• Broker storage: composite (vault + IndexedDB) construction failure → in-memory storage for the session.
• `getBrokerRuntime()` / `getProtectionRuntime()`: last-resort guards never throw — render paths call them synchronously.
• `PlatformBridge` (workspace) still runs `bootPlatform()` as an idempotent safety net, 
… (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/runtime_architecture.md.