No signal existed for which onboarding flows users actually select or complete, making post-release prioritization entirely speculative.
The FlowEngine and WalkthroughController had no telemetry hooks. The five local-first-onboarding flows shipped with zero instrumentation.
OnboardingTelemetry interface (shared/…/flow/OnboardingTelemetry.kt) with onFlowChooserTap(flowId) and onFlowCompleted(flowId), plus a NoOpOnboardingTelemetry singleton as the default.FlowEngine with an optional telemetry constructor param (defaults to no-op). A startedFlowId field tracks the top-level flow across ChainTo hops so onFlowCompleted always names the flow the user actually selected, not an internal chain leg.WalkthroughHost resolves OnboardingTelemetry via koin.getOrNull() ?: NoOpOnboardingTelemetry, fires onFlowChooserTap on chooser tap, and passes the instance into FlowEngine.FirebaseOnboardingTelemetry in androidApp/ logging flow_chooser_tap and flow_completed events with flow_id parameter. A new androidModule registers it in Koin; KrillApplication loads it after the shared modules.chooser_tap + completed) is the minimum viable signal for any multi-step flow.OnboardingTelemetry interface in shared/ so all platforms can provide implementations without touching the engine logic. Non-Android platforms default to no-op via getOrNull.