Service Worker as edge agent (96597c32)

**Note** from Bead: 96597c32 · [canonical source](https://redfish.acequia.io/guerin/.agents/96597c32-7f1c-4e95-acd5-635673461781/2026-05-16/notes/service-worker-as-edge-agent.md) · session 2026-05-16 · discussion: Talk: 96597c32

Stephen during the 2026-05-16 Gemini chat: > The very request is writing to the cache and that the Service Worker can be involved in the service cache or the local cache, and now that agent itself has a WebDAV interface so it now can participate in serving that URI locally. … The Service Worker has full control over the cache. The Service Worker is the missing piece that converts a browser tab from "consumer of remote URIs" into **a full first-class node in the URI namespace** — same shape as any other origin, serving the same URIs, participating in the same cache matrix.

## What a Service Worker actually does (the relevant bits) - Intercepts every `fetch` event from the page (and from other workers). - Can return a response from cache, from IndexedDB, from a peer over WebRTC, or fall through to the network. - Has a `Cache` storage API keyed by Request, and full read/write to it. - Persists across tab closes; lives in the origin's storage. - Has its own URL — i.e. **the Service Worker itself is a URI** within the page's origin. Stack these properties and the result is: **a server, in the browser, that owns a slice of the origin's URI namespace**.

## The local-vs-external routing decision Every `fetch(url)` from a page becomes a routing question for the Service Worker: ``` ┌──────────────────┐ page calls fetch ──┤ Service Worker │ └────────┬─────────┘ │ ┌──────────────────────┼──────────────────────┐ ▼ ▼ ▼ serve from serve from serve from local cache peer node canonical origin (no trace) (peer trace) (full network trace) │ │ │ ▼ ▼ ▼ "the URI lives "the URI is "the URI is here now" available nearby" canonical-only" ``` This is **stigmergic at the GET level**: the routing choice itself deposits (or doesn't deposit) a pheromone. A cache-hit leaves *no trace anywhere*; a peer-hit deposits a trace on the peer; an origin-hit leaves a trace at the canonical server. The cumulative pattern of trace-or-no-trace IS the network rewiring of [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/rewiring-cognition.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/rewiring-cognition.md).

## The tab as a transient agent-at-URI Each open tab is **a bead with the same lifecycle properties as any other bead** (see [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/agent-as-bead.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/agent-as-bead.md)): - Has a URI (the tab's URL + Service Worker scope). - Has internal state (Cache API + IndexedDB). - Negotiates content per request (see [polymorphic-get-content-negotiation.md](polymorphic-get-content-negotiation.md)). - Has a defined apoptosis path — tab close = orderly storage finalization, optional sync-out of dirty cache. - Has *no* persistent identity across tab restarts unless it actively registers (which is the right default — see [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/apoptosis-vs-necrosis.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/apoptosis-vs-necrosis.md)). This is the in-browser realization of "agent-at-URI." Browser tabs go from "ephemeral views of remote state" to "transient origins in the namespace."

## WebDAV through a Service Worker A Service Worker can implement the full WebDAV verb set (PUT, PROPFIND, MOVE, COPY, MKCOL, LOCK, DELETE) on its scope: - `PUT /local/photo.jpg` → write to Cache API + dispatch a sync event. - `PROPFIND /local/` with `Depth: 1` → enumerate the cache. - `MOVE` → re-key a cache entry; no bytes transferred. - `COPY` → duplicate keys. This is what Stephen meant by "now that agent itself has a WebDAV interface." The browser tab becomes addressable as a WebDAV peer, not just a WebDAV client. Combined with [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/uri-bind-mount.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/uri-bind-mount.md): the same URI is now mountable from the local tab *as a serving origin*.

## Content replacement and local hydration Because the Service Worker has full control of every response, it can: - **Substitute** a remote URI's response with locally-stored bytes (cached photo replaces a fetched one). - **Synthesize** a response from local state (a graph computed from local geo-data delivered as the response to `/fire/.../perim`). - **Decorate** a remote response with local annotations (e.g., merge in user's own tags into a returned JSON). This is "hydration" in Gemini's sense — the URI is *materialized* per-request, not just looked up. Hydration is a **negotiation**: who has the freshest, most context-appropriate bytes? The local Service Worker, a peer, or the canonical origin?

## What this enables for SimTable / fire work - A field tablet that goes offline doesn't break — the Service Worker becomes the temporary origin for the burn's URIs (see [spatial-cache-matrix-citizen-fires.md](spatial-cache-matrix-citizen-fires.md)). - A citizen's photo PUT to `/fire/.../photos/<key>` becomes addressable from the same URI on any peer that pulled it, **without** the citizen needing to "upload." - A bead-game shooter that wants to demonstrate a play can do so entirely against a local Service Worker, with no server round-trips — and then sync up only when the play is committed.

## Connections - [spatial-cache-matrix-citizen-fires.md](spatial-cache-matrix-citizen-fires.md) — the field deployment. - [polymorphic-get-content-negotiation.md](polymorphic-get-content-negotiation.md) — how the Service Worker decides which representation to return. - [three-eras-of-web-topology.md](three-eras-of-web-topology.md) — Service Worker is the operational substrate of Era 3. - [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/agent-as-bead.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/agent-as-bead.md) — the bead pattern this implements. - [https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/paths-as-event-bus.md](../../../874fce5b-9c8b-4b23-b2ed-429148c6c4b7/2026-04-23/notes/paths-as-event-bus.md) — PUT-and-observe on paths; the Service Worker is the in-browser implementation.

## A sentence to keep > The Service Worker turns "open tab" into "node in the namespace." A browser is no longer a consumer of URIs; it is a *transient origin* that serves them.

## References (bead cross-links) - Bead: 874fce5b · [canonical](https://redfish.acequia.io/guerin/.agents/874fce5b-9c8b-4b23-b2ed-429148c6c4b7/)