EarthSciIO offline-mode contract (v1)
Source of truth: spec/offline-mode.md
.
Deliverable (c) of esio-9nb.1. Status: normative.
Offline mode is what makes conformance deterministic and CI hermetic: the refinery and every conformance run touch no network. It is also the campfire C2 acceptance (“3 loaders return real arrays from cache, offline”).
1. Enabling
Offline is on when either holds:
- the Provider / opener is constructed with
offline = true, or - the environment variable
EARTHSCI_OFFLINEis set to a truthy value (1,true,yes, case-insensitive).
The explicit argument wins over the environment when both are present.
2. Semantics — cache-only, never the network
When offline:
- The
transportregistry is never consulted — no transport is constructed, no socket is opened, no DNS lookup is made, for any scheme (includingfile-as-download). - A read resolves purely against the
store: computekey = sha256(resolved_url); ifstore.get_blob(key)is present → decode and return it; the storedsha256_contentis the only integrity check. - A miss (blob absent for the resolved key) raises
CacheMissimmediately. It is never a silent empty result and never a fallback fetch.
offline read(resolved_url):
key = sha256(resolved_url)
if not store.exists(key): raise CacheMiss(resolved_url, key)
return reader.read_native(store.get_blob(key), ...)
CacheMiss MUST carry the resolved_url and key so a failure names exactly
which blob the corpus/cache is missing.
3. Conditional-GET / TTL revalidation is suppressed
The validation ladder in cache-format.md §4 is short-circuited offline: steps that need the network (conditional GET, TTL refresh of an incomplete period) do not run. Presence + stored content hash is sufficient. A stale-but-present blob is used, not refreshed — offline trades freshness for hermeticity by design.
4. Hermetic CI + conformance
- The conformance corpus (
conformance/corpus/cache) is a pre-populated$EARTHSCIDATADIR. Point a provider at it withoffline = trueand every golden case resolves from disk. - CI runs the whole suite offline → no network on the refinery, fully deterministic, reproducible on any machine.
- Live network fetches are a separate, opt-in path (
EARTHSCI_LIVE=1), one smoke test per auth realm, never in CI. Their cached results become new golden fixtures.
5. Cross-language requirement
All three tracks MUST implement identical offline semantics: same enabling
flags, same cache-only resolution, the same CacheMiss error on a missing key.
A corpus that resolves offline in Python MUST resolve offline in Julia and Rust
from the same cache/ directory — that is the whole point of the
shared cache key
.