The component reference
Version 1's site carried one hand-written page per component. Eighteen of them. They were written before the code, because writing them was how the boundaries were argued about — a component whose page cannot be written without describing another component is not a component — and they earned their place. They also went stale, twice: first carrying a notice saying no code existed long after code existed, and then describing software that had been retired.
So this reference is generated. Its spine comes from contracts/topology.json, which
is itself derived from the configuration documents the components are constructed
from, and which a drift gate rebuilds and compares on every run. A component that
exists appears here. A component that stops publishing something stops saying it does.
Nobody has to remember.
What that buys is a narrow but real guarantee: this page cannot be wrong about who may say what. It can still be incomplete about what a component is for, and the prose below is where that is said.
The components
| Component | Source | May publish on | May subscribe to |
|---|---|---|---|
advisory-source |
not a module | adv/advisories, ctl/heartbeat |
ctl/operator/command, ctl/clock |
advisory-store |
not a module | ctl/heartbeat |
adv/advisories, ctl/clock |
analyst |
app/src/backend/analyst |
ctl/analysis/published, ctl/analysis/standing, ctl/heartbeat |
obs/#, ctl/run/request, ctl/run/published, ctl/clock |
boundary |
app/src/backend/boundary |
ctl/boundary/denial, ctl/heartbeat |
ctl/clock |
broker |
app/src/backend/broker |
ctl/heartbeat |
ctl/clock |
clock |
app/src/backend/clock |
ctl/clock, ctl/heartbeat |
— |
coverage-store |
app/src/backend/coverage-store |
cov/holdings, ctl/heartbeat |
ctl/operator/command, ctl/clock |
env-generator |
app/src/backend/env-generator |
ctl/heartbeat |
ctl/operator/command, ctl/clock |
feature-store |
app/src/backend/feature-store |
ctl/heartbeat |
ctl/clock |
ingest |
app/src/backend/ingest |
ctl/heartbeat |
obs/#, ctl/clock |
model-runner |
app/src/backend/model-runner |
ctl/run/started, ctl/run/published, ctl/run/cost, ctl/forecast/features, ctl/telemetry, ctl/heartbeat |
ctl/analysis/published, ctl/clock |
monitor |
app/src/backend/monitor |
ctl/divergence, ctl/telemetry, ctl/forecast/indicator, ctl/heartbeat |
ctl/operator/command, obs/#, ctl/clock |
observation-store |
app/src/backend/observation-store |
ctl/heartbeat |
ctl/clock |
offload |
app/src/backend/offload |
ctl/offload, ctl/heartbeat |
ctl/operator/command, ctl/run/published, ctl/clock |
operator |
app/src/backend/operator |
ctl/heartbeat, ctl/platform/demand, ctl/operator/command |
ctl/heartbeat, ctl/clock |
planner |
app/src/backend/planner |
ctl/plan, ctl/heartbeat |
ctl/operator/command, obs/#, ctl/analysis/published, ctl/clock |
platform |
app/src/backend/platform |
obs/ownship/+, ctl/platform/state, ctl/heartbeat |
ctl/operator/command, ctl/platform/demand, ctl/clock |
query |
app/src/backend/query |
ctl/heartbeat |
ctl/clock |
scheduler |
app/src/backend/scheduler |
ctl/run/request, ctl/telemetry, ctl/heartbeat |
ctl/operator/command, ctl/divergence, ctl/run/published, ctl/run/cost, ctl/telemetry, ctl/clock |
sensors |
app/src/backend/sensors |
obs/+/+, ctl/heartbeat |
ctl/operator/command, obs/ownship/+, ctl/clock |
shell |
app/src/shell |
— | # |
snapshot-source |
not a module | ctl/heartbeat |
ctl/clock |
telemetry |
app/src/backend/telemetry |
ctl/telemetry, ctl/heartbeat |
ctl/operator/command, ctl/telemetry, ctl/run/published, obs/#, ctl/clock |
The two entries with no source of their own — advisory-source and advisory-store —
are roles the shore-advisory path fills without a module directory of its own.
The permission columns are permissions, not behaviour: they say what the broker will
carry for a component, not what it chooses to send. # is the read-everything filter,
held by the shell alone, because the shell's job is to display whatever crosses.
What each of them is for
The world. clock owns the time; nothing else in the system may read a wall clock,
so its heartbeat is also the first liveness signal every other component follows.
env-generator produces the 4D field — temperature, salinity, pressure, with
sound speed derived rather than stored — from a recorded
seed, with four seeded features whose ground truth is written into a manifest so
recovery can be scored.
Sensing. sensors sample the generated field along platform paths and publish
observations. ingest is the one door into the observation store: a single writer,
which is what makes the write path something you can reason about.
Storage. observation-store holds what was sensed, feature-store the ground
truth, coverage-store the gridded holdings across their three eras — a multi-decade
historic archive authored at provisioning, a now-cast replaced on a cadence, and the
accumulating forecast instances once the loop turns.
Serving. query is the only read path. It answers
OGC API-EDR and
SensorThings requests and returns
CoverageJSON; no panel reads a store directly.
boundary is the release gate, and publishes its refusals so a refusal is visible
rather than silent.
The loop. monitor scores the forecast against what is arriving.
scheduler decides when the loop should turn. model-runner advects the field
forward — see the advection derivation and
ensemble spread. planner chooses where to sample
next, by the informative path planning
method.
The edges. advisory-source and advisory-store carry shore advisories — the
world outside speaking. offload announces an export without performing one.
telemetry reports on the machinery itself. operator is the machinery interrogated
from the operator's side.
The view. shell is the front-end: the dockable panels, and the only component
holding a read-everything subscription.
The topics
Every topic on the broker, the schema its messages are governed by, and which components may publish and subscribe. This is the same generated source: a topic nobody declares does not appear, and a topic declared by a component nobody built would fail the drift gate before it reached this page.
| Topic | Message schema | Published by | Subscribed by |
|---|---|---|---|
adv/advisories |
advisory.schema.json |
advisory-source |
advisory-store, shell |
cov/holdings |
holding-published.schema.json |
coverage-store |
shell |
ctl/analysis/published |
analysis-published.schema.json |
analyst |
model-runner, planner, shell |
ctl/analysis/standing |
analysis-published.schema.json |
analyst |
shell |
ctl/boundary/denial |
boundary-denial.schema.json |
boundary |
shell |
ctl/clock |
clock.schema.json |
clock |
advisory-source, advisory-store, analyst, boundary, broker, coverage-store, env-generator, feature-store, ingest, model-runner, monitor, observation-store, offload, operator, planner, platform, query, scheduler, sensors, shell, snapshot-source, telemetry |
ctl/divergence |
divergence.schema.json |
monitor |
scheduler, shell |
ctl/forecast/features |
forecast-features.schema.json |
model-runner |
shell |
ctl/forecast/indicator |
forecast-indicator.schema.json |
monitor |
shell |
ctl/heartbeat |
heartbeat.schema.json |
advisory-source, advisory-store, analyst, boundary, broker, clock, coverage-store, env-generator, feature-store, ingest, model-runner, monitor, observation-store, offload, operator, planner, platform, query, scheduler, sensors, snapshot-source, telemetry |
operator, shell |
ctl/offload |
offload-telemetry.schema.json |
offload |
shell |
ctl/operator/command |
operator-command.schema.json |
operator |
advisory-source, coverage-store, env-generator, monitor, offload, planner, platform, scheduler, sensors, shell, telemetry |
ctl/plan |
plan.schema.json |
planner |
shell |
ctl/platform/demand |
platform-demand.schema.json |
operator |
platform, shell |
ctl/platform/state |
platform-state.schema.json |
platform |
shell |
ctl/run/cost |
run-cost.schema.json |
model-runner |
scheduler, shell |
ctl/run/published |
run-published.schema.json |
model-runner |
analyst, offload, scheduler, shell, telemetry |
ctl/run/request |
run-request.schema.json |
scheduler |
analyst, shell |
ctl/run/started |
run-started.schema.json |
model-runner |
shell |
ctl/telemetry |
telemetry.schema.json |
model-runner, monitor, scheduler, telemetry |
scheduler, shell, telemetry |
obs/# |
observation.schema.json |
— | analyst, ingest, monitor, planner, shell, telemetry |
obs/ownship/+ |
observation.schema.json |
platform, sensors |
analyst, ingest, monitor, planner, sensors, shell, telemetry |
obs/platform-a/pressure-200m |
observation.schema.json |
sensors |
analyst, ingest, monitor, planner, shell, telemetry |
obs/platform-a/salinity-050m |
observation.schema.json |
sensors |
analyst, ingest, monitor, planner, shell, telemetry |
obs/platform-a/temperature-050m |
observation.schema.json |
sensors |
analyst, ingest, monitor, planner, shell, telemetry |
obs/platform-a/temperature-200m |
observation.schema.json |
sensors |
analyst, ingest, monitor, planner, shell, telemetry |
The Version 1 reference
The eighteen hand-written pages are kept in the archive. They describe the containerised system Version 1 delivered — the reverse proxy, the publisher, the browser client as a separate thing — and they are accurate about it. They are not a description of what runs now.