Skip to content

pwa(background): design a safe deferred-work queue for offline/background tasks without data-loss claims #488

Description

@qnbs

Parent

Part of #478 — PWA first-class excellence/hardening.

Product opportunity

PWAs can defer selected work across connectivity/lifecycle boundaries using Service Worker events and, on supporting browsers, Background Sync-like capabilities. For WorldScript this is useful only for idempotent, non-authoritative deferred work.

The browser must never be treated like an always-running native daemon. The differentiator is instead: queue safe work locally, continue writing immediately, and finish/retry opportunistically when the platform allows.

Suitable candidate tasks

Potentially appropriate:

  • retrying non-sensitive deployment-independent asset fetches;
  • completing explicitly requested model/artifact downloads where browser APIs/lifecycle support it;
  • rebuilding regenerable indexes after foreground return;
  • deferred local housekeeping;
  • optional collaboration/network synchronization only if its own protocol is idempotent, encrypted and conflict-safe;
  • retrying explicitly user-requested remote operations whose API semantics support idempotency.

Tasks that must NOT depend on background execution

Do not make background APIs responsible for:

  • authoritative manuscript autosave;
  • encryption migration commit;
  • key rotation;
  • only-copy backups;
  • destructive cleanup;
  • project schema migration finalization;
  • any operation whose absence would make acknowledged edits disappear.

Authoritative local saves must complete through the foreground/local storage contract independently of background scheduling.

Deferred-work journal

Create a small versioned local queue with fields such as:

id
kind
createdAt
attemptCount
nextEligibleAt?
idempotencyKey
payloadRef / bounded non-sensitive payload
state = queued / running / succeeded / failed / cancelled
lastErrorClass?

Do not persist API keys, raw manuscript payloads or sensitive provider request bodies in a generic background queue.

Sensitive workflows require their own deliberately designed encrypted queue or remain foreground-only.

Execution policy

User UX

Expose only meaningful state, e.g.:

  • “Model download paused — will continue when possible”;
  • “3 deferred tasks”;
  • “Retry now”;
  • “Cancel”.

Do not imply the browser guarantees execution after the app is closed.

Network truth

navigator.onLine is only a hint. Treat actual request success/failure as authority.

Handle captive portals, DNS failures, server errors, rate limits and offline transitions explicitly.

Battery/data awareness

For large optional downloads:

  • user initiates them;
  • show size;
  • allow pause/cancel;
  • do not consume metered/mobile data silently;
  • where network/battery hints are unavailable, use conservative UX rather than pretending certainty.

Security/privacy

  • Service Worker queue cannot become a plaintext manuscript spool;
  • no provider secret in generic queue records;
  • validate task kind/payload before execution;
  • external share/protocol inputs cannot enqueue privileged work automatically;
  • bound queue size/attempts to prevent storage/CPU abuse;
  • redact logs.

Tests

  • API unavailable fallback;
  • offline→online;
  • browser closes before task executes;
  • task runs twice;
  • service worker updates with queued tasks;
  • multiple clients contend;
  • permanent vs retryable failure;
  • cancellation;
  • quota pressure;
  • malformed queue record;
  • large download interrupted;
  • user returns before background execution.

Acceptance criteria

Non-goals

  • emulating a native background daemon;
  • moving autosave into Service Worker background sync;
  • storing sensitive cloud requests in plaintext queues;
  • silently consuming bandwidth;
  • making background APIs a prerequisite for offline-first writing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions