# Changelog All notable changes to **nuntius** are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.1.0] - 2026-09-29 ### Added - **A contact form backend in one static binary.** nuntius serves JSON form endpoints, delivers the submissions by SMTP and writes structured JSON logs. No Node, no Python, no Redis, no Postgres, and no third-party Go module beyond the first-party [`interpres`](https://sourcedock.dev/petrbalvin/interpres) TOML parser. - **Plain HTML form posts, no JavaScript required.** Every endpoint accepts `application/x-www-form-urlencoded` and `multipart/form-data` under the fixed field names `name`, `email`, `service` and `message` beside the JSON contract, and a form with `redirect_url` set answers every accepted submission, honeypot hits included, with `303 See Other` to that page. Failures stay machine-readable JSON. Body-parse rejections report `invalid_body` across every content type. - **Four form types**: `contact`, `feedback`, `newsletter` and `generic`. Each form has its own endpoint, rate limit, CORS allowlist, honeypot field and SMTP credentials, so one process serves many independent forms. - **Declarative validation policy.** A form's rules are configuration: `services` puts an allow-list on the optional `service` payload field of any form type (the empty value always passes, the `*` entry accepts any value, an explicit empty list accepts only the empty value), `require_name` and `require_message` move the free-text fields in and out of the checks, and `min_name_runes`, `max_name_runes`, `min_message_runes`, `max_message_runes` size them. A new form shape is a matter of `config.toml`, never of Go code. - **Newsletter double opt-in.** A signup stays pending and the subscriber receives a confirmation mail with a single-use link (`GET