New run: start a run from the app, on the working copy

The site promises simulated inputs and mocked sensor values, and nothing in
the app was that. A run already is: the values are the caller's, the state is
the run's own namespace, and nothing it computes reaches the live flow. What
was missing was a screen to do it from, and the draft flag being honoured.

`/runs/new` is a flow, a field per declared input, a seed and Run; `/runs`
stays the log. A comma-separated list in a number field expands into the grid
`fluksio sweep --param` builds and goes to the sweep route, so launching one
no longer needs a terminal. Only numbers split: a comma in a string is
content, and one in JSON is syntax.

`RunCreate.draft` was validated at submit and dropped before the run
executed, so "try the working copy" ran the published one. `Run.draft` is a
column now, the driver reads the same copy the submit checked, and a retry
carries it. `FlowSummary.mode` came with it so the rail can say which flows
are batch before one is picked.

Also here: a Retry button on a finished run, which the route has always had
and the UI never did, and parameter cells truncated to their column with the
full value on hover.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TTfoK82awm8wvxXhHz3XF
This commit is contained in:
2026-09-02 15:10:24 +02:00
co-authored by Claude Opus 5
parent d471614e6a
commit 5b122341d5
20 changed files with 926 additions and 91 deletions
+20 -5
View File
@@ -41,6 +41,13 @@ value would be dropped rather than delayed, so submitting is refused instead.
## Submitting
**Runs → New run** in the app is the same call with a form in front of it: pick
a flow, fill in its declared inputs, press Run. A comma-separated list in a
number field runs every combination of them as a sweep. **Use draft** runs the
working copy rather than what is published, which is how a change is tried
before it is deployed, and each run keeps its own state, so nothing it computes
reaches the live flow.
```bash
curl -X POST $FLUKSIO/runs/flows/train_polymer_gnn \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
@@ -54,6 +61,11 @@ result, per-node record and artifacts.
Wrong parameters are refused before anything executes: an undeclared name, or
a value of the wrong type, comes back as a 422 naming the problem.
`"draft": true` on the body runs the unpublished working copy — the flow
document and the node sources the editor is showing. The copy is read again
when the run starts, so a draft published while it waited runs as the
published one.
### Sweeps
An ensemble is the same parameters at different seeds; a grid search is the
@@ -313,10 +325,11 @@ that for the runs of a sweep that did not finish.
## Looking at what ran
The **Runs** screen is the experiment log: every run newest-first, filtered by
flow, by status, or down to one sweep. A sweep is worth filtering to, since the
table then draws a column per parameter that actually varied, which is what
makes fifty runs of one flow readable.
**New run** is where one is started, and the **Runs** screen is the experiment
log: every run newest-first, filtered by flow, by status, or down to one
sweep. A sweep is worth filtering to, since the table then draws a column per
parameter that actually varied, which is what makes fifty runs of one flow
readable.
Tick two or more and their curves go side by side. Shift-click to take a
range, or the header box to take everything on screen. That comparison is the
@@ -329,7 +342,9 @@ still lie on top of each other; or against another metric of the same runs (an
epoch, or samples seen) joined on the step the two share.
One run in full is params, the per-node record with its logs and traceback,
the artifacts it made, its metrics and its result.
the artifacts it made, its metrics and its result. **Retry** submits it again
as a run of its own, keeping the flow, the inputs, the seed and the sweep it
belonged to.
### Taking it into a dataframe
+2
View File
@@ -18,6 +18,8 @@ phone the sidebar collapses to a sheet.
| **Home** | the brain graph, health, and everything that recently happened |
| **Flows** | the list of flows, and the canvas for each |
| **Dashboards** | the widget canvases, and the panels that display them |
| **Runs** | starting a run with values you choose, and the log of what ran |
| **Workers** | the machines that nodes can be placed on |
| **Secrets** | credentials your nodes reference without holding |
| **Modules** | the Python packages your node code may import |
| **Alerts** | where failures get sent |