# ADR-0011: Offline Caching and Sync Strategy

**Status**: Accepted **Date**: 2026-02-16 **Authors**: OSHUN Platform
Engineering, OSHUN Mobile Engineering, OSHUN Web Engineering **Reviewers**:
Domain Leads (Tara, Veritas, Nyx, Arete) **Supersedes**: N/A **Superseded by**:
N/A

## Context and Problem Statement

OSHUN must remain useful under intermittent or absent network conditions across:

- mobile (iOS/Android)
- website/PWA

Repository evidence shows strong but fragmented offline approaches:

- Tara web SW uses cache-first for static/audio and network-first for
  navigation.
- Veritas web includes service worker caching plus background sync queue
  patterns.
- Nyx PWA uses Workbox runtime caching (`NetworkFirst` API, `CacheFirst`
  assets/fonts/images) and local data persistence.
- Veritas mobile has offline article cache + sync queue + eviction logic.
- Tara mobile includes queue-driven download manager and storage controls.

We need one OSHUN policy for what to cache, how to sync writes, and how to
handle failures safely.

## Decision Drivers

- **Reliability** for core shell journeys during connectivity loss.
- **Consistency** across mobile and web/PWA behavior.
- **Safety** for write operations and conflict handling.
- **Performance** through predictable caching and prefetch policies.
- **Storage discipline** on constrained mobile devices.
- **Observability** for offline failure and recovery behavior.

## Considered Options

### Option 1: Network-Only Dynamic Data, Minimal Offline

**Description**: cache static assets only; all dynamic content requires network.

**Pros**:

- ✅ Lowest complexity
- ✅ Minimal cache invalidation risk

**Cons**:

- ❌ Poor user experience in weak connectivity
- ❌ Shell feels fragile in daily mobile contexts
- ❌ Misses key OSHUN reliability goals

### Option 2: Cache-First for Most Data

**Description**: aggressive cache-first for static and dynamic data.

**Pros**:

- ✅ Very fast perceived loads
- ✅ More content available offline

**Cons**:

- ❌ High staleness risk for time-sensitive data
- ❌ Complex invalidation and consistency issues
- ❌ Risky for personalized/entitled content

### Option 3: Hybrid Policy - Cache-First Static, Network-First Dynamic (Chosen)

**Description**: static assets use cache-first; dynamic personalized/API data
uses network-first with stale fallback; write operations queue offline and sync
later.

**Pros**:

- ✅ Strong balance of freshness and resilience
- ✅ Aligns with proven patterns already in repo
- ✅ Better control over stale-data risk
- ✅ Clear policy matrix for implementation and QA

**Cons**:

- ❌ Requires robust sync queue/conflict handling
- ❌ More moving parts than minimal offline strategy

## Decision Outcome

**Chosen option**: Option 3 - hybrid offline strategy.

### Normative Cache Policy Matrix

| Data Class             | Examples                          | Strategy                               | Notes                                     |
| ---------------------- | --------------------------------- | -------------------------------------- | ----------------------------------------- |
| Static shell assets    | JS/CSS/fonts/icons/manifest       | `CacheFirst`                           | Versioned, immutable cache keys           |
| Navigation documents   | shell routes                      | `NetworkFirst` + offline fallback      | return cached/offline page on failure     |
| Dynamic API read data  | home/activity/search/domain cards | `NetworkFirst` + stale fallback        | short TTL and explicit staleness metadata |
| Media                  | audio/images/star maps/downloads  | `CacheFirst` or managed download cache | entry caps + eviction required            |
| Auth/session endpoints | login/refresh/logout/entitlements | `NetworkOnly`                          | never served from cache                   |
| Mutating writes        | save/unsave, settings, check-ins  | queue offline + replay                 | idempotency required                      |

### Offline Write Queue Rules (Mandatory)

- Queue all non-destructive writes when offline.
- Each queued op includes:
  - stable operation id
  - operation type
  - payload
  - creation time
  - retry count
- Replay on reconnect with exponential backoff + jitter.
- Stop retry after max attempts and surface recoverable UI state.
- Queue processor must be idempotent-safe to prevent duplicate side effects.

### Conflict Resolution Rules

- Default strategy: server-authoritative merge for shared resources.
- Local optimistic state must rollback on authoritative rejection.
- For preference toggles, last-write-wins with server timestamp.
- For list toggles (save/unsave), de-duplicate by operation id and latest
  intent.

