Compare commits

..
2 Commits
Author SHA1 Message Date
mixandClaude Sonnet 5 1ee509dcab Version cut 1.9.3: close the panel-redesign docs prep, bump the pin
test / test (push) Canceled after 0s
CHANGELOG.md audited against the full commit history from the repo's
first commit (8ad56ed) through HEAD: version/date headings, entry
completeness, and technical claims against their diffs all check out,
no discrepancies found.

The Unreleased section (panel-redesign mockups, contract, and
decisions; preflight plan) is docs-only prep — development.md's own
rule would hold the cut until a product stage ships — but the owner
asked for a version cut now, so it becomes 1.9.3 (PATCH) and a fresh
Unreleased opens. Pin bumped in deploy/docker-compose.yml, README's
quickstart, guide.md, and development.md's planned-cuts table, which
also gains the new row (renumbering inbound-antispam-panel to 11).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 14:17:50 +03:00
mixandClaude Sonnet 5 7c8a98a1cf 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>
2026-09-22 13:22:22 +03:00
7 changed files with 39 additions and 29 deletions
+27 -19
View File
@@ -5,21 +5,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
## [Unreleased] ## [Unreleased]
Review pass over `1.4.0`…`1.9.1`: port 25 no longer shares the submission ## [1.9.3] - 2026-09-22
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, Panel-redesign prep, docs only: stage 1-2 mockups on all 33 screens, the
GUI, tests, documentation, AGPL compliance; 38 findings) produced most of what accepted header/type-scale/contrast corrections, the account e-mail and
follows. Its four open items live in [roadmap.md](docs/roadmap.md); its working inbound-delegation decisions, and the routes/quarantine/preflight roadmap
document is not part of the release. screens. Nothing in `internal/web` changes; the design stays `candidate`
(3/21) until the redesign itself ships as `2.0.0`.
### 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 ### Added
@@ -155,6 +147,21 @@ document is not part of the release.
([docs/plans/preflight.md](docs/plans/preflight.md)) — instance-level ([docs/plans/preflight.md](docs/plans/preflight.md)) — instance-level
infrastructure verification (rDNS, TLS, ports, HELO banner, proxy headers, infrastructure verification (rDNS, TLS, ports, HELO banner, proxy headers,
DKIM socket, test email). Status: candidate. 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` — - SQLite migration `0010_send_log_app_login_index.sql` —
`idx_send_log_app_login_created_at`. The journal-milter counts an `idx_send_log_app_login_created_at`. The journal-milter counts an
application's messages on every `MAIL FROM`, and the domain page computes application's messages on every `MAIL FROM`, and the domain page computes
@@ -170,6 +177,12 @@ document is not part of the release.
survived three releases because the suite only ever exercised the flags-off survived three releases because the suite only ever exercised the flags-off
path. 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 ### Fixed
- The setup account's password is hashed at bcrypt cost `12` like every other - The setup account's password is hashed at bcrypt cost `12` like every other
@@ -199,17 +212,12 @@ document is not part of the release.
guard; one check now returns a context-specific message for self-demotion. guard; one check now returns a context-specific message for self-demotion.
- Settings flash text now reflects what actually changed and only mentions - Settings flash text now reflects what actually changed and only mentions
session sign-out when the password changed. 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/...`) - Help page/drawer links now use `SourceURL` (`{{.SourceURL}}/blob/main/docs/...`)
instead of a hardcoded repository URL. instead of a hardcoded repository URL.
- Help drawer close controls include accessibility attributes (`role="button"`, - Help drawer close controls include accessibility attributes (`role="button"`,
`aria-label`) for the scrim and close action. `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 - Test coverage expanded for DMARC map token injection rejection and email
validation edge cases (ASCII/local-part/domain/freemail cases). validation edge cases (ASCII/local-part/domain/freemail cases).
- **Port 25 no longer runs the submission milter chain.** `smtpd_milters` is - **Port 25 no longer runs the submission milter chain.** `smtpd_milters` is
now always overridden on `smtp/inet` — to the optional antispam milter, or now always overridden on `smtp/inet` — to the optional antispam milter, or
to nothing. Previously, with `INBOUND_ANTISPAM_MILTER` unset, inbound mail to nothing. Previously, with `INBOUND_ANTISPAM_MILTER` unset, inbound mail
+1 -1
View File
@@ -112,7 +112,7 @@ docker run --rm -d --name selfpost-try \
-e SELFPOST_HOSTNAME=mail.local.test \ -e SELFPOST_HOSTNAME=mail.local.test \
-e PANEL_COOKIE_SECURE=false \ -e PANEL_COOKIE_SECURE=false \
-v selfpost-try-data:/data \ -v selfpost-try-data:/data \
ghcr.io/mixeme/selfpost:1.9.1 ghcr.io/mixeme/selfpost:1.9.3
``` ```
**Get the setup URL** (pick one): **Get the setup URL** (pick one):
+1 -1
View File
@@ -21,7 +21,7 @@
services: services:
selfpost: selfpost:
image: ghcr.io/mixeme/selfpost:1.9.1 image: ghcr.io/mixeme/selfpost:1.9.3
restart: unless-stopped restart: unless-stopped
environment: environment:
SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}" SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}"
+4 -2
View File
@@ -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 2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
[§ Release image](#release-image)). [§ 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.3`; adjust if semver changes mid-track):
| Stage | ID | Cut | | Stage | ID | Cut |
|---|---|---| |---|---|---|
@@ -119,7 +119,9 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
| 6 | panel-docs | `1.8.0` | | 6 | panel-docs | `1.8.0` |
| 7 | application auth IPs | `1.9.0` | | 7 | application auth IPs | `1.9.0` |
| 8 | port-25 Postfix startup fix | `1.9.1` (PATCH) | | 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 | panel-redesign prep (docs only, owner-requested cut) | `1.9.3` (PATCH) |
| 11 | inbound-antispam-panel | `1.10.0` (planned) |
Docs-only prep (checklists in plans, no product code) uses the same per-step 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. commit rule but **no** version cut until the next product stage ships.
+1 -1
View File
@@ -173,7 +173,7 @@ cat ./data/setup-token
#### Fixed image tag #### Fixed image tag
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`), `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.3`. Intermediate
CHANGELOG sections (`0.2.0`…`0.6.0`) record development cuts from before that 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 image was published. Pinning matters because of the backup version check (see
[Full backup and restore](#full-backup-and-restore)): the panel binary's [Full backup and restore](#full-backup-and-restore)): the panel binary's
+2 -2
View File
@@ -54,7 +54,7 @@ listed above and none of them urgent: [csrf-tokens](#csrf-tokens),
[template-data-typing](#template-data-typing), [template-data-typing](#template-data-typing),
[structured-logging](#structured-logging) and [structured-logging](#structured-logging) and
[review-2026-08-followups](#review-2026-08-followups). What that review [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 was removed once these four items carried everything still open, and stays in
git history. 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 **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 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 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 | | Area | Item |
|---|---| |---|---|
+3 -3
View File
@@ -23,9 +23,9 @@ Documentation.
| Database file | `/data/selfpost.db` (bind mount) | | Database file | `/data/selfpost.db` (bind mount) |
| Compatibility | 1.x MINOR releases must boot a `1.0.0` data directory | | 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 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` | | 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` | | 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 | | 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 **Kind:** *DDL* — schema only; *data* — `INSERT`/`UPDATE` that must stay correct
for operators upgrading from older 1.x images. for operators upgrading from older 1.x images.