Forge
markdowndeeb25a2
1<!-- English translation of adr/0079-ide-display-system-ids-overlay-pipeline.md. Canonical Russian: ../../adr/0079-ide-display-system-ids-overlay-pipeline.md -->
2
3# ADR 0079: IDS (Ide Display System) - IDE overlay pipeline, orthogonal to CDS
4
5**Status:** Accepted
6**Date:** 2026-04-20
7
8## Related ADRs
9
10| ADR | Role |
11|-----|------|
12| [0036](0036-cds-channel-compositor-surface-pipeline.md) | CDS: cabin, channel → CDS → composer → surface |
13| [0066](0066-cockpit-ui-vs-ide-presentation-layer.md) | Cockpit UI vs presentation IDE: chrome and overlays |
14| [0070](0070-command-palette-direct-overlay-surface.md) | Command Palette as direct overlay in active `TopLevel` |
15| [0057](0057-chat-surface-pipeline-adoption.md) | chat: surface snapshot composer; analogy for the “composition” layer |
16| [0013](0013-command-surface-and-discoverability.md) | palette and discoverability |
17| [0115](0115-cds-graph-backed-shared-layer.md) | CDS - common layer of graph-backed devices (implementation in the cockpit, not IDS) |
18
19## Summary
20
21- **IDS** — IDE overlay pipeline (intent → composer → snapshot → surface).
22- Orthogonal to CDS [0036](0036-cds-channel-compositor-surface-pipeline.md); Roslyn CASCOPE013–016.
23
24
25---
26## Context
27
28[0036](0036-cds-channel-compositor-surface-pipeline.md) defines the chain for **cockpit semantics** (PFD/MFD/instruments, `CockpitSurfaceState`, instrument slots). It **shouldn't** grow to "all IDE pixels", otherwise the CDS will become a God layer and mix with [0066](0066-cockpit-ui-vs-ide-presentation-layer.md).
29
30In parallel, the product needs **global IDE overlays**: the command palette (`Ctrl+Q`), later toast, blocking dialogs, and other “on top of the entire workspace” surfaces. They have other invariants:
31
32- binding to **active `TopLevel`** and returning focus ([0070](0070-command-palette-direct-overlay-surface.md));
33- **keyboard-first** and predictable input interception;
34- if possible - **snapshots** for tests and agent observability without reference to a specific `Control` tree.
35
36Without an explicit name and boundaries, this outline spreads across `Views/*` and `*ViewModel`, duplicating the logic of “who is on top” and “who is eating the keys”.
37
38---
39
40## Solution
41
42A separate product circuit **IDS - Ide Display System** is being introduced (namespace and types in the code: `CascadeIDE.IdeDisplay.*`).
43
44### 1. Purpose of IDS
45
46**IDS** describes a **presentation IDE** for **modal and semi-modal overlays** (and eventually other IDE-surfaces that are not cockpit devices): separating **data/intent** and **shot composition** from a specific render (Avalonia `Control`, Skia-host, hybrid).
47
48**CDS** remains canon **cockpit**; **IDS** is the canon of **IDE overlays**. Mixing the semantics of cockpit slots and the IDE overlay stack in one type is an anti-pattern; if necessary, generally only at the level of the words “channel / composer / snapshot”, not at the level of one DTO.
49
50<a id="adr0079-cds-vs-ids"></a>
51
52### Distinguishing between CDS and IDS (one application, two domains)
53
54Both circuits run **within the same process** CascadeIDE (geographically, “it’s all IDE”). The confusion is resolved by asking the **domain of meaning** rather than the exe file:
55
56| | **CDS (and the cabin around it)** | **IDS** |
57| --- | --- | --- |
58| **Question** | Where in the **Cockpit Attention Model** does the content go: PFD/Forward/MFD, Instrument Slot, Secondary Loop Page? | How to show **shell overlay** on top of workspace: palette, modal, toast; focus, z-order, input interception? |
59| **Typical test** | “On which MFD page / in which deck zone / in which device slot?” | “Modally on top of the entire window, like in a regular application, without the semantics of the device?” |
60| **Standard** | [0036](0036-cds-channel-compositor-surface-pipeline.md), [0021](0021-pfd-mfd-cockpit-attention-model.md) | this ADR, [0070](0070-command-palette-direct-overlay-surface.md) |
61| **Device vs Chrome Layers** | Semantics of **devices and zones** ([0036](0036-cds-channel-compositor-surface-pipeline.md)) | **Non-device** presentation shell ([0066](0066-cockpit-ui-vs-ide-presentation-layer.md)) |
62
63**Mnemonic:** you decide “**where in the cockpit**” → **CDS**; “**globally on top of workspace**, not device slot” → **IDS**. The border is anchored by **CASCOPE016**: `Cockpit/` does not import `IdeDisplay`.
64
65### 2. Same chain discipline as 0036 (in meaning, not in type)
66
67For each overlay in IDS, the following chain is followed:
68
691. **Channel / state** - what the user entered, what is filtered, what mode (commands / go-to / melody), without pixel coordinates.
702. **Surface Composer** - pure function (or close): from the channel builds a **snapshot** for rendering and navigation (lines, selection, tooltips, opacity).
713. **Surface** - Avalonia/Skia: focus, hit-test, animations; not the source of overlay semantics.
72General contract for composers: `IIdsSurfaceCompositor<TIntent, TSnapshot>` with the `TSnapshot Compose(TIntent intent)` method (parameter **without** `in` with contravariant `TIntent` is a C# language limitation).
73
74### 3. Single input capture host
75
76**directional** invariant: keyboard/focus hijacking for **IDE overlay stack** converges to **single place** - conditional **`IdsOverlayHost`** / **input router** at the root of the active host, rather than to disparate `PreviewKeyDown` in each overlay without policy.
77
78At the time of ADR adoption, the full host implementation may be **strangler**; the palette may temporarily remain self-contained ([0070](0070-command-palette-direct-overlay-surface.md)), but **new** overlays must not add a third independent "global intercept" without explicit negotiation in that ADR or a separate ADR.
79
80### 4. Slots (`SurfaceSlot`) - optional
81
82**`SurfaceSlot` (or `IdsSurfaceSlot`)** is introduced when there are **multiple** competing IDS surfaces at the same time or an explicit **z-order / mount id** is needed for observability and tests.
83
84For **one** palette as the only top overlay, the slot is not required. For "palette + toast + blocking dialog" - the slot or equivalent **stack** becomes part of the IDS host.
85
86Naming: Defaults to **`Ids*`** in code to avoid confusion with **`CockpitInstrumentDescriptor`** and CDS slots ([0047](0047-cockpit-instrument-descriptor-and-slot-composition.md)).
87
88### 5. Agent observability
89
90IDS snapshots (e.g. composition of palette rows and selected index) can be supplied to the MCP/agent contract **separately** from the `cockpit_surface`, or as a subtle "overlay" field in the overall summary - the JSON field decision does not capture this ADR; only **semantics separation** CDS vs IDS is recorded.
91
92### 6. Roslyn-guardrails (CASCOPE013–016)
93
94On the assembly [`CascadeIDE.ArchitectureAnalyzers`](../../CascadeIDE.ArchitectureAnalyzers/README.md):
95
96- **CASCOPE013** / **CASCOPE014** / **CASCOPE015** - in the `IdeDisplay/` directory, dependencies on `CascadeIDE.Cockpit...`, on Avalonia UI and on `CascadeIDE.Features.UiChrome` are prohibited (including types in class members in `CascadeIDE.IdeDisplay.*`).
97- **CASCOPE016** - `using CascadeIDE.IdeDisplay…` is prohibited in `Cockpit/` (the cockpit does not support IDS).
98
99Full formulations and levels are in the README of the analyzers.
100
101---
102
103## Implementation status (fixed as of ADR date)
104
105- **Done:** contract `IIdsSurfaceCompositor<TIntent, TSnapshot>`; for the palette - `CommandPaletteSurfaceIntent`, `CommandPaletteSurfaceSnapshot`, `CommandPaletteSurfaceCompositor`; updating snapshot from `MainWindowViewModel` when the palette is open; composer tests; Roslyn **CASCOPE013–016** (see §6).
106- **According to plan (strangler):** single `IdsOverlayHost` / input router; optional `IdsSurfaceSlot` for second overlay; if necessary, projection into MCP without mixing with CDS.
107
108---
109
110## Consequences
111
112- New IDE overlays are by default designed via **IDS** (intent → compositor → snapshot → surface), and not “directly in AXAML with half the logic in the VM”.
113- CDS and cockpit instrument registry **are not bloated** by responsibility for global IDE modals.
114- Tests can rely on an **IDS snapshot** where list/selection semantics are important, without a fragile tie to the visual tree.
115
116## Not goals
117
118- Replacement of Avalonia as host for overlays.
119- Renaming or repurposing **CDS** for IDE-chrome.
120- Full JSON specification for the agent in this ADR.
121
122## Rejected alternatives (briefly)
123
124- **Everything in CDS:** rejected - mixes cockpit and IDE-shell, breaks [0066](0066-cockpit-ui-vs-ide-presentation-layer.md).
125- **Separate ADR for each overlay without a common IDS name:** acceptable as a temporary measure, but leads to duplication of the input/stack policy.
View only · write via MCP/CIDE