### Storage and Eviction Rules

- Define per-platform cache budgets and hard ceilings.
- Evict using policy by class:
  - media: LRU with bookmark/pin protections where applicable
  - feed/API cache: TTL-based purge + LRU fallback
- Display user-visible storage usage and allow manual cleanup actions.

### Prefetch Rules

- Prefetch only on adequate connection (prefer Wi-Fi, respect data saver).
- Prioritize:
  - continue/resume items
  - recently used domain surfaces
  - user-saved critical content
- Abort/limit prefetch when offline, low battery, or constrained network.

### UX and Product Rules

- Always show global online/offline state indicator in shell.
- For stale fallback content, show freshness timestamp.
- Provide explicit retry actions on failed fetch/sync.
- Never silently drop user write actions.

## Platform Implementation Guidance

### Mobile

- Use managed local stores (AsyncStorage/SQLite/file system) by data class.
- Use queued sync for write actions and media download manager for offline
  media.
- Persist sync queue across app restarts.

### Web/PWA

- Use service worker strategies per matrix.
- Use IndexedDB for offline data models and sync queues.
- Use Background Sync where supported; fallback to foreground replay.

### Existing Pattern Alignment

- Aligns with Tara web SW strategy for static/nav split.
- Aligns with Veritas web sync-manager queue model.
- Aligns with Nyx Workbox runtime caching patterns.
- Aligns with Veritas mobile offline cache + queue + eviction pattern.

## Implementation Plan

### Phase 1: Policy and Contracts

- Define `libs/oshun/offline` policy APIs and cache classes.
- Define queue item schema and sync result taxonomy.
- Define per-endpoint cache classification.

### Phase 2: Shell Integration

- Integrate global offline status and retry UX in shell.
- Integrate queue persistence and replay orchestration.
- Integrate stale-data indicators for fallback reads.

### Phase 3: Hardening

- Add cache budget enforcement and eviction diagnostics.
- Add conflict resolution integration tests.
- Add partial-outage and airplane-mode scenario tests.

### Phase 4: Observability

- Emit offline/sync events for dashboarding.
- Add alerts for queue growth, replay failures, and stale fallback spikes.

## Success Metrics

- Core shell routes render with meaningful fallback in offline mode.
- Queue replay success rate >= 98% after reconnection.
- No silent write loss for queued operations.
- Cache growth remains within configured budgets across target devices.
- Offline-to-online recovery latency meets UX SLA.

## Consequences

### Positive Consequences

- ✅ Stronger reliability for real-world network conditions.
- ✅ Consistent offline behavior across mobile and web/PWA.
- ✅ Explicit and testable policy for caching and sync.
- ✅ Better trust via visible state/retry/fallback behavior.

### Negative Consequences

- ❌ Higher implementation complexity (queue + conflict logic).
- ❌ More QA permutations (network/state/storage combinations).
- ❌ Ongoing tuning needed for cache and prefetch budgets.

### Risks and Mitigations

| Risk                                  | Probability | Impact | Mitigation                                      |
| ------------------------------------- | ----------- | ------ | ----------------------------------------------- |
| Stale data shown too long             | Medium      | Medium | TTL + staleness indicators + refresh triggers   |
| Queue replay duplicates writes        | Medium      | High   | idempotency keys + server dedupe                |
| Cache pressure on low-storage devices | Medium      | Medium | strict budgets + LRU + user cleanup controls    |
| Offline logic drift across platforms  | Medium      | High   | shared policy contracts in `libs/oshun/offline` |

## Security and Compliance

- Do not cache sensitive auth/session responses.
- Encrypt or protect sensitive local data where required by policy.
- Respect user consent/privacy settings in offline telemetry collection.

## Monitoring and Observability

Track:

- offline entry/exit events
- cache hit/miss rates by data class
- queue depth and replay outcomes
- conflict resolution outcomes
- fallback-render counts and stale age distributions

## Related Decisions

- `docs/adr/ADR-0014-oshun-web-and-pwa-strategy.md`
- `docs/adr/ADR-0016-shared-identity-and-cross-domain-session-model.md`

## References

- `apps/tara/web/public/sw.js`
- `apps/veritas/web/public/sw.js`
- `apps/veritas/web/src/lib/offline/sync-manager.ts`
- `apps/nyx/mobile/vite.config.ts`
- `apps/veritas/mobile/src/services/offline.ts`
- `apps/tara/mobile/src/services/download.ts`
