Skip to content

Latest commit

 

History

History
104 lines (78 loc) · 15.7 KB

README.md

File metadata and controls

104 lines (78 loc) · 15.7 KB

Architecture Decision Records

These are short documents recording the reasoning behind major technical choices. An ADR records the decision as it stood on its date, and is not kept current. The code, the workflows and the rest of docs/ describe the system as it is now.

Every load-bearing decision in the Linux subproject has an ADR. If a contributor asks "why did we pick X", the answer should already be in this folder. If it is not, we missed an ADR.

Format

# 000N: Title

- **Status**: Accepted
- **Date**: YYYY-MM-DD

## Context

The forces at play. What is the situation that requires a decision?

## Decision

The choice we made, in one sentence.

## Rationale

Why this choice over the alternatives. Reference the alternatives explicitly.

## Consequences

What we accept by making this choice. Positive, negative, neutral.

## Alternatives considered

Brief note on each alternative and why it lost.

Context, Decision and Consequences are always there. Rationale and Alternatives considered are there when other options were weighed. A section an ADR needs beyond these, such as a matrix or a dated note, comes after them.

The Status is Accepted, Superseded by 000M or Deprecated. A decision for every platform is in core/docs/decisions/, and a Status names one of those as core 000M. An accepted ADR that a later one changed in part reads Accepted; <part> superseded by 000M (replaced) or amended by 000M (extended). The amended <date> statuses below predate this rule.

ADRs are short on purpose. If yours is more than a page, you are probably arguing instead of recording.

Changing a decision

A new ADR supersedes the old one, as in Michael Nygard's Documenting Architecture Decisions. The new ADR says what it replaces and why. The old ADR's only edit is its Status line, naming the new one, plus the same change to its row in the index. Do not rewrite an old ADR's body to match the current system.

A fact the repository keeps elsewhere, such as a workflow trigger, a branch, a variable's default or a ruleset, is pointed to from an ADR, not copied into it, so the ADR stays true without edits.

Index

