Forge
markdowndeeb25a2
1<!-- English translation of adr/0068-deck-row-payload-and-presentation-projection.md. Canonical Russian: ../../adr/0068-deck-row-payload-and-presentation-projection.md -->
2
3#ADR 0068: Channel line payload and surface projection (layout vs cell content)
4
5**Status:** Accepted
6**Date:** 2026-04-19
7
8## Related ADRs
9
10| ADR/document | Role |
11|----------------|------|
12| [0021](0021-pfd-mfd-cockpit-attention-model.md) | Channel vs slot; glossary presentation |
13| [0021 § glossary](0021-pfd-mfd-cockpit-attention-model.md#glossary-presentation-vs-channel) | Presentation slot vs line projection (**not to be confused**) |
14| [0023](0023-environment-readiness-glance.md) | Readiness vs IDE Health Channel |
15| [0036](0036-cds-channel-compositor-surface-pipeline.md) | Channel → composer → UI |
16| [0063](0063-instrument-deck-named-composition-one-anchor.md) | ContentRepresentation vs instrument deck |
17| [0064](0064-deck-primitives-visual-language-render-layer-and-palette.md) | Lamp primitives, rendering |
18| [0066](0066-cockpit-ui-vs-ide-presentation-layer.md) | Cockpit UI vs Chrome IDE |
19| [`environment-readiness-glance-v1.md`](../../design/environment-readiness-glance-v1.md) | Drawing readiness |
20
21**Not to be confused:** "view projection" here is how the **shot line** becomes a lamp/glyph; this is a level **lower** than the region slot in [0021](0021-pfd-mfd-cockpit-attention-model.md) and is not a replacement for **ContentRepresentation** in [0063](0063-instrument-deck-named-composition-one-anchor.md).
22
23---
24## Context
25
26As the product evolves, the same **logical channel snapshot** (for example, environment readiness) is shown in **several ways**: a compact strip of lamps, a list of cards, a “table” with columns, possible future modes (density, badges only, separate MFD block).
27
28In conversation and in code it is easy to **merge**:
29
301. **Layout** - where the lines are on the screen (grid, stripe, columns of the “Component / Details” header, narrow vs wide mode).
312. **Cell contents** - what exactly the user sees in the row position: lamp primitive, text glyph, link, button, mixed block.
323. **Domain string of the image** - stable id, signal level, title, detail, short signature on the lens, etc.
33
34As long as all the rows are **uniform** (one record type, for example `AnnunciatorLampItem`), merging doesn't hurt. When **different kinds of rows** appear (cell action, rich text, secondary indicator), without named separation, refactoring turns into `DataTemplate` proliferation and duplication of stripe and table.
35
36You need a **stable dictionary of layers**, not necessarily a separate assembly of types for each screen from day one.
37
38---
39
40## Solution
41
42<a id="adr0068-p1"></a>
43
44**1. Three meaningful layers (terms for ADR, review and code):**
45
46| Layer | Question | Note |
47|-----------|--------|-----------|
48| **row payload** | What does **channel** claim about the world in this line? | Domain snapshot: identity, status, texts, future line appearance options. Built in `Services/` / at the data source, **without** Avalonia. |
49| **Slot identity** | Where does the line **stand** in the ordered set and how do tests and presets refer to it? | Stable cell ids, order in deck (e.g. `EnvironmentReadinessInstrumentDeck.OrderedCellIds`), connection with the readiness channel ([0023](0023-environment-readiness-glance.md)). Orthogonal to **how** the cell is drawn. |
50| **presentation projection** | How does a **specific surface** display the **same** payload: lens in a stripe, same lens in the first column of a table, placeholder text glyph, interactive in chrome IDE? | Selecting a primitive and template; may reuse `AnnunciatorLampMetrics` / `LabeledAnnunciatorLampFace` ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)); interactive and “not a device” - according to [0066](0066-cockpit-ui-vs-ide-presentation-layer.md). |
51
52**Invariant:** changing the **layout** (strip ↔ table ↔ cards) **does not** change the **payload** contract; Only the projection and composer/View change. Change of **string semantics** (new type of content) - payload extension and/or string type discriminator, then separate projections by type.
53
54<a id="adr0068-p2"></a>
55**2. Connection with the axes [0063](0063-instrument-deck-named-composition-one-anchor.md):** the **ContentRepresentation** axis (Strip / Page / ...) specifies the **container shape** of the region; **instrument deck** — **what and in what order** in this container. **The view projection** in this ADR is the level **below**: *within* the selected shape, how **each line of the shot** turns into pixels/controls. The three layers above **do not replace** ContentRepresentation and deck; they clarify **where not to mix** channel data and options for drawing a single line.
56
57<a id="adr0068-p3"></a>
58
59**3. Pragmatic v1:** It is acceptable to store a snapshot in **one** row type (`AnnunciatorLampItem` and similar) as long as all rows are **uniform**. This does not negate the distinction between layers in the head and in the review: the strip and the table are **two projections** of the same payload, and not two different “channels”.
60
61<a id="adr0068-p4"></a>
62
63**4. When cell heterogeneity appears:** introduce explicit discrimination in the **payload model** (discriminated union, multiple record types, template key) and compare **projections** by row type; Do not multiply incompatible snapshots of the same channel without reason.
64
65<a id="adr0068-p5"></a>
66
67**5. Duplicating the same projection** (for example, a strip of lamps on top and again lamps in the first column of the table) is a **product** choice: deliberate duplication of glance vs detail or removal of redundancy. Architecturally, this is a decision at the level of **which projections are included in the mode**, and not mixing payload with layout.
68
69---
70
71## Consequences
72
73- New channel screens with deck metaphor **explicitly share** image assembly, stable id/order and projection selection in View/composer.
74- The "lamp in table cell instead of glyph" refactoring touches **projection** and primitive reuse ([0064](0064-deck-primitives-visual-language-render-layer-and-palette.md)), and does not have to change `EnvironmentReadinessSnapshotBuilder` if the semantics of the string did not change.
75- Tests: **payload** contract and id order - separate from visual **projection** tests (if they appear).
76
77## Open
78
79- Names of types/interfaces in the code (`IRowPayload`, `PresentationProjection`, etc.) - enter **as** the second heterogeneous channel or repeating pattern appears; this ADR specifies **terminology**, an optional entity in the repository on the date of acceptance.
View only · write via MCP/CIDE