James Long 3 ay önce
ebeveyn
işleme
1c453bd4e1

+ 161 - 75
dependency-graph.md

@@ -4,43 +4,42 @@ Generated for `createSimulatedRoutes` in `packages/opencode/src/server/routes/in
 
 ## Notation
 
-- `→ X` means "yields `X.Service` from its `Effect.gen` body"
+- `→ X` means "yields `X.Service` from its `Effect.gen` body at layer init (a true `RIn` of `.layer`)"
 - `(lazy)` means "uses `InstanceState.context` or similar at call time, not at layer construction"
 - `(opt)` means "uses `Effect.serviceOption(X)` — not strictly required"
+- `(internal)` means "satisfied internally by the `.layer` itself via `Layer.provide(...)`, NOT a residual requirement"
 
-## Service → Dependencies
+## Service → Dependencies (current, post-rebase)
 
 ```
 ─── External / Platform ─────────────────────────────────────────
 NodePath                   (no app deps)            provides Path.Path
-HttpClient (FetchHttp)     (no app deps)            provides HttpClient.HttpClient
+FetchHttpClient            (no app deps)            provides HttpClient.HttpClient
 HttpServer.layerServices   (no app deps)
 ChildProcessSpawner        (from SimulationSpawner) (no app deps)
 
 ─── Leaf services (no app deps) ─────────────────────────────────
 Global                     (no app deps)
-Env                        (no app deps)
-Bus                        (lazy via InstanceState)
-SyncEvent                  (lazy via InstanceState)
-AccountRepo                (uses Database directly)
-PtyTicket                  (Cache only)
-Truncate                   → AppFileSystem (+ Config opt)
+Env                        (no app deps — uses InstanceState.make, no Service yields)
+Bus                        (no app deps — uses InstanceState.make, no Service yields)
+SyncEvent                  → RuntimeFlags, Bus  (NEW — previously listed as leaf/lazy)
+AccountRepo                (no app deps — pure DB closures)
+PtyTicket                  (no app deps — Cache only)
+Truncate                   → AppFileSystem
 
 ─── Middleware/route layers (no app service deps) ───────────────
 errorLayer
 compressionLayer           → HttpServerRequest (builtin)
 corsVaryFix
 fenceLayer                 → HttpServerRequest (builtin)
-runtime
 simulationShareNextLayer   provides ShareNext (Layer.succeed override)
 
 ─── Simulation overrides ────────────────────────────────────────
-simulationBoundary:
-  SimulationFileSystem     provides AppFileSystem + FileSystem.FileSystem(noop)
-  SimulationSpawner        provides ChildProcessSpawner
-  SimulationNetwork        provides SimulationNetwork.Service + HttpClient
-                           (httpClientLayer → SimulationNetwork)
-
+SimulationFileSystem       provides AppFileSystem (does NOT provide FileSystem.FileSystem;
+                           tier0 also merges FileSystem.layerNoop({}) for that tag)
+SimulationSpawner          provides ChildProcessSpawner (Layer.succeed; no deps)
+SimulationNetwork          provides SimulationNetwork.Service + HttpClient.HttpClient
+                           (httpClientLayer composed inside `layer(options)`)
 SimulationGit              → AppFileSystem               (overrides Git tag)
 SimulationProvider         → Simulation                  (overrides Provider tag)
 Simulation                 → AppFileSystem, SimulationNetwork
@@ -48,31 +47,34 @@ Simulation                 → AppFileSystem, SimulationNetwork
 ─── Core services ───────────────────────────────────────────────
 EffectFlock                → Global, AppFileSystem
 Auth                       → AppFileSystem
+McpAuth                    → AppFileSystem
 Account                    → AccountRepo, HttpClient
 Npm                        → AppFileSystem, Global, FileSystem.FileSystem, EffectFlock
 Config                     → AppFileSystem, Auth, Account, Env, Npm
 Permission                 → Bus
