A local-first app is only local-first if it survives a cut mid-request. Most survive a cut between requests. The difference is one open socket and one blocked write.
Start with the real failure. A user hits save while the network dies. Your code awaits a fetch that never resolves. The spinner runs for thirty seconds, then the offline banner appears.
That banner is a status indicator. It is not a fallback path. The fallback is the branch that must run when the promise never settles. You cannot review that branch by reading code. You have to make the wire fail on command.
A stub that fails on four ways
I do not test this against a real provider. Real providers fail politely and rarely. A stub fails on schedule, in the exact shape you choose.
Here is a stdlib-only HTTP stub, no dependencies, four modes.…