All posts
Full Stack

Building for People Who Lose Signal

Aug 20265 min read

Before I worked on AI systems I spent a year on something with no AI in it at all, and it is still one of the hardest things I have built.

It is a field operations platform for a large power utility. Officers go door to door on overdue accounts. They record each visit, photograph the meter, log what happened, mark whether they collected. Around three hundred of them use it daily.

The requirement that changed everything was one sentence in an early meeting. Officers work in areas with bad signal, and sometimes none.

Why that one sentence is expensive

Think about what a normal web app does when you submit a form. It sends a request, waits, gets a response, then tells you what happened. Every part of that assumes a network.

Take the network away and the standard failure is a spinner, then a timeout, then an error, and the officer's work is gone. They are standing at a door with a photo they cannot upload and a form they cannot submit. Their options are to stand there hoping for a bar of signal, or to write it on paper and re-enter it later, which is exactly the process the app was meant to replace.

So the app cannot treat the network as a precondition for work. It can only treat it as something that happens eventually.

What that actually changes

This is the part I underestimated. Offline support is not a module you add. It changes how you think about every write in the application.

Submitting an attempt stops being one action and becomes two. There is recording it, which must always succeed and must happen locally. Then there is syncing it, which happens whenever the network allows, possibly minutes later, possibly after the phone has been locked and reopened.

Captures go into IndexedDB immediately. The officer gets confirmation right away, because from their point of view the job is done, and they are correct. A background process drains that queue when connectivity returns.

Once you accept that split, questions appear that never come up in a connected app. What does the officer see for something recorded but not yet synced, and how do you show that without making them anxious about whether their work counted. What happens if they close the app mid queue. What happens if the same record syncs twice because the first response was lost rather than never sent.

None of those are hard individually. There are just a lot of them, and they all follow from that one sentence in that one meeting.

The bit that surprised me

I assumed the hard part would be the sync logic. It was not. The hard part was the interface.

An officer needs to know, at a glance, whether their day's work is safe. Not through a settings screen. On the screen they are already looking at, in a way that reads instantly while they are standing outside somebody's house in the heat.

Getting that right took longer than the queue implementation, and it mattered more. A perfectly correct sync layer that officers do not trust results in them writing things on paper as a backup, which means you have built an expensive app and not removed the paper.

What it taught me about AI work

There is no model anywhere in this project, and it prepared me for AI engineering better than most things that do.

Both are about behaviour under conditions you do not control. A field app has to stay correct when the network is unreliable. A RAG system has to stay correct when the input is ambiguous, or adversarial, or about something outside what it knows.

In both cases the interesting engineering is not the happy path. It is deciding what the system does when the assumption underneath it fails, and making sure the person on the other end can tell which situation they are in.

© 2025 Bilal

All posts