-Plugin                     → Bus, Config
+Plugin                     → Bus, Config, RuntimeFlags                       (NEW: RuntimeFlags)
 Discovery                  → AppFileSystem, Path, HttpClient
-Skill                      → Discovery, Config, Bus, AppFileSystem, Global
+Skill                      → Discovery, Config, Bus, AppFileSystem, Global,
+                              RuntimeFlags                                    (NEW: RuntimeFlags)
 SystemPrompt               → Skill
 
 ─── File / git ──────────────────────────────────────────────────
 Ripgrep                    → AppFileSystem, HttpClient, ChildProcessSpawner
 File                       → AppFileSystem, Ripgrep, Git, Scope
 FileWatcher                → Config, Git
-Format                     → Config, ChildProcessSpawner
-Snapshot                   → AppFileSystem, ChildProcessSpawner, Config
+Format                     → Config, AppProcess, RuntimeFlags                 (CHANGED: was ChildProcessSpawner; now AppProcess + RuntimeFlags)
+Snapshot                   → AppFileSystem, AppProcess, Config                (CHANGED: was ChildProcessSpawner)
 Storage                    → AppFileSystem, Git
 Vcs                        → Git, Bus, Scope
-Worktree                   → Scope, AppFileSystem, Path, ChildProcessSpawner,
-                              Git, Project, InstanceStore
-Project                    → AppFileSystem, Path, ChildProcessSpawner, Bus
+Worktree                   → Scope, AppFileSystem, Path, AppProcess,
+                              Git, Project, InstanceStore                     (CHANGED: AppProcess instead of ChildProcessSpawner)
+Project                    → AppFileSystem, Path, ChildProcessSpawner,
+                              Bus, RuntimeFlags                               (NEW: RuntimeFlags)
 
 ─── Provider / LSP / MCP ────────────────────────────────────────
 ModelsDev                  → AppFileSystem, HttpClient
 ProviderAuth               → Auth, Plugin
-LSP                        → Config
+LSP                        → Config, RuntimeFlags                             (NEW: RuntimeFlags)
 McpAuth                    → AppFileSystem
 MCP                        → ChildProcessSpawner, McpAuth, Bus, Config
 
@@ -80,98 +82,146 @@ MCP                        → ChildProcessSpawner, McpAuth, Bus, Config
 Todo                       → Bus
 Question                   → Bus
 SessionStatus              → Bus
-SessionRunState            → SessionStatus
-Instruction                → Config, AppFileSystem, Global, HttpClient
+SessionRunState            → BackgroundJob, SessionStatus                     (NEW: BackgroundJob)
+Instruction                → Config, AppFileSystem, Global, HttpClient,
+                              RuntimeFlags                                    (NEW: RuntimeFlags)
 
-Session                    → Bus, Storage, SyncEvent
+Session                    → BackgroundJob, Bus, Storage, SyncEvent,
+                              RuntimeFlags                                    (NEW: BackgroundJob, RuntimeFlags)
 SessionSummary             → Session, Snapshot, Storage, Bus
 
 SessionRevert              → Session, Snapshot, Storage, Bus,
                               SessionSummary, SessionRunState, SyncEvent
-LLM                        → Auth, Config, Provider, Plugin, Permission
+LLM                        → Auth, Config, Provider, Plugin, RuntimeFlags     (CHANGED: Permission satisfied internally;
+                              (Permission satisfied internally via .layer)     RuntimeFlags is new)
 
-Agent                      → Config, Auth, Plugin, Skill, Provider
+Agent                      → Config, Auth, Plugin, Skill, Provider,
+                              RuntimeFlags                                    (NEW: RuntimeFlags)
 Command                    → Config, MCP, Skill
 
 SessionProcessor           → Session, Config, Bus, Snapshot, Agent, LLM,
-                              Permission, Plugin, SessionSummary, Scope,
-                              SessionStatus
+                              Permission, Plugin, SessionSummary,
+                              SessionStatus, Image, EventV2Bridge,
+                              RuntimeFlags, Scope                             (NEW: Image, EventV2Bridge, RuntimeFlags)
 SessionCompaction          → Bus, Config, Session, Agent, Plugin,
