Architecture decision records
Each ADR records one decision: its context, the choice, and its consequences. ADRs keep their decisions; when later work changes one, a dated "Status update" line is added under its date instead of rewriting it. A new ADR that replaces an old one says so, and the old one gets a status update pointing to it.
Statuses: accepted is in force; proposed is still being tried; superseded has been replaced by the ADR it names.
Unused numbers: ADR-0038, ADR-0040 and ADR-0047 were reserved in plans and never written, so the list skips them. ADR-0038 was for offline translation, which was deferred; ADR-0040 for a changed Parley accessibility bridge, which ADR-0027 found unnecessary; ADR-0047 for the audio encoder choice, which needed no record of its own. The numbers stay unused, so an old plan's mention never points at a different decision; a new ADR takes the number after the highest.
The records
- ADR-0001: Workspace layout and dependency policy: one crate per job, one table of approved dependencies, and no async runtime in speech.
- Status: accepted, with 3 status updates.
- ADR-0002: Text model: canonical text in a rope plus markers, and character positions.
- Status: accepted, with 2 status updates.
- ADR-0003: Speech threading and event timing: the speech thread, generations, word timing, and pause.
- Status: accepted, with 3 status updates.
- ADR-0004: Rate, pitch, and volume: engine-independent voice settings.
- Status: accepted, with 1 status update.
- ADR-0005: Narration and the OffsetMap: spoken text built together with its map back to the document.
- Status: accepted, with 1 status update.
- ADR-0006: Keymap, actions, and announcements: actions, layers, overrides, and announcing every change.
- Status: accepted, with 2 status updates.
- ADR-0007: ETI-Eloquence through an ECI host process: Eloquence with exact word timing, and its licensing.
- Status: accepted, with 1 status update.
- ADR-0008: Apple speech on macOS: the
nsspeechandavspeechbackends. - Status: accepted, with 1 status update.
- ADR-0009: SAPI5 voices on Windows: 64-bit and 32-bit voices in host processes.
- Status: accepted, with 1 status update.
- ADR-0010: PDF loader: a pure Rust PDF reader with column-aware reading order.
- Status: accepted, with 3 status updates.
- ADR-0011: Audio export: sentence-by-sentence synthesis, exact subtitles, and chapters.
- Status: accepted, with 1 status update.
- ADR-0012: One engine-host protocol and playback client: the shared protocol for Eloquence, SAPI5, and DECtalk.
- Status: accepted, with 3 status updates.
- ADR-0013: Dictation through a Whisper program: voice typing with a Whisper subprocess.
- Status: accepted, with 3 status updates; in part superseded by ADR-0023 (Whisper in-process).
- ADR-0014: GUI toolkit (wxDragon): the GUI spike's findings. The GUI moved to Xilem; the wxDragon spike was removed once the Xilem GUI passed its second screen-reader session.
- Status: superseded by ADR-0027. It has 4 status updates.
- ADR-0015: JSON-RPC server (
tw serve --stdio):tw serve --stdio, its methods, and notifications. - Status: accepted, with 2 status updates.
- ADR-0016: Rendering and bulk conversion: Markdown to accessible HTML, and fast, incremental conversion.
- Status: accepted, with 3 status updates.
- ADR-0017: Native writers (EPUB 3, DOCX, BRF, tagged PDF): EPUB 3, DOCX, BRF braille, and tagged PDF, and their accessibility checks.
- Status: accepted, with 2 status updates.
- ADR-0018: Math: LaTeX and ASCIIMath parsing, MathML, and spoken math.
- Status: accepted, with 2 status updates.
- ADR-0019: Citations: the reference library, lookup, and CSL formatting.
- Status: accepted, with 3 status updates.
- ADR-0020: Themes: star's palettes, contrast rules, and output for every frontend.
- Status: accepted, with 2 status updates.
- ADR-0021: DECtalk through a host process: DECtalk with word timing, and its licensing.
- Status: accepted, with 2 status updates.
- ADR-0022: Reading aids: RSVP, bionic reading, spacing, fonts, the ruler, and more, as pure data.
- Status: accepted, with 2 status updates.
- ADR-0023: Piper voices and Whisper dictation in-process on RTen: neural voices with word timing from the model, and in-process dictation, on a pure-Rust ONNX runtime.
- Status: accepted.
- ADR-0024: App core for the GUI: the document window, shared list and prompt state, the waker, the replace-range edit, the settings schema, and work moved off the input thread.
- Status: accepted.
- ADR-0025: Define word offline, and the message catalog: Open English WordNet and CMUdict in an fst and zstd file, and a Fluent-subset catalog with pseudo-locales.
- Status: accepted.
- ADR-0026: OCR, and formats for students: OCR of scanned pages (ocrs in process, Tesseract as the fallback), DAISY, PowerPoint, spreadsheets, archives, and web pages.
- Status: accepted.
- ADR-0027: Xilem GUI: the all-Rust GUI on Masonry, Vello, Parley, AccessKit, and winit; our own document widget, the pinned versions, the accessibility checks, and what to send upstream.
- Status: accepted.
- ADR-0028: The Xilem GUI after the first listening session: two ways to announce (a live region, or UI Automation notifications), every list option in the tree, and where the GUI's memory goes.
- Status: accepted (the first listening session answered: the live region and the background highlight stay the defaults).
- ADR-0029: MathCAT speech: MathCAT 0.7.6-rc.3 as a second math speech engine on its own thread, EPUB 3 MathML read as math, and braille waiting for MathCAT issue #827.
- Status: accepted, behind the
mathcatfeature; its two dependency exceptions were approved. - ADR-0030: Interface translations: the Fluent-subset catalog extended to every message, Spanish, French, German, Brazilian Portuguese, and Arabic built in, right-to-left display, a voice per language, and never going silent.
- Status: accepted.
- ADR-0031: Native RTF, ODT, and Word revisions: our own iterative RTF parser, ODT on roxmltree, Word and ODT comments as notes, tracked changes read as the final text or said in place, and limits for zip packages.
- Status: accepted.
- ADR-0032: Grammar, lint, highlighting, and clipboard crates: our own Markdown lint instead of rumdl, arboard where OSC 52 cannot reach, Unicode math and notes export without new crates, and harper-core and syntect held on one advisory.
- Status: accepted; highlighting is on by default, and grammar is on by default since Wave 7 (a build without the
grammarfeature leaves it out). - ADR-0033: The GUI after further accessibility testing, and edit mode: no console window, the system's file chooser for Open, text size and font keys, every button naming its key, and edit mode in the document view.
- Status: accepted.
- ADR-0034: The rope after measurement: stay on ropey 1.6: why ropey 2 and crop wait, measured on edit traces, and when to look again.
- Status: accepted.
- ADR-0035: Native LaTeX subset, and email and web archives: our own LaTeX tokenizer and two-pass parser with its limits, email and MHTML through mail-parser, and MathML read as math in every web page.
- Status: accepted.
- ADR-0036: Math braille and navigation on MathCAT: MathCAT 0.7.6-rc.3 vendored with the fix for issue #827, Nemeth (default) and UEB math in BRF files wrapped to 40 cells, and exploring a formula with MathCAT's navigation and its braille on the status line.
- Status: accepted, behind the
mathcatfeature; the status line's order waits for a further listening session. - ADR-0037: Offline intelligence, part 1: extractive summaries without a model: LexRank in-house on TF-IDF, sampled long texts,
tw summarizeand Summarize, difficult-word definitions, the RSVP flash check, and why embeddings stay off. - Status: accepted.
- ADR-0039: Automated screen-reader checks beside the listening sessions: the accessibility tree dumped on three systems and compared with main, and NVDA, Orca, and VoiceOver sessions on CI runners, which never replace a human listening session.
- Status: accepted for the tree dump and the Orca session, now standing checks that fail their job; proposed for the NVDA and VoiceOver sessions, which still only report.
- ADR-0041: Publishing templates, real Word footnotes, and PDF page labels: APA, AMA, large print, dyslexia-friendly, high contrast, and manuscript templates for EPUB, Word, and PDF, real Word footnotes, an EPUB cover with alternative text, and PDF pages labelled with their print pages.
- Status: accepted; a check with Word and JAWS is queued for a further test session.
- ADR-0042: Streaming dictation and dictation in the reader: speech found as the audio arrives, words committed while the speaker talks when two Whisper runs agree, a gate so short dictation is never slower than before, the Dictate command in edit mode with a 40-cell status line, nothing lost at close, and why the shortened encoder is not used.
- Status: accepted; the voice while recording waits for a listening session with a microphone.
- ADR-0043: Menus and the palette from one model: the menus of both frontends from one model with catalog labels and live keys, the palette's names and ranking, interface announcements with levels, logical keys on macOS, and colors in the settings.
- Status: accepted; waiting for the terminal session. The GUI's native menus are ADR-0046.
- ADR-0044: Obsidian, JSON, SVG and content MathML in the reader: Obsidian callouts, embeds, tags, and block ids read natively, with the callout rules shared with the renderer; JSON, JSON Lines, and notebooks; SVG drawings as SVG-AAM exposes them; content MathML; and LaTeX macros with arguments and bibliographies.
- Status: accepted.
- ADR-0045: A file browser on the list model: one list that enters and leaves folders and archives, rows that say the name first, members addressed as
course.zip!week1/notes.mdand never extracted, a preview read in the background, folders and files chosen for other commands, and no file ever changed. - Status: accepted.
- ADR-0046: Native menus in the GUI: the window's menus from the app's one model, a Win32 menu bar on Windows and the application menu on macOS through muda, the list menu on Linux, keys shown but handled only by the keymap, a fingerprint that keeps the menus current, and the Colors, settings file, and font dialogs they reach.
- Status: accepted; waiting for session 4 and for the dialogs of the modules still to merge.
- ADR-0048: PDF annotations, links and forms: a PDF's comments as notes, as in Word; its links followed to headings and pages, outside addresses said; filled-in form fields read label first, then value; sideways scans turned upright; scanned tables as tables; and captions found by pattern.
- Status: accepted; the owner's check 6 is still queued.
- ADR-0049: Sync beyond the place: notes, highlights, bookmarks, places, statistics, portable settings, and word lists synced through a folder the owner chooses, each computer writing only its own files, a hybrid logical clock, a merge rule per kind of data (the newest note edit wins, said, with a local backup), documents recognized by content, and no names or paths in the folder.
- Status: accepted.
- Status: accepted; the JSON-RPC methods are implemented, the other shapes are reserved, not implemented.
Writing a new ADR
- Copy the shape of an existing one:
# ADR-NNNN: Title, then- Status:and- Date:lines, then Context, Decision, Consequences, and See also. - Get the date from the machine, never from memory.
- Add it to this index and to the documentation index.
- Record a bold choice together with its fallback.
See also
- Architecture: how the decisions fit together.
- Documentation index