Stage 0, step 2. The guards land before any template is restyled.
Guard tests (guard_*_test.go under internal/web) read their rules from the
accepted mockups instead of copying them - the Bulma subset and WIDTH_OK
from check.py, the shell's classes from build.py, the stylesheet from
theme.css + brand.css, the skeletons from outlines.json:
- TestPanelClassVocabulary, TestTemplatesUseComponents,
TestPanelPageStructure, TestPanelOutlinesMatchMockups,
TestRedesignedPagesLoadOnlyTheKit: hold every page that has left
legacy_pages.txt to its mockup, in source and as rendered.
- TestPanelCSSIsTheMockupStylesheet, TestPanelCSSContract: panel.css is
brand.css + theme.css rule for rule.
- TestOutlinePortMatchesCheckPy: the Go port of outline() agrees with
outlines.json on all 33 screens.
- TestLegacyRatchetMatchesTheEngine, TestVendoredAssetsArePinned,
TestStaticHoldsOnlyTheKnownAssets.
- TestRoutesFollowNavigation: the 2.0 route table, no old path answered,
no template link the router does not serve.
The kit tests are skipped while legacy_pages.txt lists @kit and the route
test while it lists @routes; both were run with the entry removed and fail
where expected (no kit yet, old route table).
.github/scripts/design-first.sh, run per commit in test.yml: a commit that
touches the mockups or a guard touches nothing else under internal/web;
legacy_pages.txt only shrinks; a changed template is not, whitespace aside,
any template from history. Exercised on a scratch clone for each case.
Plan: Enforcement and Against resurrected pages describe the guards as
built (the ratchet is a file beside the guards, not a list inside them).
Roadmap 7/27.
go test ./internal/web/...
ok github.com/mixeme/selfpost/internal/web
ok github.com/mixeme/selfpost/internal/web/auth
ok github.com/mixeme/selfpost/internal/web/handlers
ok github.com/mixeme/selfpost/internal/web/validate
ok github.com/mixeme/selfpost/internal/web/view
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A bounce could be recorded as a successful delivery. The log-tailer's
Fixed:
- A bounce could be recorded as a successful delivery. The log-tailer's
- Log-tailer resumes where it stopped instead of jumping to end-of-file on
- Level-2 rate limit no longer overshoots under concurrency: messages that
Changed:
- The project has a single public home: `github.com/mixeme/selfpost`. Codeberg
- Code comments no longer cite the archived specification. References like
- `docs/code-review.md` is gone. Its plan is finished — phases 0 (bar the
- `docs/architecture.md` gained a *Code layers* section: a diagram of
- Phase 1 doc/code hygiene (`docs/code-review.md`): removed ~30 stale
… (1 more in CHANGELOG)
Security:
- Pre-release security review (plan § D, model Fable, 2026-08-06): full pass
- `saslpasswd2` argv: the application login is now passed after a `--`
Added:
- Optional password encryption for the two secret-bearing downloads (plan
- Domain import accepts an encrypted export: the envelope is detected by its
- `selfpost-backup` writes encrypted archives and reads them back:
- `TestParseDelivery` covers the exotic mail.log shapes the review asked for
- docs: README *Encrypting a backup or export*; `docs/security.md` §
… (14 more in CHANGELOG)
Removed:
- docs: `security.md` — accepted risk «restore old backup revives session rows»
Changed:
- docs: `implementation-plan.md` trimmed to the sole open v1.x gate — pre-release
- docs: `architecture.md` — sessions (SQLite, idle renew, password change),
- docs: `development.md` — expanded e2e stack and `release.yml` matrix workflow.
- docs: `security.md` — accepted risk for send-log rows stuck at `queued` after
- docs: `roadmap.md` — optional send-log / `mail.log` follow-ups under v1.x tail.
… (10 more in CHANGELOG)
Full detail: CHANGELOG.md (0.5.0).
Initial feature-complete implementation of the v1.0 specification (phases 0-11 of `docs/implementation-plan.md`).
Added:
- Panel (Go, single static binary) with SQLite persistence, one-time
- Domain management with per-domain DKIM (RSA-2048, generated in pure Go) and
- Application (sender identity) management: SASL credentials via `sasldb2`,
- Full Postfix relay config generated from env at container start: SMTPS 465,
- Journal milter (pure Go, `go-milter`) recording every send to `send_log`;
… (6 more in CHANGELOG)
Full detail: CHANGELOG.md (0.1.0).