Skip to content

v4.1 — Engagement & Retention

Four small, independent reasons to come back tomorrow — a private journal note, real privacy controls, an honest pledge at signup, and a home-screen glance that never asks you to open the app.

Summary

Objectuve's Phase 4 roadmap item ("Engagement & Retention") had been open since the original PRD in April 2026, with most of its original five features shipped or superseded over time. Four gaps remained: users had no lightweight way to reflect on a check-in, no way to opt out of social features or hide from discovery, no upfront statement of the product's anti-addictive philosophy, and no way to check progress without opening the app at all.

v4.1 closed all four gaps as one milestone. Each is a small, single-user-facing surface shipped behind its own kill-switch flag, deliberately built with no shared schema and no ordering dependency between them — this let all four ship independently, in risk order (lightest first, native widgets last), and be rolled back individually if needed. The Daily Micro-Journal adds an optional one-sentence note to any habit check-in, feeding the Coach's pattern reflection without adding a required step. Privacy Controls give users two account-level toggles — go solo (hide community UI) and go private (drop out of search/discovery) — with server-side fail-closed enforcement on every surface, not just the UI. The Onboarding Philosophy Pledge is a skippable slide, early in signup, that states the anti-social-app stance in the user's own words before they've committed to anything. Home Screen Widgets are the biggest lift of the four: a native iOS WidgetKit and Android App Widget, fed by a custom Capacitor bridge, that show today's habits and current streak on the home screen — read-only, tap-to-open, the literal embodiment of "check progress without entering the app."

All four phases merged to the milestone integration branch gsd/v4.1-engagement-retention, then reached staging and production users via the master-flip PR on 2026-07-12 (tag v4.0.0), which promoted all four flags together per the delivery-isolation policy locked at milestone open.

Goal

Deepen the daily loop and give users reasons to come back — human- and coach-driven — while staying true to the anti-social-app philosophy (check progress without being pulled into the app). Four independent, single-user–facing features, each shippable on its own behind a per-feature flag.

Scope — What Shipped

  • habit_completions.note (nullable, ≤280 chars) + GoalTracking::CheckInHabit(note:) + HabitCompletionType#note, owner-scoped so a note never leaks via public/community/ally goal reads
  • HabitCard.vue opt-in note capture on check-in; Coach context (Ai::BuildCoachContext) folds recent notes into its existing reflections signal — no new AI read path
  • users.go_it_alone / users.private_mode columns + UpdatePrivacySettings interaction/mutation (self-only, fails closed)
  • search_users resolver excludes private_mode candidates; go_it_alone suppresses ally/community suggestion surfaces; both gated on the target user's own flag state
  • PrivacyControlsCard.vue in Settings → Privacy — "Go solo" and "Private profile" toggles
  • Shared onboarding values module ourStoryValues.ts; new skippable PhilosophySlide.vue at onboarding index 1, drawing from the same content as the public /our-story page — no copy drift
  • Custom Capacitor plugin WidgetBridge (Swift + Java) writing a habits+streak snapshot to iOS App Group / Android SharedPreferences, with an immediate widget-reload trigger
  • Native iOS WidgetKit (SmallWidgetView/MediumWidgetView) + Android App Widget rendering all 5 states (default, all-done, empty, stale, first-run) in both themes; whole-widget tap deep-links to the dashboard
  • In-app WidgetSettingsRow.vue + WidgetSetupSheet.vue — discoverable, fail-closed widget setup affordance in Settings
  • Four independent kill-switch flags: micro_journal_enabled, privacy_controls_v1, onboarding_pledge_enabled, home_widgets_enabled — each registered in featureFlags.ts and PostHog, fail-closed
  • New feature doc docs/features/home-widgets.md; updates to docs/architecture/data-models.md, GraphQL mutation docs, docs/product/onboarding-flow.md, docs/operations/mobile-builds.md, and docs/product/roadmap.md items 24/25/26/29

Phases

PhaseNameStatusPlansHighlights
1Daily Micro-JournalShipped1Optional note on check-in, Coach pattern reflection, owner-scoped privacy
2Privacy Controls — Go It Alone & Private ModeShipped1Two self-only account toggles, fail-closed search/suggestion filtering
3Onboarding Philosophy PledgeShipped1Skippable pledge slide sourced from existing /our-story copy
4Home Screen Widgets (iOS/Android)Shipped1Native WidgetKit + App Widget, custom shared-storage bridge, in-app setup

