ADR 0103: Substrate Editor HUD - Semantic Projection, Surface Adapter, DAL/CCU/DataBus Borders¶
Status: Accepted (strangler)
Date: 2026-04-26
Related ADRs¶
| ADR | Role |
|---|---|
| 0006 | Layers, vertical slices and the role of MainWindowViewModel |
| 0009 | Strangler migration and when policy deviations are allowed |
| 0021 | PFD/MFD - Cascade IDE Cockpit Attention Model |
| 0032 | HUD above editor - custom content and grammar (like presentation) |
| 0035 | Built-in browser in MFD, external web LLMs and border with MCP |
| 0036 | Channel → CDS → surface composer → surface (Agent-first display) |
| 0039 | Workspace navigation - multiple views and "current file + related" |
| 0066 | Cockpit UI and presentation IDE layer - separate supports |
| 0067 | Graph-backed surfaces - a general contract for a family of graph screens |
| 0084 | Agent edits in the editor as the only textual source of truth; chat - intent and status; presence layer (GDocs-like, without mandatory CRDT) |
| 0085 | Editor HUD - an inline layer in the editor and the difference from the HUD banner |
| 0094 | Event delivery bus in the UI (similar to AFDX) and System.Threading.Channel<T> |
| 0097 | Cockpit Computing Units (CCU; analogue of LRU Unit) - a layer between transport, meaning and channel |
| 0098 | Semantics is primary; document and repository - projections (Semantic-First) |
| 0099 | IDE DataBus - Typed Events and State Projections |
| 0102 | Data Acquisition Layer - boundary of external interfaces and adapters |
Summary¶
- Editor HUD Substrate:
SemanticProjectionPipeline/EditorHudEngine/IEditorSurfaceAdapter. - DAL / CCU / DataBus; hi-freq bounded circuit separate from CDS.
- Baseline AvaloniaEdit; roadmap UI in
ui-ux/, comparison of hosts indesign/.
Outside ADR¶
| Document | Role |
|---|---|
| design: data-acquisition-layer-boundaries-v1 | blueprint: data-acquisition-layer-boundaries-v1 |
| drawing: comparison of editor surface candidates | drawing: comparison of editor surface candidates |
| drawing: analyzer-rollout-dal-ccu-v1 | drawing: analyzer-rollout-dal-ccu-v1 |
| ux: Forward polishing roadmap | ux: polishing roadmap Forward |
Implementation state (v1 layer is “closed” within strangler): Features/Editor - IEditorSurfaceAdapter / AvaloniaEditSurfaceAdapter, hi-freq EditorStabilizedInputThrottler (one per window) + EditorInputDelta → guard by CurrentFilePath → EditorDocumentHudLayer (per document: EditorHudEngine + EditorHudStabilizedContext) → SemanticProjectionPipeline / EditorSemanticSnapshot from DAL stripes; presentation file-level HUD banner in Application/Presentation/EditorHudBannerTextComposer (0085: not to be confused with EditorInlineHudLayer - reserved inline); VM only orchestrates Roslyn entries and assigns EditorHudBannerText, with DiagnosticsChanged the snapshot is invalidated. Outside v1: transfer of inline render (squiggles, tooltips) from DockDocumentView to the same data layer - editor-hud-inline-migration-inventory-v1, banner/inline policy - editor-hud-banner-inline-policy-v1, visual policy MFD/Forward - editor-forward-ui-cleanup-roadmap-v1. |
1. Context¶
DockDocumentView and associated view models already implement Editor HUD fragments (adorners, LSPs, tooltips) and HUD banner in the spirit of 0085, but the inline experience is not framed as a single named substratum: Quick Info contracts, inlays, ghost text, gutter are scattered. In parallel, explicit layers are attached to the stack - CCU 0097, DAL 0102, IDE DataBus 0099, ingestion 0094 - and direction semantic-first 0098.
Without a single ADR, new HUD work risks:
- dump LSP I/O and file reading in view models or in CCU (conflict with 0102 and analyzer-rollout-dal-ccu-v1);
- publish per-key traffic to DataBus (conflict with 0099: typed domain events, not a high-frequency input stream);
- mix transport (0094) with application events and ad-hoc convolution in the UI.
2. Solution¶
2.1 Substrate name: three matched circuits¶
-
SemanticProjectionPipeline- aggregates normalized entities for the Forward editor zone: diagnostics, hover payload, symbol/link context, agent presence flags, version/relevance metadata. Not owns long-term LSP stdio, raw JSON as “home” and UX graph layout (0067 remains on graph-backed surfaces). -
EditorHudEngine- policy and composition: what to show inline, what to show in HUD banner, what to give to PFD/MFD 0036 / 0039. Consumes stabilized or throttled inputs rather than unlimited "noise per symbol". -
IEditorSurfaceAdapter(or equivalent name) - implementation boundary of the actual text control: the main baseline in this repository remains AvaloniaEdit (see concept-to-implementation-map-v1, LANGUAGE-SERVICES-PLAN.md). The adapter provides the document coordinates, caret, selection and affordances of the host needed by the HUD engine, without spreading editor types across the application.
The terms 0085 do not change: Editor HUD = inline + link to document; HUD banner = file level bar; IDS = global IDE overlays, not Editor HUD 0066.
2.2 Layout: DAL, CCU, DataBus, high-frequency¶
| Question | Layer | Note |
|---|---|---|
| LSP stdio, reading file/settings, starting processes | DAL 0102 in Features/*/DataAcquisition |
Not CCU, not thick MainWindowViewModel 0006 |
Meaningful snapshots Editor HUD / Forward (dedup, priority error > warn, DocumentId + ranges, version) |
CCU 0097 and/or Features/.../Application orchestrators |
candidate names like EditorSemanticSnapshot / ForwardHudSnapshot |
Session and after debounce domain facts (CSharpLspRestarted, ActiveDocumentChanged, scenario like “diagnostics have stabilized”) |
IDE DataBus 0099 | Not per keystroke |
| Current, pointer, scroll in frame/key scale | Separate in-process path: for example System.Threading.Channels capacity 1 + BoundedChannelFullMode.DropOldest (or SPSC latest slot) |
Not the second global “grocery bus”; not replacing 0094 as an end-to-end transport. One consumer thins out and publishes less frequently to the DataBus/CCU inputs if necessary. |
| Ingestion / streams “as a log” in the UI | 0094 | Orthogonal DataBus 0099 |
2.3 Web stack and native Forward editor¶
- WebView2 in the Avalonia/Win32 host is not equal to “drag in Electron” (no Chromium+Node shell as an application). Other statement: built-in renderer, interop, trust.
- Product baseline for the code editor in Forward remains native (AvaloniaEdit). Monaco in WebView2 (and similar) not silent default: comparison / rejected for Forward by product policy; see editor-surface-candidates-comparison-v1.
- Optional web surfaces MFD - by 0035 / 0093; secondary tools, not the “editor = browser” thesis.
2.4 Invariants (do not break)¶
- 0084: when applying agent edits, editor buffer is the source of the applied truth; chat - intent/status; presence channel separately.
- 0085: do not merge inline Editor HUD and HUD banner in one control without explicit names.
- 0098: PFD/MFD semantic paths remain leading; editor tips do not take over all navigation.
- 0097 / 0102: CASCOPE020/021 and rollout analyzer-rollout-dal-ccu-v1 as a “barrier” border.
2.5 Criteria for selecting the editor core (for the appendix drawing / future spike)¶
- Inline hints, ghost text, inlays, gutter; rich hover/Quick Info; performance on large buffers; theme consistency; Pointer/Caret/Document API; integration with semantic-first cockpit 0039.
3. Strangler / migration¶
- Unbind the HUD presentation from the ad-hoc details
DockDocumentView: introduce the three outlines above without the big-bang replacementAvaloniaEdit. - Spike (default):
AvaloniaEditSurfaceAdapter+ bounded high-frequency path + one sliceSemanticProjectionPipeline/EditorHudEngine(for example diagnostics + one hover branch). More details - §5 - spike volume. - Second host adapter (for example web) - only with explicit acceptance of the risk of the web stack in Forward; not required for the first spike.
- After stabilization - if necessary, graph-backed surfaces 0067 for navigation, which does not belong in a text host.
4. Not goals (v1 of this ADR)¶
- Fix the final type names and folder layout (strangler: interfaces next to
Features/Editoror as agreed in the implementation). - Replace CDS 0036 or redefine channel in the cockpit sense.
- External message brokers or bringing all flows into one envelope.
5. Technical spike volume (default)¶
| Item | Volume |
|---|---|
| Adapter | IEditorSurfaceAdapter for AvaloniaEdit; mapping caret/selection/offsets in a document for one document type (eg C#) |
| Hi-freq | Producer(s) on editor events → Channel<EditorInputDelta> (capacity 1, drop-oldest) → one consumer with throttle (e.g. 16–50 ms) before CCU/DataBus touches |
| Pipeline | One vertical slice: LSP/diagnostics from DAL → snapshot in the spirit of CCU or thin orchestrator in Application → EditorHudEngine → adapter |
| Out of Spike | full Monaco/WebView2 adapter; full CASCOPE coverage for all types of HUD |
Success Criteria: no new LSP I/O in Cockpit/ComputingUnits/*; no unlimited per-key Publish on IDataBus; banner vs inline 0085 remains explicit.
6. Related documents¶
- Host comparison (appendix): editor-surface-candidates-comparison-v1
- Roadmap polishing UI (Forward, banner, tooltips, MFD): editor-forward-ui-cleanup-roadmap-v1
7. Consequences¶
- Plus: single point of extension Quick Info, inlays, gutter without confusing DAL, DataBus and raw editor events; agreement with 0097/0102/0099/0094.
- Minus: preliminary development of the design and adapter before each cosmetic edit; discipline so that hi-freq does not go to the DataBus.
- Risk if ignored: fallback to god-
MainWindowViewModel, event spaghetti on DataBus, CASCOPE violations between DAL and CCU.
8. Rejected alternatives (briefly)¶
- The entire carriage/diagnostics flow via DataBus - rejected: against the spirit of 0099 and an avalanche of subscribers.
- CCU reads LSP streams directly - rejected: separation of 0102 and 0097.
- Default web editor in Forward without review - rejected for baseline; optional line only with an explicit product sign-off.