Stability and versioning
Delistd follows semantic versioning from 1.0.0 onward (2.0.0 was the first major bump; see upgrading-to-2.0.md). A change that could break a working setup needs a major version (2.0). New features come in minor versions (1.x), and fixes and broker-list updates come in patch versions.
This page defines what counts as “a working setup”.
Stable: won’t break within a major version
config.yaml: every key in the schema in commands.md. A config that works on 2.0 keeps loading and behaving the same on every 1.x. New keys are optional and default to the old behaviour. Older formats still load and are rewritten in the current shape on the next save:- 1.x formats are migrated on first load (the original is kept as
config.yaml.1x.bak): the pre-0.11 top-levelprofile:block becomesprofiles: [{id: default}], and a free-textcountrybecomes an ISO code email.provideris no longer read; it drops out on the next savesmtp.use_tlscan be set explicitly- removed keys such as
pipeline.auto_confirmare ignored
- 1.x formats are migrated on first load (the original is kept as
- CLI commands and flags shown by
delistd --helpanddelistd <command> --help:- Names, arguments and meaning stay the same.
- Exit codes: 0 means success and non-zero means failure. Two flags use them deliberately:
update-brokers --checkexits 1 when an update is available, andaudit-brokers --fail-on-deadexits non-zero when a broker is dead. - A flag that’s retired keeps working, with a deprecation warning, until the next major version. (
monitor --once, retired in 1.x, was removed in 2.0;auto --onceis a different, current flag.)
history.db: upgrades migrate automatically on first run with no manual step. Downgrading to an older version after an upgrade isn’t supported.brokers.yamlformat (id,name,email,website,opt_out_url,region,category,notes, and the optionalcountries):update-brokerson any 2.x release fetches the current list frommain, so the format may only gain optional fields. Your ownoptions.broker_filelists stay valid.delistd export --format jsonfield names: fields may be added, never renamed or removed. Tools that process the evidence report can rely on them. 1.3 addedpipeline_set_byand theno_data_heldresponse and pipeline value; consumers should ignore values they don’t know.
Not covered: may change in any release
- The web UI: its pages, routes, HTMX endpoints and layout. It’s a local interface, not an API.
- Human-readable CLI output: tables, emoji and wording. Use
export --format jsonfor anything machine-read. - The removal-request templates’ wording. It’s improved as broker replies teach us what works.
delistd mcp(the MCP server, its tool names and arguments, and itsapprove/pendingsubcommands). It is experimental and outside the stability contract until it is promoted here.- The contents of the broker lists and of the mail-provider presets in setup. Presets only prefill fields, so a changed preset never alters a saved config.
- Hidden commands, such as
guides, the project website’s page generator. - Go packages under
internal/. Delistd is a program, not a library.
The Eraser → Delistd rename
The project was renamed from Eraser to Delistd in 2.3. It’s a minor release because every old name still works:
| Old | New | Status |
|---|---|---|
eraser command | delistd | Ships beside it, prints a rename notice on every run. Not available for Windows |
ERASER_* environment variables | DELISTD_* | Still read when the DELISTD_* one is unset |
ghcr.io/drumandbytes/eraser image | ghcr.io/drumandbytes/delistd | Both names get every release |
eraser Homebrew cask | delistd | The tap renames it, so brew upgrade moves you over |
eraser.drumandbytes.dev | delistd.dev | Redirects, path preserved |
go install github.com/drumandbytes/eraser/cmd/eraser@latest | go install github.com/drumandbytes/delistd/cmd/delistd@main | @latest never worked for 2.x under either path (Go ignores v2+ tags without a /v2 module suffix); under the old path it quietly installed v1.8.0. Use @main, Homebrew, Docker or a release download. There is no redirect for Go module paths |
Unchanged on purpose, because renaming them would orphan existing data: the ~/.eraser data directory (config.yaml, history.db), the eraser-data Docker volume, the launchd label com.drumandbytes.eraser.auto and systemd unit eraser-auto, and the encryption key derivation for stored passwords. An OS schedule installed before the rename keeps running through the eraser alias; re-run delistd schedule install to point it at the new name.
The next major release (3.0) removes the eraser command, the ERASER_* fallbacks and the old image name.
Before you upgrade
Release notes in CHANGELOG.md list every change. A major version’s notes include the steps for any manual migration.