**Note** from Bead: Incident Host Mvp · [canonical source](https://redfish.acequia.io/guerin/.agents/8dda0afd-2c9e-4374-8571-1a77ebf30516/2026-07-07/notes/02-bootstrap-supply-sketches.md) · session 2026-07-07 · discussion: Talk: Incident Host Mvp
*Working concept from the 2026-07-07 session (session 2, second round); verbatim source in [the chat log](https://redfish.acequia.io/guerin/.agents/8dda0afd-2c9e-4374-8571-1a77ebf30516/2026-07-07/chats/2026-07-07-orthogonal-mvp-sketches.md). Rendered sketch: [bootstrap-supply-sketches.html](https://redfish.acequia.io/guerin/.agents/8dda0afd-2c9e-4374-8571-1a77ebf30516/2026-07-07/artifacts/sketches/bootstrap-supply-sketches.html) (v0.1, build 2026-07-07).*
## The reframe Stephen fixed the demand side: the MVP's fed surface is the mashup of [plume.html](https://redfish.acequia.io/guerin/apps/camera-grid/plume.html), the [Incident Viewer](https://redfish.acequia.io/guerin/apps/incident-viewer/), the [Firewatch camera grid](https://redfish.acequia.io/guerin/apps/camera-grid/), and the [v15 grid⇄map morph sketch](https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/2026-06-24/artifacts/sketches/grid-layout-transitions-v15.html). The sketch question moves to the supply side: how to bootstrap the STAC construction, and how user onboarding, permissions, and persistence work.
## What the mashup is fed (read from the code) - The grid and plume both load a **thin camera index** (`cameras-sandy.json`): camId, name, lon/lat, view azimuth, plus **qualified URLs** for frames and telemetry under `simtable.acequia.io/incidents/2026-CA-SandyFire/`. The file says it itself: "thin index, positions/az from STAC; telemetry + frame pixels fetched live from the qualified URLs (RTE remote-first)." - The grid also reads **`?stac=` collections** directly and GET/PUTs `imageMeta`/`imagePose` **WebDAV sidecars**; the viewer reads `?stac=` catalogs and emits **`?v=` permalinks**. - Two faces already **write back**: plume's `{ } STAC` button exports carve/UV vectors as STAC assets; v15 files ballots into a **`feedback/` lane** with layered write-only-token auth. So the mashup is four faces over one catalog spine, and the spine already has a read loop and the beginnings of a write loop. The four supply questions are valves on that loop.
## The four sketches ### 1 · three origin stories (`stac-bootstrap`) How does `catalog.json` come into being from zero? The sketch animates three origins converging on the same spine: **a) accretion** (a forager's first PUT implies the catalog; it grows by use), **b) mint first** (the Host declares an empty valid spine), **c) clone a template** (a prior incident's structure copied, forage skills fill fresh assets). Grounding: the ALERTWest forage skill already builds STAC from a source; catalogs stay offered, never written into namespaces the Host does not own. ### 2 · the ladder is inside the surface (`onboarding-rung`) Onboarding is the same mashup surface growing affordances as capability rises: **watch** (anonymous read) → **contribute** (scoped write; your camera becomes a tile) → **host** (mint, invite, revoke). No account at any rung; capability is the token you hold. The fork is the rung gesture: **a)** ask and be granted (request into the dock), **b)** invited link with rungs pre-baked, **c)** doing the thing enrolls you (v15 ballot-key style, first PUT auto-enrolls). ### 3 · lanes, not roles (`permission-lanes`) Permissions attach to paths: `catalog.json` (Host only), `frames/` (foragers write-only), `feedback/` (ballots), `derived/` (sims), `request/` (questions). Identity is the token chain; the sketch animates attenuation (maria ⊆ frames/ + feedback/, her friend ⊆ frames/ only), an out-of-lane 403, and cascade revocation that leaves already-landed contributions intact. Fork: **a)** one broad invite token, **b)** per-lane tokens (the ballot box is the proven special case), **c)** an attenuable chain per invitee. ### 4 · where the incident sleeps (`persistence-master`) The catalog is thin, frames are heavy and remote-first. The sketch animates the laptop-sleeps story: WebDavSync replicates the thin spine to an origin (additive, no remote deletes); at 2am a phone still GETs the wall from the replica and contributions keep landing; on wake, new material syncs back down. Fork on mastership: **a)** laptop is master, origin is a serving cache, **b)** origin is master once minted, **c)** additive multi-master, the catalog is the union (matches WebDavSync's additive mode and the no-deletes discipline).
## First-cut recommendation (scribe, awaiting Debbie and Stephen) - **`stac-bootstrap` = b then a**: mint the spine as the Host gesture (it is also the invite anchor), then let it grow by accretion; clone (c) becomes a convenience on top, a MINT-from-template button. - **`onboarding-rung` = b for strangers, c for the feedback lane**: invited links carry rung 1 for imagery; the ballot lane stays friction-free as v15 already proved. - **`permission-lanes` = c**: chains per invitee, since cascade revocation per person is the story a Host can actually reason about; per-lane write-only tokens remain the mechanism inside each grant. - **`persistence-master` = c**: additive multi-master fits the tools that exist (additive WebDavSync, remote-first heavy assets) and dodges the wake-merge problem entirely; nothing is deleted, the union is the incident.
## Status Open. Ballots live in the sketch and file into the [`request/` dock](https://redfish.acequia.io/guerin/.agents/8dda0afd-2c9e-4374-8571-1a77ebf30516/request/); draining it is a bead-step. Logged in [Debbie's sketch log](https://redfish.acequia.io/skills/sketch-ux/sketch-log.md). This round composes with the earlier [orthogonal MVP round](https://redfish.acequia.io/guerin/.agents/8dda0afd-2c9e-4374-8571-1a77ebf30516/2026-07-07/notes/01-orthogonal-mvp-sketches.md): that one asked which thread to pull first; this one specifies the plumbing any of the threads needs.
## References (bead cross-links) - Bead: Firewatch Camera Grid · [canonical](https://redfish.acequia.io/guerin/.agents/65783732-7907-4a36-983a-3b015e75e80b/)