Customer Integration Pattern — AnyHazard in a Deep Customer Stack (31bd5380)

**Note** from Bead: 31bd5380 · [canonical source](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/customer-integration-pattern.md) · session 2026-06-03 · discussion: Talk: 31bd5380

This note responds to Stephen's directive in turn 40 (2026-06-03): > *"Let's start a general section in our critique. This is more in the acequia as pattern. The main focus is viewing AnyHazard and Acequia from one of customer's perspective. San Bernardino County Fire Department. Assume they have a deep tech application stack. AlertWildfire cameras they control as a platform, Technosylva, TabletCommand, Intterra, a computer aided dispatch CAD system, an AVL platform, Cesium ION, Genasys/ZoneHaven, ATAK with TAK servers, a home assessment application platform for home hardening, IFDSS and Google Earth. AnyHazard needs to read and write layers and integrate with these platforms. One pattern might be AnyHazard just looks like another 'user' on those platforms with an access token for read/write permissions and maybe a webhook for callbacks/pub-sub."* This is **acequia-as-pattern** territory. The customer's view: they already have a heavy investment in specialized platforms; AnyHazard's value isn't being yet-another-platform — it's being the **integration layer** that pulls these heterogeneous sources into one coherent operating view, governed by the acequia pattern. The framework for this is already documented in Stephen's [google-earth-integration.md](https://redfish.acequia.io/guerin/docs/realtime-earth/google-earth-integration.md) — "Google Earth as a Duck-Typed Acequia Node." That note's central insight generalizes: > *"GE was never designed as a participant in a decentralized peer-to-peer network... But it speaks HTTP, it issues structured demand signals encoding its full viewer state, and it consumes contextual responses scoped to that demand through a persistent channel. If it emits situated requests and receives situated responses through a refreshable link, it behaves like an acequia node. We can duck-type it."* **Every platform in SBCFD's stack can be duck-typed the same way.** Each has an HTTP API (with auth), most have streaming/webhook mechanisms, all expose addressable resources at URIs. AnyHazard's job is to act as a "user" (machine account) on each one — holding an access token for that platform's namespace, calling its APIs, optionally registering webhooks back — and to compose what it gets into the acequia substrate.

## The reframe — AnyHazard as integration layer, not competing platform A fire department with SBCFD's stack has already chosen its tools. They have Technosylva for wildfire modeling, TabletCommand for incident command, ATAK for tactical awareness, AlertWildfire for cameras they operate. **The last thing they need is another standalone application competing for the same attention.** What they need is something that pulls their existing tools into a single coherent operating view, with governance (who can see what, when, where, audited), with cross-tool correlation (the camera view at this angle + the AVL position of the strike team + the CAD event timestamp + the Technosylva prediction at this hour), and with the ability to *re-publish* the integrated view to downstream consumers (the public information channel, the next-jurisdiction handoff, the after-action archive). **That's AnyHazard's value proposition.** Not "we replace your stack" — "we integrate your stack." This re-framing has consequences for the pitch: - The user/customer-facing language should emphasize *integration* over *application features* - Effort 2's Layer Manager should foreground "consume from external sources" as much as "manage native resources" - The pitch should explicitly enumerate the integration patterns AnyHazard supports out of the box (vs requires custom work) - Pricing/positioning likely scales with the number and depth of integrations, not seat count

## The canonical pattern — "AnyHazard as user, with access token + webhook" Stephen's stated pattern: > *"AnyHazard just looks like another 'user' on those platforms with an access token for read/write permissions and maybe a webhook for callbacks/pub-sub."* Concretely, this is **OAuth-Pattern-B-style integration** (see [tokens.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/tokens.md) — App acts on behalf of user) generalized: 1. The fire department's admin provisions AnyHazard as a "user" or "service account" on each external platform — typically via that platform's admin console 2. Each platform issues AnyHazard credentials — usually an **access token** (OAuth client credentials, API key, or platform-specific equivalent) with **scoped read/write permissions** 3. AnyHazard stores the credentials in its credential store — named per the platform + purpose (e.g., `sbcfd-tabletcommand-readonly`, `sbcfd-alertwildfire-ptz`); these are the [named API tokens](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/tokens.md) pattern from the platform's own side 4. **For reads**: AnyHazard calls the external platform's API or subscribes to its streaming endpoint 5. **For writes**: AnyHazard `PUT`/`POST`s to the external platform's API 6. **For callbacks (pub/sub)**: AnyHazard exposes a webhook endpoint at its own URI (e.g., `https://anyhazard.acequia.io/orgs/sbcfd/integrations/cad/events`) and registers it with the external platform; the platform `POST`s events when state changes The external platform sees AnyHazard as a single user/service-account; AnyHazard sees the external platform as a source of URI-addressable resources it has read/write capabilities on. The integration is bidirectional and continuously synced. The acequia-pattern alignment: each external platform's resources become URIs in AnyHazard's namespace via *mounts* (per [Gap 2 in the gaps note](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/gaps-to-acequia-mission.md)). The Technosylva model output at `https://technosylva.example/api/scenarios/12345` becomes accessible as `https://anyhazard.acequia.io/orgs/sbcfd/mounts/technosylva/scenarios/12345` — same content, AnyHazard's URI scheme + governance + audit overlay.

## SBCFD's stack — per-platform integration sketches Each integration breaks into a small number of mechanical questions: - **Auth model** — how does AnyHazard authenticate? (OAuth, API key, mTLS, custom) - **Read interface** — what does AnyHazard pull from this platform? (REST API, streaming, file export) - **Write interface** — what does AnyHazard push? (REST API, file import, message bus) - **Push/callback** — does the platform send events to AnyHazard? (webhook, SSE, WebSocket, MQTT) - **Acequia overlay** — what URIs in AnyHazard's namespace mount the platform's resources? ### AlertWildfire cameras (operated by SBCFD) - **Pattern**: Sensor-network acequia (per [acequia-as-group-ics-template.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/acequia-as-group-ics-template.md) sensor-acequia section); SBCFD operates it as a platform within the broader AlertWildfire/ALERTWest network - **Auth**: Platform-specific (probably API key + per-camera PTZ permissions) - **Read**: Live camera feeds (MJPEG / HLS / WebRTC), latest frames, PTZ position, archive lookups by timestamp - **Write**: PTZ control (pan/tilt/zoom commands) for cameras where AnyHazard's operator role has permission - **Push**: Movement detection events; significant-change alerts - **Acequia overlay**: Camera URIs become `https://anyhazard.acequia.io/orgs/sbcfd/cameras/<location>/` with sub-URIs for `/latest`, `/stream`, `/params/*`, `/actions/*` (per the [Simtable camera worked example in the vocab](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/user-representation-vocabulary.md)) ### Technosylva (wildfire modeling, FIRE0/FireSight) - **Pattern**: Simulation-as-a-service; request/response with possibly long-running async jobs - **Auth**: Enterprise SSO + API key - **Read**: Run-by-run prediction outputs (fire perimeters over time, time-of-arrival rasters, weather forecast inputs, fuel inputs), pre-computed catalogs of likely scenarios - **Write**: Submit new model runs (ignition point, fuel moisture, weather conditions); cancel runs; tag runs for retention - **Push**: Run-completion webhooks; alerts on threshold-breaching predictions - **Acequia overlay**: Each model run becomes a [dynamic resource URI](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/user-representation-vocabulary.md) — `GET` returns current state (queued / running / complete + output URIs); `POST /inputs/` submits new runs ### TabletCommand (incident command) - **Pattern**: Command/control with bidirectional state; AnyHazard reads incidents, writes layers, updates display - **Auth**: OAuth (per their published integration docs) with org-scoped tokens - **Read**: Active incidents, resource assignments, tactical objectives, drawn-on-map annotations, ICS form data - **Write**: Push computed layers (Technosylva predictions, AlertWildfire frustums, AVL clusters) as TabletCommand overlays; push synthesized situational summaries - **Push**: Incident-state-changed webhooks (new incident, IC changed, status update, demobilization) - **Acequia overlay**: Each incident in TabletCommand mounts as `https://anyhazard.acequia.io/orgs/sbcfd/incidents/<id>/` with synced sub-URIs ### Intterra (mapping/analytics platform) - **Pattern**: Layer source + analytics - **Auth**: API key - **Read**: Pre-computed risk layers, historical incident catalogs, run-spread overlays - **Write**: Tag layers for shared use - **Push**: New-layer-available notifications - **Acequia overlay**: Layers mount under `https://anyhazard.acequia.io/orgs/sbcfd/mounts/intterra/` ### CAD (Computer Aided Dispatch) - **Pattern**: Real-time event stream (dispatches, unit-status changes, scene-arrivals) - **Auth**: Internal — probably mTLS or VPN-bounded API access (CADs are typically locked-down) - **Read**: Active dispatches, unit status by unit ID, incident attributes, dispatch timeline - **Write**: Rarely — most CAD integrations are read-only from external systems; some support back-channel comments - **Push**: Per-dispatch webhooks; unit-status-changed events (high frequency) - **Acequia overlay**: Dispatches become `https://anyhazard.acequia.io/orgs/sbcfd/cad/dispatches/<id>/`; the dispatch stream becomes a subscription URI `cad/stream` ### AVL (Automatic Vehicle Location) - **Pattern**: Real-time geo-positioning of fleet vehicles - **Auth**: Internal API + vehicle-fleet ownership - **Read**: Current positions, heading, speed; historical tracks - **Write**: None typically - **Push**: Position-update webhooks (high frequency — 5-30s); geofence-cross events - **Acequia overlay**: Vehicles become dynamic URIs `https://anyhazard.acequia.io/orgs/sbcfd/avl/units/<id>/` with `/position`, `/track`, `/stream` ### Cesium ION (3D terrain and tiles) - **Pattern**: Tile/3D-mesh content delivery - **Auth**: API token - **Read**: 3D terrain tiles, imagery tiles, photogrammetry meshes; per-asset URLs - **Write**: Upload custom imagery / meshes for asset hosting (rare for AnyHazard; possible for archival) - **Push**: None (pure content delivery) - **Acequia overlay**: Cesium assets mount as `https://anyhazard.acequia.io/orgs/sbcfd/mounts/cesium-ion/assets/<asset-id>/`; the Cesium-hosted tiles can be referenced directly or proxied ### Genasys / ZoneHaven (evacuation zone management + alerts) - **Pattern**: Read zones + push alerts - **Auth**: API key with org-scoped permissions - **Read**: Defined evacuation zones (polygons with metadata), current zone status (warning / order / shelter-in-place), historical zone activations - **Write**: Trigger zone activations (with appropriate authorization — typically restricted to specific roles); update zone status - **Push**: Zone-status-changed webhooks; public-alert-broadcast events - **Acequia overlay**: Zones mount as `https://anyhazard.acequia.io/orgs/sbcfd/zones/<zone-id>/` with `/status`, `/history`, `/alerts`

### ATAK with TAK servers - **Pattern**: Tactical awareness with explicit federation (the closest external platform to the acequia pattern itself) - **Auth**: Cert-based mutual TLS; TAK-server federation tokens - **Read**: All cot (cursor-on-target) traffic in the federation — unit positions, casevac requests, situation reports, drawing/shape data - **Write**: Inject AnyHazard-computed shapes (Technosylva perimeters, AlertWildfire frustums, Genasys zones) as CoT into the TAK federation - **Push**: Streaming CoT (continuous bidirectional channel) - **Acequia overlay**: TAK servers are themselves acequia-pattern-aligned (explicit federation, peer-to-peer, capability-scoped). AnyHazard joins the federation as a TAK peer; the integration is mostly a bridge between TAK CoT and acequia's bind/mount ### Home assessment app (home hardening) - **Pattern**: Read assessment data per address; tabular + photo data - **Auth**: API key - **Read**: Per-property assessment scores, photo links, hardening recommendations, last-visit dates - **Write**: Record AnyHazard-derived risk-context-when-visited; tag properties for re-visit - **Push**: New-assessment-available - **Acequia overlay**: Properties mount as `https://anyhazard.acequia.io/orgs/sbcfd/properties/<parcel-id>/` ### IFDSS (Interagency Fuels Decision Support System) - **Pattern**: Federal public-dataset source - **Auth**: Federal credentials (federated identity through fire-agency SSO) - **Read**: Fuel layers, treatment polygons, prescribed-burn plans, fuel-condition forecasts - **Write**: Submit treatment proposals for review; record AnyHazard-derived risk assessments - **Push**: Plan-status-changed webhooks - **Acequia overlay**: Federal datasets mount as `https://anyhazard.acequia.io/orgs/sbcfd/mounts/ifdss/<dataset>/` ### Google Earth - **Pattern**: Visualization client; bidirectional via NetworkLink (download) + File System Access API or filesystem watcher (upload) - **Auth**: None for NetworkLink read; depends on direction for upload - **Read**: Camera pose via NetworkLink request parameters (the GE viewer's camera position becomes structured demand signal) - **Write**: KML response — AnyHazard generates the layer the GE viewer sees, scoped to their camera pose, refreshed as they pan/zoom - **Push**: Per [google-earth-integration.md](https://redfish.acequia.io/guerin/docs/realtime-earth/google-earth-integration.md) — the NetworkLink polling IS the demand signal; AnyHazard's response IS the supply - **Acequia overlay**: GE is duck-typed into the acequia network per Stephen's existing note. AnyHazard exposes a NetworkLink endpoint; GE clients fetch updated views; their camera poses are published into group shared state for cross-viewer frustum visibility

## Integration categories — by acequia-pattern shape The 12 platforms above cluster into 7 categories by acequia-pattern shape: | Category | Platforms | Acequia pattern | |---|---|---| | **Sensor / live-source** | AlertWildfire (cameras), AVL (vehicles), CAD (dispatches) | Dynamic URI with `/latest`, `/stream`, `/params/*`, `/actions/*` (per the [Simtable camera pattern](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/user-representation-vocabulary.md)) | | **Simulation as service** | Technosylva | Submit input → poll/subscribe for output; long-running jobs as dynamic resources | | **Command/control bidirectional** | TabletCommand, ATAK+TAK | Mount the external's resources + push AnyHazard-computed layers back | | **Layer / tile source** | Cesium ION, Intterra, IFDSS | Mount as read-only namespace with tile / asset URIs | | **Zone / alert** | Genasys/ZoneHaven | Mount zone definitions; bind triggers for activation (scope-restricted) | | **Tactical federation** | ATAK+TAK (special case) | Acequia-to-acequia federation; AnyHazard joins as a TAK peer; CoT-to-bind/mount bridge | | **Visualization client** | Google Earth (also Cesium-based viewers, Leaflet, etc.) | NetworkLink-style demand-signal + KML-style situated response; per the existing duck-typing note | The seven shapes are the integration vocabulary. Document A should describe these as the *general patterns* AnyHazard supports; Document B should give per-platform implementation specifics.

## What AnyHazard's value-add actually is Once these integrations are in place, AnyHazard's value isn't replicating any single platform — it's the *combination*: 1. **One coherent operating view** — instead of five tabs across five platforms, the IC sees AlertWildfire camera + Technosylva forecast + AVL positions + CAD active dispatches + Genasys evacuation zones in one acequia-rendered space. Each comes from its source-of-truth; AnyHazard composes them. 2. **Cross-source correlation** — "show me the camera frustums that cover the area where Technosylva predicts the fire will be in 30 minutes." This requires reading from two sources at once and joining them spatially/temporally. AnyHazard does the join. 3. **Acequia governance over the integration** — who in SBCFD can see which integration's data, when, where, audited. The IC at the Type 1 incident sees the cross-jurisdictional ATAK feed; the public information officer sees only the Genasys public-zone-status; the after-action archivist sees the entire historical chain with attribution. 4. **Re-publishing the integrated view** — the IC's coherent view can be shared (as a URI) with the next-jurisdiction handoff, the news media (via the news-acequia pattern), the public (sanitized public-information URI), or the after-action review (full audit-preserved snapshot). The integration view is itself a first-class acequia resource that can be bound, federated, and apoptotically managed. 5. **The acequia governance pattern overlaid on platforms that don't natively support it** — most of these external platforms have their own internal governance models (TabletCommand permissions, IFDSS roles, CAD scopes). AnyHazard layers acequia-governance *across* these — so the IC's role in the SBCFD acequia determines what they see in the integrated view, regardless of the underlying platform's specifics.

## Risks worth naming This integration approach has real costs/risks Kaz's pitch should acknowledge: 1. **Per-platform token + scope maintenance** — each external platform's API has its own auth model, scope grammar, renewal cycle. AnyHazard's credential store grows linearly with integrations; rotation discipline matters. 2. **API drift** — external platforms change their APIs; integrations break. AnyHazard needs versioned integration adapters and graceful degradation when an integration is down. 3. **Rate limits / cost** — some external platforms (Cesium ION tile delivery, Technosylva model runs) have usage-based pricing or rate limits. AnyHazard's caching and request-batching strategy matters; the [URI hosting](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/user-representation-vocabulary.md) pattern (cache hosting role for dynamic URIs) directly addresses this. 4. **Walled-garden resistance** — some platforms deliberately limit third-party integration to protect their own product surface. ATAK is friendly (federation is the design); some commercial platforms are less so. Per-platform negotiation may be needed. 5. **Latency for chained calls** — composing five platforms into one view means up to five HTTP round-trips per render. Streaming subscriptions + cached state + per-source freshness windows mitigate this; need explicit attention in the design. 6. **Security boundary** — AnyHazard's credentials for external platforms become attack-attractive. Each integration's token compromise is a separate risk; scope minimization and frequent rotation are essential. 7. **Customer's existing governance vs acequia's** — the customer's existing user model (in TabletCommand, in CAD, in IFDSS) may not map cleanly to their acequia governance. Cross-mapping admin tooling is required (e.g., "this person is a Strike Team Leader in CAD; in our acequia, they're a Section Chief on the active incident-acequia").

## Implications for the pitch Specific changes Kaz's pitch should consider: - **Add an "Integrations" section to effort-2** (Layer Manager). The seven integration shapes above; per-shape patterns and supported platforms. Currently the pitch's resource-ingestion section (effort-2 §3.3) is about *uploading*; should be re-anchored on *integration with external sources* with upload as one specific case. - **Add a "Customer stack" appendix** to the pitch. SBCFD's stack is realistic for a mid-sized county; other customers (city fire departments, federal interagency teams, state-level emergency management) will have different stacks but similar shapes. Naming the stack makes the integration scope concrete. - **Re-anchor pricing on integrations**. The [account-layer](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/account-layer.md) note suggests the platform charges for higher-tier services. Per-integration pricing (or integration-tier pricing — 5 integrations, 10 integrations, unlimited) is a natural axis. - **The 7-shapes vocabulary should appear in Document A** — these are how Kaz's customers will think about their integration needs. They won't ask "does AnyHazard support TabletCommand specifically?"; they'll ask "does AnyHazard let us read our incident system and write back layers?" — that's the command/control bidirectional shape. - **The duck-typing principle** (from google-earth-integration.md) should be elevated to a stated design commitment: any HTTP-speaking external platform can be integrated using one of the 7 shapes. Customers can self-onboard new integrations using the AnyHazard SDK, not just wait for AnyHazard to ship per-platform connectors.

## Related - Canonical template: [google-earth-integration.md](https://redfish.acequia.io/guerin/docs/realtime-earth/google-earth-integration.md) — "Google Earth as a Duck-Typed Acequia Node" - [acequia-the-word.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/acequia-the-word.md) — pattern + platform foregrounding; this integration pattern lives in the *pattern* sense - [acequia-as-group-ics-template.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/acequia-as-group-ics-template.md) — ICS template + multi-template acequia ecology (sensor-network acequias like alert.live / AlertWildfire are one kind) - [tokens.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/tokens.md) — named API tokens are how AnyHazard's external-platform credentials get represented; the OAuth Pattern B (app acts on behalf of user) section is the per-integration pattern - [account-layer.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/account-layer.md) — integrations are an account-layer service; pricing scales with integration depth/breadth - [user-representation-vocabulary.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/user-representation-vocabulary.md) — the Simtable camera worked example generalizes to AlertWildfire and other sensor platforms - [gaps-to-acequia-mission.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/gaps-to-acequia-mission.md) — Gap 2 (URI bind/mount); integrations are mounts of external platforms' namespaces into AnyHazard's - [participants-and-resources-in-uri-sense.md](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/notes/participants-and-resources-in-uri-sense.md) — URI patterns for dynamic resources (cameras, sensors, simulations) - [fused critique](https://redfish.acequia.io/guerin/.agents/31bd5380-d743-420f-81a1-9258e7fbbf9a/2026-06-03/artifacts/anyhazard-user-model-critique-fused.md) — the customer-perspective integration section