C.W.K.
Stream
Lesson 01 of 04 · published

Decide Before You Send

~11 min · selection-before-send, rekindle-lesson, privacy, offline

Level 0Unlit
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"An offline request that never builds a remote call can't leak. That's not a promise — it's a shape."

The Rekindle Inheritance

Firekeeper's writing sibling, Rekindle, learned a hard rule about offline modes, and Firekeeper inherits it exactly: provider selection happens before a single byte leaves the process. The active connection mode is resolved into a concrete provider first; only then is a request built and sent. This sounds like a detail. It is actually the entire difference between real offline and offline theater.

Two Architectures, One Fatal Difference

Compare the two ways to structure a fallback. The fallback-on-failure design tries the remote call, and only routes locally if it fails — which means an offline-intended request has already attempted (or prepared) a network call before anyone checked. The selection-before-send design picks the provider from the chosen mode up front, so an offline request routes to the local provider and a remote call is never constructed at all. The first hopes nothing leaked; the second makes leaking structurally impossible.

Fallback-on-failure (theater):
  build remote call -> try send -> failed? -> now go local   # remote was attempted!

Selection-before-send (real):
  read chosen mode -> offline? -> build LOCAL call only       # remote never exists

Why 'Structural' Beats 'Careful'

You could try to make fallback-on-failure safe with careful checks — "only send if online, and definitely cancel before it goes out." But careful is fragile: one refactor, one race, one forgotten branch, and the remote call slips out. Selection-before-send doesn't rely on care. In offline mode the code path that builds a remote request simply isn't reached, so there's nothing to slip. When the safety property is a consequence of the control flow rather than a guard bolted onto it, you can't accidentally regress it.

Make privacy a shape, not a guard. A privacy property enforced by a check ('don't send if offline') can be defeated by any change that reaches the send without the check. A privacy property enforced by structure ('the offline path never constructs a remote call') survives refactors, because the dangerous code is never on that path at all. Prefer architectures where the unsafe thing is unreachable, not merely guarded.

Code

The provider is resolved from the mode before any request exists·swift
func cleanup(_ req: CleanupRequest, mode: ConnectionMode) async -> CleanupResult {
    // Resolve provider FIRST. The offline mode returns a local provider,
    // and no remote URLSession/curl call is ever built on this path.
    let provider: CleanupProvider = switch mode {
        case .localMiniOllama: OllamaMiniPippaProvider()   // localhost only
        case .pippaFullThisMac: CwkPippaProvider(.localhost)
        case .pippaFullTailscale: CwkPippaProvider(.tailscale)
    }
    // Only now is a request built — by a provider that already knows where it goes.
    return await provider.clean(req)
}
// There is no branch that 'tries remote, then falls back to local'.
// Offline can't leak because the leaking code is never reached.

External links

Exercise

Take an app that claims an offline or 'local-only' mode. Reason about whether its safety is a guard ('check, then maybe send') or a shape ('the send code isn't on the offline path'). Which refactors could break the guard version without breaking the shape version?
Hint
The guard version breaks whenever a change reaches the send without re-checking the flag — a new early-return, a moved condition, a race between the check and the send. The shape version has no send code on the offline path to break. That resilience is why 'unreachable' beats 'guarded' for anything privacy-critical.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.