Files
counters/todo.md
T
Dimitrije DimitrijevicandClaude Opus 5.5 54f9626121 Add 80% limit warning, stop repeat notifications, fix review findings
Notifications:
- Warn once when a counter reaches warn_percent of its limit, through
  separate warn_*_url endpoints.
- Write ntf/ markers so a lost Redis reply cannot re-send a breach.
- Retry only when the request never left or the web app answered 429/5xx.

Fixes:
- Retry transactions Redis rejected; treat pool timeouts as definite.
- Install the signal handler before startup work.
- Stop logging the login suffix; redact notify URL credentials.
- Reject corrupt or empty CDBs, truncated hash tables included.
- Require a Sentinel password, refuse example placeholders, and default
  admin_addr to localhost.
- Normalise /counters domains, count on the arrival day, log rejections,
  hide internals in errors and exit 1 on a failed drain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 09:01:56 +01:00

55 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO — migadu_counters
State as of 2026-11-09. Review findings refer to `review/README.md`; the proof tests live in
`review/_proof_tests/` and should become regression tests as each item is fixed (round 1 and items
7–8 are mapped at the end of `review/_proof_tests/README.md`).
## Done
- Review round 1: #1–#6 (queue + 202, lenient validation + IDN, token logins, INCR with per-key
results and master re-read, CDB parse cache, mandatory token / port 5555), plus
`contrib/pull-domains.sh` and `counterctl --in/--out`.
- #7 plus-addressing counts against the mailbox (`domains.Mailbox`).
- #8 malformed CDB row is "not hosted" + warning (`domains.ErrMalformed`).
## Review round 2 — done 2026-11-09
#9-#17 fixed, plus the new findings from the 2026-11-09 review: repeat notifications after a lost Redis
reply, pool timeouts treated as unknown outcomes, login suffix in the counting log, no retry of rejected
transactions, `/counters` punycode, counter day taken from arrival time, CDB corruption checks, context
deadlines on Redis sockets, example config path and placeholders, non-zero exit on a failed drain.
Also added: the 80% early warning (`warn_percent`, `warn_*_url`) and per-counter notification markers.
## Open
- [ ] **Persistent / recoverable counting on Redis outage** (deferred from round 1, #4). A Redis stall
longer than a few seconds fills the queue and new requests are dropped (503, `dropped_total`).
Decide whether drop-and-alert is acceptable before building anything.
- [ ] **Exempt `mail_from` on `/in`.** An outside sender using `MAIL FROM:<support@migadu.com>` avoids the
recipient's incoming count, unless mizu rejects such senders inbound (not confirmed). Matches the
old Lua rule; decide whether to keep it.
- [ ] **Test gap.** Watcher tests can occasionally pass on a stale signal: make them wait for the
specific reload they triggered.
## Outside this repo (deployment prerequisites)
- [ ] **mailqueuer client**: `[counters]` section and a fire-and-forget POST `/in`|`/out` per recipient
inside the publish loop of `mailqueuer/internal/handler/ingest.go` (after a successful publish;
`/out` when `X-Auth-User` is set). Reply is `202 {"accepted":true}`; counted values only in the
counting log and `GET /counters`.
- [ ] **Ansible role** in `ansible-freebsd3`, cloned from `roles/rcptd`: user/group, `config.toml.j2`
(`auth_token` is mandatory, port 5555), rc.d script under `daemon(8)`, newsyslog entries for
`app.log`, `counting.log`, `pull.log`, templated `contrib/pull-domains.sh` +
`contrib/migadu_counters-pull.cron` (see `contrib/README.md`), agent host key acceptance,
firewall: mailqueuer hosts → :5555, service → Sentinel :26379/:6379 and admin.migadu.com:443.
- [ ] **migadu_web** `/api/limits` `D` branch (domain level); until then `notify.domain_url` stays empty.
- [ ] **migadu_web3 branch `limit-warning-notifications`**: review the warning email wording, merge and deploy,
then set `warn_org_url` and `warn_address_url`. Until then warnings stay off.
- [ ] **Firewall / monitoring**: `admin_addr` now defaults to localhost; set it explicitly if `/metrics` or
`/health` are scraped from another host.
- [ ] **Limits re-tuning**: outgoing is counted per recipient (Lua counted per message), so existing
`*/o` limits are stricter. Review before relying on `outgoing_limit_exceeded!`.
- [ ] **Retire stats-merger's quota module** once this service is the source (only fernrohr reads it).
- [ ] **Dependencies**: `golang.org/x/net` is pinned to v0.43.0 because the offline module cache had
it; run `go get -u golang.org/x/net && go mod tidy` with network access.