-                              SessionProcessor, Provider
+                              SessionProcessor, Provider, EventV2Bridge,
+                              RuntimeFlags                                    (NEW: EventV2Bridge, RuntimeFlags)
 SessionPrompt              → Bus, SessionStatus, Session, Agent, Provider,
                               SessionProcessor, SessionCompaction, Plugin,
                               Command, Config, Permission, AppFileSystem,
                               MCP, LSP, ToolRegistry, Truncate,
                               ChildProcessSpawner, Scope, Instruction,
                               SessionRunState, SessionRevert,
-                              SessionSummary, SystemPrompt, LLM
+                              SessionSummary, SystemPrompt, LLM,
+                              Image, Reference, EventV2Bridge,
+                              RuntimeFlags                                    (NEW: Image, Reference, EventV2Bridge, RuntimeFlags)
 
-ToolRegistry               → Config, Plugin, Agent, Skill, Truncate (+ many
-                              tool deps: Question, Todo, Session, Provider,
-                              Git, LSP, Instruction, AppFileSystem, Bus,
-                              HttpClient, ChildProcessSpawner, Ripgrep,
-                              Format, Truncate)
+ToolRegistry               → Config, Plugin, Question, Todo, Agent, Skill,
+                              Session, SessionStatus, BackgroundJob,
+                              Provider, Git, Reference, LSP, Instruction,
+                              AppFileSystem, Bus, HttpClient,
+                              ChildProcessSpawner, Ripgrep, Format,
+                              Truncate, RuntimeFlags                          (NEW: BackgroundJob, Reference, RuntimeFlags)
 
 ─── Share / Workspace ───────────────────────────────────────────
 ShareNext                  (provided by simulationShareNextLayer in sim)
-SessionShare               → Config, Session, ShareNext, Scope, SyncEvent
+SessionShare               → Config, Session, ShareNext, Scope, SyncEvent,
+                              RuntimeFlags                                    (NEW: RuntimeFlags)
 Workspace                  → Auth, Session, SessionPrompt, HttpClient,
-                              SyncEvent, Vcs
-                              (also uses InstanceStore/Bootstrap via
-                               Effect.provide inside runInWorkspace)
+                              SyncEvent, Vcs, AppFileSystem, RuntimeFlags    (NEW: AppFileSystem (explicit), RuntimeFlags)
 
 ─── Misc ────────────────────────────────────────────────────────
-Installation               → HttpClient, ChildProcessSpawner
+Installation               → HttpClient, AppProcess                           (CHANGED: AppProcess instead of ChildProcessSpawner)
 Pty                        → Config, Bus, Plugin
 
 ─── Instance lifecycle ──────────────────────────────────────────
 InstanceBootstrap          → Config, File, FileWatcher, Format, LSP, Plugin,
-                              Project, ShareNext, Snapshot, Vcs
+                              Project, Reference, ShareNext, Snapshot, Vcs   (NEW: Reference)
 InstanceStore              → Project, InstanceBootstrap, Scope
 
 Observability              (no app deps; provides Logger + tracer)
 ```
 
+## NEW dependencies introduced since previous graph
+
+The rebase pulled in several new cross-cutting services that need to be
+satisfied somewhere in tier0/tier1 of the simulated chain. They are NOT yet
+listed in the `Tier*Services` unions or merged into any tier in `server.ts`:
+
+```
+RuntimeFlags.Service        — yielded by ~17 services (Plugin, Skill, Project,
+                              Session, SyncEvent, Format, LSP, Instruction,
+                              Agent, LLM, SessionShare, SessionProcessor,
+                              SessionCompaction, ToolRegistry, SessionPrompt,
+                              Workspace, SessionRunState).
+                              Source: `@/effect/runtime-flags`.
+
+AppProcess.Service          — yielded by Installation, Format, Snapshot,
+                              Worktree (and prod Git, but sim uses SimulationGit).
+                              Source: presumed `@opencode-ai/core/app-process`
+                              or similar — needs `AppProcess.defaultLayer`.
+
+BackgroundJob.Service       — yielded by Session, SessionRunState, ToolRegistry.
+                              Needs `BackgroundJob.defaultLayer`.
+
+Image.Service               — yielded by SessionProcessor, SessionPrompt.
+
+EventV2Bridge.Service       — yielded by SessionProcessor, SessionCompaction,
+                              SessionPrompt. Source: `@/event-v2-bridge` (already
+                              imported in server.ts but never added to a tier).
+
+Reference.Service           — yielded by ToolRegistry, SessionPrompt,
+                              InstanceBootstrap.
+```
+
 ## Dependency Tiers (topological order)
 
 Roughly, build order from leaves to roots:
 
 ```
 Tier 0 (no deps):
