Rides the same arrival transition the visit log is built from, so "arrived" has
exactly one definition in this service rather than two that could disagree.
- notify_on_arrival (default off) is the "if enabled" half: push me when someone
gets home. announce_arrivals (default ON) is a separate per-person opt-OUT of
being announced, for anyone who doesn't want their comings and goings
broadcast. The asymmetry is deliberate — if both defaulted off, ticking
"notify me" would look broken until everyone else opted in too.
- Per-person notify_topic falling back to NTFY_DEFAULT_TOPIC. Topics are
deduplicated, or a five-person household sharing one topic would get five
identical pushes per arrival. The arriver is never told about themselves;
subscribers who are away still are, since that's most of the point.
- The first sample after startup notifies nobody and establishes a baseline
instead — otherwise a restart after a gap would fire "X just got home" for
everyone already on the sofa. Costs one missed notification in that window.
- Face-recognition arrivals say "was just recognised at home", not "just got
home" — the signals aren't equally reliable and the reader should know which.
- Pushes are sent outside _db_lock and isolated from each other, so a hanging
ntfy can't stall request handling and one bad push can't swallow the rest.
- POST /people/<id>/test-notification, because the alternative way to find a
typo'd topic is to wait for someone to walk in and notice nothing happened.
identity itself never touches the WAN — it POSTs to the ntfy already in this
stack. Whether the push reaches a phone that's AWAY is a network question, and
docs/network-integration.md's existing answer (WireGuard in, never a
port-forward) applies unchanged; iOS can't do this locally at all, since ntfy's
iOS app needs APNs and therefore an upstream relay. Documented as a table.
Also fixes two pre-existing bugs found while wiring this up: chores' template
pointed IDENTITY_URL and NTFY_URL at 127.0.0.1, which inside that container is
the container itself. chores would have reached neither identity nor ntfy, and
done nothing at all — silently, since both paths fail soft by design. Deployed
chores.env files still carry the old values and need editing by hand.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>