Forge
markdowndeeb25a2
1<!-- English translation of 0060-keyboard-chord-stack-fms-tactical-strategic.md. Canonical Russian: ../../adr/0060-keyboard-chord-stack-fms-tactical-strategic.md -->
2
3# ADR 0060: Chord layer (FMS-style), S/T, and overlay — keyboard-first extension (ADR 0013)
4
5**Status:** Accepted (partial: Intent Melody catalog + chord/palette v1; full FMS T/S overlay — per ADR)
6**Date:** 2026-04-19
7
8## Related ADRs
9
10| ADR | Role |
11|-----|------|
12| [0013](0013-command-surface-and-discoverability.md) | palette, toolbar, discoverability — **this ADR does not replace** the palette |
13| [0070](0070-command-palette-direct-overlay-surface.md) | palette as overlay surface |
14| [0008](0008-mcp-contracts-and-testable-infrastructure.md) | MCP and commands |
15| [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md) | `IdeCommands`, `hotkeys.toml`, registry |
16| [0017](0017-multi-window-workspace-and-agent-surfaces.md) | multi-window, focus |
17| [0021](0021-pfd-mfd-cockpit-attention-model.md) | PFD / MFD |
18| [0032](0032-hud-banner-configuration-and-grammar.md) | HUD / mode captions — optional |
19| [0055](0055-skia-instrument-composition-pipeline.md) | Skia — overlay |
20| [0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md) | tactical / EFB on MFD, Manager |
21| [0072](0072-chat-topic-cards-intent-melody-keyboard-contract.md) | chat topic navigation — **chat-domain refinement**, not a replacement for this ADR |
22| [0081](0081-parametric-intent-melodies-editor-line-ranges.md) | parametric melody `:start:end` for editor; builds on Command Melody from §11 |
23
24### Outside ADR
25
26| Document | Role |
27|----------|------|
28| [north-star — keyboard-first](../../design/north-star-cursor-mcp-cascade-workbench-v1.md) | north-star — keyboard-first |
29| [chord-notation-cascadeide.md](../chord-notation-cascadeide.md) | chord notation cascadeide |
30
31**Partial refinement (chat-domain):** navigation across **chat topics** (topic cards, drill-in/back, minimal intent command set, parity across palette / Melody / Chords) is fixed in [0072](0072-chat-topic-cards-intent-melody-keyboard-contract.md). This ADR (**0060**) remains the canon for the general **Melody**, **CascadeChord**, and **Command Melody (`c:`)** model; **0072** does **not** cancel §1–§11 wholesale and does **not** reassign S/T/M/E for the cockpit outside chat-topic navigation.
32
33---
34## Context
35
36[0013](0013-command-surface-and-discoverability.md) establishes the **command palette** as the anchor (string search, full catalog) and **keyboard-first** as a product direction. For the cockpit that is not enough: an FMS pilot first picks a **section**, then a **parameter** — two meaningful steps without typing. CascadeIDE also needs a **thinking scale** (tactical vs strategic, see [0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md)) that **does not reduce** to “open another window”.
37
38A **second keyboard entry** is needed: a **chord layer** (prefix → second key), aligned with `IdeCommands` ([0030](0030-command-ids-hotkeys-and-ui-registry-layers.md)) and not duplicating the palette.
39
40## Summary
41
42- Chord layer (**Ctrl+K**), FMS-style tactical/strategic, overlay on top of [0013](0013-command-surface-and-discoverability.md).
43- Extends discoverability without replacing the palette and IdeCommands.
44- Tied to intent melody and chat-domain ([0072](0072-chat-topic-cards-intent-melody-keyboard-contract.md)).
45
46---
47
48## Decision
49
50<a id="adr0060-p1"></a>
51
52### 1. Two entries, one command model
53
54| Entry | Purpose | Anchor in [0013](0013-command-surface-and-discoverability.md) |
55|------|------------|------------------------------------------------------------------|
56| **Command palette** (default hotkey **Ctrl+Q** in shipped `hotkeys.toml`) | Full catalog, search by name, recents | Decision §2 item 2 |
57| **Chord root** — working name **`CascadeChord`** (default hotkey **Ctrl+K** in the product; override — user `hotkeys.toml`) | Short FMS flow: prefix → second key → execute **one** command from a pre-limited set of “cockpit” actions | keyboard-first extension **without** canceling the palette |
58| **Same `command_id` as text in the palette** — prefix **`c:`** (**Command Melody**, [§11](#adr0060-p11)) | Compact mnemonic (`c: gs`, …) without changing window; fuzzy on title/id as before | Not a third “physical” entry: still **Ctrl+Q**, extended by query string |
59
60**Rule:** **Ctrl+K** does not replace **Ctrl+Q**; the user chooses “search by name”, “go by known chord letter”, or enter **melody** after opening the palette. Conflicts with editor/OS hotkeys — detect on load and reflect in UX (see open questions).
61
62<a id="adr0060-p2"></a>
63
64### 2. First level after `CascadeChord`: **S / T** (scale canon)
65
66The **canonical** first choice after the prefix is **thinking scale** and depth of coupling with Roslyn MCP ([0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md)), not “which monitor”:
67
68| Key (after prefix) | Name | Meaning |
69|---------------------------|-----|--------|
70| **T** | **Tactical** | Local semantics around the cursor; tactical PFD / Forward contour; narrow contract |
71| **S** | **Strategic** | Global / layered graph; **MFD / EFB** contour; `Profile.GlobalMap` in the sense of [0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md) |
72
73**Plus:** one axis reflects CascadeIDE’s essence — **we change depth of immersion**, not only “view”.
74
75Executing a specific command (e.g. `cascade.focus_tactical_map`, `cascade.focus_strategic_efb`) — via **`IdeCommands`** and MCP parity ([0008](0008-mcp-contracts-and-testable-infrastructure.md), [0002](0002-debug-human-agent-parity.md)).
76
77<a id="adr0060-p3"></a>
78
79### 3. Alternative / second level: **M / E** (displays)
80
81Splitting **MFD** vs **EFB** ([0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md): EFB = **MFD**, not PFD) may move to a **second chord step** or a **parallel** letter set when the product needs explicit **display** binding:
82
83| Key | Name | Meaning (idea) |
84|---------|-----|----------------|
85| **M** | MFD focus | Instruments, logs, terminal — “on the ground” / diagnostics |
86| **E** | EFB / strategic | Map, architecture on MFD |
87
88**Mixing rule:** do not put S/T and M/E on **one level** without a documented scheme (e.g. prefix → **S or T** → optional second chord **M or E** to refine surface). Minimal v0 — **S/T only** after prefix.
89
90<a id="adr0060-p4"></a>
91
92### 4. “Vector” variant (combined)
93
94Optional (separate iteration or hotkey preset):
95
96- **Digits 1 / 2 / 3** after prefix — quick **focus on monitor / TopLevel** ([0017](0017-multi-window-workspace-and-agent-surfaces.md)) in user configuration order.
97- **F** — toggle **Flight** / exit “flight mode” (tie to [0010](0010-ui-modes-toml-configuration.md) — do not mix with S/T without explicit UI label).
98
99This is **not** mandatory for v0; recorded so independent chord roots are not spawned without a registry.
100
101<a id="adr0060-p5"></a>
102
103### 5. Chord state machine
104
105- After **CascadeChord** the IDE enters **“waiting for second key”** for a short **timeout** (default and override — optionally in `settings.toml`, see §7).
106- **Esc** — exit without action; focus returns per [0013](0013-command-surface-and-discoverability.md) / [0017](0017-multi-window-workspace-and-agent-surfaces.md).
107- **Editor:** do not steal text input while chord-wait is active unless focus policy explicitly gives events to the application window (implementation details in code; tests for “do not eat a letter in the line”).
108
109<a id="adr0060-p6"></a>
110
111### 6. Overlay hints (discoverability)
112
113After pressing the prefix, show **semi-transparent hints** (letters/labels) over **zones** or in a **screen corner** for a short time — so the user does not guess “what next”. Implementation:
114
115- preferably **Skia** overlay on the host ([0055](0055-skia-instrument-composition-pipeline.md): overlay must not become a separate “instrument” duplicating the pipeline);
116- **Reduced motion** / disable hints — settings flag;
117- do not obscure critical PFD indicators without density policy.
118
119<a id="adr0060-p7"></a>
120
121### 7. Mode indication on PFD (situational awareness)
122
123A small line such as **`MODE: TACTICAL`** / **`STRATEGIC`** / sub-modes **ECHELON** / **COMBAT** ([0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md)) in a PFD corner or HUD layer ([0032](0032-hud-banner-configuration-and-grammar.md)) — **recommended** so visuals match what the profile Manager does. Single source of truth (VM / CDS / mode service), not duplicated out of sync with the chord.
124
125<a id="adr0060-p8"></a>
126
127### 8. Configuration: where things live
128
129| What | Where |
130|-----|-----|
131| Binding **prefix** and chords to **`command_id`** | **`Hotkeys/hotkeys.toml`** (ship) + `%LocalAppData%\CascadeIDE\hotkeys.toml` ([0013](0013-command-surface-and-discoverability.md), [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md)) |
132| Execution implementation | **`IdeCommands`** + input handler (chord state machine) in C# |
133| Optional: `chord_timeout_ms`, `chord_overlay_enabled` | **`settings.toml`** or UI-adjacent section — **do not** duplicate the full key map in `settings.toml` ([0013](0013-command-surface-and-discoverability.md) — rejected variant: store all hotkeys only in settings) |
134
135**Work order (recommendation):** first **command ids and chord machine** in C#; then lines in **`hotkeys.toml`**; then overlay and MODE line.
136
137<a id="adr0060-p9"></a>
138
139### 9. Command migration logic and step evolution (implementation)
140
141**What we do not move to chord without separate discussion**
142
143- **Editor / OS standard** gestures users expect “everywhere”: save (**Ctrl+S**), undo/redo (**Ctrl+Z** / **Ctrl+Y**), cut/copy/paste, often **Ctrl+W** / close tab, **Ctrl+F** in editor. Keep on direct gestures or editor settings; do not force into **CascadeChord** for uniformity alone.
144- **Already fixed global IDE hotkeys** from `hotkeys.toml` (**Ctrl+Q** palette, **F5** debug, …) are not broken: chord is a **second** entry, not a replacement.
145
146**Target layered scheme (after v0)**
147
1481. **CascadeChord** (prefix, e.g. **Ctrl+K**).
1492. **First letter step — S / T scale** (§2): tactical vs strategic; tie to Roslyn MCP profile / attention contour ([0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md)).
1503. **Second step — subsystem** (letter “pages”): e.g. **M** = intent map (**P** / **F** / **D**), **B** = build/tests, **G** = Git, etc. So we do not mix a dozen unrelated letters and thinking scale on one level.
151
152**Current multi-step scheme (code)**
153
154- **Prefix** → **M** → **M / P / F**: cockpit zones — **MFD** (expand region), **PFD** (expand region), **Forward** (focus editor). “Zone settings/focus” metaphor without a second **Ctrl+M** root: second letter is **M** right after prefix (FMS page), third — zone choice.
155- **Prefix** → **S** → **P / F / D**: intent map — view / level / detail (as in [0055](0055-skia-instrument-composition-pipeline.md)).
156- Overlay shows allowed keys **for the current step**; timeout and **Esc** reset the machine (§5).
157
158**Discoverability rule**
159
160- Any command available only via chord must have the **same `command_id`** in palette and MCP ([0008](0008-mcp-contracts-and-testable-infrastructure.md)), so “forgot the letter” ≠ “lost the action”.
161
162<a id="adr0060-p10"></a>
163
164### 10. UX philosophy: invisible instrument, muscle memory, rehearsal vs performance
165
166> “A good actor is one you do not see. Because only the character remains.”
167
168**IDE as invisible actor.** The product must not “perform itself”: endlessly showcasing tools, hotkeys, menus, panels, overlays. The interface should **vanish** where possible and leave **code, task, developer thought** at the center. CascadeIDE cockpit is the **invisible actor** metaphor: PFD, MFD, Forward, intent map are not “IDE face for IDE’s sake” but **pilot instruments**, extensions of thought. In work the pilot does not think “I press a button on MFD” — they hold **course** while hands find the gesture.
169
170**Chords and muscle memory.** After enough practice the user stops reciting key sequences and operates **semantic layers** (e.g. Modification → Navigation → View → Strategic as intent mnemonic, not abstract key list). Fingers lock the pattern; mind stays on the task. Concrete **step grammar** (one root prefix vs extra modifiers, letter order, S/T axis vs intent-first G/B/D/… families) evolves with registry and hotkeys; the philosophical layer is **not tied** to one letter table but requires any grammar version to stay **readable** and **teachable**.
171
172**Metaphors (one direction — background and shedding the “extra”):**
173
174| Metaphor | For CascadeIDE |
175|----------|----------------------------|
176| Pärt tintinnabuli | Two voices: contextual background (prefixes/input layers) + “melody” of following letters — simple, strict, meditative structure |
177| Satie furniture music | IDE as **background**: does not demand constant attention, holds work atmosphere |
178| Good actor | IDE **vanishes**; code and task remain |
179
180**Consequences for ADR and notation**
181
182- **Documentation notation** must be **transparent**: the reader should not spend mental energy decoding. Notation like `<C-k> …` in [chord-notation-cascadeide.md](../chord-notation-cascadeide.md) is supplemented with **mnemonic gloss** where it speeds understanding (what intent, not only which VK).
183- **Overlay (§6)** — **prompter**, not director: appears when the next step must be hinted and **does not block the scene** (code, critical indicators). See density policy and Reduced motion in §6.
184- **Palette (Ctrl+Q) vs chord (CascadeChord)** — **rehearsal vs performance**: palette — full catalog and learning; chord — fast entry for mastered actions ([0013](0013-command-surface-and-discoverability.md), §1 of this ADR). Both use one **`command_id`** model.
185
186**Tie to intent-first and surface routing.** The idea “chord fixes **intent** (Git, Build, Debug…), **where** to show result is surface routing” **aligns** with this section: cockpit surfaces remain display context, not mandatory first level of mental formula for every gesture. v1 grammar detail (command families, S/T axes) — separate ADR/registry iterations; §10 goal — **UX principles**, not a concrete letter table.
187
188**See also:** product narrative “invisible instrument” vs cloud-assistant risk class — [cascadeide-philosophy-v1.md](../../design/cascadeide-philosophy-v1.md), [ADR 0071](0071-ai-assistance-sovereignty-locality-invisibility.md).
189
190<a id="adr0060-p11"></a>
191
192### 11. Command Melody (`c:`) — palette, mnemonic alias, and bridge to chord
193
194**Language spec (lexicon, EBNF, motivation, open questions):** [intent-melody-language-v1.md](../intent-melody-language-v1.md) (**Intent-based Melody Language**, IML v1).
195
196**Origin:** melody (`c:`) spec was shaped in the **Comet** line (external dialogue); here — product norm. Pointer in personal KB canon (agent-notes) — `knowledge/personal/assistantLines/comet/comet-command-melody-cascade-palette-2026-04-19.md`.
197
198**Purpose.** Prefix **`c:`** introduces **melody** mode in the **command palette** ([0013](0013-command-surface-and-discoverability.md), [0070](0070-command-palette-direct-overlay-surface.md)): short **mnemonic aliases** in a developer-first vocabulary. The user can type compact forms like `c: gs`, `c: br`, `c: da` and get the command without relying only on fuzzy search on long titles. **Frequency → length** heuristic and deferred disambiguation — [intent-melody-language-v1.md](../intent-melody-language-v1.md) §3.5.
199
200**Goal.** The mode is **not** to replace ordinary search but **fast semantic entry**, shared across:
201
202- palette (query string);
203- chord layer (**CascadeChord**);
204- canonical **`command_id`** in registry ([0030](0030-command-ids-hotkeys-and-ui-registry-layers.md));
205- MCP / agent call ([0008](0008-mcp-contracts-and-testable-infrastructure.md)) — same identifier.
206
207**Three representations of one command**
208
209| Layer | Example |
210|------|--------|
211| Human title | `Git: Status` |
212| Melody alias | `c: gs` |
213| Canonical id | `git.status` *(or equivalent in `IdeCommands`; exact string — registry [0030](0030-command-ids-hotkeys-and-ui-registry-layers.md))* |
214
215The palette **must** find and show the command by **any** of these (title, alias, id).
216
217**Syntax**
218
219- Common namespace prefix: **`c:`** — enter melody.
220- After `c:` one or more mnemonic tokens; **v1 base form** — **two letters**: first = **family**, second = **action**.
221- Examples (logical names; actual `command_id` — per registry):
222
223| Input | Purpose (meaning) |
224|------|---------------------|
225| `c: gs` | Git → Status |
226| `c: gc` | Git → Commit |
227| `c: gp` | Git → Push |
228| `c: gm` | Git → Merge |
229| `c: gsu` | Git → Submodules |
230| `c: br` | Build → Run / Rebuild (per registry terminology) |
231| `c: bt` | Build → Test |
232| `c: da` | Debug → Attach |
233| `c: dc` | Debug → Continue |
234| `c: dl` | Debug → Launch (`debug_launch`) |
235| `c: cps` | Chat → **P**age → **S**how (`show_chat_page`; DOI) |
236| `c: cs` | Chat → **S**end — send input draft as user (`send_chat` without `message`) |
237| `c: cex` | Chat → **ex**port (readable Markdown) |
238| `c: ctf` | Chat → **T**hread → **F**ork (three-letter DOI: domain → object → intent; `fork_chat_thread`) |
239| `c: ers` | Environment → **R**eadiness → **S**how (`show_environment_readiness_page`) |
240| `c: ts` | **T**erminal → **S**how (`show_terminal_panel`) |
241
242Melody registry in repo: **`IntentMelody/intent-melody-aliases.toml`** (see [intent-melody-language-v1.md](../intent-melody-language-v1.md)).
243
244**v1 families (narrow start, recognizable domains)**
245
246| Letter | Family |
247|-------|--------|
248| **g** | Git |
249| **b** | Build |
250| **d** | Debug |
251| **r** | Run |
252| **e** | Editor |
253| **m** | Map (intent map / map navigation) |
254| **c** | Chat |
255| **t** | Terminal (panel / terminal page in secondary contour) |
256
257“Show page” transitions in the secondary contour are encoded **domain first** (intent): e.g. Chat → Page → Show = `c: cps`, not synthetic prefix **P** = Pages (**`pcs`**, **`pes`**, …) that puts IDE topology above command meaning. For **environment readiness** DOI fixes a chain like **Environment → Readiness → Show** (`ers` when alias appears in registry), not “Pages → Environment”.
258
259This aligns with **intent-first**: the developer thinks **task domain**, not IDE topology ([§10](#adr0060-p10)).
260
261**Alias selection principles**
262
2631. Alias **recognizable** to developers without separate training.
2642. Alias **shorter** than human title but not shell-golf “cipher”.
2653. Alias **stable** even if UI wording shifts slightly.
2664. Alias expresses **intent**, not **surface placement** (bad base example: tie to “primary deck” instead of command meaning).
2675. **Frequency → length (heuristic):** the more typical the command for a workday, the shorter the reasonable alias in registry (Huffman-prefix analogy; [intent-melody-language-v1.md](../intent-melody-language-v1.md) §3.5). First — **base** by consensus and review; **re-sort by measured frequency** (incl. telemetry) — **deferred** until registry and palette stabilize.
268
269**Conflict resolution**
270
2711. Within one **workspace** one melody alias → exactly **one** canonical `command_id`.
2722. On conflict: either **fix** one mapping in registry, others as secondary matches; or require **three-letter** form; or mark conflicting alias **invalid** until resolved.
2733. **Human title** and **canonical id** remain **always** valid search paths even if alias is ambiguous.
274
275**Palette behavior in melody mode**
276
277- On `c:` the palette switches to melody mode: empty tail after `c:` — **help** and **top families**; on `c: g` — available Git commands and tails; on `c: gs` — direct match (e.g. Git: Status).
278- Result line shows **human title**, **alias**, and optionally **chord hint**. Example:
279 `Git: Status — c: gs — git.status`
280
281**Link to chord layer (one semantic path)**
282
283Melody **does not live apart** from chord: the same path as `c: gs` in the palette, in intent-first mental model, is chord **`Ctrl+K` → `G` → `S`** (family and action letters), and in registry — the same **`command_id`**. Palette gives **text** compact form; chord — **keyboard**; MCP — **identifier**.
284
285**UX constraints**
286
287- `c:` — **accelerator**, not the only way: command must also be found by **ordinary fuzzy** on human title.
288- In UI show alias **next to command** (and chord hint if needed) so the language is learned gradually.
289- Overlay / help may suggest: “Try `c: gs` for Git Status” ([§6](#adr0060-p6)).
290
291**Minimal v1 dictionary (starter set)**
292
293| Alias | Logical meaning (canonical id — confirm in registry) |
294|-------|------------------------------------------------------|
295| `c: gs` | git.status |
296| `c: gc` | git.commit |
297| `c: gp` | git.push |
298| `c: gm` | git.merge |
299| `c: gsu` | git.submodules |
300| `c: bt` | build.test |
301| `c: br` | build.run or build.rebuild |
302| `c: da` | debug.attach |
303| `c: dl` | `debug_launch` |
304| `c: dc` | debug.continue |
305| `c: ms` | map.semantic / show semantic map (per adopted naming) |
306
307Dictionary extension — as commands appear in `IdeCommands`; duplicates and conflicts — per rules above.
308
309---
310
311## Consequences
312
313- A **second UX pattern** appears beside the palette; user docs must explain **Q vs K**.
314- Command registry ([0030](0030-command-ids-hotkeys-and-ui-registry-layers.md)) gains **melody alias** layer and conflict rules; palette ([0070](0070-command-palette-direct-overlay-surface.md)) — **`c:`** mode and title / alias / id triple display.
315- Tests: timeout, Esc, hotkey conflict, MCP `ide_execute_command` for same `command_id`.
316- Dependency on [0059](0059-roslyn-mcp-profiles-manager-tactical-strategic-efb.md): tactical/strategic must align semantically with chord commands.
317
318---
319
320## Open questions
321
322- Is **Ctrl+K** reserved for the editor (Vim/Emacs-like plugins in future)?
323- One global chord machine per app or account for **second TopLevel** ([0017](0017-multi-window-workspace-and-agent-surfaces.md))?
324- Overlay letter localization (EN-only in v0?)?
325- How **S/T axis** (§2) and **intent-first G/B/D/…** ([§11](#adr0060-p11)) combine in one state machine: two chord presets, mode switch, or sequential migration?
326
327---
328
329## Rejected at ADR level
330
331- **Replace palette with Ctrl+K** — rejected: different jobs (catalog vs short FMS flow).
332
View only · write via MCP/CIDE