Make the docs state things rather than argue them
Docs / docs (push) Successful in 37s
Playwright Tests / test-playwright (1, 2) (push) Failing after 1m35s
Playwright Tests / test-playwright (2, 2) (push) Failing after 17s
pre-commit / pre-commit (push) Failing after 2m8s
Test Backend / test-backend (push) Failing after 2m48s
Compose Smoke Test / test-compose (push) Failing after 13s
Playwright Tests / merge-reports (push) Failing after 2m25s

The site read as a design journal: rationale paragraphs, hedges
("deliberately", "on purpose", "genuinely"), meta-commentary about the docs
themselves, and one em-dash every ten lines carrying an aside.

Roughly twenty rationale blocks are gone or reduced to what a reader needs
in order to use the thing. Em-dashes go from 507 to 135, and what is left is
structural rather than prose: list and definition separators, table cells,
and four inside code blocks that quote what the CLI actually prints.

Also: api.example.com becomes api.fluksio.com (the emails stay, since
bootstrap.py really defaults to admin@example.com and RFC 2606 reserves it);
the mqtt table gains the two settings it had drifted behind on and inject's
wording matches the engine; llms.txt lists the two connector pages that were
in the nav but not in it; and the two device/device_policy notes now agree.

Builds clean under `zensical build --strict`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YrQnKV3bnQd4K342y8tKj
This commit is contained in:
2026-08-31 10:49:58 +02:00
co-authored by Claude Opus 5
parent 2422a9b22b
commit bdad6d7fc2
25 changed files with 450 additions and 479 deletions
+17 -20
View File
@@ -3,10 +3,8 @@
Every type the canvas can place. Each is configured by filling in a form the
editor generates from its parameter schema, so they all behave the same way.
Anything here could be written as a **Function** node — that is what the
function node is for. These exist because the same handful of shapes account
for most of a real instance, and a rule you fill in is easier to read on a
canvas, and to change, than five lines of code repeated eighty times.
Anything here can also be written as a **Function** node. These types cover the
shapes that come up most often, as a form to fill in rather than repeated code.
`GET /flows/node-types` returns this list with each type's full parameter
schema, including any [connectors](#connectors) installed on your instance.
@@ -40,13 +38,15 @@ A node with *outputs only* subscribes; a node with *inputs* publishes.
| `qos` | `0` | 0, 1 or 2 |
| `retain` | `false` | on published messages |
| `keepalive` | `60` | seconds |
| `timeout` | `10.0` | seconds before a broker operation is given up on |
| `publish_queue_size` | `256` | payloads that may wait for the broker; past this the oldest is dropped and the node reports degraded |
| `json_key` | — | key to lift out of an object payload; one for every port, or `{"port": "key"}` |
A topic may be a filter: `+` matches one level, `#` the rest. Everything a
filter matches lands on the same port, so use one port per topic where the
difference matters.
`json_key` is for a device that wraps its reading Victron publishes
`json_key` is for a device that wraps its reading: Victron publishes
`{"value": 47}` on every path. Without it, a payload object is unwrapped only
when it happens to carry the port's own name as a key.
@@ -100,10 +100,8 @@ Outputs only makes it a **webhook**: the engine mounts a route at
written, and the rows come back on the first output port as
`{"rows": [{ts, value, field, measurement, tags}], ...}`.
That is what keeps a database node a database node: it holds the credentials
and the connection and nothing else. Building a query and shaping its rows are
ordinary Function nodes on either side, so a dashboard widget never learns which
database answered it.
A database node holds the credentials and the connection, nothing else.
Building a query and shaping its rows are Function nodes on either side.
### Notification
@@ -126,7 +124,7 @@ thing configured elsewhere.
### Inject
**`inject`** — emit a value on request, on a schedule, or when the flow starts.
**`inject`** — emit a value on request, on a timer, or when the flow starts.
| Setting | Default | Notes |
|---|---|---|
@@ -138,8 +136,8 @@ thing configured elsewhere.
| `start_delay` | `1.0` | how long to wait before that first emission |
The scheduler: a `cron` expression here is what makes a flow run by the clock.
It is also the most-placed node in a real instance mostly as a button
someone presses.
It is also the most-placed node in a real instance, mostly as a button someone
presses.
### Delay & schedule
@@ -165,7 +163,7 @@ needs a busy cascade slot waits for one.
!!! note "Not in a batch flow"
A rate limit holds a value back for a timer to release, and a run has no
timer the value would be dropped rather than delayed. Submitting a batch
timer, since the value would be dropped rather than delayed. Submitting a batch
flow with a rate-limited port is refused instead.
### Trigger
@@ -183,13 +181,13 @@ starts from a value arriving. For a cron tick, see [`inject`](#inject).
| `passthrough` | `false` | send the incoming value instead of `first` |
| `wait_port` | — | an input carrying the wait, when it differs per message |
The shape this exists for: *the door opened turn the light on, and off again
in two minutes unless it opens again.*
The shape this exists for: *the door opened, so turn the light on, and off
again in two minutes unless it opens again.*
`wait_port` covers the case where how long to wait is itself a value: a
rollershutter takes 26 seconds up and 28 down, so the node that decides the
direction says how long to run for as well. A wait of zero or less sends
nothing afterwards and still cancels whatever the last message scheduled,
nothing afterwards, and still cancels whatever the last message scheduled,
which is how a *stop* is commanded exactly once.
## Logic
@@ -289,13 +287,12 @@ reloads identically.
|---|---|---|
| `seed` | `0` | |
Kept as a worked example of numeric logic rather than as a modelling tool. If
you are training something, that is a [batch flow](../concepts/runs.md) and a
Function node.
A worked example of numeric logic, not a modelling tool. To train something,
use a [batch flow](../concepts/runs.md) and a Function node.
## Connectors
Anything else in the palette came from an installed **connector** package a
Anything else in the palette came from an installed **connector** package: a
node type written against a published contract and discovered through the
`fluksio.node_types` entry point group. The editor shows which package supplied
it.