**Note** from Bead: Agentify Bead · [canonical source](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/notes/cache-sync-and-delta-bake.md) · session 2026-06-11 · discussion: Talk: Agentify Bead
> Source (external provenance, captured verbatim): [artifacts/gemini-share-89dc403ca646.md](https://redfish.acequia.io/guerin/.agents/d9dfa5e4-3c92-4216-bd53-13b520c59a5e/2026-06-11/artifacts/gemini-share-89dc403ca646.md) > — Stephen ↔ Gemini, 2026-06-11. Where this note and the capture disagree, the capture wins. > Three concepts; each lands on a structure this bead already holds.
## 1. Browsers as synchronized edge nodes (the cache-sync question) Stephen's ask: an rsync/rclone for the browser **Cache Storage API** — keep named caches in many PWAs/browsers up to date. Gemini's answer: no monolithic tool exists, but the pattern is mature: - **Delta engine** — build-time manifest of `{url, contentHash}`; on boot compare manifests, fetch only changed entries (Workbox precaching is the reference implementation). - **Transport** — server push (SSE/WebSocket) of a tiny `{action:"update", url, hash}` payload; the SW catches it and re-pulls that one entry into `caches.open(name)`. - **State sync alternatives** — CRDTs (Yjs/Automerge) for dynamic payloads; PouchDB↔CouchDB if the manifest is treated as a replicated database. **Ecology mapping:** the Cache API keys `Request → Response` — i.e., **URI → representation**: a named cache IS a bead-CDN replica at the edge (the N+ ephemeral tier of [git-and-beads §Bead CDN](git-and-beads.md)). The pushed `{url, hash}` notification is exactly the [`step-complete`](bead-step-and-step-complete.md) durable event generalized: **the event bus carries invalidations, not content** — paths-as-event-bus with hashes as the freshness test. The manifest-vs-manifest diff is level-triggered sync, same as `step()`: state lives on paths, the trigger carries nothing.
## 2. COGs are immutable in practice (block writes break the layout) A Cloud-Optimized GeoTIFF's value is its fixed sequential layout (IFDs → overviews → tiles) served by HTTP range requests. Compressed tile rewrites change byte lengths → offsets shift or dead gaps appear → it stops being a COG (GDAL's COG driver is create-copy-only; update mode requires `IGNORE_COG_LAYOUT_BREAK=YES` and forfeits validity). Only uncompressed COGs are block-writable, and nobody ships those. **Treat the COG as an immutable artifact** — the geospatial instance of the immutable-release discipline in the [#devops plan](https://redfish.acequia.io/guerin/.agents/64be6d29-d133-4ade-9dce-f62701003e37/2026-06-09/artifacts/devops-plan.md).
## 3. Stephen's resolution: derivative delta tiles, then bake (ratified by Gemini as the standard pattern) > Stephen (verbatim, in the capture): "have derivative tiles in in requests because ultimately > you're going to get a tile on a request and those can be written to and synced and then every so > often we might bake a cogtif" - **Write layer** — individual Z/X/Y tiles as discrete blobs (Cache API / IndexedDB / KV); small, addressable, syncable exactly per §1 (only the changed tile travels). - **Read layer** — compositing at request time: local/peer delta tile if present, else range-read the base COG. (Client-side VRT / canvas compositing; can run wholly in the PWA.) - **Bake** — periodically merge deltas + rebuild overviews + single-pass write a **new** COG; clear the covered deltas; cycle resets. **This is the same shape three other things in this bead already have:** | Delta-tiles-then-bake | Equivalent | |---|---| | delta tiles (write-ahead, discrete, synced) | git loose objects; dock deposits awaiting `step()` | | bake to fresh immutable COG | `git gc`/repack into a packfile; immutable `releases/` cut | | read-time compositing (delta over base) | per-caller namespace: local bind shadows the base URI (SW mount over acme.com) | | clearing covered deltas after bake | step-complete ack; channel `state.json` ledger advance | | live deltas (present) vs baked COG (past) | WebDAV-live vs git-history duality ([git-and-beads](git-and-beads.md) §c) | So "bake" is a named lifecycle operation worth keeping: **bake = compact the mutable delta layer into a new immutable artifact and advance the pointer.** Candidate addition to the bead lifecycle vocabulary alongside step (`step` drains inputs; `bake` compacts outputs).
## Open - Is `bake` a step variant (a step that emits an immutable artifact + pointer flip) or its own lifecycle verb? Leans devops-tenant, not substrate. - Cache-manifest format: reuse `keywords.json`-style sidecar, or adopt Workbox's manifest shape for interop? - Who runs the baker in the mesh — the lease-holding animator (it already owns the durable lanes)?
## References (bead cross-links) - Bead: Devops · [canonical](https://redfish.acequia.io/guerin/.agents/64be6d29-d133-4ade-9dce-f62701003e37/)