# Title Status Summary
0001 No plugin system; drivers are statically linked Superseded by core 0004 Drivers are crates, registered at compile time. No .tableplugin-equivalent on Linux.
0002 Rust + GTK4 + libadwaita Accepted; version floor superseded by 0015, the Relm4 consequence by 0012 Validated by spike. Only stack with a production virtualized data grid (GtkColumnView).
0003 Relm4 for app architecture Superseded by 0012 Elm-style components scale to TablePro's view count.
0004 Secret storage through oo7 Accepted; store API and Flatpak path amended 2026-09-15, the rules for edits 2026-10-15 The Secret Service on the host, and oo7's own keyring file with a key from the Secret portal inside Flatpak; never a plain-text file.
0005 Supply-chain policy Accepted; the MySQL CA bundle's watch list amended by 0037 Maintained crates first; custom code needs recorded evidence and a removal trigger.
0006 Meson drives Cargo Accepted; where the version lives amended by 0017, the release tarball and the place of the Cargo workspace amended by core 0001 Meson owns install, data files and the build-time config; Cargo stays the Rust compiler.
0007 Preferences and window geometry in GSettings Accepted; the schema id and path per profile amended 2026-10-15 A schema with ranges and enums replaces preferences.json and window.json; keyed data stays in files.
0008 Flatpak sandbox permissions Accepted; the Flathub submission deferred by 0018; local sockets amended by 0035; Flathub permission review amended by 0041 Network, display, home and removable drives for SQLite, the SSH agent and the Kerberos KCM socket; portals for the rest; two Flathub lint exceptions.
0009 One crypto provider, upstream sources and dependency bans Accepted; sources and the PostgreSQL and ClickHouse TLS setup superseded by 0016, the ring ban amended by 0023, the rsa ban amended by core 0008 aws-lc-rs only; deny.toml enforces sources, licenses, bans and advisory ignores.
0010 DDL plans against table definitions Accepted; truncating and schema and database changes amended by core 0013 Each engine plans structure changes through its DdlDialect against the table's definition; the UI offers only what the plan accepts.
0012 One window per connection session, built from gtk-rs subclasses Accepted; what a window holds superseded by 0028 One TableProApplication per profile through D-Bus uniqueness; a window holds at most one session and returns to the picker on disconnect; the application, the window and its workspace are subclasses, not Relm4 components.
0013 SSH through the system OpenSSH client Accepted; the forced options amended by 0019, the TCP port amended by 0023, the russh consequence amended by core 0008 ControlMaster per connection, Unix-socket forwards, prompts through an askpass helper.
0014 Lossless values and engine dialects Accepted A value reaches the user and goes back without loss; every statement is spelled by the dialect of the connection that runs it.
0015 GNOME 50 platform floor Accepted; the runtime row amended by 0018 GTK 4.22, libadwaita 1.9, GtkSourceView 5.18, GLib 2.88; AdwShortcutsDialog replaces the shortcuts window.
0016 Driver contract v2 Accepted; the no-fork rule for tiberius superseded by core 0005, a database change outside a transaction amended by core 0013 Owned calls with engine stops, phase-aware write outcomes, server-side row limits; PostgreSQL on tokio-postgres; no forks.
0017 Distribution channels Superseded by 0018 Flathub, a .deb for Ubuntu 26.04 on GitHub Releases built with rustup, and an .rpm for Fedora 44 on COPR, all from meson install and one vendor tarball; no AppImage.
0018 A PPA and COPR first, Flathub later Accepted; the source tarball amended by core 0001; release channels and the Snap alternative superseded by 0041; Flathub permission review amended by 0041; the source of debian/copyright superseded by 0040 A Launchpad PPA built with rustc-1.97 and a COPR project built on each release are the primary channels; Flathub follows as a submission a maintainer writes; Rust 1.97 is the MSRV.
0019 A chosen SSH key file limits the keys ssh offers Superseded by 0020 A key file comes with IdentitiesOnly=yes, so the agent's other keys cannot use up MaxAuthTries first.
0020 Pin only a key file the agent does not hold Accepted IdentitiesOnly=yes only for a key file the agent lacks, so an agent-held certificate or encrypted PEM key still signs.
0021 Engines without SQL keep the driver contract and say what they hold Accepted; amended by 0026 A key-value engine states DataModel::KeyValue, lists keys with scan_keys and reads them with read_key, has its own SqlGrammar variant, and is held read-only by the driver's check where the server cannot.
0022 An AI assistant and a local MCP server Accepted; the level of connections saved before it existed superseded by 0033 An MCP server on 127.0.0.1, off until turned on, with a token and a per-connection External Clients level, every client write approved in the app; an AI assistant with no provider until the user adds one and a per-connection AI policy.
0023 A loopback relay for the CQL client Accepted; the Linux-only relay amended by core 0008 Each scylla session dials a 127.0.0.1 relay that serves only this user and carries every connection over Transport::open, so CQL reaches a server through an SSH forward.
0024 Multiple cursors on text marks, in the app Accepted The SQL editor's view, a GtkSourceView subclass, keeps extra cursors as GtkTextMark pairs, runs GTK's own commands once per cursor and repeats committed text from end-user-action, so one undo takes back every cursor's edit.
0025 DuckDB built from the duckdb crate's bundled sources Accepted; the crate version superseded by 0031 No PPA or COPR target but Ubuntu 26.10 ships libduckdb, so DuckDB 1.5.6 is compiled from the crate on every channel, with no extension fetched or loaded on its own.
0026 Document collections open in the table tab, and their statements are shell calls Accepted A document engine states DataModel::Document, lists collections as tables, opens them in the table tab, and every builder writes a mongosh call with bound values through a document arm chosen by the grammar.
0027 One data grid on GtkColumnView, with rows and a focused cell Accepted; row numbers superseded by 0044 Every surface shows rows in one DataGrid: row selection plus a focused cell, stable row slots, a row number column, values as text and a row detail pane.
0028 A window holds several sessions in one tab view Accepted A WorkspaceShell per window shares one tab view among its sessions, each with its own workspace; the sidebar is a tree of the saved connections with each open session's schemas and tables.
0029 Images from the database decode in glycin's sandbox Accepted Row Details decodes a value's picture with the glycin crate 3.x, in a sandboxed loader process, never with GTK's in-process loaders.
0030 A query tab's database, and another database as a session of its own Accepted; dropping a sibling's database amended by 0034 A query tab's own editor session moves to its database through the driver, or opens there where the engine binds it at connect; another database the window shows is a sibling session with its own workspace and sidebar row.
0031 DuckDB 2.0, writing files DuckDB 1.x reads Accepted duckdb 1.20000.1 compiles DuckDB 2.0.0, and every database opens with storage_compatibility_version = 'v0.10.2' so new and attached files stay readable by DuckDB 1.x.
0032 The connection list is the library's tree in a list view Accepted The picker and the window's tree show groups nested and in the library's order from one outline keyed by id, with Favourites and Recent sections in the picker, drag and drop, and a menu item for every move.
0033 No compatibility with pre-release states Accepted Every app-owned format starts at version 1 with no upgrade step and the history schema is one migration; nothing reads what a build before the first release wrote.
0034 Dropping a database the window holds open Accepted Drop is never offered for a session's own database; a sibling is closed after its prompts before the connection drops its database; a session whose database is gone parks.
0035 Flatpak access to local database sockets Accepted The manifest grants /run/postgresql and /run/mysqld read-only, so PostgreSQL, MySQL and MariaDB sockets reach the sandbox; /tmp and /var/lib/mysql stay out.
0036 A query tab edits the one result of its run, through the table tab's save Accepted One tracker per query tab under its tab id, held by the run's one editable result; saves go through the window's connection with Confirm Writes, history and row guards, and the statement runs again after a save.
0037 When the MySQL CA bundle goes Accepted sqlx #4044/#4045 add rustls-platform-verifier features, not a caller's ClientConfig; the bundle goes once sqlx's own TLS passes system-trust, extra-CA and name tests against MySQL.
0038 Preferences > Account, the device limit dialog, offline files and the license ask Accepted; the Features section superseded by 0042 The page shows the plan and features from the entitlement and the teams and devices from /v2; over the limit a dialog removes a device in place; an offline file works signed out; from the 30th day of use without a license a toast asks, then every 90 days.
0039 Usage data through posthog-rs, on by default as on macOS Accepted posthog-rs's blocking client sends the clients.md events to the key -Dposthog_key gives; on by default, off from Preferences > General > Privacy; no key, no client.
0040 The copyright file describes the source tarballs Accepted debian/copyright covers every crate cargo vendor ships and the code crates carry from other projects, from cargo metadata and each crate's license files; the binary inventory keeps the About dialog, the notices and the RPM License tag.
0041 Beta repositories, a Flatpak repository of our own, and packages on every GitHub release Accepted; the run that builds a tag's packages amended by 0043 A beta tag goes to a beta PPA, COPR project and Flatpak repository that testers add beside the stable ones; a signed Flatpak repository on R2 serves every other distribution with updates; every GitHub release carries the tested .deb and .rpm and a Flatpak bundle that updates from that repository, with SHA256SUMS.
0042 Preferences > Account lists only the features TablePro for Linux has Accepted Features lists only the codes whose platform flag is on and hides when none is; the licensing links move to a License group; the copy speaks of the plan and the license, never of a feature missing on Linux.
0043 A tag publishes what its commit's dry run built Accepted A tag's run takes the tarballs, template, source packages, packages and unsigned Flatpak repositories from the green dry run of its commit, re-signs only the Flatpak, checks the rest against the dry run's SHA256SUMS, and fails before publishing when there is no such run.
0044 Row numbers share the grid’s scrolling and input Accepted A passive gutter shares the main grid’s selection and vertical adjustment inside one scroller; native input stays in the main view.

0011 is not used. It was reserved for the DDL decision, which was recorded as 0010, and docs cite ADRs by number, so the later ones keep theirs.

Adding an ADR

  1. Take the number after the highest one. Never reuse a number, even a deprecated ADR's.
  2. Copy the format above into a new file. Use a dash-separated lowercase title slug.
  3. If it replaces an earlier decision, set the earlier ADR's Status to Superseded by 000N, or Accepted; <part> superseded by 000N, in the same PR.
  4. Open a PR. ADRs go through the same review as code.
  5. After merge, link from the index above.