-  Global, Env, NodePath, AccountRepo, PtyTicket, Bus (lazy),
-  SyncEvent (lazy), AppFileSystem (sim), ChildProcessSpawner (sim),
-  HttpClient (sim), SimulationNetwork, errorLayer, compressionLayer,
-  corsVaryFix, fenceLayer, runtime, simulationShareNextLayer
+  Global, Env, NodePath, AccountRepo, PtyTicket, Bus, SyncEvent,
+  AppFileSystem (sim), ChildProcessSpawner (sim), HttpClient (sim),
+  SimulationNetwork, FileSystem.layerNoop, simulationShareNextLayer
+  + (NEW REQUIRED) RuntimeFlags, AppProcess, BackgroundJob, Image,
+                   EventV2Bridge, Reference
+  (SyncEvent now depends on RuntimeFlags + Bus, so it's actually tier 1.)
 
 Tier 1:
   Auth, Truncate, EffectFlock, Permission, Todo, Question,
-  SessionStatus, McpAuth, Discovery, SimulationGit, Simulation,
-  Ripgrep, Storage, Vcs
+  SessionStatus, McpAuth, Discovery, SimulationGit, Ripgrep, Account,
+  SyncEvent (needs RuntimeFlags + Bus)
 
 Tier 2:
-  Account, Npm, LSP, Skill, SessionRunState, ModelsDev, File,
-  Project, Worktree (needs InstanceStore — cycle hint), MCP,
-  Installation, Pty, SystemPrompt
+  Npm, ModelsDev, Project, Installation, Storage, Vcs, SessionRunState
 
 Tier 3:
-  Config, FileWatcher, Format, Snapshot, ProviderAuth, Session,
-  SessionShare, SessionSummary
+  Config, File, Simulation, Session
 
 Tier 4:
-  Plugin, Agent, Command, LLM, SessionRevert,
+  Plugin, FileWatcher, Format, Snapshot, LSP, MCP, Skill, Instruction,
   SimulationProvider (= Provider)
 
 Tier 5:
-  SessionProcessor, SessionCompaction, Workspace
+  Pty, ProviderAuth, SessionSummary, Agent, Command, LLM, SystemPrompt
 
 Tier 6:
-  SessionPrompt, ToolRegistry
+  SessionRevert, SessionProcessor, SessionShare
 
 Tier 7:
-  InstanceBootstrap (needs many of the above)
+  SessionCompaction, ToolRegistry
 
 Tier 8:
-  InstanceStore (needs InstanceBootstrap + Project)
+  SessionPrompt
+
+Tier 9:
+  Workspace, InstanceBootstrap
+
+Tier 10:
+  InstanceStore
+
+Tier 11:
+  Worktree
 ```
 
 ## Potential cycles / hazards
@@ -180,8 +230,7 @@ Tier 8:
 Worktree → InstanceStore → InstanceBootstrap → Project → (back to Worktree?)
   - InstanceBootstrap requires Project (yes)
   - Project does NOT require Worktree directly
-  - Worktree requires InstanceStore — only used inside its methods,
-    but yielded at layer init, so it's a true requirement
+  - Worktree requires InstanceStore at layer init
   → Worktree must be built AFTER InstanceStore.
 
 SimulationProvider provides Provider tag, depends on Simulation.
@@ -189,26 +238,63 @@ SimulationProvider provides Provider tag, depends on Simulation.
   SimulationProvider in this layer chain.
 
 SimulationGit provides Git tag, used by File, FileWatcher,
-  Storage, Vcs, Worktree, ToolRegistry tools, Project (no — Project
-  uses ChildProcessSpawner instead).
+  Storage, Vcs, Worktree, ToolRegistry tools.
 
 LLM.layer pipes Layer.provide(Permission.defaultLayer) internally.
-  That means LLM brings its own Permission — beware double-providing
-  Permission (sim chain also provides Permission.layer separately).
+  So LLM's residual requirements no longer include Permission, BUT the
+  sim chain still provides Permission.layer separately (correct — used by
+  SessionProcessor, SessionPrompt directly).
 ```
 
-## Why the simulated chain fails with stepwise `provideMerge`
-
-`Layer.provideMerge(self, that)` builds `that` independently and uses it to satisfy `self`'s reqs. `that` cannot see services already provided inside `self`. So when you write:
+## Why the simulated chain fails today
 
-```ts
-withCoreAppServices                       // contains Config.layer, Plugin.layer, ...
-  .pipe(Layer.provideMerge(Npm.layer))    // Npm needs EffectFlock
+The current `server.ts` `Tier0Services` union lists:
+```
+AppFileSystem, FileSystem.FileSystem, ChildProcessSpawner, HttpClient,
+SimulationNetwork, Path, Global, Env, Bus, AccountRepo, ShareNext,
+SyncEvent, PtyTicket
 ```
 
-`Npm.layer` is built in isolation and its `EffectFlock` requirement must be filled from OUTSIDE the entire pipe — not from inside `withCoreAppServices`. Same for every other "consumer added later" combination.
-
-Production avoids this because every service is added via `Layer.provide([... defaultLayer, defaultLayer, ...])` — flat mergeAll of self-contained layers, all visible to each other.
+But the actual `Layer.mergeAll(...)` body at tier0 has residual requirements
+beyond that union. The TS error says
+`Layer<..., never, Service | Service>` — those two unresolved `Service`s
+are members of the NEW dependencies table above.
+
+The most likely culprits, in order of leakage:
+
+1. **`SyncEvent.layer`** now yields `RuntimeFlags` and `Bus`. `Bus` is in tier0
+   already, but `RuntimeFlags` is not provided anywhere in `createSimulatedRoutes`.
+   So `SyncEvent` leaks `RuntimeFlags` into tier0's `RIn`.
+
+2. Downstream tiers also leak `RuntimeFlags`, `AppProcess`, `BackgroundJob`,
+   `Image`, `EventV2Bridge`, `Reference` — these cascade through every higher
+   tier as `Service | Service | ...` in the error type.
+
+## Fix strategy
+
+The minimal change to make tier0 type-check:
+
+1. Add `RuntimeFlags.defaultLayer` to tier0 and `RuntimeFlags.Service` to
+   `Tier0Services`. This satisfies `SyncEvent`'s new dep and unblocks every
+   service that yields `RuntimeFlags`.
+2. Add `AppProcess.defaultLayer` (or a simulated equivalent) to tier0 and
+   `AppProcess.Service` to `Tier0Services`. Needed by `Installation`, `Format`,
+   `Snapshot`, `Worktree`.
+3. Add `BackgroundJob.defaultLayer` to tier0 and `BackgroundJob.Service` to
+   `Tier0Services`. Needed by `Session`, `SessionRunState`, `ToolRegistry`.
+4. Add `Image.defaultLayer` to tier0 (or wherever it fits) and `Image.Service`
+   to `Tier0Services`. Needed by `SessionProcessor`, `SessionPrompt`.
+5. Add `EventV2Bridge.defaultLayer` to tier0 and `EventV2Bridge.Service` to
+   `Tier0Services`. (Note: `EventV2Bridge` is already imported in `server.ts`
+   for the production routes but is not in any simulated tier.)
+6. Add `Reference.defaultLayer` to a tier that satisfies its deps (it's a leaf
+   wrt the listed graph above) and `Reference.Service` to the corresponding
+   tier union. Needed by `ToolRegistry`, `SessionPrompt`, `InstanceBootstrap`.
+
+Production routes (`createProductionRoutes`) already include
+`RuntimeFlags.defaultLayer` and `EventV2Bridge.defaultLayer` in the flat
+`Layer.provide([...])` list — they were simply never carried over to the
+simulated chain after the rebase.
 
 ## See also
 

+ 4 - 0
packages/opencode/src/cli/cmd/tui/simulate.ts

@@ -165,6 +165,10 @@ export const SimulateCommand = cmd({
           [OPENCODE_RUN_ID]: ensureRunID(),
           PWD: simulatedDirectory,
           [simulatedCwdEnv]: simulatedDirectory,
+          // Simulated filesystem lives in InMemoryFs — SQLite needs to be in-memory
+          // too, since real fs writes to `/opencode/.local/share/opencode/...` will
+          // fail (the directory only exists in the sim FS).
+          OPENCODE_DB: ":memory:",
         }),
       })
       worker.onerror = (e) => {

+ 43 - 14
packages/opencode/src/server/routes/instance/httpapi/server.ts

@@ -1,6 +1,11 @@
 import { Config as EffectConfig, Context, Effect, Layer, FileSystem, Path } from "effect"
 import { ChildProcessSpawner } from "effect/unstable/process"
 import { NodePath } from "@effect/platform-node"
+import { AppProcess } from "@opencode-ai/core/process"
+import { EventV2 } from "@opencode-ai/core/event"
+import { BackgroundJob } from "@/background/job"
+import { Image } from "@/image/image"
+import { Reference } from "@/reference/reference"
 import { Git } from "@/git"
 import { HttpApiBuilder, OpenApi } from "effect/unstable/httpapi"
 import {
@@ -318,8 +323,10 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | Bus.Service
     | AccountRepo.Service
     | ShareNext.Service
-    | SyncEvent.Service
     | PtyTicket.Service
+    | RuntimeFlags.Service
+    | BackgroundJob.Service
+    | EventV2.Service
 
   const tier0: Layer.Layer<Tier0Services, never, never> = Layer.mergeAll(
     SimulationFileSystem.layer({
@@ -341,8 +348,10 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     Bus.layer,
     AccountRepo.layer,
     simulationShareNextLayer,
-    SyncEvent.layer,
     PtyTicket.layer,
+    RuntimeFlags.defaultLayer,
+    BackgroundJob.layer,
+    EventV2.layer,
   )
 
   // ─── Tier 1: services depending only on tier 0 ──────────────────────────
@@ -358,6 +367,8 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
   // Discovery → AppFileSystem, Path, HttpClient
   // Ripgrep → AppFileSystem, HttpClient, ChildProcessSpawner
   // Account → AccountRepo, HttpClient
+  // SyncEvent → RuntimeFlags, Bus
+  // AppProcess → ChildProcessSpawner
   const tier1: Layer.Layer<
     | Tier0Services
     | Git.Service
@@ -371,7 +382,9 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | SessionStatus.Service
     | Discovery.Service
     | Ripgrep.Service
-    | Account.Service,
+    | Account.Service
+    | SyncEvent.Service
+    | AppProcess.Service,
     never,
     never
   > = Layer.mergeAll(
@@ -387,6 +400,8 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     Discovery.layer,
     Ripgrep.layer,
     Account.layer,
+    SyncEvent.layer,
+    AppProcess.layer,
   ).pipe(Layer.provideMerge(tier0))
 
   type Tier1Services =
@@ -403,15 +418,18 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | Discovery.Service
     | Ripgrep.Service
     | Account.Service
+    | SyncEvent.Service
+    | AppProcess.Service
 
   // ─── Tier 2: services depending only on tier 0 + tier 1 ─────────────────
   // Npm → AppFileSystem, Global, FileSystem, EffectFlock
   // ModelsDev → AppFileSystem, HttpClient
-  // Project → AppFileSystem, Path, ChildProcessSpawner, Bus
-  // Installation → HttpClient, ChildProcessSpawner
+  // Project → AppFileSystem, Path, ChildProcessSpawner, Bus, RuntimeFlags
+  // Installation → HttpClient, AppProcess
   // Storage → AppFileSystem, Git
   // Vcs → Git, Bus
-  // SessionRunState → SessionStatus
+  // SessionRunState → BackgroundJob, SessionStatus
+  // EventV2Bridge → EventV2, Bus, SyncEvent
   const tier2: Layer.Layer<
     | Tier1Services
     | Npm.Service
@@ -420,7 +438,8 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | Installation.Service
     | Storage.Service
     | Vcs.Service
-    | SessionRunState.Service,
+    | SessionRunState.Service
+    | EventV2Bridge.Service,
     never,
     never
   > = Layer.mergeAll(
@@ -431,6 +450,7 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     Storage.layer,
     Vcs.layer,
     SessionRunState.layer,
+    EventV2Bridge.layer,
   ).pipe(Layer.provideMerge(tier1))
 
   type Tier2Services =
@@ -442,6 +462,7 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | Storage.Service
     | Vcs.Service
     | SessionRunState.Service
+    | EventV2Bridge.Service
 
   // ─── Tier 3: services depending only on tier 0-2 ────────────────────────
   // Config → AppFileSystem, Auth, Account, Env, Npm
@@ -457,15 +478,17 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
   type Tier3Services = Tier2Services | Config.Service | File.Service | Simulation.Service | Session.Service
 
   // ─── Tier 4: services depending on tier 0-3 (mostly Config) ─────────────
-  // Plugin → Bus, Config
+  // Plugin → Bus, Config, RuntimeFlags
   // FileWatcher → Config, Git
-  // Format → Config, ChildProcessSpawner
-  // Snapshot → AppFileSystem, ChildProcessSpawner, Config
-  // LSP → Config
+  // Format → Config, AppProcess, RuntimeFlags
+  // Snapshot → AppFileSystem, AppProcess, Config
+  // LSP → Config, RuntimeFlags
   // MCP → ChildProcessSpawner, McpAuth, Bus, Config
-  // Skill → Discovery, Config, Bus, AppFileSystem, Global
-  // Instruction → Config, AppFileSystem, Global, HttpClient
+  // Skill → Discovery, Config, Bus, AppFileSystem, Global, RuntimeFlags
+  // Instruction → Config, AppFileSystem, Global, HttpClient, RuntimeFlags
   // SimulationProvider → Simulation (provides Provider tag)
+  // Image → Config
+  // Reference → Config, AppFileSystem, Git, RuntimeFlags
   const tier4: Layer.Layer<
     | Tier3Services
     | Plugin.Service
@@ -476,7 +499,9 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | MCP.Service
     | Skill.Service
     | Instruction.Service
-    | Provider.Service,
+    | Provider.Service
+    | Image.Service
+    | Reference.Service,
     never,
     never
   > = Layer.mergeAll(
@@ -489,6 +514,8 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     Skill.layer,
     Instruction.layer,
     SimulationProvider.layer,
+    Image.layer,
+    Reference.layer,
   ).pipe(Layer.provideMerge(tier3))
 
   type Tier4Services =
@@ -502,6 +529,8 @@ export function createSimulatedRoutes(corsOptions?: CorsOptions): ReturnType<typ
     | Skill.Service
     | Instruction.Service
     | Provider.Service
+    | Image.Service
+    | Reference.Service
 
   // ─── Tier 5: services depending on tier 0-4 ─────────────────────────────
   // Pty → Config, Bus, Plugin