Settings change history
Every settings change is kept in a durable history that says who changed what, when, and what the value was before and after. Secrets are never stored, navigation bookkeeping is never recorded, and the history can be read back with one command.
What it answers
A setting is easy to change and hard to explain afterwards. The config file keeps only the newest value, and a log line rarely says who made the change. The settings history answers the question that comes up days later: what changed, when, and who changed it — whether the change came from the settings window, an agent over the command line, or a migration during boot.
What a record holds
- When the change landed.
- Who made it — the surface (the settings window, a session, an external caller, or a migration) and, for a session, which one.
- Which keys changed, and how many.
- A bounded before-and-after for each changed key, so a value is readable without the row growing without limit.
What is deliberately left out
- Secrets are never stored. API keys, tokens and sealed values are recorded as
<redacted>, and personal recipient lists are recorded as counts only. The history can be read without exposing a credential. - Navigation bookkeeping is never recorded. The pair of "which session was I on" values, and the tour one-shot stamps, change many times a minute; recording them would push every real change out of the window.
- A save that changes nothing records nothing.
How far back it goes
The history is a bounded rolling window: the newest 5,000 changes. Rows from system-level writers are separately capped at 500, so background activity can never crowd out the changes a person made. When the window is full, the oldest rows fall away first.
Reading it
GET /settings/history # newest first
GET /settings/history?key=theme # only the changes that touched one key
GET /settings/history?limit=20
The route is a read over the standard CLI authentication, and it never changes anything. limit is clamped between 1 and 500, and the response also carries droppedCount — the number of records dropped while the database was not yet open, so a gap in the history is visible rather than silent.
Where it comes from
A record is written on the one settings write path, so any change made through the app, the CLI, or a boot migration is covered. The boot-migration records name the migration that made the change, which is how an unexplained value after an update is traced to the migration that set it.