Service Lifecycle
SkillDev toolsVPN/proxy service lifecycle, coordinators, status, telemetry, handovers, and remembered policy.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Service Lifecycle skill
What this skill tells your AI
The instructions your AI receives, as published by po4yka/ripdpi in .agents/skills/service-lifecycle/SKILL.md and read by ahel’s review.
Overview
The Android services are thin shells now. Real lifecycle behavior lives in runtime coordinators plus ServiceStatusReporter, not in a single global app-state singleton.
Service work in this repo usually touches one or more of:
- start/stop orchestration
- remembered-policy replay
- handover-triggered restarts
- active-policy signature tracking
ServiceStateStorestatus, events, and telemetry- hidden first-seen-network
quick_v1diagnostics probes after successful handovers
Architecture
ServiceController.start(mode)
-> START_ACTION / STOP_ACTION intent
-> RipDpiVpnService or RipDpiProxyService
-> ProxyServiceRuntimeCoordinator / VpnServiceRuntimeCoordinator
-> ConnectionPolicyResolver
-> proxy / tunnel runtime start-stop-restart
-> ServiceStatusReporter
-> ServiceStateStore
Key Components
| Component | Location | Role |
|---|---|---|
ServiceController / DefaultServiceController | core/service/.../ServiceManager.kt | App entry point for start/stop |
RipDpiVpnService | core/service/.../RipDpiVpnService.kt | Android VPN service shell |
RipDpiProxyService | core/service/.../RipDpiProxyService.kt | Android foreground proxy service shell |
BaseServiceRuntimeCoordinator | core/service/.../ServiceRuntimeCoordinator.kt | Shared mutex, lifecycle state machine, stop/start/handover flow |
ProxyServiceRuntimeCoordinator | core/service/.../ProxyServiceRuntimeCoordinator.kt | Proxy-mode runtime orchestration |
VpnServiceRuntimeCoordinator | core/service/.../VpnServiceRuntimeCoordinator.kt | VPN-mode proxy+tunnel orchestration, resolver refresh, DNS failover |
ServiceStatusReporter | core/service/.../ServiceStatusReporter.kt | Maps runtime changes into UI-facing status/events/telemetry |
ServiceStateStore | core/data/.../ServiceStateStore.kt | Shared StateFlow / SharedFlow store observed by the app |
ConnectionPolicyResolver | core/service/.../ConnectionPolicyResolver.kt | Resolves live or remembered policy for the current network |
NetworkHandoverMonitor | core/service/.../NetworkHandoverMonitor.kt | Detects actionable network changes |
ActiveConnectionPolicyStore | core/service/.../ActiveConnectionPolicyStore.kt | Persists active policy metadata for diagnostics and telemetry |
State Management
interface ServiceStateStore {
val status: StateFlow<Pair<AppStatus, Mode>>
val events: SharedFlow<ServiceEvent>
val telemetry: StateFlow<ServiceTelemetrySnapshot>
fun setStatus(status: AppStatus, mode: Mode)
fun emitFailed(sender: Sender, reason: FailureReason)
fun updateTelemetry(snapshot: ServiceTelemetrySnapshot)
}
Runtime code should usually write through ServiceStatusReporter. That keeps status, events, and telemetry consistent.
Lifecycle Pattern
Start/stop logic is serialized inside the coordinator mutex:
suspend fun start() {
mutex.withLock {
val resolution = resolveInitialConnectionPolicy()
applyActiveConnectionPolicy(...)
startResolvedRuntime(...)
serviceRuntimeRegistry.register(session)
updateStatus(ServiceStatus.Connected)
startNetworkHandoverMonitoring()
startModeTelemetryUpdates()
}
}
The VPN coordinator adds:
VpnTunnelRuntimestartup and shutdown- resolver refresh via
VpnResolverRefreshPlanner - encrypted-DNS recovery via
VpnEncryptedDnsFailoverController
The proxy coordinator adds:
ProxyRuntimeSupervisorstartup and shutdown- proxy telemetry polling
- proxy exit handling and failure classification
Where To Make Changes
- Change Android service classes only for Android-framework concerns such as intents, foreground-service behavior, or
onRevoke(). - Change
ProxyServiceRuntimeCoordinatororVpnServiceRuntimeCoordinatorfor runtime orchestration. - Change
ServiceStatusReporterfor UI-visible status, failure, or telemetry projection. - Change
ConnectionPolicyResolver,NetworkHandoverMonitor, or resolver refresh logic when the behavior depends on network context. - Treat
ServiceTelemetrySnapshotandServiceEventas compatibility-sensitive contracts used by tests, diagnostics, and exports.
Common Mistakes
| Mistake | Fix |
|---|---|
| Patching only the Android service shell | Most lifecycle logic lives in the coordinator layer now |
Writing directly to ServiceStateStore from arbitrary runtime code | Prefer ServiceStatusReporter so fields stay coherent |
| Ignoring the coordinator mutex or lifecycle state machine | Start/stop/handover paths must stay serialized |
| Forgetting remembered-policy or handover side effects | Service restarts affect policy replay, telemetry, and hidden diagnostics probes |
| Treating telemetry fields as disposable | ServiceTelemetrySnapshot is part of the repo’s compatibility surface |
Signals
- GitHub stars
- 69
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
service-lifecycle- Source
- github.com/po4yka/ripdpi