- Gate both Redis ingestion paths (canonical + legacy) behind separate
default-off flags (GROW_EVENTS_REDIS_ENABLED, LEGACY_SERVICE_REDIS_ENABLED).
The redis module is never imported when both flags are off.
- Sever legacy URL cascade: interview/roleplay/resume/courses Redis URLs
resolve ONLY from their own explicit env vars, never from REDIS_URL or
GROW_EVENTS_REDIS_URL.
- Export resolveRedisConfig() pure resolver for testability.
- Fix onboarding signal ID from 'onboarding.completed_baseline' to
'onboarding.completed' (registry-valid in all v2 formula JSONs).
- Ensure interview/roleplay completed events emit at least a single
completion signal when session_count/scenario_count is absent (default 1).
- Extract computeStreakFromDays() into streak-utils.ts (pure, no DB dep)
with defensive dedup so duplicate days never inflate streaks.
- Add focused tests: redis-gating, signal-registry membership, count
fallback, streak policy (current/longest/duplicate/gap/recovery/7-day),
service-ingest projector behavior.
- typecheck: 80 pre-existing errors unchanged, 0 new.
Brings the backend from a scaffold to a working end-to-end MVP — real auth,
persistent actor registry, Anthropic tool-use loop in the Grow Agent, and
per-user Gitea+OpenCode provisioning. Also adds the client-facing
architecture diagram under docs/architecture.html.