clusterflux-public/operator_panel_notes.md
Disasmer release dry run f22d0a5791 Public dry run dryrun-309831e1e021
Source commit: 309831e1e021f962c118452336776fd9a94025f9

Public tree identity: sha256:6fa95c1745579bd6256dbeb3d476db0b07c2f24aa9213b0f7783ce1adfc8aca5
2026-07-03 16:07:13 +02:00

4.3 KiB

Disasmer Operator Panel Notes

Disasmer programs should be able to expose a small human-facing UI through the coordinator web page.

This is useful for long-running build systems, repo watchers, task dashboards, and manual controls.

Core idea

Disasmer program renders UI state
Coordinator displays it in a webpage
Human clicks/types/selects
Coordinator sends typed events back to the program
Program reacts by spawning, stopping, restarting, or debugging tasks

The browser is only a view. The Disasmer program owns the state and logic.

Terminology

Operator Panel
  A small immediate-mode UI exposed by a virtual process.

Widget
  A built-in UI element such as a button, textbox, dropdown, progress bar, or task table.

UI Event
  A typed event sent from the coordinator webpage back into the virtual process.

Example use case

A long-running build program can expose:

repo picker
branch dropdown
parallelism input
start/stop buttons
running task table
progress bars
log tail
artifact links
debug/restart/cancel buttons per task

This makes the build system controllable without external YAML, dashboards, or proprietary CI UI.

Rust sketch

use disasmer::prelude::*;

#[disasmer::main]
async fn main() -> Result<()> {
    let panel = ui::panel("Repo builder").await?;

    let mut cfg = BuildConfig {
        repo: None,
        branch: "main".into(),
        parallelism: 4,
    };

    let mut builds = BuildState::load().await?;

    loop {
        let action = panel.draw(|ui| {
            ui.heading("Repo builder");

            cfg.repo = ui.git_repo_picker("Repository", cfg.repo.clone());
            cfg.branch = ui.git_branch_dropdown("Branch", cfg.repo.as_ref(), &cfg.branch);
            cfg.parallelism = ui.number("Parallel builds", cfg.parallelism);

            if ui.button("Start watcher").clicked() {
                ui.emit(Action::Start(cfg.clone()));
            }

            if ui.button("Stop").clicked() {
                ui.emit(Action::Stop);
            }

            ui.progress("Current build", builds.current_progress());
            ui.task_table("Running tasks", builds.running_tasks());
            ui.log_tail("Recent output", builds.log_stream());
        }).await?;

        match action {
            Some(Action::Start(cfg)) => builds.start_watcher(cfg).await?,
            Some(Action::Stop) => builds.stop_watcher().await?,
            Some(Action::RestartTask(id)) => builds.restart_task(id).await?,
            Some(Action::CancelTask(id)) => builds.cancel_task(id).await?,
            None => {}
        }

        builds.poll().await?;
    }
}

What this proves

A Disasmer build system can be expressed as one normal program containing:

build logic
repo watching
branch selection
parallel task spawning
human controls
progress reporting
logs
artifact links
debug hooks

The build loop is just normal program logic. Build tasks are virtual threads.

Task controls

A task table should support simple per-task actions:

Debug
Restart
Cancel
View logs
Open artifacts

Example row:

commit abc123 | linux-x64 | running | 72% | Debug | Restart | Cancel

Debugging behavior

When the virtual process is running:

operator panel is interactive
button clicks become UI events
program handles events normally

When the virtual process is stopped in a debugger:

panel shows last rendered state
program-level UI events are disabled or queued
control-plane actions may remain available

For the MVP, prefer:

running process  -> interactive panel
stopped process  -> read-only panel plus control-plane actions

This avoids executing program code while the debugger says the process is stopped.

MVP widget set

Start with:

text
heading
button
textbox
number input
checkbox
dropdown
progress bar
task table
log tail
artifact link
git repo picker
git branch picker

Avoid initially:

custom HTML
custom JavaScript
complex layout
live charts
drag/drop workflow editors
browser-side business logic

Design rule

The operator panel should stay boring, typed, and immediate-mode.

One source file can define:
  distributed execution
  build orchestration
  environment selection
  filesystem/artifact behavior
  debugging behavior
  human operator UI