This directory contains the Architecture Decision Records (ADRs) for the forgiven terminal code editor. Each ADR captures a significant technical decision: the context that motivated it, what was decided, and the consequences.
| # | Title | Status |
|---|---|---|
| 0001 | Terminal UI Framework: ratatui + crossterm | Accepted |
| 0002 | Async Runtime and Event Loop Design | Accepted |
| 0003 | LSP Integration Architecture | Accepted |
| 0004 | GitHub Copilot Enterprise Authentication | Accepted |
| 0005 | Copilot Inline Completions and Ghost Text | Accepted |
| 0006 | Copilot Chat / Agent Panel | Accepted |
| 0007 | Vim-style Modal Editing and Spacemacs Leader Keys | Accepted |
| 0008 | Normal Mode Editing Operations and Multi-key Sequences | Accepted |
| 0009 | Syntax Highlighting with syntect | Accepted |
| 0010 | File Explorer Tree Sidebar | Accepted |
| 0011 | Agentic Tool-Calling Loop | Accepted |
| 0012 | Agent UX: Context Injection, File Refresh, and Chat Rendering | Accepted |
| 0013 | Multi-Project Support: Project Folder Argument | Accepted |
| 0014 | Agent Model Selection: Dynamic Discovery and Ctrl+T Cycling | Accepted |
| 0015 | File Creation and Explorer Enhancements | Accepted |
| 0016 | Vim Yank / Paste Register | Accepted |
| 0017 | Multi-line Yank / Delete and Visual Line Mode | Accepted |
| 0018 | Horizontal Scroll Viewport Fix | Accepted |
| 0019 | Snapshot-based Undo / Redo | Accepted |
| 0020 | LazyGit Integration | Accepted |
| 0021 | Render Loop Performance Optimisations | Accepted |
| 0022 | Markdown Rendering (Agent Panel + Editor Preview) | Accepted |
| 0023 | Which-Key Popup Render Timer | Accepted |
| 0024 | Project-wide Text Search | Accepted |
| 0025 | Explorer Hidden Files Toggle | Accepted |
| 0026 | Copilot Stream Resilience | Accepted |
| 0027 | Agent Round Limits and Continuation Prompts | Accepted |
| 0028 | Model Selection Persistence | Accepted |
| 0029 | Task Panel for Work Tracking | Accepted |
| 0030 | In-File Search and Replace | Accepted |
| 0031 | Agent-Driven Plan Strip | Accepted |
| 0032 | Recent Files in the Find File Picker | Accepted |
| 0033 | Mermaid Diagrams and Markdown Browser Export | Accepted |
| 0034 | Explorer File Deletion | Accepted |
| 0035 | Agent Apply-Diff Overlay | Accepted |
| 0036 | Multi-line Agent Panel Input | Accepted |
| 0037 | Think-Block Rendering in the Agent Panel | Accepted |
| 0038 | Unified Model Selection: Removing the model_picker_enabled Filter |
Accepted |
| 0039 | Agent Status Indicator: Live Phase Tracking in the Agent Panel Title | Accepted |
| 0040 | Context Gauge: Token Usage Display in the Agent Panel Title | Accepted |
| 0041 | Agent Panel Copy Code Block (Ctrl+K) and Yank Reply (Ctrl+Y) |
Accepted |
| 0042 | Agent Panel Paste Summary | Accepted |
| 0043 | Vertical Split Screen | Accepted |
| 0044 | Explorer New Folder | Accepted |
| 0045 | MCP Client Integration | Accepted |
| 0046 | Agent Retry Visibility | Accepted |
| 0047 | Git Commit Message Generation | Accepted |
| 0048 | MCP Server Status Visualisation | Accepted |
| 0049 | Diagnostics Overlay (SPC d) |
Accepted |
| 0050 | MCP Server Environment Variable Secret Resolution | Accepted |
| 0051 | Startup Loading Indicator and Service Parallelisation | Accepted |
| 0052 | .NET LSP — Switch Default to csharp-ls | Accepted |
| 0053 | MCP Non-blocking Startup (isolation superseded) | Accepted |
| 0054 | Editor Quality-of-Life Improvements | Accepted |
| 0055 | Release Notes Generation (SPC g n) |
Accepted |
| 0056 | Pluggable Prompt-Framework Integration (spec-kit) | Accepted |
| 0057 | Agent ask_user Tool |
Accepted |
| 0058 | Agent Panel Rendering Performance | Accepted |
| 0059 | Agent File Context Picker (Ctrl+P) | Accepted |
| 0060 | Vim Character Motions (f/t/F/T, dt/df/yt/yf/ct/cf) | Accepted |
| 0061 | Agent Stream Abort (Ctrl+C) and Ctrl-Chord Keybinding Migration |
Accepted |
| 0062 | Offline Resilience: Request Timeouts, MCP Startup Bound, and Error Visibility | Accepted |
| 0063 | Structural Refactor: Buffer Combinator, RenderContext, and Editor Sub-states | Accepted |
| 0064 | Filesystem Watcher: External Change Detection and Auto-Reload | Accepted |
| 0065 | Terminal Redraw on Resume (Resize, SIGCONT, Ctrl+L) | Accepted |
| 0066 | Agent Image Clipboard Paste | Accepted |
| 0067 | Agent Input Box Scroll-to-Cursor | Accepted |
| 0068 | Which-Key Dynamic Height and Ask-User Dialog Formatting | Accepted |
| 0069 | Model Loading Modernisation | Accepted |
| 0070 | Markdown Preview Visual Refresh | Accepted |
| 0071 | File Watcher Self-Save Suppression | Accepted |
| 0072 | MCP Child Process Cleanup on Exit | Accepted |
| 0073 | MCP HTTP Transport: Externally-Managed Servers | Accepted |
| 0074 | Agentic Loop Mid-Session Token Refresh | Accepted |
| 0075 | Slash-Menu Description Hints | Accepted |
| 0076 | Mermaid Diagram Browser Preview (Ctrl+M) |
Accepted |
| 0077 | Agent Context Window Management (SPC a n, token-aware truncation) |
Accepted |
| 0078 | Prompt Caching — Cached Token Tracking | Accepted |
| 0079 | Diff-Only Tool Results for File Write/Edit Operations | Accepted |
| 0080 | Tool Call Batching — read_files and search_files | Accepted |
| 0081 | Importance-Scored History Retention | Accepted |
| 0082 | Symbol-Aware Context Tools (get_file_outline, get_symbol_context) | Accepted |
| 0083 | MCP Memory Server for Cross-Session Context | Accepted |
| 0084 | LLMLingua MCP Sidecar for Tool Result Compression | Accepted |
| 0085 | LSP Navigation (Goto Definition, Find References, Symbols) and C# Revival | Accepted |
| 0086 | Copilot Model-Switch Detection and 429 Rate-Limit Handling | Accepted |
| 0087 | Context Bloat Audit and Session Token Instrumentation | Accepted |
| 0088 | Automatic Tool-Result Compression via LLMLingua | Accepted |
| 0089 | Large File Split: editor, agent, and ui modules | Accepted |
| 0090 | Visual indent/dedent, Markdown table rendering, MCP call log | Accepted |
| 0091 | LSP Hover popup and Rename (WorkspaceEdit) | Accepted |
| 0092 | Persistent Session Metrics JSONL Log | Accepted |
| 0093 | Cap Open-File Context Injection to 150 Lines | Accepted |
| 0094 | Fetch Models Before Context-Budget Computation | Accepted |
| 0095 | Persistent Log File at XDG Data Directory | Accepted |
| 0096 | Session Rounds Counter and Average Tokens per Invocation | Accepted |
| 0097 | Spec-Kit Auto-Clear Context Per Phase | Accepted |
| 0098 | Ollama Local Provider | Accepted |
| 0099 | Context Breakdown: Per-Segment Token Awareness (Phase 1) | Accepted |
| 0100 | Spec Slicer: Virtual Context for Implement Phase | Accepted |
| 0101 | Auto-Janitor: Rolling History Compression (Phase 3) | Accepted |
| 0102 | Submit Hot-Path Optimisations | Accepted |
| 0103 | Speckit Output Formatting Conventions | Accepted |
| 0104 | Tree-sitter Core Integration | Accepted |
| 0105 | Tree-sitter Text Objects | Accepted |
| 0106 | AST-Based Code Folding | Accepted |
| 0107 | Sticky Scroll Context Header | Accepted |
| 0108 | Non-Decision: Multi-Cursor Editing | Accepted |
| 0109 | Non-Decision: Integrated Terminal Pane | Accepted |
| 0110 | Surround Operations | Accepted |
| 0111 | Inline Assistant (Selection Transform) | Accepted |
| 0112 | Agent Checkpoints / Session Undo | Accepted |
| 0113 | Multi-File Review / Change Set View | Accepted |
| 0114 | Agent Hooks / Background Automation | Accepted |
| 0115 | Agent Brevity Constraints | Accepted |
| 0116 | Multi-Provider LLM Backend (Anthropic, OpenAI, Gemini, OpenRouter) | Accepted |
| 0117 | Auto-Janitor Fixes: Archive Preservation, Input Save/Restore, Status Variants, Ollama Fallback | Accepted |
| 0118 | Aggregate File-Block Token Cap | Accepted |
| 0119 | CPU & Memory Performance Pass (Janitor / Streaming) | Accepted |
| 0120 | Auto-Janitor Distinct Streaming UX | Accepted |
| 0121 | Auto-Janitor: Deferred Trigger and Context Grounding | Accepted |
| 0122 | No Duplicate File Buffers | Accepted |
| 0123 | Context Management v2: Observation Masking + Disk Persistence | Implemented |
| 0124 | Agent Input History, Mid-line Cursor, and Label Rename | Accepted |
| 0125 | CSV and JSON Preview Modes | Accepted |
| 0126 | Token Efficiency and LLM Interaction Quality Analysis | Accepted |
| 0127 | Dependency Audit and Advisory Suppression Policy | Accepted |
| 0128 | Investigation Subagent (SPC a v) |
Accepted |
| 0129 | Insights Dashboard: Collaboration Analytics | Accepted |
An Architecture Decision Record documents an architectural decision made in a project. The format used here follows the lightweight template:
- Context — why was this decision needed?
- Decision — what was decided?
- Consequences — what are the trade-offs and implications?
┌───────────────────────────────────────────────────────────────────────────────┐
│ forgiven editor │
│ │
│ main.rs [--dir DIR | DIR positional] │
│ → set_current_dir(canonical) ← project root for all downstream calls │
│ → Editor::new() → Editor::run() (tokio async main) │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Editor event loop (50 ms poll) │ │
│ │ handle_key() → KeyHandler → Action → execute_action() │ │
│ │ drain_lsp_msgs() │ poll_agent_stream() │ render() │ │
│ └───────────┬────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────┴──────────┐ ┌───────────────────────────────────────────┐ │
│ │ LspManager │ │ UI (ratatui) — three-panel layout │ │
│ │ ┌──────────────┐ │ │ │ │
│ │ │rust-analyzer │ │ │ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
│ │ │LspClient │ │ │ │ Explorer │ │ Editor │ │ Agent │ │ │
│ │ │reader thread │ │ │ │ 25 cols │ │ Min(1) │ │ 35% │ │ │
│ │ │writer thread │ │ │ │ │ │ │ │[model] │ │ │
│ │ └──────────────┘ │ │ │ ▼ src/ │ │ syntect │ │ chat │ │ │
│ │ ┌──────────────┐ │ │ │ mod.rs │ │ highlight│ │ history│ │ │
│ │ │copilot-ls │ │ │ │ ▶ tests/ │ │ ghost txt│ │ input │ │ │
│ │ │LspClient │ │ │ │ n=new │ │ │ │Ctrl+T │ │ │
│ │ └──────────────┘ │ │ │ r=reload │ │ │ │=model │ │ │
│ └────────────────────┘ │ └──────────┘ └──────────┘ └────────┘ │ │
│ └───────────────────────────────────────────┘ │
│ │ │
│ ┌─────────┴──────────────────────────────────────────────────────────┐ │
│ │ AgentPanel │ │
│ │ messages: Vec<ChatMessage> pending_reloads: Vec<String> │ │
│ │ stream_rx: mpsc::UnboundedRx streaming_reply: Option<String> │ │
│ │ available_models: Vec<String> selected_model: usize │ │
│ │ │ │
│ │ ensure_models() ──────────────► GET /models (lazy, cached) │ │
│ │ tokio::spawn(agentic_loop) ──► api.githubcopilot.com │ │
│ │ model_id = selected_model_id() │ │
│ │ MAX_ROUNDS=20 tools: read_file / write_file │ │
│ │ parse SSE tool_call deltas edit_file / list_directory │ │
│ │ execute tools (safe_path sandbox) │ │
│ │ StreamEvent: Token | ToolStart | ToolDone | FileModified | Done │ │
│ │ │ │
│ │ FileModified → pending_reloads → Buffer::reload_from_disk() │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ Highlighter (syntect) — SyntaxSet + ThemeSet loaded once at startup │
│ FileExplorer — lazy tree rooted at current_dir(); reload() on r │
│ clipboard: Option<String> — shared yank/delete register │
└───────────────────────────────────────────────────────────────────────────────┘
Normal ──── i/a/I/A/o/O ──► Insert
──── v ──► Visual (charwise, extend with h/j/k/l/w/b/0/$)
──── V ──► VisualLine (linewise, extend with j/k/G/g)
──── : ──► Command (:e path, :w, :q, :wq, :q!, copilot status/auth)
──── / ──► InFileSearch (type pattern, Enter=search, Esc=cancel)
──── SPC b b ──► PickBuffer
──── SPC f f ──► PickFile (fuzzy search)
──── SPC f n ──► Command (pre-filled "e " for new file)
──── SPC a a/f ──► Agent
──── SPC e e/f ──► Explorer
──── SPC m p ──► MarkdownPreview
Explorer ── Esc/Tab ──► Normal
── Enter/l ──► (opens file → Normal) or (toggles dir)
── n ──► Command (pre-filled "e <dir>/" for new file)
── r ──► RenameFile (inline popup)
── d ──► DeleteFile (confirmation popup)
── h ──► (toggle hidden files, stays in Explorer)
── R ──► (reload tree from disk, stays in Explorer)
RenameFile ── Enter ──► Explorer (rename confirmed)
── Esc ──► Explorer (cancelled)
DeleteFile ── y/Y ──► Explorer (deleted)
── n/N/Esc ──► Explorer (cancelled)
Agent ── Esc/Tab ──► Normal
── Ctrl+T ──► cycle model (loads /models list on first press)
── Ctrl+C ──► stop agent (cancels in-flight LLM request)
── Ctrl+K ──► copy code block (cycles through blocks; wraps)
── Ctrl+Y ──► yank full reply to clipboard (raw markdown)
── Ctrl+A ──► ApplyDiff (when a code block is present)
ApplyDiff ── y/Enter ──► Normal (change applied to file or buffer)
── n/Esc ──► Agent (discarded)
── j/k ──► (scroll down/up one line)
── Ctrl+D/U ──► (scroll down/up half-page)
Preview ── Esc/q ──► Normal
── j/k ──► scroll down/up one line
── Ctrl+D/U ──► scroll down/up half-page
── g/G ──► jump to top/bottom
Insert ──── Esc ──► Normal