Forge
markdowndeeb25a2
1<!-- English translation of adr/0029-configuration-toml-canonical-ui-facade.md. Canonical Russian: ../../adr/0029-configuration-toml-canonical-ui-facade.md -->
2
3# ADR 0029: Configuration — **TOML-First** (On-Disk Canon); **Holistic** Settings UI — **Deferred**; Point UI — **Canon Facade**, Not a Second Truth
4
5**Status:** Accepted · Implemented (TOML-first on disk; holistic settings UI — deferred; point UI — facade)
6**Date:** 2026-04-08
7**Updated:** 2026-04-08 — holistic center deferred; subsection “Why point UI”; dynamic UI from model perspective; point UI = code weight. Details — [§ History](#adr0029-history).
8
9## Related ADRs
10
11| ADR | Role |
12|-----|------|
13| [0028](0028-user-settings-toml-localappdata-and-secrets.md) | Path and format of `settings.toml` |
14| [0010](0010-ui-modes-toml-configuration.md) | Modes and `workspace.toml` merge |
15| [0015](0015-editor-toml-syntax-highlighting.md) | TOML in built-in editor; external editor with rich tooling — conscious option |
16| [0013](0013-command-surface-and-discoverability.md) | Palette, hotkeys in separate file |
17| [0027](0027-small-team-focus-vs-public-maturity.md) | Axis B: standalone settings app and heavy onboarding — deferred backlog until triggers |
18| [0026](0026-markdown-preview-surfaces-and-placement.md) | Some keys in merged `workspace.toml` — team canon in repo |
19
20## Summary
21
22- **TOML-first** configuration; holistic settings UI — deferred.
23- Point UI is a **facade** over the same file, not a second source of truth.
24
25---
26
27## Context
28
29Three facts hold at once in the product:
30
311. **Files** are the accepted storage canon: user `settings.toml`, bundle/repo for modes and chrome ([0010](0010-ui-modes-toml-configuration.md), [0028](0028-user-settings-toml-localappdata-and-secrets.md)).
322. **UI** already changes some preferences (panel visibility, UI mode, providers, LSP, etc.) via model and save to disk.
333. Discussion oscillates between **“TOML only”** and **“full settings screens”** — without a dedicated ADR it is easy to mix expectations: what is “real” truth, must every key have UI, is living in one file alone allowed.
34
35We need **one priority model**: disk and file format **define canon**; any UI that touches settings **must not** create a second truth — but **how much** screen UI (one button vs full “settings center”) is a separate product decision aligned with [0027](0027-small-team-focus-vs-public-maturity.md).
36
37---
38
39## Decision
40
41### 1. Canon — **text configs on disk** (TOML where already adopted)
42
43- User preferences — **`settings.toml`** and related files under `%LocalAppData%\CascadeIDE\` ([0028](0028-user-settings-toml-localappdata-and-secrets.md)).
44- Layout/metrics/mode presets — **`UiModes/`** and merge with **`.cascade/workspace.toml`** ([0010](0010-ui-modes-toml-configuration.md)).
45- **Secrets** — separate file **`ai-keys.toml`**, not in `settings.toml` ([0028](0028-user-settings-toml-localappdata-and-secrets.md)).
46
47Extending keys — **model + file + serialization first**, then (as needed and on axis B) UI elements.
48
49### 2. **Holistic** settings UI — **deferred** ([0027](0027-small-team-focus-vs-public-maturity.md))
50
51**Holistic** means: **single page/center “all settings”**, separate **settings application**, large wizards — what [0027](0027-small-team-focus-vs-public-maturity.md) puts in deferred backlog until triggers (external contributor, RC, explicit pain, etc.).
52
53- This is **not** a ban on **point** toggles in the main window that exist or appear with features.
54- This is **not** a ban on documenting “edit `settings.toml`” as a primary path for part of the audience.
55
56Net: **we do not invest now** in a full-screen discoverability settings product; **we do** live on TOML + docs + examples ([0027](0027-small-team-focus-vs-public-maturity.md)) until the queue says otherwise.
57
58### 3. Point UI — when present, **facade of canon** (not a parallel database)
59
60When a control in the app changes a preference stored in `settings.toml` (or other canonical file):
61
62- it uses the **same** model (`CascadeIdeSettings`, etc.) as serialization;
63- save goes through **`SettingsService.Save`** (and equivalents), **without** a shadow in-memory-only registry as source of truth;
64- **no** policy “settings live only in UI and sometimes export” — see rejected alternatives.
65
66**Facade** in this ADR = **architectural rule** for existing or point-added UI: it reflects the file, does not replace it with a hidden copy. It is **not** a promise to **collapse** all config into rich UI in the next release (see §2).
67
68#### Why point UI if everything can be edited in TOML?
69
70Canon remains the **file**; point UI **does not** add a second truth and is **not** required for every user.
71
72- **Friction:** frequent actions (panel visibility, UI mode, etc.) are cheaper with a cockpit click than opening `%LocalAppData%\CascadeIDE\`, finding a snake_case key, saving, and sometimes restarting.
73- **Rare one-off setup** is fine: e.g. enable external agent (ACP), set `cursor-agent` path — convenient from UI **or** the same key in `settings.toml` per docs; both entries hit one canon ([0016](0016-agent-client-protocol-external-agent.md)).
74- “I never open settings UI, everything in TOML” is **valid and expected** for part of the audience; “I only opened UI once for one option” **does not** contradict TOML-first — alternative **entry**, not canceling the file.
75
76### 4. **TOML-only** mode is first-class
77
78- Editing `settings.toml` (and other canonical files) manually, in the **built-in** editor or **external** ([0015](0015-editor-toml-syntax-highlighting.md)), is a normal workflow including for agents and machine diffs.
79- Missing **holistic** settings UI (§2) is **not** a gap by itself. Missing UI for individual keys is also OK; a checkbox per model field is **not** mandatory ([0027](0027-small-team-focus-vs-public-maturity.md)).
80
81### 5. When to add/extend **point** UI on top of TOML
82
83- High **frequency**, **safety** (secret masking), **live validation** — natural **point** control candidates (still §3 rules).
84- Complex structures (MCP server JSON lists, etc.) — **as** UI if they reduce hand-editing errors; serialized result still lives in the canonical file field.
85- **Holistic** “settings center” — only after [0027](0027-small-team-focus-vs-public-maturity.md) triggers or explicit pain, not default queue.
86
87### 6. Session limitation (implementation honesty)
88
89- **`SettingsService.Load()`** typically runs at app start; **direct** edits to `settings.toml` on disk during a session **may** need restart for all subsystems to pick up values (unless a key gets explicit reload). This is **not** an argument against TOML-first; “reload settings” or a watcher is a **separate** task, not mixed with canon question.
90
91---
92
93## Consequences
94
95- New settings: design **key in model and file** first; **holistic** UI — not required and not default queue; point UI — as needed.
96- Docs for users and agents: “how to change X” may start with **file path and key**; screens are optional convenience and alternate entry (§3, “Why point UI”).
97- [0027](0027-small-team-focus-vs-public-maturity.md): deferred **settings app/center** aligns with this ADR: on-disk canon exists, rich UI later per triggers.
98- Point UI **increases code volume** (bindings, VM, tests) — add consciously; alternative to form sprawl when a holistic center appears — see “Perspective” below.
99
100---
101
102## Perspective (not a implementation commitment)
103
104When a **holistic** settings center is no longer deferred per [0027](0027-small-team-focus-vs-public-maturity.md), consider **not** a pile of hand-built screens but a **dynamic form** built from the **same model** as `settings.toml` serialization (e.g. reflection/generator on `CascadeIdeSettings` + **metadata** layer).
105
106**Plus:** new model/TOML field — with metadata, appears in UI **without** N manual bindings; one canon.
107
108**Not “CLR type only”:** need labels, order, groups, hidden fields, localization; **secrets** stay outside this form ([0028](0028-user-settings-toml-localappdata-and-secrets.md)); **JSON blobs** and nonstandard fields — separate templates or multiline editor.
109
110This is **not** “build now” and **does not** cancel §2 (holistic layer still not default queue); recorded as **future direction** if a trigger pulls settings center from backlog.
111
112---
113
114## Rejected alternatives
115
116- **UI only, TOML as hidden export** — rejected: breaks transparency, diffs, agent workflow, “fixed in Notepad”.
117- **Two sources of truth** (part registry, part TOML) without explicit canon — rejected: duplication and drift.
118- **Mandatory UI for every `CascadeIdeSettings` field** — rejected: excessive for current axis B ([0027](0027-small-team-focus-vs-public-maturity.md)); TOML-only remains valid forever for advanced users.
119
120---
121
122## Change history
123
124<a id="adr0029-history"></a>
125
126| Date | Change |
127|------|--------|
128| 2026-04-08 | Holistic center deferred; subsection “Why point UI”; dynamic UI from model perspective; point UI = code weight. |
129
View only · write via MCP/CIDE