Releases: denzuko/mlisp
Releases · denzuko/mlisp
v0.8.0
What's Changed
- refactor: DRY admin dispatcher + bugs maildir consolidation by @denzuko in #81
- refactor: convert 4 cmd-* to define-admin-cmd macro (batch 1) by @denzuko in #82
- refactor: convert 4 cmd-* to define-admin-cmd macro (batch 2) by @denzuko in #83
- refactor: convert 8 cmd-* to define-admin-cmd macro (batch 3) by @denzuko in #84
- refactor: convert 5 cmd-* to define-admin-cmd macro (batch 4) by @denzuko in #85
- refactor: convert 3 cmd-* to define-admin-cmd macro (batch 5) by @denzuko in #86
- refactor: add define-admin-cmd* shadow macro for optional/rest args by @denzuko in #87
- refactor: two-phase flag parsing via parse-flags + define-admin-cmd+ by @denzuko in #88
- refactor: consolidate three cmd-* macros into one canonical impl by @denzuko in #89
- refactor: convert 2 more cmd-* to define-admin-cmd(+) (batch 6) by @denzuko in #90
- refactor: boolean flags + convert 3 more cmd-* (batch 7) by @denzuko in #91
- refactor: convert bugs-list, bugs-report to define-admin-cmd+ (batch 8) by @denzuko in #92
- refactor: convert export-ldif, export-csv to define-admin-cmd+ (batch 9) by @denzuko in #93
- refactor: convert set-option, add-namespace to define-admin-cmd(+) (batch 10) by @denzuko in #94
- refactor: convert cmd-init to define-admin-cmd+ (batch 11) by @denzuko in #95
- refactor: convert 3 zero-arg cmd-* to define-admin-cmd (batch 12) by @denzuko in #96
- feat: mlisp-procmail-gen -- s-expr DSL for procmailrc (#98) by @denzuko in #101
- ci: release workflow -- Linux tarball (working) + experimental pkgsrc + FreeBSD port skeleton (#97) by @denzuko in #102
- ci: fix pkg_create flags after first dispatch run (#97) by @denzuko in #103
- ci: promote linux-pkgsrc to stable, attach .tgz to releases (#97) by @denzuko in #104
- build: Makefile missing mlisp-bugs and mlisp-procmail-gen (build-all/install/clean/test-bats) by @denzuko in #105
- build: pattern-based Makefile rules for binaries and test suites by @denzuko in #106
- ci: automate GitHub Release creation on tag push (#97) by @denzuko in #108
- ci: fix linux-pkgsrc incorrectly skipping on branch dispatch (#97) by @denzuko in #109
- release: merge develop -> main (v0.8.0 candidate) by @denzuko in #114
- release: v0.8.0 hotfix -- restore #97 fixes on main by @denzuko in #118
Full Changelog: v0.7.0...v0.8.0
v0.7.0 — mlisp-bugs
Added
- mlisp-bugs: Debbugs-compatible email bug tracker (#69 #70)
- Maildir-as-database architecture: bug state derived by scanning the archive, exactly as Debbugs does
- Wire protocol:
<pkg>-bugs-submit@host,<pkg>-bugs-N@host,<pkg>-bugs-N-done@host,<pkg>-bugs-control@host - Control commands:
severity,tags,close,reopen,retitle,owner,forwarded,block,merge,quit - New binary
mlisp-bugs+ ASDF systemmlisp-bugs.asd - New admin subcommands:
bugs-add-package,bugs-list-packages,bugs-list,bugs-show,bugs-report,install-bugs-procmail
- 29 new BATS specs (
test_mlisp_bugs.bats)
Fixed
maildir-unique-name: reads PID from/proc/self/status(avoidssb-posixdependency); eliminates Maildir filename collisions on rapid sequential writesmaildir-messageswildcard:(make-pathname :name :wild :type :wild)fixes directory listing for files with hostname extensions
Test coverage: 445 tests (78 FiveAM + 367 BATS)
Full Changelog: v0.6.2...v0.7.0
v0.6.2
Added
- Self-hosted CI (
.github/workflows/): build-and-test workflow on a self-hosted runner - Send-email workflow: GitHub Actions workflow for outbound mail testing
- Migration guide: documentation for upgrading from prior versions
Full Changelog: v0.6.1...v0.6.2
v0.6.1
Added
- Quicklisp dist (
dist/): self-hosted distribution athttp://panix.com/~denzuko/dist/mlisp/distinfo.txt.make distgenerates from HEAD;make dist-uploadrsyncs to panix.com. Resolves the Debian packaging Quicklisp dependency — build scripts already conditionally load Quicklisp when present and fall through to bare ASDF. - contrib/mlisp.el: Emacs minor mode for mlisp administration. Shell-out backend (default): calls
mlisp-adminbinary directly. SLIME/vlime backend (mlisp-use-slime t): evaluates in connected SBCL image. 16M-x mlisp-*commands; completing-read on live list IDs;set-optioncompletion over all known keys.(mlisp-setup-keys "C-c m")binds all commands under a prefix key. - Makefile:
dist,dist-upload,dist-cleantargets.
Full Changelog: v0.6.0...v0.6.1
v0.6.0
Added
- Subscriber self-service commands (
src/requests.lisp):info,who(gated by:advertised),query(own settings),set mail|nomail|digest - BITNET-style archive search (
src/requests.lisp):search <keyword>,index,get <list> <N>against Maildir archives;:search-enabledper list - AllFix file distribution (
src/state.lisp):filescommand (FILES.BBS),mlisp-admin hatch(add file + announce);:distrib-filesstate tracking - Plugin filter pipeline (
src/filters.lisp)::pre-filterand:post-filterhooks; exit codes 0=pass 1=reject 2=hold 3=discard; space-separated filter chains;invoke-filter-chain/invoke-single-filter - Example filters:
etc/filters/spamassassin,etc/filters/clamav,etc/filters/gemini-archive,etc/unsubscribe-cgi/unsub.sh - mlisp-admin hatch: add file to distrib archive + announce to subscribers
- 27 new BATS specs (
test_mlisp_v06.bats+test_mlisp_filters.bats)
Fixed
string-trim " \t"trimming literaltfrom filter paths — fixed to(list #\Space #\Tab)(classic CL footgun:\tin a string is\+t)string-to-message: CRLF normalisation — strip\rbefore header parsingsb-posix:getpidreplaced with(random 99999)for standalone binary compat- Duplicate
windowed-increment-bounceremoved fromdiagnose.lisp - Forward declarations added to
distrib.lisp,metrics.lisp *compile-file-failure-behaviour*set to:warnin all build scripts
Test coverage: 416 tests (78 FiveAM + 338 BATS)
Full Changelog: v0.5.0...v0.6.0
v0.5.0
Added
- 9 subgroups:
:owner(forward-only),:security(embargo-capable),:commits(bot-post-only),:users(subscriber-writable) added to namespace model - Attachment policy:
:attachment-policy allow|strip|rejectper list - Subject keyword filtering:
:subject-allow/:subject-denypatterns; action:hold|:reject|:discard - Message sequence numbering:
:message-numbering tadds[list #NNN] - CSV subscriber export:
mlisp-admin export-csv; RFC 4180 with consent metadata - List management ops:
rename-list,copy-list,list-stats - Per-sender rate limiting: rolling 24h window;
:max-posts-per-day N; action:hold|:reject|:discard;state/ratelimit/cache - Embargo mode:
mlisp-admin embargo <list> <ISO8601>/release-embargo - DKIM-Signature stripped on redistribution (RFC 6376 §5)
- Authentication-Results preserved as
X-Original-Authentication-Results - RFC 8058 one-click unsubscribe:
List-Unsubscribe-Postwhen:unsubscribe-urlconfigured; HTTPS URI first inList-Unsubscribe - List-Id domain derived from
:drop-address(not hardcoded) - List-Archive and List-Owner headers when configured
- Complete manpages:
mlisp(1),mlisp-admin(1),mlisp-intro(7),mlisp-distrib(1);make mantarget - 37 new BATS specs (
test_mlisp_v05.bats)
Test coverage: 402 tests (78 FiveAM + 324 BATS)
Full Changelog: v0.4.0...v0.5.0
v0.4.0
Added
- SHA-256 hash contacts at rest:
:hash-contacts t; pure-CL SHA-256 - GPG require-signed:
:require-signed t;gpg(1)verification - DMARC rewrite:
:dmarc-rewrite auto|always|never; DNS_dmarc.TXT lookup; From-rewrite forp=reject/p=quarantinedomains - VERP bounce attribution: VERP-encoded envelope sender;
verp-decode - LDIF export:
export-ldif; RFC 2849groupOfNamesfor LDAP sync - Diagnosis:
mlisp-admin diagnose; health report by email or stdout - Double opt-in confirmation (
src/confirm.lisp): 32-char hex token; configurable expiry (:confirm-window-hours);:confirm-subscribe t|nil - Mass subscribe:
add-sub-batch(stdin or file,Name <addr>format) - Multigram bounce threshold: time-windowed (
:bounce-window-days); soft-bounce tracking; resets window on gap - 37 new BATS specs across two suites
Test coverage: 365 tests (78 FiveAM + 287 BATS)
Full Changelog: v0.3.0...v0.4.0
v0.3.0 — Feature release
mlisp v0.3.0
18 new features over v0.2.0. 275 tests (78 FiveAM + 197 BATS).
Highlights
Mail processing
- Inbound MIME stripping (HTML→text); outbound always 7-bit ASCII
- Daemon/auto-responder discrimination (Return-Path: <>, Precedence: junk/bulk, Auto-Submitted)
- Duplicate message detection (24h Message-Id ring buffer per list)
- Unsubscribe synonyms:
remove me,remove,signoff,opt-out
List types
- Moderated lists: held queue +
approve/rejectadmin commands - Digest mode: buffer posts, flush on demand or cron
- Exploder: list-of-lists fan-out with per-member RFC 2369 headers
- mlisp-distrib: file distribution channel binary
Headers & compliance
- RFC 2369 List-* headers (List-Unsubscribe, List-Subscribe, List-Post, List-Help)
- X-BeenThere, X-Mailing-List, Precedence: list
- BCC delivery: individual sendmail per subscriber, no address exposure
- MDN/RRT headers on command replies (RFC 8098/3461)
Privacy & security
- SHA-256 hash contacts at rest (pure CL, no FFI)
- GPG require-signed mode
- Prometheus metrics (OpenMetrics textfile, node_exporter compatible)
Operations
- XDG Base Dir (
~/.config/mlisp/) path resolution --home/--modeCLI flags- Maildir write-only spool for notmuch/mutt archiving
- procmail sample +
mlisp-admin install-procmail - 20+ mlisp-admin subcommands
ASDF systems
(ql:quickload :mlisp) ; core engine
(ql:quickload :mlisp-admin) ; management CLI
(ql:quickload :mlisp-distrib) ; file distribution
(asdf:test-system :mlisp) ; 275 testsBuild
sbcl --load build.lisp # bin/mlisp (11 MB compressed)
sbcl --load build-admin.lisp # bin/mlisp-admin
sbcl --load build-distrib.lisp # bin/mlisp-distrib
make test # all 275 testsv0.2.0 — CAN-SPAM / GDPR / CASL / LGPD compliance
mlisp v0.2.0
Full privacy-law compliance without requiring a web UI.
Compliance coverage
| Law | Mechanism |
|---|---|
| CAN-SPAM § 7704(a)(1) | Subject [list-id] tag on every outbound message |
| CAN-SPAM § 7704(a)(2) | Sender: and List-Id: headers injected |
| CAN-SPAM § 7704(a)(3) | Unsubscribe instruction in every message footer |
| CAN-SPAM § 7704(a)(5)(A) | Physical postal address in every message footer |
| GDPR Art. 7 / CASL S.6 | Subscribe records :subscribed-at + :consent-method in state.sexp |
| GDPR Art. 17 / LGPD Art. 18 | Unsubscribe removes address immediately |
| GDPR Art. 30 | state/audit.sexp append-only ROPA event log |
| GDPR Art. 13 | Privacy notice included in welcome message |
| CASL S.6(2)(c) | Opt-out honoured within same process invocation |
Changes from v0.1.0
- Compliance footer appended to every distributed message
- Subject line tagged
[list-id]on outbound - Subscriber records promoted to plists with
:subscribed-atand:consent-method state/audit.sexpappend-only event log for subscribe / unsubscribe / post-distributed / post-rejected- Three new footer templates (
{discuss,announce,devel}.footer.sexp) state/state.sexpextended with:postal-addressand:privacy-urlper list
Test coverage
- FiveAM unit tests: 53 (+13)
- BATS integration: 21
- BATS regression: 8
- BATS compliance: 23 (new)
- Total: 105 passing
v0.1.0 — Initial release
mlisp v0.1.0
Compiled standalone SBCL mailing list manager replacing the legacy smartlist suite.
What's included
- RFC 2822 email parser with CRLF tolerance
- Loop detection via
X-Loop-List-<Name>headers - Subscribe / unsubscribe / help command routing
- S-expression state engine (
state/state.sexp) pre-seeded with discuss / announce / devel lists - Routing to
denzuko+mlist-<list>@panix.comdrop addresses - troff -ms DSL compiled through
groff -ms -Tutf8 -P-c - Nine troff templates (welcome / help / goodbye × 3 lists)
MLISP_HOMEandMLISP_SENDMAILruntime env-var overrides
Test coverage
- FiveAM unit tests: 40
- BATS integration: 21
- BATS regression: 8
Build
make build # requires sbcl, groff
make test # requires bats, quicklisp