Step 3/12 of docs/plans/inbound-antispam-panel.md.
The panel serves a second milter while the inbound relay is on
(internal/milter/inbound.go, socket INBOUND_JOURNAL_MILTER_SOCKET,
default /run/selfpost/inbound-journal.sock). build/postfix-config.sh
puts it last on port 25, after the optional antispam milter, with
default_action=accept; postfix-wrapper.sh waits for its socket. At
end-of-message it writes one inbound_spam_log row per recipient at an
inbound domain - other port-25 recipients (DMARC report addresses) get
none - and always accepts. With a filter attached it reads the verdict
from X-Rspamd-Action and X-Spamd-Result (action, score, up to six
weighted symbols, only what the patterns recognise, 255 bytes); without
one those headers are the sender's and are not read. The plan named
X-Rspamd-Score, which rspamd does not have.
The antispam compose fragment mounts rspamd/milter_headers.conf into
the sidecar so that it adds the two headers (checked in rspamd 3.11:
both routines exist and remove a sender's own headers of those names).
Store: InsertInboundSpam, IsInboundDomain.
Checked on the test server, uncommitted tree: go vet ./... ok,
go test ./... ok (22 packages), make e2e ok - the relayed message of
inbound_relay_delivers_and_refuses has its journal row (accept by
selfpost) and the DMARC report sent through the same listener has none.
Not yet seen in a real run: a verdict written by rspamd reaching this
milter. The e2e stand has no filter, and the test server's only inbound
domain has no upstream, so it accepts no mail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 2/12 of docs/plans/inbound-antispam-panel.md, the first migration
after the 2.0 baseline (2.0.1 was cut before it, as agreed).
0002_inbound_spam_log.sql adds inbound_spam_log (one row per recipient:
domain, client IP, envelope, subject, decision, engine, detail) with
indexes on created_at and (inbound_domain, created_at), and
inbound_spam_list (allow / deny entries, unique per list). DDL only;
decision, engine, list_type and entry_type carry CHECKs, as the
baseline does for its own enumerations. Nothing reads or writes the
tables yet.
Tests: TestBaselineSchema pins both tables and user_version 2;
TestOpenMigratesA20Database opens a file holding the baseline alone and
finds its user kept; TestInboundSpamConstraints.
go test ./internal/store/ ok; go vet ./... ok.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/preflight is /server/preflight and the retention setting is on /server/settings; the routes are renamed, so the plan no longer says once they are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan-only cut, owner-requested. The redesign goes first as 2.0.0 and
inbound-antispam-panel follows as 2.1.0 on the 2.0 baseline (migration
0002_inbound_spam_log.sql), built from the redesign's component kit so its
two screens are styled once. No product code changes.
Changed:
- panel-redesign plan: Component kit section and stage 0 (partials with
typed inputs in components.go, one panel.css, /server/components kit
page, acceptance before any page is restyled); staged checklist (5/27);
Health decided inside 2.0, queue pages left as old content in the new
shell.
- panel-redesign plan: Against resurrected pages - shrink-only
legacyPages ratchet in the guard tests enforced by CI, the outline
golden, the old-path test and a history-blob check, so an old template
from git history cannot pass as a redesigned page.
- roadmap: new candidate delivery-log-storage - the Delivery log box on a
message page is empty for anything older than the last daily rotation
because the lines are grepped from the current mail.log on each view
and never stored.
- development.md version table, image pin 1.9.4 in compose, README, guide.
Full detail: CHANGELOG.md (1.9.4).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Added:
- SQLite migration `0010_send_log_app_login_index.sql` —
- DMARC aggregate reports are accepted as **zip** as well as gzip or plain XML
- e2e: `checkPort25ConfigCombinations` regenerates the Postfix configuration
Changed:
- README hero line and a **Positioning** block in `docs/product.md` record the
Fixed:
- The setup account's password is hashed at bcrypt cost `12` like every other
- Login/setup rate limiter: protecting blocked buckets from eviction is now
- `postqueue -p` output is bounded to 4 MiB (the timeout alone left the size of
- [schema-migrations.md](docs/schema-migrations.md): the schema section was
- postqueue reader is now time-bounded: `postqueue -p` runs under a 5-second
… (11 more in CHANGELOG)
Changed:
- [roadmap.md](docs/roadmap.md) now carries everything the 2026-08-19 code
- Extracted `internal/configsafe` — the empty-value and forbidden-character
- Build, deploy and migration comments no longer cite the archived
- Dropped the `parseDomainRateLimitForm` / `parseAppRateLimitForm` pass-through
- Extracted shared helpers: `internal/atomicfile` (atomic temp-write+rename) and
… (7 more in CHANGELOG)
Removed:
- Unused legacy asset `docs/assets/icon.png` (superseded by the four brand SVGs
- Plan documents for already-shipped features: `domain-stats-auto-ratelimit`,
Full detail: CHANGELOG.md (1.9.2).
Port-25 Postfix startup when inbound relay, DMARC ingest, or the inbound antispam milter are enabled. Schema-migration reference and roadmap plans for inbound antispam and quarantine. Upgrading from 1.9.0 is a tag bump; no migration.
Added:
- [docs/plans/inbound-antispam-panel.md](docs/plans/inbound-antispam-panel.md) —
- [docs/plans/inbound-quarantine.md](docs/plans/inbound-quarantine.md) — candidate
- [docs/schema-migrations.md](docs/schema-migrations.md) — living reference for the
Changed:
- [docs/roadmap.md](docs/roadmap.md) — `inbound-antispam-panel` (agreed, 1/12)
- [docs/development.md](docs/development.md) — plan checklists may override
- [docs/development.md](docs/development.md), [docs/roadmap.md](docs/roadmap.md),
Fixed:
- `build/postfix-config.sh`: enabling inbound relay, DMARC ingest, and/or the
Full detail: CHANGELOG.md (1.9.1).