Architecture Decision Records
This directory holds rio's architecture decision records (ADRs), in the style described at adr.github.io and in Michael Nygard's original template. Each record states one decision: the situation that called for it, what was decided, and what follows from it.
Names
Decisions are recorded here and nowhere else (ADR-0144).
- D1 to D136 are the names the old decision log in AGENTS.md used. Source comments
and the changelog still cite them. A record's Decision: line carries its D number.
- D1 to D111 are ADR-0001 to ADR-0111.
- D112 to D136 are ADR-0118 to ADR-0143:
grep -l 'Decision:\*\* D123' adr/*. - ADR-0112 to ADR-0117 never had one.
- From ADR-0144 on a decision has one name:
ADR-NNNN.
Statuses
| Status | Meaning |
|---|---|
| Accepted | In force. |
| Accepted, not implemented | In force as design; no code yet. |
| Amended by ADR-NNNN | In force, with a later record changing part of it. |
| Superseded by ADR-NNNN | Replaced; kept for its reasoning. |
| Rejected | Tried or considered and reversed; kept so it is not proposed again. |
Index
| ADR | Title | Status | Date |
|---|---|---|---|
| 0001 | Three layers: core, frontends, optional server | Accepted; amended by 0030 | 2026-06-24 |
| 0002 | The core API is a transport-independent message protocol | Accepted; amended by 0030 | 2026-06-24 |
| 0003 | The core owns the document; frontends are views | Accepted | 2026-06-24 |
| 0004 | Tcl/Tk for core and GUI, Ck for the TUI | Accepted; the TUI is deferred by 0112 | 2026-06-24 |
| 0005 | The TUI is keyboard-only | Accepted, not implemented (the TUI is deferred, 0112) | 2026-06-24 |
| 0006 | Windows TUI through Cygwin, PDCurses as fallback | Accepted, not implemented (the TUI is deferred, 0112) | 2026-06-24 |
| 0007 | Git by shelling out to git | Accepted | 2026-06-24 |
| 0008 | LLM access behind a stable provider interface | Accepted | 2026-06-24 |
| 0009 | The responsive layout rule is a shared pure function | Accepted, not implemented (the TUI is deferred, 0112) | 2026-06-24 |
| 0010 | Asynchrony through the event loop and coroutines | Accepted | 2026-06-24 |
| 0011 | Newline-delimited JSON wire protocol | Accepted; amended by 0113 | 2026-06-24 |
| 0012 | Document model: a list of lines, line.col positions | Accepted | 2026-06-24 |
| 0013 | Fixed layout regions and a collapsible section stack | Accepted; amended by 0035 | 2026-06-24 |
| 0014 | Responsive tiers and the unified-diff fallback | Accepted, not implemented (the TUI is deferred, 0112) | 2026-06-24 |
| 0015 | No terminal pane; a headless command primitive only | Accepted | 2026-06-25 |
| 0016 | A plugin is a protocol participant | Accepted, not implemented (the general plugin platform is deferred) | 2026-06-24 |
| 0017 | Contribution points for extensions | Accepted, not implemented (the general plugin platform is deferred) | 2026-06-24 |
| 0018 | UI contributions are declarative | Accepted, not implemented (the general plugin platform is deferred) | 2026-06-24 |
| 0019 | Plugin manifest and permissions; no marketplace platform | Accepted; distribution amended by 0039 | 2026-06-24 |
| 0020 | Agent orchestration in the core, providers and tools outside | Accepted | 2026-06-24 |
| 0021 | Plain-text configuration in XDG locations, never executed | Accepted; session storage amended by 0031 | 2026-06-25 |
| 0022 | Preserve encoding and line endings; cursors are frontend-local | Accepted | 2026-06-25 |
| 0023 | Keybindings are data | Accepted; amended by 0143 | 2026-06-25 |
| 0024 | Themes are semantic-role data files | Accepted; amended by 0142 | 2026-06-25 |
| 0025 | JSON encoding is shape-aware, never value-sniffed | Accepted | 2026-06-25 |
| 0026 | The agent's first slice, on the official API key only | Accepted; amended by 0034, 0069, 0083, 0104 | 2026-06-27 |
| 0027 | Icons are monochrome Unicode glyphs | Accepted | 2026-06-29 |
| 0028 | A core line diff and a read-only compare view | Accepted | 2026-06-29 |
| 0029 | The GUI can drive a remote core over a socket | Superseded by 0030 | 2026-06-30 |
| 0030 | The frontend is always a client over a channel | Accepted; amended by 0096 | 2026-06-30 |
| 0031 | Sessions and preferences, split by owner, out of tree | Accepted | 2026-07-01 |
| 0032 | Syntax highlighting: swappable per-line scanners in the frontend | Accepted; the viewport scoping deferred here arrived with 0133 | 2026-07-01 |
| 0033 | Two side-by-side editor groups | Accepted | 2026-07-06 |
| 0034 | A core-owned, provider-agnostic system prompt | Accepted; amended by 0070, 0079, 0105 | 2026-07-08 |
| 0035 | Tool windows live in dock sites, not in the document tabs | Accepted | 2026-07-12 |
| 0036 | Find and replace: the engine in the core, a bar in the GUI | Accepted | 2026-07-12 |
| 0037 | Stale-link detection at the protocol layer | Accepted | 2026-07-12 |
| 0038 | Editing modes as a bind-tag layer | Accepted; amended by 0041, 0143 | 2026-07-12 |
| 0039 | Extension repositories over plain HTTP, apt-sources style | Accepted; amended by 0066, 0107, 0109, 0124 | 2026-07-17 |
| 0040 | Column editing as a GUI-only vertical cursor | Accepted | 2026-07-23 |
| 0041 | The core ships one editing mode; emacs and vi are extensions | Accepted | 2026-08-03 |
| 0042 | The files pane is a rich list drawn on a text widget | Accepted; amended by 0043, 0087 | 2026-08-06 |
| 0043 | A shared rich-list component; git flags in the files pane | Accepted | 2026-08-06 |
| 0044 | Pane context menus and the first git write operations | Accepted | 2026-08-07 |
| 0045 | Commit from a bar that appears only when something is staged | Accepted; amended by 0081 | 2026-08-07 |
| 0046 | Highlighters can register by file name | Accepted | 2026-08-10 |
| 0047 | Disk writes are announced with fs.changed | Accepted | 2026-08-18 |
| 0048 | File management as core operations | Accepted; target directory rule amended by 0087 | 2026-08-18 |
| 0049 | A line-number gutter drawn from the text widget's geometry | Accepted | 2026-08-19 |
| 0050 | Cursor position in the status bar | Accepted | 2026-08-19 |
| 0051 | Find in files: a core engine and a bottom results panel | Accepted; scope amended by 0052 | 2026-08-19 |
| 0052 | One search panel: two engines, three scopes | Accepted | 2026-08-19 |
| 0053 | LLM integration is assisted, not autonomous | Accepted; amended by 0084 | 2026-08-23 |
| 0054 | Every entry point pins the source encoding to UTF-8 | Accepted | 2026-09-03 |
| 0055 | Questions about the core's host are answered by the core | Accepted | 2026-09-03 |
| 0056 | The editor font is a user override on the theme font | Accepted; amended by 0143 | 2026-09-03 |
| 0057 | Tab overflow: page, wrap, or list | Accepted; amended by 0074, 0078 | 2026-09-03 |
| 0058 | A Preferences window that owns no state | Accepted; amended by 0085, 0092 | 2026-09-03 |
| 0059 | Patching Tk's menu click behaviour | Rejected (shipped, then reverted) | 2026-09-04 |
| 0060 | Current-line highlight | Accepted | 2026-09-04 |
| 0061 | Click a line number to select the line | Accepted | 2026-09-04 |
| 0062 | Hide dotfiles in the files pane by default | Accepted | 2026-09-04 |
| 0063 | Hover tooltips for glyph controls | Accepted | 2026-09-04 |
| 0064 | Menus are kept within screen height by grouping | Accepted | 2026-09-04 |
| 0065 | A second provider, and hardening the provider contract | Accepted; distribution amended by 0066; keys made per profile by 0138 | 2026-09-04 |
| 0066 | Providers install from repositories, behind a versioned API | Accepted; amended by 0069 | 2026-09-04 |
| 0067 | The Extensions window moves to the Settings menu | Accepted; the item moved once more in 0137 | 2026-09-04 |
| 0068 | Static help must look different from controls | Accepted | 2026-09-04 |
| 0069 | Claude is an installable provider; echo is the only built-in | Accepted | 2026-09-04 |
| 0070 | A defined place for user and project prompts | Accepted; amended by 0079, 0105 | 2026-09-04 |
| 0071 | Relative line numbers | Accepted | 2026-09-05 |
| 0072 | A session for work with no project open | Accepted | 2026-09-08 |
| 0073 | Compare gets its own top-level menu | Accepted | 2026-09-08 |
| 0074 | A bounded buffer picker replaces the Tabs menu | Accepted; generalised by 0092 | 2026-09-08 |
| 0075 | A top-level Find menu | Accepted | 2026-09-08 |
| 0076 | About rio shows the build's commit identity | Accepted; the release version it lacked arrived with 0130 | 2026-09-08 |
| 0077 | Open several files from the native chooser | Accepted | 2026-09-08 |
| 0078 | Multi-line tabs flow into packed, justified rows | Accepted | 2026-09-08 |
| 0079 | A per-provider prompt layer | Accepted | 2026-09-08 |
| 0080 | Git discard for everyday use | Accepted; amended by 0093, 0097 | 2026-09-08 |
| 0081 | An optional commit message body | Accepted | 2026-09-08 |
| 0082 | A busy indicator while the agent works | Accepted | 2026-09-09 |
| 0083 | The agent runs commands: gated, asynchronous, time-bounded | Accepted; amended by 0084 | 2026-09-09 |
| 0084 | Human-authored command allow-lists | Accepted | 2026-09-09 |
| 0085 | Agent configuration lives in Preferences | Accepted | 2026-09-09 |
| 0086 | Drop a file on the window to open it, with optional tkdnd | Accepted | 2026-09-09 |
| 0087 | The files pane becomes a tree from the project root | Accepted | 2026-09-09 |
| 0088 | Reopen the last folder on launch | Accepted; amended by 0089 | 2026-09-09 |
| 0089 | Remember the unfolded tree; survive a deleted folder | Accepted | 2026-09-09 |
| 0090 | Undo coalescing by word, decided in the core | Accepted | 2026-09-10 |
| 0091 | The user manual lives in the source tree | Accepted | 2026-09-10 |
| 0092 | The theme menu becomes a bounded picker | Accepted | 2026-09-10 |
| 0093 | Discard from the file tree, and discard all | Accepted | 2026-09-10 |
| 0094 | Buffers detect changes to their files | Accepted | 2026-09-10 |
| 0095 | A headless run never asks a human anything | Accepted | 2026-09-11 |
| 0096 | rio speaks the protocol; it does not dial | Accepted | 2026-09-11 |
| 0097 | Discarding a rename restores the old name | Accepted | 2026-09-11 |
| 0098 | Files inside an untracked folder can be tracked individually | Accepted | 2026-09-11 |
| 0099 | rio shows its own manual | Accepted; amended by 0100 | 2026-09-11 |
| 0100 | The manual is rendered, with working links and search | Accepted | 2026-09-11 |
| 0101 | Plan mode: a core tool and a readable plan view | Accepted; amended by 0102, 0103 | 2026-09-11 |
| 0102 | The edit policy is chosen when a plan is approved | Accepted | 2026-09-11 |
| 0103 | The plan tool is offered in every mode | Accepted | 2026-09-11 |
| 0104 | No step cap; a Stop button instead | Accepted | 2026-09-11 |
| 0105 | rio's shipped prompt is complete and visible | Accepted | 2026-09-11 |
| 0106 | Model and effort are provider-declared options | Accepted; extended by 0135 and 0138 | 2026-09-12 |
| 0107 | Extension versions are semver and are compared | Accepted | 2026-09-12 |
| 0108 | The editor has a context menu built from the Edit menu's table | Accepted; amended by 0121, 0143 | 2026-09-12 |
| 0109 | https beside http, trusted from the host's CA store | Accepted; amended by 0110, 0111, 0120 | 2026-09-12 |
| 0110 | The agent refuses https without host-name checks unless allowed | Accepted; amended by 0120 | 2026-09-15 |
| 0111 | A certificate that fails verification can be accepted by fingerprint | Accepted; amended by 0120 | 2026-09-15 |
| 0112 | The TUI is deferred after a successful Ck spike | Accepted | 2026-06-27 |
| 0113 | A small, stable error-code taxonomy | Accepted | 2026-06-26 |
| 0114 | A project is one root folder held by the core | Accepted | 2026-06-27 |
| 0115 | Hard dependencies are minimal; optional ones must degrade cleanly | Accepted | 2026-09-09 |
| 0116 | Verification is automated, offline, and proven against injected faults | Accepted | 2026-09-11 |
| 0117 | A fact kept in two places must have a guard | Accepted | 2026-09-10 |
| 0118 | A buffer's language can be picked by hand | Accepted | 2026-09-16 |
| 0119 | Change with Agent: a request about the selected text, and only that | Accepted | 2026-09-16 |
| 0120 | One core-wide switch for https without host-name checks | Accepted | 2026-09-17 |
| 0121 | A context menu on every text widget outside the editor | Accepted; amended by 0143 | 2026-09-17 |
| 0122 | A missing dependency names the package to install | Accepted | 2026-09-17 |
| 0123 | rio has a window and taskbar icon | Accepted; the artworks it compares were removed by 0127 | 2026-09-18 |
| 0124 | A repository can be signed, and rio checks it | Accepted; amended by 0125; trust on first use superseded by 0126 | 2026-09-16 |
| 0125 | Every repository signing key rio trusts is listed, and can be forgotten | Accepted; amended by 0126 | 2026-09-19 |
| 0126 | A signing key is trusted when the user confirms it, never because it arrived first | Accepted | 2026-09-19 |
| 0127 | rio ships only artwork it can pass on | Accepted | 2026-09-20 |
| 0128 | rio is MIT-licensed | Accepted; amended by 0129 | 2026-09-20 |
| 0129 | An extension payload carries its licence inside it | Accepted | 2026-09-20 |
| 0130 | rio is 0.1.0: semver for releases, integers for contracts | Accepted | 2026-09-20 |
| 0131 | rio has a changelog, and a guard keeps it current | Accepted; amended by 0144 | 2026-09-20 |
| 0132 | A file too big or too binary to open is declined, not read | Accepted; the budget was raised by 0133 | 2026-09-20 |
| 0133 | A big file is slow because of what rio does to it, not because it is big | Accepted | 2026-09-20 |
| 0134 | A headless run must not be able to receive real input | Accepted; amended by 0140 | 2026-09-21 |
| 0135 | A provider declares its own settings, and rio renders them | Accepted; where the settings window lives reversed by 0137 — the option vocabulary, the thinking verb and provider-api 4 stand; amended by 0138 | 2026-09-22 |
| 0136 | One install script per platform, and a launcher that makes rio an application | Accepted; amended by 0141 | 2026-09-22 |
| 0137 | A top-level Extensions menu; each extension configures itself | Accepted | 2026-09-23 |
| 0138 | A provider keeps several named configurations, and an option may name a file | Accepted | 2026-09-23 |
| 0139 | Autosave writes a separate recovery copy, never the file you are editing | Accepted | 2026-09-26 |
| 0140 | On macOS, platform facts are asked of Tk, not assumed | Accepted; amended by 0141 | 2026-09-29 |
| 0141 | macOS gets its own installer, and rio.app is a copy of wish | Accepted | 2026-09-29 |
| 0142 | On Aqua, the theme reaches the native controls, and chrome text has a floor | Accepted | 2026-09-29 |
| 0143 | On a Mac, rio uses the Mac's keys and its right mouse button | Accepted | 2026-09-29 |
| 0144 | Decisions live in adr/ only; AGENTS.md is instructions | Accepted | 2026-10-02 |
| 0145 | The GUI is one file per concern; rio-gui.tcl is the entry | Accepted | 2026-10-02 |
| 0146 | Undo has a budget, and a step holds a text once | Accepted | 2026-10-02 |