With the network off
Every screen in the journey is a file written at build time, so there is nothing to fetch when you open one. That is what makes the offline story cheap rather than clever: a service worker keeps the pages you have already opened, and they were complete when they arrived.
What survives airplane mode
- Every screen you have already opened. Cached on the way past, served from the cache after that.
- The two entry screens, English and Hindi, which are fetched when the worker installs so there is always a way back in.
- Nothing you have not opened. Ask for a screen you have never visited while offline and you get the entry screen instead of a browser error page, which at least leaves you somewhere you can navigate from. Said plainly because the alternative is worse, and the next section is why.
Every claim in that list is executed on each build, not asserted: scripts/verify.mjs installs the worker, walks the journey, shuts the web server down, and requires the Verdict to still render with the same stamp, the same blocker count and the same coverage line as it had online. Emulated offline was tried first and thrown out — a service worker is its own network target, so its fetch ignores the emulation and every check passed by quietly reaching the network.
Why we do not download all of it up front
The whole site — 66 journey screens, 13 languages, the engine — is about 1.38 MB gzipped. Precaching it is four lines of code and it was written first. Then it was measured: on the EDGE connection this product exists for, roughly 20 kB/s, that is over a minute of somebody's data spent in the background on screens they will never open.
A service worker that makes the first visit worse to make a later visit faster is not an optimisation. It moves the cost onto the person least able to carry it. So the precache is the two entry screens and everything else is kept as you walk past it.
The gap, named
The worker is registered from the language pages. If you deep-link straight to a journey screen and go offline without ever having loaded a language page, nothing is cached and nothing works. One visit to any language page fixes it permanently.
The engine really does run in your browser
A verdict is a pure function of a case and a rule bundle, with no I/O anywhere in it, which is the reason it can run in a browser at all. The five engine files are copied to /kosh-engine/ verbatim — not bundled, not transpiled — alongside the rule bundle and the eight cases as JSON. About 189 kB raw, 54 kB gzipped.
No journey screen imports any of it. There would be no point: the verdict is already in the HTML, and loading 54 kB to recompute a number you can already read would be a cost with nothing on the other side. It is there so the claim can be checked, and CI checks it on every build by running the browser copy against the server's answer and requiring them to be identical.
What is not built
Form state is not written to IndexedDB. The specification asks for it, and there is no form whose state could be lost: /start has one field and this build has no EPFO login to submit it to, which that page says on its face. Persisting a field that goes nowhere would be code written to satisfy a checklist. It is recorded as a gap rather than faked.