Key Decisions

  • Per-feature flags, not one umbrella flag — each of the four surfaces is a small, single-user blast radius with no shared schema, so each got its own kill switch (micro_journal_enabled, privacy_controls_v1, onboarding_pledge_enabled, home_widgets_enabled) instead of v4.0 Teams' single teams_enabled trunk-flag model.
  • Milestone integration branch, not flags-on-master — every phase PR merges to gsd/v4.1-engagement-retention, not master; a single master-flip PR at milestone close promotes all four flags to staging/production together. This is the house precedent from v1.10/v1.16/v2.x, chosen over v4.0's flags-on-master trunk model because "shipped" here means "merged to the integration branch, green, Vicki-closed" — staging/production exposure is deliberately deferred to one coordinated flip.
  • Journal privacy is enforced at the GraphQL type layer, independent of the Privacy Controls phaseHabitCompletionType#note is scoped to the completion's owner regardless of whether that user has go_it_alone/private_mode set. The two privacy guarantees don't depend on each other, by design.
  • Widgets are read-only in V1 — interactive check-in from the widget itself is an explicit, documented fast-follow, not shipped here. The widget's only interaction is "tap to open the app."
  • Custom native bridge over @capacitor/preferences — the widget-reload trigger needs a native call regardless, so a small custom Capacitor plugin (WidgetBridge) avoided a split-brain risk between a generic preferences plugin and the App Group/SharedPreferences the native widgets actually read from.
  • Android widget in Java, not Kotlin — avoided introducing a second native-Android build toolchain for one phase; RemoteViews, not Glance, for the same reason.

Requirements Coverage

23 / 23 requirements satisfied — JOURNAL 5/5, PRIVACY-J 1/1, PRIVACY 6/6, PLEDGE 5/5, WIDGET 6/6.

CategoryCountStatus
JOURNAL-*5All satisfied
PRIVACY-J1Satisfied
PRIVACY-*6All satisfied
PLEDGE-*5All satisfied
WIDGET-*6All satisfied (2 success criteria — real-device rendering — pending human verification; see Tech Debt)

Full requirements list and per-phase detail: v4.1-engagement-retention-ROADMAP.md on GitHub. No separate REQUIREMENTS.md file exists for this milestone — requirements are defined inline per phase in the ROADMAP.

Outcomes

Users can now: attach a private note to any habit check-in and have their Coach reference the pattern over time; opt out of social features entirely or hide from search/discovery, enforced server-side rather than just hidden in the UI; see the product's anti-addictive stance stated plainly during onboarding, skippable if they'd rather get started; and glance at today's habits and current streak from their home screen without opening the app — the clearest embodiment yet of the "check without entering" philosophy. All four features shipped to real users 2026-07-12 via the master-flip on tag v4.0.0 — see ionic_frontend/CHANGELOG.md [4.0.0] - 2026-07-12.

Tech Debt

  • (Phase 4) Real-device/simulator visual verification of both native widgets is still outstanding — no sandbox across the phase could render either widget end-to-end (a reproducible Android System UI ANR; broken iOS Simulator-toolchain layers). Every acceptance check came from source-level UI-SPEC tracing and Storybook capture of the in-app surfaces only. A human with Xcode/Android Studio + device access should confirm both widgets against Desi's 12 mockup PNGs before treating this as fully visually verified.
  • (Phase 4) First-run widget glyph diverges by platform (iOS gradient vs. Android flat circle) — no native primary/primary-light color-token pair was defined in the UI-SPEC. Needs a design confirmation.
  • (Phase 4) Android in-app setup step 2 copy ("Tap Widgets, then find Enkidu.") is an inferred variant, not verbatim spec text — needs sign-off.
  • (Milestone) The master-flip PR promoting all four flags to staging/production, and the resulting version tag, is deferred release work — not part of this docs close. Resolved 2026-07-12: master-flip landed on tag v4.0.0 (see ionic_frontend/CHANGELOG.md [4.0.0] - 2026-07-12).
  • 6a65f830a — feat(journal): Phase 1 — daily micro-journal note on check-in (#1271)
  • 20a07e1fc — feat(privacy): Phase 2 — go-it-alone & private-mode controls (#1281)
  • 1c48f186c — docs(privacy): data-models, GraphQL reference, roadmap for privacy controls (OBJ-1146)
  • c8f2645b3 — feat(onboarding): Phase 3 — philosophy pledge slide (#1300)
  • ec5af0e08 — feat(widgets): WidgetBridge native bridge + iOS App Group + Android widget skeleton (#1306)
  • 8d5689850 — feat(widgets): iOS WidgetKit + Android widget UI for all 5 states (#1321)
  • e2d0ac44e — feat(widgets): in-app "Add widget" affordance (Stage 4) (#1325)
  • d2e9bf3e4 — docs(widgets): Stage 5 docs pass for v4.1 Phase 4 home-screen widgets (#1331)

Last updated: 2026-07-18 Version: v4.0.0 (master-flip landed 2026-07-12)

Loading…