Wire fire-and-forget PostHog telemetry into every lifecycle hook
(session_start, stop, pre_compact, task_completed, user_prompt,
post_tool_use) matching the same project key, endpoint, and payload
structure used by the Python SDK, CLI, and OpenClaw.
- 10% sampling on ALL events to keep PostHog costs predictable
- Anonymous distinct_id: MD5(api_key) or SHA-256(username)
- Opt-out via MEM0_TELEMETRY=false
- Platform detection: Claude Code / Cursor / Codex
- Never sends user content, API keys, or raw identifiers
- 16 new tests (110 total passing)
- Sanitize project_id in onboard marker path (tr '/:' '--') to handle
slashes from env var overrides
- Fire on_pre_compact.py REST backup from PreCompact hook (was only
called from Stop hooks — crash before Stop = data loss)
- Source _identity.sh in on_stop_codex.sh and on_stop_cursor.sh so
MEM0_PROJECT_ID + API key fallback are available
- Note dream --schedule is Claude Code-only (Codex/Cursor lack schedule)
Tour was filtering on metadata.type which missed platform-categorized
memories. Rewritten to use get_memories (list all) + group by platform
categories field. All write hooks now use app_id as top-level entity
param instead of metadata.project_id. Branch stamped on every write.