Files
hq/03-DESIGN/00-as-is/09-interfaces-and-observability.md
T
jschoubben c0b35652d0 The numbering is the flow: decisions are 02, design is 03
papa-hq reads 01 research -> 03 decision -> 02 design. The order is a
scar, not a choice: 02-DESIGN existed from its initial commit, and when
adr/ was finally promoted on 2026-07-13 it took the next free number
rather than its place in the sequence. By then design was too settled to
renumber.

hal-hq was three commits old, so it is not. adr/ becomes 02-DECISIONS and
02-DESIGN becomes 03-DESIGN, and following the folder numbers now walks
the process in the order it happens: research produces a decision, the
decision authorises a design.

00-GENESIS becomes 00-META, matching papa's rename from the same
restructure.

Every path reference rewritten across documents, frontmatter, playbooks
and skills. All links resolve; all 58 frontmatter blocks parse and their
path fields still point at files that exist.
2026-08-23 18:05:11 +02:00

79 lines
3.5 KiB
Markdown

---
layer: as-is
status: implemented
code: [hal]
updated: 2026-08-23
decisions:
- 02-DECISIONS/0001-nodes-communicate-over-a-broker.md
- 02-DECISIONS/0008-a-failed-step-fails-the-job.md
---
# Interfaces and observability
How the mesh is reached, and how anyone can tell what it is doing.
## Capabilities are the primary interface
The mesh's primary interface is not a web console. It is a set of **capabilities**, exposed to
a session and callable in language.
A capability is contributed by a module and is available on any node, wherever it actually
runs: local ones directly, remote ones through a stand-in created at startup that forwards over
the broker. The caller does not know the difference, and the credentials never move.
This is the mesh's stated vision made concrete — an agent states an intent and the mesh works
out which node holds the thing. It is also why a capability's **schema** is load-bearing in a
way that is easy to underestimate: a parameter name that collides with the transport's own
reserved names breaks the call, and a validation-library version mismatch has silently dropped
every argument while the call still appeared to succeed.
## The board
A web interface presents the mesh — nodes, modules, pipelines, agents, work. It is a **view**.
Its own guidance is that shared logic belongs in the mesh's library rather than inline in the
board, precisely so the board does not quietly become a second implementation of the mesh's
rules.
## Public exposure
Nodes carrying a public name run a reverse proxy as the sole entry point. A module declares the
names its interfaces answer on, portably, and the proxy's configuration is **generated** from
those declarations rather than written — generated files are marked as such and anything
hand-written beside them is left alone.
Nodes without a public role use a local equivalent with locally-trusted certificates. The
generation step degrades quietly on a node with no proxy, which is intended and is one more
place where "nothing happened" is the correct outcome and looks identical to a failure.
Certificate issuance currently always targets the public authority's production endpoint,
which consumes real quota for every experiment
([`04-ISSUES/004`](../../04-ISSUES/004-certificate-issuance-targets-production/00-report.md)).
## Health
Nodes run checks and report. The mesh's health surface answers whether things are up.
What it does **not** answer is whether they are correct, and that gap is the recurring theme of
this whole system: the deploy path reports transport rather than effect, so absence reads as
success. A check that confirms a service is running does not confirm the service is running the
code that was just deployed, and a node has been left on old code with a version marker that
had already advanced.
## Thoughts
Every node's daemon runs a periodic loop that surfaces observations from that node's own
context. They are stored in the mesh and can inform a session or trigger action.
It is the one part of the mesh that is not request-driven — the mesh noticing things rather
than being asked.
## The honest summary
Observability tells you the mesh is **up**. Establishing that it is **right** currently means
reading the operational record and checking by hand.
That is the gap the lab is designed to close
([`01-to-be/01-end-to-end-testing.md`](../01-to-be/01-end-to-end-testing.md)): a place where a
change can be run end to end and a verdict produced, cheaply enough that producing one is
routine.