Commit Graph
644 Commits
Author SHA1 Message Date
stroblme 599e01b0bf Run child tables cascade from run.id
Migration ccb21eacf5d5 deletes rows whose run is gone, then adds foreign keys
with ON DELETE CASCADE from run_node, run_metric and run_artifact to run.id.
Deleting runs is now the one statement. A node or metric written after its
run was deleted is dropped with an info line. Migrations run with foreign keys
off, since a batch rebuild of run would otherwise cascade into every child row.
2026-10-15 10:32:33 +02:00
stroblme 44223ab168 Take the portal's JWKS from the tunnel and verify by kid
The welcome frame's keys replace the set pinned at enrolment, but only
over wss:// or loopback, the rule enrolment applies to the portal
address. Portal tokens are verified against the key their kid names, so
the hub can publish a new key beside the old one. A welcome without keys,
from an older hub, leaves the pinned set alone.
2026-10-15 10:31:40 +02:00
stroblme 1d66b30d0c List and revoke portal members under Admin → Users
GET /cloud/members asks the portal who it admits to this instance and
marks those with a local user. DELETE /cloud/members/{portal_sub} takes a
membership back. Admin → Users lists the members who have not arrived
yet, with Revoke, which also surfaces a membership left standing when a
local user was deleted while the portal could not be told.
2026-10-15 10:31:25 +02:00
stroblme 8b47b32d3f Delete a member's local user when the portal removes them
On a member_removed frame the connector deletes the local user mapped to
that portal account, never the owner and never a superuser, since the
portal only ever creates ordinary accounts here. An instance offline at
the time keeps the inert row, as before.
2026-10-15 10:31:08 +02:00
stroblme dd50d7a16a Stand down when the portal revokes this instance
The connector treats close code 4410 from the hub as final: it stops
dialling, keeps cloud.json so a new claim code replaces it, and reports
revoked in /cloud/status, which Settings → Remote access shows as Removed
at the portal. Enrolling again, or a restart, brings the link back. An
older hub still answers 403 and the link keeps retrying as before.
2026-10-15 10:30:38 +02:00
stroblme 21cfed7d39 GET /runs/{id}/nodes/{node}/outputs serves what a node returned
The stage cache's stored outputs, as kept (up to 256 kB of JSON). A node
that kept none answers 404 saying why. Listed in the API docs.
2026-10-15 10:23:39 +02:00
stroblme e75b0297fd A restored node whose source run is gone says its curve was lost
The run detail works out curve_lost per node when read, from whether its
cached_from run still exists. The run page names the deleted run in place
of the generic NO_CURVE note.
2026-10-15 10:22:09 +02:00
stroblme caa2cff6b1 A run keeps the inputs its flow declared at submit
Run.declared (migration 2e7ca7d10044) snapshots the declarations on submit
and import. The run detail's Inputs panel reads them, and a run from before
falls back to the flow's current declarations.
2026-10-15 10:20:29 +02:00
stroblme eca3fa0049 A panel writes only what its dashboards' inputs target
It still reads every message its dashboards show. A message a tile only
draws, or a setting is bound to, is no longer writable from the panel.
2026-10-15 10:10:44 +02:00
stroblme e85b18092f Flow inputs carry an origin hint, run or panel
The Inputs editor and the canvas label show it, and the run forms leave
panel inputs out.
2026-10-15 10:08:46 +02:00
stroblme 43498037be PUT /panels/ carries a version and refuses a stale one with 409
The Panels dialog re-reads the list on 409. A panels.json without a
version reads as 0.
2026-10-15 10:07:50 +02:00
stroblme 589ddecbb1 Library delete 409s on published usages as well as draft ones 2026-10-15 10:05:21 +02:00
stroblme 0562753d9c http sender drops reply keys no output port declares
A sender without outputs no longer fails on a {"status": "ok"} reply.
2026-10-15 09:57:51 +02:00
stroblme e6afc23952 sweep_artifacts: narrow the optional flow store for mypy 2026-10-15 09:55:41 +02:00
stroblme 5e5f1836cb wren runs its model on one BLAS thread
threadpoolctl scopes the limit to wren.act, so other numpy calls in the
engine keep their threads.
2026-10-15 09:55:02 +02:00
stroblme f2a823218a GPUs follow the engine's own CUDA_VISIBLE_DEVICES
Its entries are the cards present, and a local child's allocation is
named through them, so under =2,3 card 0 is device 2. Remote workers
keep mapping against their own mask.
2026-10-15 09:53:38 +02:00
stroblme 290b9fa705 Superuser route to flush the metrics collector now
POST /observability/flush handles what the collector has queued and writes
it, so the soak harness no longer sleeps FLUSH_INTERVAL_S before clearing
its own rows.
2026-10-15 09:53:19 +02:00
stroblme ae81d95fd7 Warn at startup when worker or cascade limits are far past the cores
More than four times os.cpu_count() logs one warning; the value is kept.
2026-10-15 09:51:38 +02:00
stroblme 9a029a85f8 Engine timings move to FLOW_* settings
NODE_STOP_TIMEOUT, REBUILD_WAIT, FLOW_REBUILD_WAIT, BACKOFF and
CANCEL_GRACE keep their defaults and are read from Settings.
2026-10-15 09:50:18 +02:00
stroblme 1f213460ad Audit shared-library source writes
A shared source goes live in every flow using it the moment it is saved, so
the write is recorded in the audit trail like a publish. Private source saves
stay drafts and are not audited.
2026-10-15 09:50:04 +02:00
stroblme 0004e4b9bd Retire a shared node in use with ?detach=true
DELETE /flows/library/{name} still answers 409 while nodes use the source.
With detach=true each of them keeps a copy of the code, in the published
flow and the draft, the source is deleted and the running users rebuild.
2026-10-15 09:48:47 +02:00
stroblme 96f4fa5a38 Warn when a node that runs no code names a device
A device on a node without source was accepted and silently ignored. The
build now reports it as ignored_device, an advisory issue.
2026-10-15 09:45:24 +02:00
stroblme c9fda50601 Connection nodes speak of listener and sender, and of send_queue_size
mqtt and http take websocket's vocabulary: their Mode is LISTENER/SENDER,
default names read mqtt_listener_… and http_listener_…, and mqtt's
publish_queue_size is send_queue_size. No alias stays behind, so the flow
store rewrites the old setting in every published and draft mqtt node when it
opens, in the same migration as trigger → debounce. Every mqtt and http
setting carries a one-line description for the editor, and the node-types
reference uses one wording for direction and says that an http sender
publishes a JSON object response on its outputs.
2026-10-15 09:44:22 +02:00
stroblme c032898135 A supervised loop that crashes reports its node down
A push session that failed before it listened left only a task_crashed
event. The wrapper in _run_supervised now reports down with the exception,
unless the loop already said why it is down.
2026-10-15 09:42:01 +02:00
stroblme 565d492f19 Give a rate-limit flush its own run, linked to the run that held the value
A flush ran its cascade under no id, so its executions and failures belonged
to no run. It now records a run with source "flush", and the holding run's id
travels on the queue item into a new `flow_run.parent` column, also on the
`/observability/runs` rows.
2026-10-15 09:37:30 +02:00
stroblme cfb9e53d68 Rename the trigger node type to debounce, migrating stored flows
The store rewrites `"type": "trigger"` to `debounce` in every published and
draft flow when it opens, bumps the version and commits once. No alias stays
behind, so `trigger` is now an unknown type.
2026-10-15 09:34:40 +02:00
stroblme 4a776e52c4 Delay node: hold the latest value inside the interval and send it at the window's end
The interval now rides the output ports, so the pipeline's own hold and flush
keep what arrives inside the window instead of the node dropping it.
2026-10-15 09:32:35 +02:00
stroblme abf7cd5c2a development.md: verify takes its domain off the running stack 2026-10-15 08:37:32 +02:00
stroblme afe4362bb2 Verify shoots the flow canvas and media tile from the Demo, not the media example
The canvas shot opens the Demo's music flow; the media shot reads the Demo's
Media screen, so neither needs the `camera` dashboard.
2026-10-15 08:36:38 +02:00
stroblme 8cfb0faca0 Merge remote-tracking branch 'origin/main' 2026-10-15 08:20:11 +02:00
Melvin Strobl 300d9017fd Merge remote-tracking branch 'origin/main' 2026-10-15 07:47:21 +02:00
stroblme e3fce944bf Docs: endpoint labels sweep when a value passes 2026-10-15 00:23:14 +02:00
stroblme bff20a9fb2 Endpoint labels sweep instead of pulse: left to right on a label publishing into the flow, right to left on one reading out of it, one pulse long, off under reduced motion; snapshot values are marked prior so catching up sweeps nothing 2026-10-15 00:23:01 +02:00
stroblme 9fb0e3ab90 Dashboard editor undo: ⌘Z / ⇧⌘Z over a 50-entry history of commits, folding keystrokes and the grid's own correction as the flow editor does 2026-10-15 00:07:58 +02:00
stroblme c9e38ede58 Stored state lists its keys, each with a two-press delete beside Clear 2026-10-15 00:04:03 +02:00
stroblme ddc281c81c Colour tile tests: the disc on the shared widgets panel for every look's screenshot, and a key's release sending rgb and hex 2026-10-14 23:59:24 +02:00
stroblme 2fba7b66d7 soak: pass flow names as SQL parameters so observability cleanup parses 2026-10-14 23:51:24 +02:00
stroblme 1dfdfe0ae4 Soak engine scenario: a sleeping fixture node keeps cascades in flight for the kill, and the report says how many were unacknowledged 2026-10-14 23:49:07 +02:00
stroblme 4be6a5b303 Test hygiene: forget the refused study, quiet _Tee on a closed stream, wait for connector recovery 2026-10-14 23:41:31 +02:00
stroblme 6ca2a484ed Phone header: assistant button in the corner, gated on an available provider as the sidebar entry is; header triggers on the right at 44px 2026-10-14 23:41:30 +02:00
stroblme e35eb67a21 Locked slider dims its rail: :has() on the slider, since the rail comes before the input and no sibling selector reaches it 2026-10-14 23:41:29 +02:00
stroblme 4e08a97354 Stat unit sized against the hero numerals: dui-hero on the readout's outer span, so the unit's 0.4em is of the hero rather than the 14px body text 2026-10-14 23:41:28 +02:00
stroblme e96fa46e0d make clean goes on past a root-owned backend/htmlcov, with a hint to sudo rm it 2026-10-14 23:40:03 +02:00
stroblme b345587ab9 Shared node changes rebuild the flows whose published copy uses them, not their drafts 2026-10-14 23:34:47 +02:00
stroblme ef9d9824bb Dev backend reloads on worker edits too: fastapi dev with --reload-dir over backend and worker, worker in develop.watch 2026-10-14 23:34:07 +02:00
stroblme 245e68449f Memory-queue ids carry a per-instance boot token, so a restart without Redis no longer overwrites earlier run rows 2026-10-14 23:33:25 +02:00
stroblme 2ac997ce37 ValueSource kind includes panel; Panels dialog no longer suggests the screen port openpanel does not serve 2026-10-14 23:32:32 +02:00
stroblme d423c47ca6 Socket snapshot carries the nodes waiting for a machine, so a reconnecting browser restores their queued dots 2026-10-14 23:31:54 +02:00
stroblme 30fa2b07db Remote exception names are cut to 128 identifier characters before a class is built for them 2026-10-14 23:31:47 +02:00
stroblme df78cdac72 Artifact sweep keeps what a flow input's initial references, published or draft 2026-10-14 23:30:46 +02:00