* refactor: single _default_analytics() instead of duplicated default dicts
* fix: merge analytics defaults so an old/partial file doesn't KeyError on record
* test: analytics load merges defaults; record survives a partial file
* fix: only extract quotes whose closing quote matches the opening one
* fix: same mismatched-quote bug in the services search copy
* test: extract_quotes requires matching open/close quotes
* feat: publish all configured email addresses for reply-all exclusion
* fix: exclude all of the user's own addresses from reply-all, not just the active one
* test: reply-all excludes all of the user's configured addresses
* fix: match topic keywords on word boundaries, not substrings
* fix: apply word-boundary matching to topic example snippets too
* test: topic keywords match whole words, not substrings
* fix: extract full year in research query entities, not just the century
* fix: same year capture-group bug in the services search copy
* test: research query extracts the full year
* fix: drop over-broad 'cookie'/'copyright' low-quality markers
* fix: detect cookie/copyright boilerplate via phrases, not bare words
* test: keep research findings that merely mention cookies or copyright
* fix: fail fast when ChromaDB is unreachable instead of blocking startup
* fix: only cache the ChromaDB client after a successful heartbeat
* test: cover ChromaDB fast-fail preflight and no-cache-on-failure
* fix: populate window._myEmailAddress from the active email account
* fix: keep Cc recipients in reply-all when own address is empty or unknown
* test: cover reply-all recipient building (issue #360)
* fix: coerce null endpoint_url when delivering task result to a session
* fix: also coerce null model so the session insert satisfies NOT NULL
* test: cover task session delivery on an empty database