The Network Monitor That Always Said "Online"
A Simple Request: Stop Copying Offline Logic
My task looked small: when there's no internet, show a friendly "No internet connection" screen on two surfaces of our Flutter app, the Journal and the Saved posts screen. My first version worked, but it worked the hard way. Each feature figured out "offline" on its own. The networking layer reports a request that never got a reply as statusCode == 0. In the Community module I carried an offline flag from the HTTP source to the page model (CommunityBookmarkPage.offline()), then to the repository, the view model state and finally the screen. That's five files for one boolean, in one module. My senior saw where this was going: every new screen would copy the same chain. The suggestion was a single connectivity event emitter in kernel_shell.dart, the host that connects our modular app together, with each module listening and deciding how to react.
Reading the Code Before Writing Any
Before adding anything, I searched for what already existed, and the answer was surprising. The kernel already had a ConnectivityService contract with a status getter and a changes stream, reachable as kernel.connectivity. Screens could already read context.status.network.isOnline. The EverTracker module was already subscribing to kernel.connectivity.changes to pause and resume uploads. On paper, the app had full connectivity awareness. In practice, none of it worked.
The Detector That Couldn't Detect
The only implementation was InMemoryConnectivityService, a stub that starts as "online" and never emits anything, and there was no connectivity_plus anywhere in the project. One comment in profile_sync.dart had already spotted the trap: it explained that the sync deliberately used a backoff timer, because subscribing to the stub "would look like a fix and do nothing." It got worse. AppHost created its own stub to feed context.status, and kernel_shell.dart created a second, separate stub for kernel.connectivity. Even with a real detector plugged into one of them, the two halves of the app could have disagreed about whether the phone was online. And the event system I was about to extend already had the slot ready: the generated event catalog listed a network emitter with Network.Online.Restored and Network.Offline.Detected events. Nothing had ever been built to fire them.
Fixing the Source, Then Splitting the Two Jobs
The fix started at the source. I wrapped connectivity_plus in a real ConnectivityPlusService inside packages/foundation. It starts as online so the first frame never flashes a false "offline", and it only emits when the status actually changes. main.dart creates exactly one instance and passes it to both AppHost and KernelShell. Then I wrote a small NetworkEmitter following the existing CalendarEmitter pattern and registered it next to the others in _buildEventEngine. The design question that mattered most was what an event is good for. Events fire on a change, so a screen opened after the connection dropped would never hear "offline". So the two jobs split. Deciding what to draw reads the current state (context.status.network.isOnline). Reacting to a change uses the event: both view models listen for Network.Online.Restored and reload if they're showing an error, and they remove that listener in close(). On the Community side, the old per-request offline flag in the data layer could then be deleted entirely.
The Lesson: An Interface Is Not an Implementation
The biggest lesson was that a clean interface can hide an empty implementation. Calls like kernel.connectivity.changes look trustworthy at every call site, and that's exactly why nobody noticed the stub behind them never fired. Turning it on also changed behaviour elsewhere: the journal's WireCache asks whether the device is offline before discarding expired data, so with real connectivity it now shows the last saved journal offline instead of a blank screen. That's what it was designed to do all along; the stub had simply been hiding it. So when a task says "add an event emitter", start by finding out where the signal comes from and whether anything real ever produces it. Making that source real, and having only one copy of it, did more for this feature than any amount of listener code on top of a fake would have.