The plan said "Hunspell pt-PT vendored like en-US". Measuring that first is what saved it: nspell expands affixes eagerly on construction, and European Portuguese's 1,340 rules over 44,257 stems want over a gigabyte of browser heap — ~340 MB for the first 12,000 entries, and no return at all after three minutes on the whole file. So the expansion runs once at build time instead: 1,039,058 forms, 2.66 MB gzipped, read by the same nspell in 842 ms. The obvious npm package would also have shipped the wrong language. Both dictionary-pt and dictionary-pt-br carry VERO, the Brazilian word list, so vendoring by name puts pt-BR spellings behind a pt-PT label — the drift SUGGESTIONS §3 warns about, arriving through the packaging where no reviewer can see it. The source is Projecto Natura's, and the build script now asserts the fault lines (receção in, recepção out) before writing anything. Spellcheck consults both dictionaries and flags only what both reject, which is the no-detector answer to a pair with no script boundary. The word card does the same in the other direction: "data" is a word in both languages, so Petal shows both readings rather than guessing which she meant. Writing the tests caught the one real bug — extendedAlphabet was a snapshot while correct/suggest read live, and her dictionary arrives after English, so every lookup would have resolved "cora" while the underlines were already right. Not done, and not claimed: the pack has not been read by a pt-PT speaker, and the Piper voice is deferred with the deploy. Claude-Session: https://claude.ai/code/session_016y6gyuHkQXPiEuW8RGQyua
🌸 Petal
A self-hosted, privacy-first writing editor with warm bubbly design, auto-save, and
local-LLM grammar/ESL suggestions. See petal-spec.md for the full
design spec and BUILD_PLAN.md for build progress.
Stack
Go + chi backend · SQLite (modernc, pure Go) · React + Vite + Tiptap + Tailwind v4 frontend ·
local vLLM/Ollama for AI suggestions. Single-binary deployment (frontend embedded via go:embed).
Local development
Two processes during development:
# 1. Backend (serves /api on :8080)
go run ./cmd/server
# 2. Frontend dev server (HMR on :5173, proxies /api → :8080)
cd web && npm install && npm run dev
Open http://localhost:5173 while developing.
Production build (single binary)
cd web && npm run build # emits web/dist (embedded by the Go binary)
cd .. && go build -o petal ./cmd/server
./petal # serves UI + API on :8080
Configuration is via environment variables — copy .env.example to .env.
Deployment
docker compose up -d --build # petal + the two Piper read-aloud sidecars
Behind Traefik on the parodia.dev VPS; vLLM stays on millenia over headscale.
Full runbook — first deploy, the LLM link, backups and restore — in
deploy/README.md.
Status
Early build, multi-session. Auth (Authentik OIDC) is next; Copyleaks plagiarism is
still parked — see BUILD_PLAN.md.