Version cut 1.9.2: close the code review pass, bump the pin
The 2026-08-19 full-tree code review's fixes were sitting in Unreleased alongside in-progress, docs-only panel-redesign prep. Per development.md § Roadmap track, docs-only prep gets no version cut until its product stage ships, so the review-pass entries (all real code/behaviour fixes, plus migration 0010, the DMARC-zip and port-25 e2e additions) move to a new [1.9.2] section; the panel-redesign and preflight roadmap items stay in a fresh Unreleased. Also drops two duplicate CHANGELOG bullets (bcrypt cost, rate-limiter eviction) that restated an earlier entry verbatim, and updates every 1.9.1 pin reference (docker-compose image, README quickstart, guide.md, development.md's planned-cuts table, schema-migrations.md's migration-0010 row, roadmap.md's review-closure links) to 1.9.2. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+21
-21
@@ -5,22 +5,6 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
Review pass over `1.4.0`…`1.9.1`: port 25 no longer shares the submission
|
||||
milter chain, DMARC reports are validated before they are stored, and the auto
|
||||
rate limit is correct for a non-default level-1 window. Schema migration
|
||||
`0010` (index only). Upgrading is a tag bump.
|
||||
|
||||
A full-tree code review on 2026-08-19 (architecture, code quality, security,
|
||||
GUI, tests, documentation, AGPL compliance; 38 findings) produced most of what
|
||||
follows. Its four open items live in [roadmap.md](docs/roadmap.md); its working
|
||||
document is not part of the release.
|
||||
|
||||
### Changed
|
||||
|
||||
- README hero line and a **Positioning** block in `docs/product.md` record the
|
||||
tagline (`YOUR SMTP. YOUR RULES.`) and hero copy; the stamp subtitle stays
|
||||
`SELF-HOSTED SMTP RELAY`. `docs/assets/selfpost-proof.html` updated to match.
|
||||
|
||||
### Added
|
||||
|
||||
- Panel redesign, account e-mail and notifications: a user's e-mail is its own
|
||||
@@ -155,6 +139,21 @@ document is not part of the release.
|
||||
([docs/plans/preflight.md](docs/plans/preflight.md)) — instance-level
|
||||
infrastructure verification (rDNS, TLS, ports, HELO banner, proxy headers,
|
||||
DKIM socket, test email). Status: candidate.
|
||||
|
||||
## [1.9.2] - 2026-09-22
|
||||
|
||||
Review pass over `1.4.0`…`1.9.1`: port 25 no longer shares the submission
|
||||
milter chain, DMARC reports are validated before they are stored, and the auto
|
||||
rate limit is correct for a non-default level-1 window. Schema migration
|
||||
`0010` (index only). Upgrading is a tag bump.
|
||||
|
||||
A full-tree code review on 2026-08-19 (architecture, code quality, security,
|
||||
GUI, tests, documentation, AGPL compliance; 38 findings) produced most of what
|
||||
follows. Its four open items live in [roadmap.md](docs/roadmap.md); its working
|
||||
document is not part of the release.
|
||||
|
||||
### Added
|
||||
|
||||
- SQLite migration `0010_send_log_app_login_index.sql` —
|
||||
`idx_send_log_app_login_created_at`. The journal-milter counts an
|
||||
application's messages on every `MAIL FROM`, and the domain page computes
|
||||
@@ -170,6 +169,12 @@ document is not part of the release.
|
||||
survived three releases because the suite only ever exercised the flags-off
|
||||
path.
|
||||
|
||||
### Changed
|
||||
|
||||
- README hero line and a **Positioning** block in `docs/product.md` record the
|
||||
tagline (`YOUR SMTP. YOUR RULES.`) and hero copy; the stamp subtitle stays
|
||||
`SELF-HOSTED SMTP RELAY`. `docs/assets/selfpost-proof.html` updated to match.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The setup account's password is hashed at bcrypt cost `12` like every other
|
||||
@@ -199,17 +204,12 @@ document is not part of the release.
|
||||
guard; one check now returns a context-specific message for self-demotion.
|
||||
- Settings flash text now reflects what actually changed and only mentions
|
||||
session sign-out when the password changed.
|
||||
- Login/setup rate-limiter bucket eviction now prefers the nearest-expiry bucket
|
||||
and does not evict currently blocked buckets.
|
||||
- Help page/drawer links now use `SourceURL` (`{{.SourceURL}}/blob/main/docs/...`)
|
||||
instead of a hardcoded repository URL.
|
||||
- Help drawer close controls include accessibility attributes (`role="button"`,
|
||||
`aria-label`) for the scrim and close action.
|
||||
- Password hashing now uses explicit bcrypt cost `12` in settings/user password
|
||||
updates, instead of `bcrypt.DefaultCost`.
|
||||
- Test coverage expanded for DMARC map token injection rejection and email
|
||||
validation edge cases (ASCII/local-part/domain/freemail cases).
|
||||
|
||||
- **Port 25 no longer runs the submission milter chain.** `smtpd_milters` is
|
||||
now always overridden on `smtp/inet` — to the optional antispam milter, or
|
||||
to nothing. Previously, with `INBOUND_ANTISPAM_MILTER` unset, inbound mail
|
||||
|
||||
@@ -112,7 +112,7 @@ docker run --rm -d --name selfpost-try \
|
||||
-e SELFPOST_HOSTNAME=mail.local.test \
|
||||
-e PANEL_COOKIE_SECURE=false \
|
||||
-v selfpost-try-data:/data \
|
||||
ghcr.io/mixeme/selfpost:1.9.1
|
||||
ghcr.io/mixeme/selfpost:1.9.2
|
||||
```
|
||||
|
||||
**Get the setup URL** (pick one):
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
services:
|
||||
selfpost:
|
||||
image: ghcr.io/mixeme/selfpost:1.9.1
|
||||
image: ghcr.io/mixeme/selfpost:1.9.2
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}"
|
||||
|
||||
+3
-2
@@ -107,7 +107,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
||||
2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
|
||||
[§ Release image](#release-image)).
|
||||
|
||||
**Planned version cuts** (from pin `1.9.1`; adjust if semver changes mid-track):
|
||||
**Planned version cuts** (from pin `1.9.2`; adjust if semver changes mid-track):
|
||||
|
||||
| Stage | ID | Cut |
|
||||
|---|---|---|
|
||||
@@ -119,7 +119,8 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
||||
| 6 | panel-docs | `1.8.0` |
|
||||
| 7 | application auth IPs | `1.9.0` |
|
||||
| 8 | port-25 Postfix startup fix | `1.9.1` (PATCH) |
|
||||
| 9 | inbound-antispam-panel | `1.10.0` (planned) |
|
||||
| 9 | 2026-08-19 code review pass | `1.9.2` (PATCH) |
|
||||
| 10 | inbound-antispam-panel | `1.10.0` (planned) |
|
||||
|
||||
Docs-only prep (checklists in plans, no product code) uses the same per-step
|
||||
commit rule but **no** version cut until the next product stage ships.
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ cat ./data/setup-token
|
||||
#### Fixed image tag
|
||||
|
||||
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`),
|
||||
deliberately never `:latest`. The current pin is `1.9.1`. Intermediate
|
||||
deliberately never `:latest`. The current pin is `1.9.2`. Intermediate
|
||||
CHANGELOG sections (`0.2.0`…`0.6.0`) record development cuts from before that
|
||||
image was published. Pinning matters because of the backup version check (see
|
||||
[Full backup and restore](#full-backup-and-restore)): the panel binary's
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ listed above and none of them urgent: [csrf-tokens](#csrf-tokens),
|
||||
[template-data-typing](#template-data-typing),
|
||||
[structured-logging](#structured-logging) and
|
||||
[review-2026-08-followups](#review-2026-08-followups). What that review
|
||||
produced is in [CHANGELOG.md](../CHANGELOG.md) `[Unreleased]`; its own document
|
||||
produced is in [CHANGELOG.md](../CHANGELOG.md) `[1.9.2]`; its own document
|
||||
was removed once these four items carried everything still open, and stays in
|
||||
git history.
|
||||
|
||||
@@ -262,7 +262,7 @@ estimate: 3–4 hours.
|
||||
**Goal:** the leftovers of the 2026-08-19 full-tree code review that are too
|
||||
small to be roadmap items of their own. Everything still open from that review
|
||||
is in the table below; the rest of it shipped in
|
||||
[CHANGELOG.md](../CHANGELOG.md) `[Unreleased]`.
|
||||
[CHANGELOG.md](../CHANGELOG.md) `[1.9.2]`.
|
||||
|
||||
| Area | Item |
|
||||
|---|---|
|
||||
|
||||
@@ -23,9 +23,9 @@ Documentation.
|
||||
| Database file | `/data/selfpost.db` (bind mount) |
|
||||
| Compatibility | 1.x MINOR releases must boot a `1.0.0` data directory |
|
||||
|
||||
Last updated in **[Unreleased]** (`0010_send_log_app_login_index`); **1.9.1**
|
||||
Last updated in **[1.9.2]** (`0010_send_log_app_login_index`); **1.9.1**
|
||||
had no schema change. The release column below records the cut a migration
|
||||
shipped in — fill `0010`'s in at the next version cut.
|
||||
shipped in.
|
||||
|
||||
---
|
||||
|
||||
@@ -65,7 +65,7 @@ replace the embedded set (see [Planned 2.x squash](#planned-2x-squash)).
|
||||
| 7 | `0007_rate_limit_auto.sql` | 1.6.0 | DDL | `rate_limits.mode`, `auto_multiplier`, `auto_updated_at` |
|
||||
| 8 | `0008_dmarc_reports.sql` | 1.7.0 | DDL | `dmarc_reports`, `dmarc_report_records` |
|
||||
| 9 | `0009_application_auth_ips.sql` | 1.9.0 | DDL + data | `applications.auth_ip_restrict`, `auth_allowed_ips`; move legacy app `rate_limits.allowed_ips` into auth columns; clear those IPs on rate limits |
|
||||
| 10 | `0010_send_log_app_login_index.sql` | Unreleased | DDL | `idx_send_log_app_login_created_at` — app-scoped rate-limit counts and per-application send statistics were scanning the `created_at` range |
|
||||
| 10 | `0010_send_log_app_login_index.sql` | 1.9.2 | DDL | `idx_send_log_app_login_created_at` — app-scoped rate-limit counts and per-application send statistics were scanning the `created_at` range |
|
||||
|
||||
**Kind:** *DDL* — schema only; *data* — `INSERT`/`UPDATE` that must stay correct
|
||||
for operators upgrading from older 1.x images.
|
||||
|
||||
Reference in New Issue
Block a user